Skip to content

Commit

Permalink
python/smb - let dionaea understand DoublePulsar's opcode and commands
Browse files Browse the repository at this point in the history
- dionaea will interpret the inbound DoublePulsar opcode and commands (e.g. ping, exec, kill)
- make sure dionaea store only the final payload/executable as the collection on disk
  • Loading branch information
gento committed May 25, 2017
1 parent d17ebf3 commit 17da8e1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
35 changes: 27 additions & 8 deletions modules/python/scripts/smb/smb.py
Expand Up @@ -35,7 +35,7 @@
import binascii
import os
import hashlib
from dionaea.util import xor
from dionaea.util import *
from uuid import UUID

from .include.smbfields import *
Expand Down Expand Up @@ -545,6 +545,22 @@ def process(self, p):
h = p.getlayer(SMB_Trans2_Request)
if h.Setup[0] == SMB_TRANS2_SESSION_SETUP:
smblog.info('Possible DoublePulsar connection attempts..')

# determine DoublePulsar opcode and command
# https://zerosum0x0.blogspot.sg/2017/04/doublepulsar-initial-smb-backdoor-ring.html
# The opcode list is as follows:
# 0x23 = ping
# 0xc8 = exec
# 0x77 = kil
op = calculate_doublepulsar_opcode(h.Timeout)
op2 = hex(op)[-2:]
oplist = [('23','ping'), ('c8','exec'), ('77','kill')]
for fid,command in oplist:
if op2 == fid:
smblog.info("DoublePulsar request opcode: %s command: %s" % (op2, command))
if op2 != '23' and op2 != 'c8' and op2 != '77':
smblog.info("unknown opcode: %s" % op2)

# make sure the payload size not larger than 10MB
if len(self.buf2) > 10485760:
self.buf2 = ''
Expand All @@ -561,23 +577,26 @@ def process(self, p):
smblog.info('DoublePulsar payload - MD5 (before XOR decryption): %s' %(hash_buf2.hexdigest()))
hash_xor_output = hashlib.md5(xor_output);
smblog.info('DoublePulsar payload - MD5 (after XOR decryption ): %s' %(hash_xor_output.hexdigest()))

#f = tempfile.NamedTemporaryFile(delete=False, prefix="xorfull-"+hash_xor_output.hexdigest()+"-", suffix="", dir=g_dionaea.config()['downloads']['dir'])

dir=g_dionaea.config()['downloads']['dir'] + "/"
f = open(dir+hash_xor_output.hexdigest(),'wb')
f.write(xor_output)
f.close
# f = open(dir+hash_xor_output.hexdigest(),'wb')
# f.write(xor_output)
# f.close

# payload = some data(shellcode or code to load the executable) + executable itself
# try to locate the executable and remove the prepended data
# now, we will have the executable itself
offset = 0
for i, c in enumerate(xor_output):
if ((xor_output[i] == 0x4d and xor_output[i+1] == 0x5a) and xor_output[i+2] == 0x90):
offset = i
smblog.info('DoublePulsar payload - MZ header found...')
break

hash_xor_output_mz = hashlib.md5(xor_output[offset:]);

# save the captured payload/gift/evil/buddy to disk
smblog.info('DoublePulsar payload - MD5 final: %s. Save to disk' %(hash_xor_output_mz.hexdigest()))
#f1 = tempfile.NamedTemporaryFile(delete=False, prefix=hash_xor_output_mz.hexdigest()+"-", suffix="", dir=g_dionaea.config()['downloads']['dir'])
f1 = open(dir+hash_xor_output_mz.hexdigest(),'wb')
f1.write(xor_output[offset:])
f1.close
Expand Down
4 changes: 4 additions & 0 deletions modules/python/scripts/util.py
Expand Up @@ -51,3 +51,7 @@ def xor(data, key):
return bytearray((
(data[i] ^ key[i % l]) for i in range(0,len(data))
))

def calculate_doublepulsar_opcode(t):
op = (t) + (t >> 8) + (t >> 16) + (t >> 24);
return op

0 comments on commit 17da8e1

Please sign in to comment.