brain fuck
0x01
这题使用了六个个运算符来修改p指针以及所指的内容
初始位置p->0x0804A0A0(tape),这样我们可以根据前面的运算符来修改p指向的地址,如将p指向got,然后将got表内地址篡改到我们想要的地址,就可以控制程序流的执行。
0x02 leak
利用”<”、”>”运算符将p移到got表,利用“.”运算符将got表内地址读取,即可完成地址泄露。
0x03 利用方法
刚开始我的想法是将putchar的got读出来后,篡改putchar的got为system的地址,然而后面发现putchar的参数其实是一个字符而不是地址。想法一失败
然后我想到的是选择strlen()作为got中修改的对象。
然后就是修改了一个字节以后这个循环就进行不下去了,错误推出
只好去网上找前辈的方案:rickgrey
发现原来是这样利用的:
将got修改成下面的样子:
这样在我们就改好got表时,使用“.”就可以将控制流牵引到main程序开始,由于got表内已经设置好了地址,在调用memset时就会调用gets()函数,然后我们输入‘/bin/sh’,就会将这串字符存到栈中,随后调用fgets()时,实际上是调用system,参数就是我们刚刚输入的字符串的地址。
这里是exp
md5 calculator
0x01
刚开始硬是没找出来溢出点。。。倒是去了解了一下MD5和BASE64,还是去前一题前辈的博客去取经了
rickgrey
找到了溢出点:可以输入1024个BASE64字符,但是给decode后存储的字符空间只有0x200=512,1024个BASE64字符最多可以解码成1024/4*3 = 738 个字符,所以存在溢出。
|
|
但是问题来了,process_hash()函数的栈上有canary,想要覆盖返回地址就需要把canary的值找到。
然后在my_hash()函数中找到了canary在验证码中也被使用,也就是验证码中有canary的信息,怎么提取是一个问题,
还是学前辈的姿势:my_hash()函数中使用了8次rand()函数,并取其中七个值和canary一起来构建验证码。
然后就是前面的srand()函数使用的随机数种子是系统的时间。并且在第一次获取后没有改变,也就是说种子一直没有改变。
考虑到这个,由于产生的伪随机数,只要种子不变产生的随机数序列是不变的。这样我们可以通过获取系统时间,然后产生8个随机数,
将canary反推出来。这样就可以覆盖栈上的返回地址了,还可以设置参数。
0x02 leak
这里我们不需要leak地址,因为函数中已经调用了system,所以我们的返回地址可以设置为
system.plt、或者是main()函数中的call system的地址。
0x03 exploit
反推canary源码:
设置栈分布:
playload
|
|
另外一个有趣的东西是:如何获取服务器的时间,题目中给出的提示是
hint : this service shares the same machine with pwnable.kr web service
那么很自然的或者说是正统的做法是web获取服务器的时间,然后用这个时间来复现canary,但是时间确实是不准的
即使加入一个随机的延迟或者说超前都是很看概率的问题。最后就是将exp上传至服务器本地(使用其他题的账户),然后运行
我一直觉得这样是不行的原因是之前有个瓜皮传了一个pwn.py到/tmp/文件夹,然后在服务器上就不能使用pwntools,所以很难受。