cyclechaser

Posted by Humb1e on 2023-03-06
Estimated Reading Time 2 Minutes
Words 664 In Total
Viewed Times

KalmarCTF Re cyclechaser

在void爷的帮助下做出来的

image-20230306203848420

这个程序是跑在靶机的终端上的,题目让我们自己本地先跑通再去nc

但是这道题的libc版本是2.34太高了,没法运行和动调,只能纯静态分析

上面代码的逻辑就是生成了一个种子,并且打印了种子的值

image-20230306210636966

之后的代码就用到了很多断言(用于处理错误,并且执行一些func),首先malloc了一个ptr

这个ptr很重要

ptr读取了stream也就是flag.txt里的72个字符

然后利用断言进行了一些判断(这些都不重要)

image-20230306211026958

之后的内容从stdin读入了16393个数值放入了input

并且calloc了v14(calloc和malloc的区别是calloc会把初值全部赋值为0)

我们能看到在循环次数在0x1FFFF之前v4的值是v12中读取的

然而我们交叉引用找一下v12发现v12是malloc出来的,并没有初值

也就是说v12的值是随机的

我们进入step函数查看

image-20230306211323640

step读入了两个参数,一个是input,另一个就是0x4009也就是input的长度16393

里面有两个循环,这两个细究起来很有意思,是算法里的大整数的操作

我们可以看到v9是存储v8+3*input[i]

最后把v9赋值给了input[i],把v9>>8放到了v8

这时候我们很容易把v8类比到汇编里的CF,v8就是存储了每次对input操作后溢出的值

看下面的代码,就是把input[0]的最后一位作为程序的返回值,并且把input[i+1]的最后一位放到了input[i]的最高位

所以说,这就是一个大整数运算

我们可以把input视为在内存中连续不间断的位(事实上本来就是连续的,只不过不是按高位到低位有序存储的)

image-20230306212636920

这样之后我们就明白了,这个step的操作就是把input最低位拿出来,如果是1那么就进行+1乘3的操作

然后每一次都会把input整体右移一位,也就是/2

这样的逻辑就非常明显了

image-20230306212903511

看之前的函数,v14是calloc出来的,初始值都是0,所以也就是说我们如果能使我们输进去的input做到前0x1FFF位都是0,之后的位数都是1那么他答应出来的v14的值就是flag

好了,这样就可以写脚本了。

1
2
3
4
5
from pwn import *
r=remote("3.123.91.129",13339)
pd='\x00'*0x4000+'\xFF'*9
r.sendline(pd)
r.interactive()

这样就直接给出flag的十六进制了


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !