Skip to content

Commit

Permalink
Incorporate Pennyw0rth/NetExec Impacket changes into Fortra Impacket …
Browse files Browse the repository at this point in the history
…(reloaded) (#1721)

* Add ServerName argument to srvs.hNetrShareEnum

* [dcom] fix dcom disconnect issues

Signed-off-by: XiaoliChan <[email protected]>

* Implement better windows os enumeration with checking the build version

---------

Signed-off-by: XiaoliChan <[email protected]>
Co-authored-by: cnotin <[email protected]>
Co-authored-by: XiaoliChan <[email protected]>
Co-authored-by: Alexander Neff <[email protected]>
  • Loading branch information
4 people authored Mar 27, 2024
1 parent 608f426 commit cc2c2e1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 12 deletions.
13 changes: 7 additions & 6 deletions impacket/dcerpc/v5/dcomrt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1086,14 +1086,15 @@ def get_dce_rpc(self):
return DCOMConnection.PORTMAPS[self.__target]

def disconnect(self):
if DCOMConnection.PINGTIMER is not None:
# https://github.com/fortra/impacket/issues/1039
if self.__target in DCOMConnection.PORTMAPS.keys():
del(DCOMConnection.PORTMAPS[self.__target])
if self.__target in DCOMConnection.OID_SET.keys():
del(DCOMConnection.OID_SET[self.__target])
if len(DCOMConnection.PORTMAPS) == 0:
# This means there are no more clients using this object, kill it
DCOMConnection.PINGTIMER.cancel()
DCOMConnection.PINGTIMER.join()
DCOMConnection.PINGTIMER = None
if DCOMConnection.PINGTIMER and len(DCOMConnection.PORTMAPS) == 0:
DCOMConnection.PINGTIMER.cancel()
DCOMConnection.PINGTIMER.join()
DCOMConnection.PINGTIMER = None
if self.__target in INTERFACE.CONNECTIONS:
del(INTERFACE.CONNECTIONS[self.__target][current_thread().name])
self.__portmap.disconnect()
Expand Down
7 changes: 5 additions & 2 deletions impacket/dcerpc/v5/srvs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3095,9 +3095,12 @@ def hNetrShareDel(dce, netName):
request['NetName'] = netName
return dce.request(request)

def hNetrShareEnum(dce, level, resumeHandle = 0, preferedMaximumLength = 0xffffffff):
def hNetrShareEnum(dce, level, resumeHandle = 0, preferedMaximumLength = 0xffffffff, serverName = '\x00'):
# serverName example: "\\\\1.2.3.4\x00"
if serverName[-1] != '\x00':
serverName += '\x00' # final NULL byte is mandatory
request = NetrShareEnum()
request['ServerName'] = '\x00'
request['ServerName'] = serverName
request['PreferedMaximumLength'] = preferedMaximumLength
request['ResumeHandle'] = resumeHandle
request['InfoStruct']['Level'] = level
Expand Down
55 changes: 52 additions & 3 deletions impacket/smb3.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,54 @@
'Connection' : 0,
}

# Source:
# https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions
# https://www.gaijin.at/en/infos/windows-version-numbers
WIN_VERSIONS = {
102:"Windows 3.1",
103:"Windows 3.1",
153:"Windows 3.2",
300:"Windows 3.11",
528:"Windows NT 3.1 SP3",
807:"Windows NT 3.5",
950:"Windows 95",
1057:"Windows NT 3.51",
1381:"Windows NT 4.0",
1998:"Windows 98",
2195:"Windows 2000",
2222:"Windows 98 Second Edition",
2600:"Windows XP",
2700:"Windows XP",
2710:"Windows XP",
3000:"Windows Me",
3790:"Windows XP / Server 2003 / Server 2003 R2",
6002:"Windows Vista",
6003:"Windows Server 2008",
7601:"Windows 7 / Server 2008 R2",
8400:"Windows Home Server 2011",
9200:"Windows 8 / Server 2012",
9600:"Windows 8.1 / Server 2012 R2",
10240:"Windows 10",
10586:"Windows 10",
14393:"Windows 10 / Server 2016",
15063:"Windows 10",
16299:"Windows 10 / Server 2016",
17134:"Windows 10 / Server 2016",
17763:"Windows 10 / Server 2019",
18362:"Windows 10 / Server 2019",
18363:"Windows 10 / Server 2019",
19041:"Windows 10 / Server 2019",
19042:"Windows 10 / Server 2019",
19043:"Windows 10",
19044:"Windows 10",
19045:"Windows 10",
20348:"Windows Server 2022",
22000:"Windows 11",
22621:"Windows 11",
22631:"Windows 11",
25398:"Windows Server 2022",
}


class SessionError(Exception):
def __init__( self, error = 0, packet=0):
Expand Down Expand Up @@ -1001,15 +1049,16 @@ def login(self, user, password, domain = '', lmhash = '', nthash = ''):
version = ntlmChallenge['Version']

if len(version) >= 4:
self._Session['ServerOS'] = "Windows %d.%d Build %d" % (indexbytes(version,0), indexbytes(version,1), struct.unpack('<H',version[2:4])[0])
if struct.unpack('<H',version[2:4])[0] in WIN_VERSIONS.keys():
self._Session['ServerOS'] = WIN_VERSIONS[struct.unpack('<H',version[2:4])[0]] + " Build %d" % struct.unpack('<H',version[2:4])[0]
else:
self._Session['ServerOS'] = "Windows %d.%d Build %d" % (indexbytes(version,0), indexbytes(version,1), struct.unpack('<H',version[2:4])[0])
self._Session["ServerOSMajor"] = indexbytes(version,0)
self._Session["ServerOSMinor"] = indexbytes(version,1)
self._Session["ServerOSBuild"] = struct.unpack('<H',version[2:4])[0]

type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, respToken['ResponseToken'], user, password, domain, lmhash, nthash)



respToken2 = SPNEGO_NegTokenResp()
respToken2['ResponseToken'] = type3.getData()

Expand Down
2 changes: 1 addition & 1 deletion impacket/smbconnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ def listShares(self):
dce = rpctransport.get_dce_rpc()
dce.connect()
dce.bind(srvs.MSRPC_UUID_SRVS)
resp = srvs.hNetrShareEnum(dce, 1)
resp = srvs.hNetrShareEnum(dce, 1, serverName="\\\\" + self.getRemoteHost())
return resp['InfoStruct']['ShareInfo']['Level1']['Buffer']

def listPath(self, shareName, path, password = None):
Expand Down

0 comments on commit cc2c2e1

Please sign in to comment.