#!/usr/bin/env python # # Author: St0rn # Site: st0rn.anbu-pentest.com # # Description: # smb2Dump is a tool to dump live smb2 file transfert. # You can save file # but if is not alone (transfert multiple files) # or too big # the file will be corrupted. # # Use: Scapy # Usage smb2Dump.py [device] # ###### Imports ###### """ Native Imports """ import socket import random from os import mkdir,path,system,unlink from sys import exit,argv from struct import * from multiprocessing import Process """ Scapy is used for IP(), TCP() layers """ try: from scapy.all import * except: print "Scapy not installed\n" exit(0) ###### Variable ###### """ filename:ip """ fileDump=list() ###### Functions ###### """ Banner """ def banner(): print "\n#############################" print "# smb2Dump #" print "# Author: St0rn #" print "# anbu-pentest.com #" print "#############################\n ctrl-c to stop capture\n" """ Clear CLI """ def clear(): system("/usr/bin/clear") """ Create Loot dir """ def createDir(): if not path.isdir("Loot"): mkdir("Loot") print "[+] Loot dir created\n" else: print "[!] Loot dir is present\n" #### Wait for SMB2 Transfert #### def GetSMB2Transfert(sock): while True: buf=sock.recvfrom(65536) """ Decode buf string to TCP/IP packet """ pck=Ether(buf[0]) """ If the destination port is 139 or 445 (Netbios-over-tcp) and packet have data """ if pck.haslayer(TCP) and pck.haslayer(Raw): if pck[TCP].dport==139 or pck[TCP].dport==445: """ Search for SMB2 Create Request packet (0x05) """ load=pck[Raw].load ## SMB2 Header ## """ Re-used of buf to avoid error with scapy's layers """ """ Ethernet+IP+TCP+NBSS => 14+20+20+4=58 """ smb2Header=unpack("!4s2B2BL2B2BLLQLLQ2Q",buf[0][58:122]) command=smb2Header[6] """ If Create cmd (0x05) """ if command==5: """ Get File name in SMB2 Create Request """ ## SMB2 Create Request ## """ SMB2 Create Request Frame have 52 bytes before Buffer field """ """ 3 Bytes at first before oplock field (search Lease oplock => 0xff) """ """ 52-(3+1)=48 """ """ And 4 bytes before full path filename """ """ 3+1+(48+4) bytes to unpack before extract filename """ smb2CR=unpack("!3s1B52s"+str(len(buf[0][178:]))+"s",buf[0][122:]) oplock=hex(smb2CR[1]) if oplock=="0xff": temp=str() for i in smb2CR[3]: if i!='(' and i!="\x00": temp+=i if i=='(': break filename=" " filename=temp """ Process file dump """ if filename not in fileDump: fileDump.append(filename) print "[+] %s download %s to Server %s\n" %(pck[IP].src,filename,pck[IP].dst) return pck[IP].src, pck[TCP].sport,pck[IP].dst,filename break #### Dump documents (client IP/Port is for security) #### def smb2Dump(sock,clientIp,clientPort,serverIp,loot): dump=list() print "[+] Dump started" while True: buf=sock.recvfrom(65536) """ Decode buf string to TCP/IP packet """ pck=Ether(buf[0]) """ If the destination port is 139 or 445 (Netbios-over-tcp) and packet have data "" if pck.haslayer(TCP) and pck.haslayer(Raw): if pck[IP].src==serverIp and pck[IP].dst==clientIp and pck[TCP].dport==clientPort: if pck[TCP].sport==139 or pck[TCP].sport==445: """ Search for SMB2 Read Response packet (0x08) """ load=pck[Raw].load ## SMB2 Header ## """ Re-used of buf to avoid error with scapy's layers """ """ Ethernet+IP+TCP+NBSS => 14+20+20+4=58 """ smb2Header=unpack("!4s2B2BL2B2BLLQLLQ2Q",buf[0][58:122]) command=smb2Header[6] """ If Read cmd (0x08) """ if command==8: smb2RResp=unpack("!HHIII"+str(len(buf[0][138:]))+"s",buf[0][122:]) dump.append(smb2RResp[5]) loot.write(smb2RResp[5]) print smb2RResp[5] while True: buf=sock.recvfrom(65536) """ Decode buf string to TCP/IP packet """ pck=Ether(buf[0]) """ If the destination port is 139 or 445 (Netbios-over-tcp) and packet have data """ if pck.haslayer(TCP) and pck.haslayer(Raw): if pck[IP].src==serverIp and pck[IP].dst==clientIp and pck[TCP].dport==clientPort: if pck[TCP].sport==139 or pck[TCP].sport==445: """ Search for SMB2 Read Response packet (0x08) """ load=pck[Raw].load try: smb2RResp=unpack("!HHIII"+str(len(buf[0][138:]))+"s",buf[0][122:]) except: #Do nothing donothing=1 loot.write(smb2RResp[5]) dump.append(smb2RResp[5]) print smb2RResp[5] ###### Main ###### if len(argv)==2: """ Begin """ clear() banner() createDir() rnd=random.randint(1000,9999) loot=open("Loot/"+str(rnd),"w") """ Main socket """ s=socket.socket(socket.AF_PACKET,socket.SOCK_RAW) s.bind((argv[1],0x800)) try: """ Detect transfert """ client,clientPort,server,name=GetSMB2Transfert(s) """ and dump """ smb2Dump(s,client,clientPort,server,loot) except KeyboardInterrupt: rep=raw_input("\nSave file? [y/n]: ") if rep.lower()=="y" or rep.lower()=="yes": print "\n[+] Saving file with name %s\n" %rnd loot.close() else: loot.close() unlink("Loot/"+str(rnd)) else: print "\nUsage: %s [device]\n" %argv[0]
St0rn