关于MS08-067的一点细节 's

admin 2017年4月29日06:38:55评论320 views字数 3566阅读11分53秒阅读模式
摘要

作者:刺这个漏洞就不介绍了,已经沸沸扬扬了。首先milw0rm上那个exp的编译问题,作者在里面放的些小trick很容易fix,主要麻烦的是midl编译idl文件后,在VC6环境下编译可能出现rcpt库的错误。可能是SDK的版本导致的,云舒用最新的SDK(好像是2008?)编译成功了。

其次是触发问题,什么权限都不需要,空连接后就能触发。

作者:

这个漏洞就不介绍了,已经沸沸扬扬了。

首先milw0rm上那个exp的编译问题,作者在里面放的些小trick很容易fix,主要麻烦的是midl编译idl文件后,在VC6环境下编译可能出现rcpt库的错误。可能是SDK的版本导致的,云舒用最新的SDK(好像是2008?)编译成功了。

其次是触发问题,什么权限都不需要,空连接后就能触发。

ncacn_np:////192.168.152.101[//pipe//srvsvc] 直接请求就可以了。

问题还是出在 NetpwPathCanonicalize() 的第二个参数,这个漏洞非常奇特。

首先这个参数的长度不能超过 0x207(unicode)

71BB58F6    81FF 07020000   CMP EDI,207
71BB58FC ^ 0F87 F447FFFF   JA NETAPI32.71BAA0F6   // 如果大于了就直接函数返回了
71BB5902 ^ E9 1247FFFF     JMP NETAPI32.71BAA019

然后会走到一个wcscat的地方,这里没有问题,因为空间是足够的
71BAA019    8D85 E8FBFFFF   LEA EAX,DWORD PTR SS:[EBP-418]
71BAA01F    53              PUSH EBX
71BAA020    50              PUSH EAX
71BAA021    FF15 9810BA71   CALL DWORD PTR DS:[<&msvcrt.wcscat>]     ; msvcrt.wcscat

继续往下会把所有的 “/” 替换为 “/” 这里也无关紧要

然后就走到出问题的函数

71BAA05A    8D85 E8FBFFFF   LEA EAX,DWORD PTR SS:[EBP-418]
71BAA060    50              PUSH EAX
71BAA061    E8 AB020000     CALL NETAPI32.71BAA311

跟进去后很复杂,可以参考下这里的伪代码
http://www.phreedom.org/blog/2008/decompiling-ms08-067/

估计很多人在这里绕晕了,我跟了一晚上,总算搞明白了一点。

首先是为什么老是会上溢的问题,这个就是这个漏洞的原因所在了。cocoruder在blog上引用了这么一段话:
There are two copies, the first copy is OK, but when there is another “../”, it will lead to start the another copy (repeat the first copy codes), the second copy firstly does not calculate the base pointer correctly (firstly it is basePointer-2, so the ‘JZ’ checking in the loop of searching character ‘/’ will never come ture), that lead to get an unexpected stack pointer which is below the base pointer, after the wrong calculation, it starts the second copy and uses the unexpected pointer as the first parameter of function “wcscpy()”, therefore, the wrong-calculation memory will be rewritten. The EIP will be controlled in the main function, probably.

实际上就是在找目录的时候,

/x/../yyyyyyyyyyyyy

会拷贝为 /yyyyyyyyyyyy   中间的 /x/.. 就没有了。

然后程序会往栈的上面去找 “/” 的存在,但是往往栈低址里没有 “/”的存在,所以就找完了整个栈,上溢了。

很多同学估计都卡在这个地方了。

bp 0x71baa398 first copy 第一次拷贝,这里没问题

71BCDC12    8D46 04         LEA EAX,DWORD PTR DS:[ESI+4]
71BCDC15    8BCE            MOV ECX,ESI
71BCDC17    50              PUSH EAX
71BCDC18    51              PUSH ECX
71BCDC19    FF15 2C10BA71   CALL DWORD PTR DS:[<&msvcrt.wcscpy>]     ; msvcrt.wcscpy

此时 si = 0x2e 然后前后判断是否是 /../

71BAA363    8D46 FE         LEA EAX,DWORD PTR DS:[ESI-2]
71BAA366    3BD8            CMP EBX,EAX
71BAA368    0F85 50380200   JNZ NETAPI32.71BCDBBE
71BAA36E    8D46 02         LEA EAX,DWORD PTR DS:[ESI+2]
71BAA371    66:8B10         MOV DX,WORD PTR DS:[EAX]
71BAA374    66:83FA 2E      CMP DX,2E
71BAA378    0F85 8A380200   JNZ NETAPI32.71BCDC08
71BAA37E    8D46 04         LEA EAX,DWORD PTR DS:[ESI+4]
71BAA381    66:8B18         MOV BX,WORD PTR DS:[EAX]
71BAA384    66:83FB 5C      CMP BX,5C

second copy 第二个拷贝,把中间的 /x/.. 弄没了
71BAA388   /0F85 3D380200   JNZ NETAPI32.71BCDBCB
71BAA38E   |85FF            TEST EDI,EDI
71BAA390   |0F84 0B630000   JE NETAPI32.71BB06A1
71BAA396   |50              PUSH EAX
71BAA397   |57              PUSH EDI
71BAA398   |FF15 2C10BA71   CALL DWORD PTR DS:[<&msvcrt.wcscpy>]     ; msvcrt.wcscpy

漏洞代码就是下面这个:
71BCDBDE    8D47 FE         LEA EAX,DWORD PTR DS:[EDI-2]
71BCDBE1    66:8338 5C      CMP WORD PTR DS:[EAX],5C
71BCDBE5   /75 18           JNZ SHORT NETAPI32.71BCDBFF
71BCDBE7   |66:8B38         MOV DI,WORD PTR DS:[EAX]
71BCDBEA   |8B4D 08         MOV ECX,DWORD PTR SS:[EBP+8]
71BCDBED   |66:83EF 5C      SUB DI,5C
71BCDBF1   |66:F7DF         NEG DI
71BCDBF4   |1BFF            SBB EDI,EDI
71BCDBF6   |F7D7            NOT EDI
71BCDBF8   |23F8            AND EDI,EAX
71BCDBFA ^|E9 55C7FDFF     JMP NETAPI32.71BAA354
71BCDBFF   /3B45 08         CMP EAX,DWORD PTR SS:[EBP+8]
71BCDC02 ^ 74 E3           JE SHORT NETAPI32.71BCDBE7
71BCDC04    48              DEC EAX
71BCDC05    48              DEC EAX
71BCDC06 ^ EB D9           JMP SHORT NETAPI32.71BCDBE1

试图往栈低址去寻找”/”,结果错误计算了开始的地址,导致根本找不到。

按照cocoruder的说法,在计算错误后,有机会第二次执行第二个 wcscpy ,从而覆盖那个错误计算出的地址。

不过我没找到能再次执行拷贝的方法,我的整个栈低址几乎就是一片0,每次都上溢了.

有的机器里也许能够找到那个“/”吧,或者存在一种能够稳定利用的方法。

使用 //pipe/browser 好像也有机会控制EIP,可以继续搞搞。

瞎扯到这里,不说了,大家再一起继续郁闷吧。

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2017年4月29日06:38:55
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   关于MS08-067的一点细节 'shttp://cn-sec.com/archives/45722.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息