-
-
[原创]KCTF 2019 Q2 SU战队 Writeup
-
发表于: 2019-6-25 09:56 5441
-
异常处理,flag为一个地址的字符串形式
两次edit机会,应该是unlink
堆区写上指针,offbyone修改堆头后unlink,之后修改isadmin,拿到leak。。
只edit一次的话,也有思路的,一共两种
1.在拿到unlink之后使用一次edit编辑堆区内容,造两根指针指向堆区同一块fake chunk,然后free、add修改其他正常tcache的next指针和下一堆块的堆头(改大size),造个loop出来,把tcache0x30的count减到ff,然后free下一堆块拿到unsorted bin,再来一发unsorted bin attack干掉chglimit和isadmin 之后就和原来的打法一样 完事儿
2.bss写个假头 bss-heap大小就行
bss的fsb 把one_gadget写栈上
VirtualAlloc把data段的数据整成了函数,整理出来是个异或+方程
输入16字节,前八字节为X,后八字节为Y,方程为X**2-7*Y**2=8(最低位差为8,其余位相同,忽略发生进位的1/32概率)
然而z3是解不出来的
Wolfram计算得到通解公式
又X和Y应为64bits,故n<16 ,算出所有可能解
一个一个试orz。。最后发现是倒数第二组解,再回头异或,得到flag L3mZ2k9aZ0a36DMM
安卓,so,解密发现一个html,内嵌wasm,逆向wasm,解方程,xor
两次单表替换的base64
自写的cxk0壳
通过PEB获得kernel32.dll的地址,然后根据函数名称,从dll中拿到了一堆函数的地址,放在栈内备用,拿到了许多的反调试相关的函数,
大概就是上面这堆,开始了第一次函数调用
kernel32_CreateMutexA,传入的是kernel32_CreateMutexA(0,0,"lyd");感觉是防止多开爆破使用的函数
然后执行kernel32_IsDebuggerPresent,直接干掉,然后紧接着又是CheckRemoteDebuggerPresent
过了连个反调试以后,程序继续读入了自身的Procbase,拿到了蔡徐坤0号的地址,紧接着程序新建了一个名为-的文件,然后继续执行反调试函数,直接干掉
后面程序拿到了SH_LYD和cxk1的addr,其中cxk1内有数据,然后拿到了一个地址4D0824,跟过去看了一下,好像是一个现成的exe文件的魔数。有趣的地方开始了,跟到了解码的地方,smc,xor解密,过循环康康。
解密出了一个exe文件,dump出来,发现内容中存在运行时打印的东西,但是dump有了一些问题,无法运行,先继续跟初始题目文件。最后的调用中,又拿到了一堆函数
加载了user32库,拿到MessageBoxA的地址,直接跳过这个函数,感觉这个函数是在初始化第二个文件的文件头,但是运行后dump再打开,发现依旧不能运行,打开后也有许多相对的地址调用,同时在解密出的文件中,也可以看到遍历调试器的操作,感觉就是在这个里面,这个函数的返回值是即将跳转的地方,然后继续跟进,发现跳到了一个有奇怪指令的cxk0里面。对文件进行分析,大概看到了一些浮点运算和crc32的运算,同时也有输入转到内存的运算
cxk0运行报错,换一下OD查一下是否触发了什么其他地方的函数,怀疑存在动态反调试,将程序带到了另一个地方。
函数内部读取了DOS头和head,然后按页加载了一些东西,同时函数中存在好多个gadget,xxxret这种,依次alloc后将机器码复制进去,两次大循环,依次进行拿到了KERNEL32.dll和USER32.dll,看了下421000,421140,已经被初始化了,里面有好多个地址,跟进去看了一下,发现是dll中的一些函数的地址,每次运行这些都会ret一个不同函数的地址
前面的函数都没有发现什么奇怪的地方,跟到了sub_4CFD74,感觉会有坑
sub_4021C0
sub_4011D0 antidbg
-----------------壳脱好了---------------
输入字节转数据然后sprintf再次转字节,保证输入都是大写,输入的长度必须大于6,然后每两个一组,作为步数
验证crc32 ,初始值0xACF7F7C7,后面都是116轮,0x1B0184E6,0x27D3DD3A
算法链接
要求步数为0,算了一下生成规则,不是常见的规则
算法不会逆。。。感觉要开始猜了
参考Riatre的猜法 https://bbs.pediy.com/thread-248426.htm
随机数生成器是Marsaglia’s MWC algorithm
对于0x0124292B这个seed,周期5亿多
但是有的种子可能回不来
参考一个Paper,https://arxiv.org/pdf/1201.3016.pdf
还是不会
限制输入长度0x20的hex字符串
unhexlify之后和0C1F070A093617000F071A78206E4FE9进行异或
设Semaphore信号上限5,开5个Thread跑enc
enc是查表法实现的CRC
每次都会生成一样的码表 起始地址40402c
魔改crc修正str内容,作为shellcode被执行,此外str还需要经过一个hashcheck
要写一个能弹出Win的shellcode,或者是把错误弹窗的文本改成Win然后跳回去
最后的check逆出来了,有很多的解
需要提前写一些可能的shellcode,看看哪个能过校验
这个。。。实现方式有点多啊。。。
mov [ebp], 'Win'; push 0 push ebp push ebp jmp刚好,但是过不了check
mov Text,'\x00niW';push ...;ret;
\xc7\x05\x80\x3e\x40\x00\x00\x6e\x69\x57\xe9 \x68\x5B\x12\x40\x00 \xC3 16bytes (空格隔开的可以改成其他地址)
布星啊。。。
题目判犯规了,GG
利用多线程去leak出libc地址,具体就是利用250-255之间的线程会使得idx加一最后回绕导致0被free的原理leak出地址。接着直接double free写free_hook为system即可。
Windows逆向,获取输入的Flag,长度6到145
形式为part1XXXXpart2,part2要全是数字
然后转成3个大数结构体,part1 256进制,part2 10进制,还有一个它给的十进制数,进404270这个函数Check
3个数字转换成256进制大整数结构体
part1 256进制 -> a,part2 十进制 = b
a加了0xA
保存了一个数组,
然后算了一个
m就是上面那个7f……
然后用a减了一下x,y=a-x,需要这个y是个零,就是a==x
先手动过掉,看看后面干啥了
a的字符集范围是A到Z
a的最后一字节加了0xA
翻过来读了a的每一个字节,做了如下的一个映射
把这个数字拿了出来,然后循环这样乘
实际上这个东西就是在算一个25进制数
a长度小于等于10个字节
然后要求这个x没有小于0x1000的素因子
这个也可以跳掉
然后check了前面那个x
求了这个x对m-1的逆元gg
求了powmod(a_num, gg, m),要求这个等于b_num
求了powmod(b_num, x, m),要求这个等于a_num
这两个只要一个成立。。。
这两个奇怪的num是随机选的,所以应该对4个数都成立,需要找一找
那么就是解离散对数了,上个Sage
有一个东西叫Discrete log lambda,如果知道离散对数的范围,可以以O(根号(max-min))的复杂度算出来
因为是25进制的最多10位数,所以范围是有的
大概几十秒,算出来了
转成25进制字符串
加那个0xA
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)