开启WebDAV服务的IIS6.0存在缓冲区溢出漏洞可以任意代码执行,目前针对 Windows Server 2003 R2 可以稳定利用。在WebDAV服务的ScStoragePathFromUrl函数存在缓冲区溢出漏洞,恶意访问者通过构造以 If:<http:// 开始的较长header头的PROPFIND请求执行任意代码。
windbg:用于附加w3wp进程进行动态调试
IDA:用于对httpext.dll进行静态分析
操作机:windows 2003
本次测试的系统环境是Windows Server 2003,首先需要开启WebDVA服务扩展
然后打开服务配置窗口,并启用WebClient服务
运行Process Explorer来监视当前进程
然后运行exp(exp在后面进行分析)
通过构造以 If:<http:// 开始的较长header头的PROPFIND请求打开了计算器
可以看到calc.exe进程已经创建,说明漏洞触发成功,用户名是NetWork Service,所以没有在桌面上直接弹出计算器。
为了后续使用Win调试W3wp进程进行调试,现在需要把calc.exe和python.exe进程结束掉
使用IDA打开httpext.dll进行分析,在左侧函数窗口找到ScStoragePathFromUrl函数,然后看一下伪代码,看到qmencpy函数,参数v35表示复制的目的地址
查看对V35变量的交叉引用
可以看到v35由a3赋值,所以向目标地址复制这个操作实际是复制到a3所指向的地址上。而向上看Scstoragepathfromurl的函数声明,可以看出a3就是Scstoragepathfromurl函数的第三个参数。
漏洞源于memcpy操作,在复制时没有对复制的大小进行检查,复制的目的地址为a3,也就是调用该函数的上层函数传入的变量会被溢出。
漏洞调试思路是一步一步逆向分析,从ScStoragePathFromUrl 函数到它的上层函数调用情况去分析
打开windbg,附加w3wp.exe 进程,首先要在Scstoragepathfromurl 函数开始的地方和v21=v35的地方下断点
在WinDbg中输入bp httpext!ScStoragePathFromUrl和bp httpext!ScStoragePathFromUrl+0x31e
输入bl查看下断点的情况
之后输入g让w3wp 进程继续运行,然后像之前那样打开exp,程序断在了ScStoragePathFromUrl函数的入口处
输入g两次后来到第二个断点673f6f99 处,即第一个断点被中断了两次,说明在第一次被中断时,程序并没有进入memcpy 操作.
在第二次中断时才进入memcpy 操作。继续按F10来单步执行到673f6faf 处,这里就是执行第一个memcpy操作的地址
然后输入dc esi lecx来查看要复制的信息
然后继续按F10单步执行到673f6fdb 处,输入dc esi lecx和dd edi lecx分别来查看要复制的内容以及复制目的地址范围。
可以看到复制的内容为/aaa ... ,目的地址范围为0x6af828-0x6af948。
继续输入g来执行到下一次调用Scstoragepathfromurl 函数的开始位置,即673f6c7b处,然后输入g 来到673f6f99 后
继续按F10 单步执行到 673f6fdb 处。这时输入dc esi lecx来查看要复制的内容,再输入dd edi lecx来查看复制目的地址范围
从结果中我们可以看到这次esi 指向的数据为/bbb ... ,目的地址范围为0x680312e4- 0x680318d4
同样继续输入g后在ScStoragePathFromUrl 函数中断下来,再次输入g,这次没有在673f6f99 处中断,而仍然是在ScStoragePathFromUrl函数中断下来,所以继续输入g后在673f6f99 处中断下来。
接下来按F10 单步执行到673f6fdb 处,输入dc esi lecx 来查看第三次复制的内容, 输入dd edi lecx 来查看这次复制的目的地址范围
从结果中可以看出这一次复制的目的地址为0x006afad8-0x006afbf8
继续输入g ,程序在ScStoragePathFromUrl 函数处(673f6c7b)中断下来,之后按F10一直单步执行,注意到 call ScStripAndCheckHttpPrefix 函数处
在这里按F11单步进入,该函数的功能是检查url 的合法性,如果使用ida pro 来查看ScStripAndCheckHttpPrefix 函数
可以发现674035f3 处有一个call dword ptr [eax+24h], 该处调用了IEcb 对象的0x24 偏移处指向的虚函数。
继续我们的调试,进入该函数后,按F10来单步执行到 call dword ptr [eax+24h] 处(674035f3),继续按F11进入这个虚函数调用
可以看到IEcb 对象的0x24 指向 68016082的位置,ecx 赋值给esp 以此来控制栈空间,当执行完ret 返回时,eip会被引导到了ROP 阶段,以此来绕过DEP
继续F10单步执行,在单步的过程中可以发现有一连串由POP、RET等指令组成的ROP 链
一直按F10,执行完ROP 后正式来到了shellcode 处(68031460)
从以上的调试中可以发现,POC 通过覆盖IEcb 对象的0x24 偏移处的虚函数地址以此来控制eip ,进一步的使用ROP 来引导到shellcode
因为此漏洞为栈溢出漏洞,所以还需要在ScStoragePathFromUrl 函数的上一层函数调用处去观察,其中具体的溢出覆盖过程还要进一步分析。
在IDA Pro中查看ScStripAndCheckHttpPrefix() 函数发现IEcb 对象为该函数的第一个参数,而该对象同样是ScStripAndCheckHttpPrefix() 的上层函数ScStoragePathFromUrl() 函数的第一个参数。
下面我们要通过栈回溯找到调用ScStoragePathFromUrl 函数的上层函数,首先我们先依次点击WinDbg菜单栏的和。然后像之前一样在命令提示符窗口依次输入
接下来再用WinDbg 重新附加w3wp 进程,并在命令行内输入下断点,然后输入运行
然后运行exp
发送数据触发漏洞,进程会在ScStoragePathFromUrl 函数入口处中断,这时我们输入kb来进行栈回溯,查看是哪个函数调用了ScStoragePathFromUrl函数
从结果中我们可以看出 httpext!HrCheckIfHeader+0x124 处调用了ScStoragepathfromurl 函数。
使用IDA Pro 打开 httpext!HrCheckIfHeade r函数,可以看到在函数内共有两处调用了ScStoragePathFromUrl 函数,ScStoragepathfromurl 函数的第三个参数str 为栈上的单元,可以通过查看ebp-328 地址开始的内容来得到str 的内容。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)