Skip to content

Commit

Permalink
Add feature to listPath to allow for listing directories decorated wi…
Browse files Browse the repository at this point in the history
…th a @gmt timestamp value
  • Loading branch information
rxwx committed Sep 30, 2019
1 parent 1c8544f commit 08039fa
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
54 changes: 50 additions & 4 deletions impacket/smb3.py
Original file line number Diff line number Diff line change
Expand Up @@ -968,9 +968,16 @@ def create(self, treeId, fileName, desiredAccess, shareMode, creationOptions, cr
smb2Create['Buffer'] = '\x00'

if createContexts is not None:
smb2Create['Buffer'] += createContexts
smb2Create['CreateContextsOffset'] = len(SMB2Packet()) + SMB2Create.SIZE + smb2Create['NameLength']
smb2Create['CreateContextsLength'] = len(createContexts)
contextsBuf = ''.join(x.getData() for x in createContexts)
smb2Create['CreateContextsOffset'] = len(SMB2Packet()) + SMB2Create.SIZE + len(smb2Create['Buffer'])

# pad offset to 8-byte align
if (smb2Create['CreateContextsOffset'] % 8):
smb2Create['Buffer'] += '\x00'*(8-(smb2Create['CreateContextsOffset'] % 8))
smb2Create['CreateContextsOffset'] = len(SMB2Packet()) + SMB2Create.SIZE + len(smb2Create['Buffer'])

smb2Create['CreateContextsLength'] = len(contextsBuf)
smb2Create['Buffer'] += contextsBuf
else:
smb2Create['CreateContextsOffset'] = 0
smb2Create['CreateContextsLength'] = 0
Expand Down Expand Up @@ -1410,7 +1417,45 @@ def writeFile(self, treeId, fileId, data, offset = 0):
writeOffset += written
return writeOffset - offset

def isSnapshotRequest(self, path):
#TODO: use a regex here?
return '@GMT-' in path

def timestampForSnapshot(self, path):
timestamp = path[path.index("@GMT-"):path.index("@GMT-")+24]
path = path.replace(timestamp, '')
from datetime import datetime
fTime = int((datetime.strptime(timestamp, '@GMT-%Y.%m.%d-%H.%M.%S') - datetime(1970,1,1)).total_seconds())
fTime *= 10000000
fTime += 116444736000000000

token = SMB2_CREATE_TIMEWARP_TOKEN()
token['Timestamp'] = fTime

ctx = SMB2CreateContext()
ctx['Next'] = 0
ctx['NameOffset'] = 16
ctx['NameLength'] = len('TWrp')
ctx['DataOffset'] = 24
ctx['DataLength'] = 8
ctx['Buffer'] = 'TWrp'
ctx['Buffer'] += '\x00'*4 # 4 bytes to 8-byte align
ctx['Buffer'] += token.getData()

# fix-up the path
path = path.replace(timestamp, '').replace('\\\\', '\\')
if path == '\\':
path += '*'
return path, ctx

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

if self.isSnapshotRequest(path):
createContexts = []
path, ctx = self.timestampForSnapshot(path)
createContexts.append(ctx)

# ToDo: Handle situations where share is password protected
path = path.replace('/', '\\')
path = ntpath.normpath(path)
Expand All @@ -1424,7 +1469,8 @@ def listPath(self, shareName, path, password = None):
# ToDo, we're assuming it's a directory, we should check what the file type is
fileId = self.create(treeId, ntpath.dirname(path), FILE_READ_ATTRIBUTES | FILE_READ_DATA, FILE_SHARE_READ |
FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN, 0)
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN, 0,
createContexts=createContexts)
res = ''
files = []
from impacket import smb
Expand Down
2 changes: 1 addition & 1 deletion impacket/smb3structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ class SMB2_CREATE_ALLOCATION_SIZE(Structure):

class SMB2_CREATE_TIMEWARP_TOKEN(Structure):
structure = (
('AllocationSize','<Q=0'),
('Timestamp','<Q=0'),
)

class SMB2_CREATE_REQUEST_LEASE(Structure):
Expand Down

0 comments on commit 08039fa

Please sign in to comment.