pwn1:
- 先file查看文件
- 观察到是32位文件后拖到ida中,找到main函数,发现是gets函数导致的溢出。
- 关于gets函数,gets函数经常和puts函数配对使用,puts函数用于显示字符串并自动在字符串后面添加一个换行符,gets函数读取一行数据遇到换行符就返回,但是gets函数有一个缺陷:它不会检查地址能否装下输入行。gets函数在输入的字符串过长,会导致缓冲区溢出,多余的字符超过了指定目标,gets函数就会访问未被分配的内存空间。
- 然后查看gets(&s)的偏移
所以偏移为3b-10=2b - 我们可以发现print_flag函数就在下面,所以当我们填充2b个字符再继续输入字符,那么剩下的字符就会到v5这个空间里面,而当我们使v5这个空间的东西为0xDEA110C8时,我们就可以解出这个题目了flag将会输出。
- 然后我们尝试着去虚拟机里面调试运行一下,看一看程序的运行情况。
- 我们在ida分析程序也可以了解到需要向文件发送3次数据,第三次则是需要先覆盖再输入0xDEA110C8
现在我们可以写exp了~
- 然后再运行exp.py
pwn2
- 一样先查看文件,
- 然后根据她是32位的拉进ida,分析一下函数
- 见gets函数就比较敏感,可以看见gets函数和后面的函数取的都是s的地址,查看s的偏移。
s的偏移为27+4=31 - 然后查看一下select_func函数
- src取的是s的地址,它里面是31位,但是dest的偏移却是30(2A-C),函数里面的strncmp函数就是把0x1F(31)的数据从src复制到dest,所以此时就发生了溢出。发生溢出以后多余的字符会覆盖掉ret,导致最后弹回eip的是多出来的后面的内容,我们利用这个便可以去到我们想要访问的地址。
- 我们找到一个后门函数,print_flag,然后我们只要让函数跳到这里,我们便可以得到flag了。
下面是exp
'\xd8’我之前一直不理解,其实就是上面的地址0x000006d8的简写,由于前面的000006都是一样的因此就省略了,如果不省略,反而容易出错些。
pwn3
- 第一步虚拟机file
- checksec函数pwn3
当PIE开启就说明地址随机化
拉进32位ida - 首先是函数
asm()函数接收一个字符串作为参数,得到汇编码的机器代码。shellcraft()是shellcode的模块,包括一些生成shellcode的函数,asm(shellcraft.sh())可以用于作为执行/bin/sh的shellcode。 - s的偏移为12a+4,当我们在s的空间里面填充大于12a+4覆盖掉ret,eip就会返回到我们想到的地址。
- 那我们如何获得s的地址呢,虽然函数开启了地址随机化,但是在上面的函数print里面外面就可以知道s的地址了,因为它自己输出了函数的地址,利用recv得到函数输出的值即s的地址,将字符转化为16 进制。首先我们覆盖了s,然后我们让它返回到s+4的地方也就是12a+8,在上面的图上可以看见有一个end of stack variables,也就是返回到了那里,然后asm执行了/bin/sh,获得了shell。
- exp如下
- 得到shell,见下。
pwn4
- 同理file,shecksec,见下。
- 开启nx,说明栈中数据没有执行权限,不能像以前一样直接搞到eip上,跳到我们要去的地方,一般情况需要利用到rop,(但是这次没有哦),拉进ida
- 关于这道题,反正我就知道gets不是个什么好东西,我写了一个很傻的exp,然后意外输出了shell一样的东西,但是我得不到flag,我以为我对了,好吧~错觉。。。。。
然后我看了别的师兄的wp,还是不太懂,但是基本有一个模板在哪那里,我就查了好久。。。。。。终于了解到了。 - 首先,补充一下os.system()函数,这是一个Python的基本函数,它的作用是将字符串转化为命令在服务器上执行,这个函数常常用于得到shell,遇见’Enter the arguments you would like to pass to ls:'以后,我们输入了s,而system刚好也就是取的s的内存里的数据。
- 然后,我们需要了解到在Linux函数里面的命令&&和||,&&一般是连接两个命令的,而且必须是左边的执行成功了后面的才能执行后面的,而||就是必须要左边的执行不了才能执行后面的。
- 好了,现在就来说说,怎么写这一题,我们需要执行命令&& cat flag.txt或者xx||cat flag.txt,前者就是在上面的命令(也就是程序本来自己执行的,当然可以顺利执行)所以位于&& 后面的cat flag.txt自然然就执行了,而后者,至于xx是什么,我试了什么cc啊或者dd啊,发现他都可以得到flag,拿到shell,然后我就想那既然如此,当 || 前面是返回的是1(即 || 前面顺利执行时,那是不是cat flag就执行不了呢?是的,我创了一个文件【1.txt】里面只有一个数字1,文件顺利执行,cat就执行不了!耶!说明思路对了。
- 第一种方案:
exp,如下,我甚至连偏移都没填充,只是告诉系统我要在什么时候给你数据,给你命令。
终端显示如下:
- 第二种方案,我将我要执行的&& cat flag.txt直接写进去,记得在后面加上’\n’,终端遇到它直接就执行了。
exp如下:
终端显示:
pwn5
同理:
- 以前我一直没有注意过什么静态链接 什么的(statically linked),同样在这题里面我们可以看见开启了nx,栈上数据没有执行权限,值得注意的是上面所有的题是动态链接哦~
关于静态链接的ROP,直接用ROPgadget --binary xx --ropchain 就可以生成rop链了。
- exp如下:
运行结果: