前言
大家好,上一篇文章小弟发表/解了一个简单的pwn,剩下的2个level也已经有小伙伴帮忙解题了,感觉大家好像都挺喜欢该类型的。这次小弟打算开始写一个新的系列文章,如果写的不好,或者有什么意见、建议欢迎各位大佬点评。本篇文章为入门篇故仅提供了8个level的栈溢出练习实验,均未开启任何保护的。后面的文章会进一步升级。
下载、实验环境
实验代码下载:https://pan.baidu.com/s/16bpbJoI5qdWctH3n6owqnw
实验环境:ubuntu 4.15
辅助插件:Peda 下载地址:https://github.com/longld/peda
开始实验
本次实验环境分别为 level0-level7 均提供了源码和编译好的程序
level0
我们先查看一下c源码:
通过源码可以看出存在明显的栈溢出漏洞,我们先来运行看看,
通过简单的输入12个A和6个6,可以看到我们还是没有成功,
当我们输入70个‘A’时,发现程序弹出 我们已经能成功更改‘modified’变量了。
level1
查看源码:
下面我们运行一个这个程序,当我们不带任何字符时,程序给出
说明我们还在“argc”代码块。
当我们运行并带入20个“A”时,程序给出
说明我们已经来到了“modified”函数出,但是我们还没到溢出点。
当我们运行并带入70个“A”时,程序给出
说明我们已经来到了“modified”函数出,并且我们也已经找到到溢出点。
(此处的0x41414141 为ascii码的 大写“A”)
通过上面简单的调试,我们就知道该怎么做了,如图:
level2
查看源码:
下面我们运行一个这个程序,当我们不带任何字符时,程序给出
请让我们设置 ‘GREENIE’的环境变量,我们搜索一下看看本系统有没有,如图:
可以看到在该系统中并没有设置定义,下面我们就设置一下看看
本次就写了一个python,运行
level3
我们查看一下源码:
下面我们运行一下这个程序看看,
通过输入70个“A”,可以发现程序接收了我们的输入,并成功控制了内存地址指针,但是我们还是在main下的‘fp’函数判断处,通过源代码我们知道有个‘win’函数,我们查看一下
通过 objdump 搜索到了,该函数的地址 “0x08048424”
(这里小伙伴们也可以使用IDA搜索)
下面我们就直接利用了
如图,我们已经成功控制内存地址跳转到win函数并执行。
level4
我们查看一下源码:
可以看到源码里的‘win’函数被定义了,但是没有被程序直接调用,该等级还是一样,我们要控制内存指针到win函数运行。
下面我们开始如何判断偏移量,需要借助 gdb工具的 peda插件,能帮助我们节省很多工作
1.用gdb加载该level,并使用 “pattern_create” 来生产80个规律且均不一样的字符
2.使用 run 运行该程序,并输入刚刚生产的字符,回车
3.eip成功被改为 0x41344141
4.通过 “pattern_offset” 得出偏移量为 76个字节
最后我们确认一下该偏移量是否正确,如图:
可以看到溢出位是正确的,下面我们跟上面一样继续搜索 ‘win’函数的地址
最后利用成功:
level5
我们查看一下源码:
下面老规矩,我们来确定偏移量,操作如图:
这里为什么要生产200个字符哪?因为我们要往内写入shellcode,所以我们要判断一下大概能写入多少字节,防止shellcode过大,无法放入的问题,
如图:
可以看到刚刚生产的200个字符,覆盖掉偏移量后剩下的字符被成功放入,其实地址从 0xffffd0c8 – 0xffffd050 = 0x78 转化为十进制刚刚好是120个字节,故我们能写入一些正常的shellcode(msf生成的大部分为100个字节左右),
下一步我们就是直接编写exploit的了,如图:
76个‘A’后面跟的是ESP的地址上图有,后面带入10个‘nop’空指令(防止我们的shellcode被破坏),最后为shellcode代码 输出到s5.txt文件内,(该段shellcode代码为在本机开启1337端口等待链接 (其他更多功能shellcode,请移步https://www.exploit-db.com/shellcodes))
下面我们让程序来加载s5.txt运行
我们确认一下shellcode是否成功被执行,查看一下:
本机1337端口成功被打开并等待链接,我们使用nc链接并成功拿到shell
level6
我们查看一下源码:
下面老规矩,我们来确定偏移量,操作如图:
偏移量为80,下面我们来确认一下偏移量是否正确,
通过测试可以看到偏移量是对的,我们也能成功控制ESP,下面我们来确认查看写入内存空间的大小,如图:
可以看到一大堆,那写shellcode就够了,小弟懒就不去算了。。。
下面重点来了,这里可以看到我们的源代码处要求我们在0xbf00000内找ret,但是我们这里的环境没有这个地址,那怎么办呢?各位请注意,它不是要‘ret’吗?那我们就找一下本地系统的ret给它啊,反正我们不是也能控制指令吗?那么如图:
可以看到我们找到很多,这里就随便挑一个吧,所以我们这里的exp是这样的:
echo python -c "print 'A'*80+'x5fx83x04x08'+'x44xd0xffxff'+'x90'*10+'x6ax66x58x6ax01x5bx31xf6x56x53x6ax02x89xe1xcdx80x5fx97x93xb0x66x56x66x68x05x39x66x53x89xe1x6ax10x51x57x89xe1xcdx80xb0x66xb3x04x56x57x89xe1xcdx80xb0x66x43x56x56x57x89xe1xcdx80x59x59xb1x02x93xb0x3fxcdx80x49x79xf9xb0x0bx68x2fx2fx73x68x68x2fx62x69x6ex89xe3x41x89xcaxcdx80'"
> s6.txt
我们执行后,成功拿到shell
level7
我们先查看一下源码
下面老规矩,我们来确定偏移量,操作如图:
‘ret’地址查找
下面我们来写个规范一点exploit脚本,如图:
(注:小弟在写这个exp的时候虚拟机重启一下,故 esp地址发生的改变,只需要获取新地址修改一下即可。shellcode为上面那个)
下面运行脚本,加载执行文件,如图:
成功拿到shell。
最后再说一下,本次文章中的前面几个level,均未开启任何保护,如图:
level7:
level1:
结语
通过本章的学习,相信小伙伴们也都能理解什么叫栈溢出,栈溢出是怎么调试操作的,希望各位小伙伴们也在自己环境中调试实验,希望小伙伴们都能理解,因为后面的文章难度会加高。最后祝您及家人生活愉快,新春快乐!! :)