Skip to content

Commit

Permalink
add checker.py script for finding accessible named pipe
Browse files Browse the repository at this point in the history
  • Loading branch information
worawit committed Jul 11, 2017
1 parent af235b6 commit 44d8dcc
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 17 deletions.
87 changes: 87 additions & 0 deletions checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from mysmb import MYSMB
from impacket import smb, smbconnection, nt_errors
from impacket.uuid import uuidtup_to_bin
from impacket.dcerpc.v5.rpcrt import DCERPCException
from struct import pack
import sys

'''
Script for
- check target if MS17-010 is patched or not.
- find accessible named pipe
'''

USERNAME = ''
PASSWORD = ''

NDR64Syntax = ('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0')

MSRPC_UUID_BROWSER = uuidtup_to_bin(('6BFFD098-A112-3610-9833-012892020162','0.0'))
MSRPC_UUID_SPOOLSS = uuidtup_to_bin(('12345678-1234-ABCD-EF00-0123456789AB','1.0'))
MSRPC_UUID_NETLOGON = uuidtup_to_bin(('12345678-1234-ABCD-EF00-01234567CFFB','1.0'))
MSRPC_UUID_LSARPC = uuidtup_to_bin(('12345778-1234-ABCD-EF00-0123456789AB','0.0'))
MSRPC_UUID_SAMR = uuidtup_to_bin(('12345778-1234-ABCD-EF00-0123456789AC','1.0'))

pipes = {
'browser' : MSRPC_UUID_BROWSER,
'spoolss' : MSRPC_UUID_SPOOLSS,
'netlogon' : MSRPC_UUID_NETLOGON,
'lsarpc' : MSRPC_UUID_LSARPC,
'samr' : MSRPC_UUID_SAMR,
}


if len(sys.argv) != 2:
print("{} <ip>".format(sys.argv[0]))
sys.exit(1)

target = sys.argv[1]

conn = MYSMB(target)
try:
conn.login(USERNAME, PASSWORD)
except smb.SessionError, e:
print('Login failed: ' + nt_errors.ERROR_MESSAGES[e.error_code][0])
sys.exit()
finally:
print('Target OS: ' + conn.get_server_os())

tid = conn.tree_connect_andx('\\\\'+target+'\\'+'IPC$')
conn.set_default_tid(tid)


# test if target is vulnerable
TRANS_PEEK_NMPIPE = 0x23
recvPkt = conn.send_trans(pack('<H', TRANS_PEEK_NMPIPE), maxParameterCount=0xffff, maxDataCount=0x800)
status = recvPkt.getNTStatus()
if status == 0xC0000205: # STATUS_INSUFF_SERVER_RESOURCES
print('The target is not patched')
else:
print('The target is patched')
sys.exit()


print('')
print('=== Testing named pipes ===')
for pipe_name, pipe_uuid in pipes.items():
try:
dce = conn.get_dce_rpc(pipe_name)
dce.connect()
try:
dce.bind(pipe_uuid, transfer_syntax=NDR64Syntax)
print('{}: Ok (64 bit)'.format(pipe_name))
except DCERPCException, e:
if 'transfer_syntaxes_not_supported' in str(e):
print('{}: Ok (32 bit)'.format(pipe_name))
else:
print('{}: Ok ({})'.format(pipe_name, str(e)))
dce.disconnect()
except smb.SessionError, e:
print('{}: {}'.format(pipe_name, nt_errors.ERROR_MESSAGES[e.error_code][0]))
except smbconnection.SessionError, e:
print('{}: {}'.format(pipe_name, nt_errors.ERROR_MESSAGES[e.error][0]))


conn.disconnect_tree(tid)
conn.logoff()
conn.get_socket().close()
49 changes: 32 additions & 17 deletions mysmb.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# impacket SMB extension for MS17-010 exploit.
# this file contains only valid SMB packet format operation.
from impacket import smb
from impacket import smb, smbconnection
from impacket.dcerpc.v5 import transport
from struct import pack
import os
import random
Expand Down Expand Up @@ -113,11 +114,15 @@ def __init__(self, remote_host, use_ntlmv2=True, timeout=8):
self._pkt_flags2 = 0
self._last_tid = 0 # last tid from connect_tree()
self._last_fid = 0 # last fid from nt_create_andx()
self._smbConn = None
smb.SMB.__init__(self, remote_host, remote_host, timeout=timeout)

def set_pid(self, pid):
self._pid = pid

def get_pid(self):
return self._pid

def set_last_mid(self, mid):
self._last_mid = mid

Expand All @@ -127,40 +132,50 @@ def next_mid(self):
self._last_mid += 0x120
return self._last_mid

def get_smbconnection(self):
if self._smbConn is None:
self.smbConn = smbconnection.SMBConnection(self.get_remote_host(), self.get_remote_host(), existingConnection=self, manualNegotiate=True)
return self.smbConn

def get_dce_rpc(self, named_pipe):
smbConn = self.get_smbconnection()
rpctransport = transport.SMBTransport(self.get_remote_host(), self.get_remote_host(), filename='\\'+named_pipe, smb_connection=smbConn)
return rpctransport.get_dce_rpc()

# override SMB.neg_session() to allow forcing ntlm authentication
def neg_session(self, extended_security=True, negPacket=None):
smb.SMB.neg_session(self, extended_security=self.__use_ntlmv2, negPacket=negPacket)

# to use any login method, SMB must not be used from multiple thread
def login(self, user, password, domain='', lmhash='', nthash='', ntlm_fallback=True, maxBufferSize=None):
_setup_login_packet_hook(maxBufferSize)
smb.SMB.login(self, user, password, domain, lmhash, nthash, ntlm_fallback)

def login_standard(self, user, password, domain='', lmhash='', nthash='', maxBufferSize=None):
_setup_login_packet_hook(maxBufferSize)
smb.SMB.login_standard(self, user, password, domain, lmhash, nthash)

def login_extended(self, user, password, domain='', lmhash='', nthash='', use_ntlmv2=True, maxBufferSize=None):
_setup_login_packet_hook(maxBufferSize)
smb.SMB.login_extended(self, user, password, domain, lmhash, nthash, use_ntlmv2)

def connect_tree(self, path, password=None, service=smb.SERVICE_ANY, smb_packet=None):
self._last_tid = smb.SMB.tree_connect_andx(self, path, password, service, smb_packet)
return self._last_tid

def get_last_tid(self):
return self._last_tid

def nt_create_andx(self, tid, filename, smb_packet=None, cmd=None, shareAccessMode=smb.FILE_SHARE_READ|smb.FILE_SHARE_WRITE, disposition=smb.FILE_OPEN, accessMask=0x2019f):
self._last_fid = smb.SMB.nt_create_andx(self, tid, filename, smb_packet, cmd, shareAccessMode, disposition, accessMask)
return self._last_fid

def get_last_fid(self):
return self._last_fid

def set_default_tid(self, tid):
self._default_tid = tid

def set_pkt_flags2(self, flags):
self._pkt_flags2 = flags

Expand All @@ -178,7 +193,7 @@ def send_echo(self, data):

self.sendSMB(pkt)
return self.recvSMB()

def do_write_andx_raw_pipe(self, fid, data, mid=None, pid=None, tid=None):
writeAndX = smb.SMBCommand(smb.SMB.SMB_COM_WRITE_ANDX)
writeAndX['Parameters'] = smb.SMBWriteAndX_Parameters_Short()
Expand All @@ -192,7 +207,7 @@ def do_write_andx_raw_pipe(self, fid, data, mid=None, pid=None, tid=None):

self.send_raw(self.create_smb_packet(writeAndX, mid, pid, tid))
return self.recvSMB()

def create_smb_packet(self, smbReq, mid=None, pid=None, tid=None):
if mid is None:
mid = self.next_mid()
Expand All @@ -216,7 +231,7 @@ def create_smb_packet(self, smbReq, mid=None, pid=None, tid=None):

def send_raw(self, data):
self.get_socket().send(data)

def create_trans_packet(self, setup, param='', data='', mid=None, maxSetupCount=None, totalParameterCount=None, totalDataCount=None, maxParameterCount=None, maxDataCount=None, pid=None, tid=None, noPad=False):
if maxSetupCount is None:
maxSetupCount = len(setup)
Expand All @@ -242,7 +257,7 @@ def create_trans_packet(self, setup, param='', data='', mid=None, maxSetupCount=
transCmd['Parameters']['Setup'] = setup
_put_trans_data(transCmd, param, data, noPad)
return self.create_smb_packet(transCmd, mid, pid, tid)

def send_trans(self, setup, param='', data='', mid=None, maxSetupCount=None, totalParameterCount=None, totalDataCount=None, maxParameterCount=None, maxDataCount=None, pid=None, tid=None, noPad=False):
self.send_raw(self.create_trans_packet(setup, param, data, mid, maxSetupCount, totalParameterCount, totalDataCount, maxParameterCount, maxDataCount, pid, tid, noPad))
return self.recvSMB()
Expand Down Expand Up @@ -288,7 +303,7 @@ def create_trans2_packet(self, setup, param='', data='', mid=None, maxSetupCount
transCmd['Parameters']['Setup'] = setup
_put_trans_data(transCmd, param, data, noPad)
return self.create_smb_packet(transCmd, mid, pid, tid)

def send_trans2(self, setup, param='', data='', mid=None, maxSetupCount=None, totalParameterCount=None, totalDataCount=None, maxParameterCount=None, maxDataCount=None, pid=None, tid=None, noPad=False):
self.send_raw(self.create_trans2_packet(setup, param, data, mid, maxSetupCount, totalParameterCount, totalDataCount, maxParameterCount, maxDataCount, pid, tid, noPad))
return self.recvSMB()
Expand Down Expand Up @@ -333,7 +348,7 @@ def create_nt_trans_packet(self, function, setup='', param='', data='', mid=None
transCmd['Parameters']['Setup'] = setup
_put_trans_data(transCmd, param, data, noPad)
return self.create_smb_packet(transCmd, mid, pid, tid)

def send_nt_trans(self, function, setup='', param='', data='', mid=None, maxSetupCount=None, totalParameterCount=None, totalDataCount=None, maxParameterCount=None, maxDataCount=None, pid=None, tid=None, noPad=False):
self.send_raw(self.create_nt_trans_packet(function, setup, param, data, mid, maxSetupCount, totalParameterCount, totalDataCount, maxParameterCount, maxDataCount, pid, tid, noPad))
return self.recvSMB()
Expand Down

0 comments on commit 44d8dcc

Please sign in to comment.