Skip to content

Instantly share code, notes, and snippets.

@hugsy

hugsy/aplib.py Secret

Last active October 13, 2017 01:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hugsy/9b141827b66843ebbabc183731649f53 to your computer and use it in GitHub Desktop.
Save hugsy/9b141827b66843ebbabc183731649f53 to your computer and use it in GitHub Desktop.
import os
from ctypes import *
__all__ = [ 'depack', ]
_aplib = CDLL("/home/hugsy/ctf/flareon_2017/12/level12/libaplib.so")
def depack(src, dstlen):
srclen = len(src)
if srclen <= 0 or dstlen <= 0:
raise ValueError('Invalid input.')
dst = create_string_buffer(dstlen)
dstlen = _aplib.aP_depack_asm_safe(src, srclen, dst, dstlen)
if dstlen == -1:
raise ValueError('Decompression error.')
return buffer(dst, 0, dstlen)
import zlib
import struct
import copy
import os
import sys
import subprocess
from ctypes import *
from hexdump import hexdump
from Crypto.Cipher import Blowfish
from Crypto.Cipher import DES3
import camellia
import aplib
import lzo
def from_utf16(msg):
return msg#.decode('utf16')
def p32(x, endianness="little"):
if endianness=="big":
return struct.pack("!I",x)
return struct.pack("<I",x)
def u32(x, endianness="little"):
if endianness=="big":
return struct.unpack("!I",x)[0]
return struct.unpack("<I",x)[0]
# secondstage
magic_exe_value = "155BBF4A1EFE1517734604B9D42B80E8".decode('hex')
magic_exe_cmd = "F37126AD88A5617EAF06000D424C5A21".decode('hex')
magic_exe = "51298F741667D7ED2941950106F50545".decode('hex')
string_delim_utf = "F47C51070FA8698064B65B3B6E7D30C6".decode('hex')
string_delim_ascii = "F46D09704B40275FB33790A362762E56".decode('hex')
plugin_types = [
"CMD", # send and receive commands
"COMP", # compression
"CRPT", # crypto
]
current_magic = None
#
# secondstage-lm-1.exe (r.dll)
# rc4
magic_r_dll = "C30B1A2DCB489CA8A724376469CF6782".decode('hex')
def swap_byte(buf1, i1, buf2, i2):
temp1 = buf1[i1]
temp2 = buf2[i2]
buf1[i1] = temp2
buf2[i2] = temp1
return
def swap_bytes_1(msg):
buf = bytearray()
for _ in range(256): buf.append(_)
buf.append(0)
buf.append(0)
v6 = 0
msg = bytearray(msg)
for j in range(256):
v6 = (v6 + msg[j % len(msg)] + buf[j]) & 0xff
swap_byte(buf, j, buf, v6)
return str(buf)
def swap_bytes_2(a1, a2):
a1 = bytearray(a1)
a2 = bytearray(a2)
a3 = bytearray()
for _ in range( len(a2) ):
a3.append(0)
for i in range( len(a2) ):
a1[256] = (a1[256] + 1) & 0xffL
a1[257] = (a1[257] + a1[ a1[256] ]) & 0xffL
swap_byte(a1, a1[256], a1, a1[257])
c = (a1[a1[257]] + a1[a1[256]]) & 0xff
a3[i] = a1[c] ^ a2[i]
return str(a3)
#
# secondstage-lm-2.exe (t.dll)
# shuffle
magic_t_dll = "38BE0F624CE274FC61F75C90CB3F5915".decode('hex')
def unshuffle(msg):
shuffled_bytes = [
0x0C7, 0x19, 0x30, 0x0C, 0x0A8, 0x10, 0x0AD, 0x0D5, 0x0D4, 0x16,
0x52, 0x0FC, 0x1B, 0x82, 0x7D, 0x32, 0x34, 0x1, 0x0E6, 0x4C, 0x12,
0x8, 0x2B, 0x0F7, 0x0AC, 0x8B, 0x3F, 0x67, 0x48, 0x72, 0x21, 0x0DC,
0x0ED, 0x0F6, 0x85, 0x0B8, 0x4F, 0x5F, 0x53, 0x0A, 0x4, 0x28, 0x0DF,
0x0D8, 0x7E, 0x6, 0x3D, 0x3, 0x40, 0x36, 0x68, 0x73, 0x25, 0x0B7,
0x5D, 0x1E, 0x0D2, 0x0D, 0x0C6, 0x0C3, 0x22, 0x0F2, 0x20, 0x0E,
0x17, 0x0CC, 0x60, 0x5C, 0x51, 0x0C2, 0x1D, 0x4A, 0x0CB, 0x33,
0x1C, 0x0F8, 0x66, 0x83, 0x6B, 0x3E, 0x27, 0x0E3, 0x9F, 0x0F5,
0x3A, 0x0AA, 0x8A, 0x26, 0x7F, 0x5A, 0x42, 0x0CF, 0x7C, 0x7, 0x58,
0x71, 0x0EB, 0x5, 0x0BA, 0x29, 0x4B, 0x7A, 0x0E0, 0x0EC, 0x9A,
0x7B, 0x2E, 0x37, 0x0FE, 0x0A4, 0x0BE, 0x49, 0x0DE, 0x0, 0x0C5,
0x0BB, 0x96, 0x0E9, 0x0C4, 0x79, 0x99, 0x87, 0x0F4, 0x13, 0x1A,
0x15, 0x63, 0x0F9, 0x0A0, 0x0D1, 0x2, 0x0D6, 0x9, 0x1F, 0x0E5, 0x92,
0x6A, 0x0E7, 0x18, 0x43, 0x91, 0x6E, 0x41, 0x0C8, 0x0A3, 0x0B2,
0x2C, 0x0EE, 0x8D, 0x0A6, 0x5B, 0x0EF, 0x24, 0x0B9, 0x75, 0x57,
0x0F, 0x6F, 0x11, 0x47, 0x9B, 0x3B, 0x76, 0x0E1, 0x9D, 0x64, 0x54,
0x0A7, 0x0C1, 0x55, 0x0B3, 0x89, 0x31, 0x0FD, 0x0AB, 0x0B1, 0x94,
0x0B6, 0x14, 0x2F, 0x0F3, 0x0BC, 0x69, 0x0BF, 0x0A1, 0x80, 0x59,
0x0B, 0x0BD, 0x0C9, 0x2A, 0x0D7, 0x81, 0x3C, 0x23, 0x0D3, 0x0F1,
0x0FA, 0x0EA, 0x39, 0x38, 0x9E, 0x5E, 0x0B5, 0x45, 0x61, 0x0FF,
0x4E, 0x77, 0x4D, 0x65, 0x9C, 0x0E8, 0x0D9, 0x93, 0x0AF, 0x50,
0x0A2, 0x84, 0x88, 0x78, 0x98, 0x0E2, 0x86, 0x0CE, 0x0DD, 0x8C,
0x8E, 0x0A9, 0x95, 0x70, 0x0AE, 0x0E4, 0x0CA, 0x62, 0x0CD, 0x90,
0x0C0, 0x0FB, 0x0B0, 0x0DB, 0x0B4, 0x0D0, 0x97, 0x0F0, 0x2D,
0x46, 0x0DA, 0x6C, 0x6D, 0x44, 0x74, 0x0A5, 0x8F, 0x56, 0x35,
]
res = bytearray()
for c in bytearray(msg):
res.append(shuffled_bytes[c])
return str(res)
assert unshuffle("Jqqq") == p32(0x1c)
#
# secondstage-lm-3.exe (6.dll)
# base64
magic_6_dll = "BA0504FCC08F9121D16FD3FED1710E60".decode('hex')
def tobase64(s, padd = False):
b64s = "B7wAOjbXLsD+S24/tcgHYqFRdVKTp0ixlGIMCf8zvE5eoN1uyU93Wm6rZPQaJhkn"
b64p = "="
ret = ""
left = 0
for i in range(0, len(s)):
if left == 0:
ret += b64s[ord(s[i]) >> 2]
left = 2
else:
if left == 6:
ret += b64s[ord(s[i - 1]) & 63]
ret += b64s[ord(s[i]) >> 2]
left = 2
else:
index1 = ord(s[i - 1]) & (2 ** left - 1)
index2 = ord(s[i]) >> (left + 2)
index = (index1 << (6 - left)) | index2
ret += b64s[index]
left += 2
if left != 0:
ret += b64s[(ord(s[len(s) - 1]) & (2 ** left - 1)) << (6 - left)]
if(padd):
for i in range(0, (4 - len(ret) % 4) % 4):
ret += b64p
return ret
def frombase64(s):
b64s = "B7wAOjbXLsD+S24/tcgHYqFRdVKTp0ixlGIMCf8zvE5eoN1uyU93Wm6rZPQaJhkn"
b64p = "="
ret = ""
s2 = s.replace(b64p, "")
left = 0
for i in range(0, len(s2)):
if left == 0:
left = 6
else:
value1 = b64s.index(s2[i - 1]) & (2 ** left - 1)
value2 = b64s.index(s2[i]) >> (left - 2)
value = (value1 << (8 - left)) | value2
ret += chr(value)
left -= 2
return ret
assert frombase64("XBBBBB") == p32(0x1c)
#
# secondstage-lm-4.exe (x.dll)
# xtea
magic_x_dll = "B2E5490D2654059BBBAB7F2A67FE5FF4".decode('hex')
def _xtea_decrypt(block, key):
v11 = u32(block[0:4], endianness="big")
v10 = u32(block[4:8], endianness="big")
k = [ u32(key[i:i+4]) for i in range(0, len(key), 4) ]
iv = 0x9E3779B9L
m = 0xffffffffL
delta = (iv << 5) & m
for _ in range(32):
edx = (v11 << 4) & m
eax = (v11 >> 5) & m
edx = edx ^ eax
edx = (edx + v11) & m
ecx = ((delta >> 11) & m) & 3
esi = delta + k[ecx]
edx = edx ^ esi
ecx = (v10 - edx) & m
v10 = ecx
delta = (delta - iv) & m
eax = (v10 << 4) & m
ecx = (v10 >> 5) & m
eax = eax ^ ecx
eax = (eax + v10) & m
edx = delta & 3
esi = (delta + k[edx]) & m
eax = eax ^ esi
edx = (v11 - eax) & m
v11 = edx
return p32(v11, endianness="big") + p32(v10, endianness="big")
key = "0e7af86bd6235b5d10ac6a883d33a407".decode('hex')
text = "91471302dd5a7fd5".decode('hex')
result = "c821cbd2444ce75c".decode('hex')
assert _xtea_decrypt(text, key) == result, _xtea_decrypt(text, key).encode('hex') + " != " + result.encode('hex')
def xtea_decrypt(buf, key, iv):
assert len(buf) % 8 == 0
dec = bytearray()
for i in range(0, len(buf), 8):
block = buf[i:i+8]
temp = copy.deepcopy(block)
res = _xtea_decrypt(block, key)
for j in range(8):
dec.append( ord(res[j]) ^ ord(iv[j]) )
iv = temp
return str(dec)
#
# secondstage-lm-5.exe (z.dll)
# zlib
magic_z_dll = "5FD8EA0E9D0A92CBE425109690CE7DA2".decode('hex')
def inflate(x):
return zlib.decompressobj().decompress(x)
# secondstage-lm-6.exe (f.dll)
# sha1
magic_f_dll = "F47C51070FA8698064B65B3B6E7D30C6".decode('hex')
# secondstage-lm-7.exe (s.dll)
# send/receive commands to cmd.exe
magic_s_dll = "F46D09704B40275FB33790A362762E56".decode('hex')
# secondstage-lm-8.exe (m.dll)
# screen capture
magic_m_dll = "A3AECCA1CB4FAA7A9A594D138A1BFBD5".decode('hex')
# p.dll
# proxy
magic_p_dll = "77D6CE92347337AEB14510807EE9D7BE".decode('hex')
# srv2-1.dll
# blowfish
magic_b_dll = "2965E4A19B6E9D9473F5F54DFEF93533".decode('hex')
def blowfish_decrypt(key, ciphertext, iv):
bs = Blowfish.block_size
if len(ciphertext) % 8 != 0:
ciphertext += '\x00' * (8- (len(ciphertext) % 8))
cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext)
return plaintext
# srv2-2.dll
magic_e_dll = "8746E7B7B0C1B9CF3F11ECAE78A3A4BC".decode('hex')
def e_decrypt(iv, ciphertext):
plaintext = bytearray()
iv = u32(iv)
bs = 4
if len(ciphertext) % bs != 0:
ciphertext += '\x00' * (bs - (len(ciphertext) % bs))
for i in range(0, len(ciphertext), bs):
b = ciphertext[i:i+4]
c = iv ^ u32(b)
for b in p32(c):
plaintext.append(b)
return str(plaintext)
# srv2-3.dll
# des
magic_d_dll = "46C5525904F473ACE7BB8CB58B29968A".decode('hex')
def des_decrypt(key, ciphertext, iv):
bs = 8
if len(ciphertext) % bs != 0:
ciphertext += '\x00' * (bs - (len(ciphertext) % bs))
cipher = DES3.new(key, DES3.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext)
return plaintext
# srv2-4.dll
# camellia
magic_c_dll = "9B1F6EC7D9B42BF7758A094A2186986B".decode('hex')
def camellia_decrypt(key, ciphertext):
bs = 16
plaintext = ""
print("[*] c_dll -> key=%s , len(enc)=%d" % (key.encode('hex'), len(ciphertext)))
cipher = camellia.CamelliaCipher(key=key, mode=camellia.MODE_ECB)
for i in range(0, len(ciphertext), bs):
block = ciphertext[i:i+bs]
plaintext+= cipher.decrypt(block)
print("[*] c_dll -> len(dec)=%d" % (len(plaintext)))
return plaintext
# srv2-5.dll
# aplib (compression)
magic_a_dll = "503B6412C75A7C7558D1C92683225449".decode('hex')
def aplib_deflate(hdr, msg, inlen, outlen):
assert hdr.startswith("AP32")
_,_, len_compressed_data, _, len_decompressed_data, _ = struct.unpack("<IIIIII", hdr)
print("[*] a_dll -> len_compressed_data=%d , len(msg)=%d" % (len_compressed_data, len(msg)))
msg = msg[:len_compressed_data]
res = aplib.depack(msg, outlen+0x2048)
print ("[*] a_dll -> outlen=%d , len(msg)=%d" % (inlen, len(res)))
return str(res)
# srv2-6.dll
#
magic_l_dll = "0A7874D2478A7713705E13DD9B31A6B1".decode('hex')
def l_inflate(msg, inlen, outlen):
print ("[*] l_dll -> inlen=%d , len(msg)=%d , outlen=%d" % (inlen, len(msg), outlen))
msg = msg[:inlen]
d = lzo.decompress(msg, False, outlen+0x2048)
print("[*] l_dll -> outlen=%d , len(res)=%d" % (outlen, len(d)))
return str(d)
# srv2-7.dll
# m.dll -> screenshot stuff
magic_cryp = "FFFFFFFFF47C51070FA8698064B65B3B".decode('hex')
#
# main
#
magics_lm = [
magic_exe ,
magic_r_dll ,
magic_t_dll ,
magic_6_dll ,
magic_x_dll ,
magic_z_dll ,
magic_f_dll ,
magic_s_dll ,
magic_m_dll ,
magic_p_dll ,
magic_b_dll ,
magic_e_dll ,
magic_d_dll ,
magic_c_dll ,
magic_a_dll ,
magic_l_dll ,
]
magics_lm_str = [
"secondstage" ,
"rc4_dll" ,
"magic_t_dll" ,
"base64_dll" ,
"xtea_dll" ,
"zlib_dll" ,
"magic_f_dll" ,
"magic_s_dll" ,
"bitmap_dll" ,
"proxy_dll" ,
"blowfish_dll" ,
"magic_e_dll" ,
"des_dll" ,
"camellia_dll" ,
"aplib_dll" ,
"l_dll" ,
]
magics_action = [
string_delim_ascii ,
string_delim_utf ,
]
magics_action_str = [
"string_delim_ascii" ,
"string_delim_utf" ,
]
buffered = ""
proxy_buffered_len = 0
class Packet:
def __init__(self, buf):
assert len(buf) >= 0x14
assert buf.startswith("2017")
q = struct.unpack("<IIIII", buf[:0x14])
self.prefix, self.checksum, self.header_size, self.data_size, self.real_data_size = q
self.magic = buf[0x14:0x24]
self.header = buf[:self.header_size]
self.data = buf[self.header_size: self.header_size + self.data_size]
self.buf = buf[:]
return
def parse(self):
return self.parse_with_magic(self.magic, self.data, self.header[8:])
def parse_with_magic(self, magic, data, header):
global buffered, proxy_buffered_len, current_magic
if data.startswith(p32(0x20170417)):
return self.parse_body(data, header)
if magic == magic_p_dll:
# PROXY
print("[*] 'magic_dll' -> writing %d B to proxy" % len(data))
open("/tmp/proxy", "a+b").write(data)
return data
header_size, before_data_size, after_data_size = struct.unpack("<III", header[:0xc])
print("[*] magic='%s' header_size=0x%x before_data_size=0x%x after_data_size=0x%x" % (magics_lm_str[magics_lm.index(magic)], header_size, before_data_size, after_data_size))
if magic == magic_exe:
# EXE
hdr_sz, data_sz1, data_sz2 = struct.unpack("<III", data[:0xc])
print("[*] magic_exe -> header_sz=0x%x data_size1=0x%x data_size2=0x%x" % (hdr_sz, data_sz1, data_sz2))
action_magic = data[0xc:0x1c]
if action_magic == magic_exe_cmd: # secondstage @ 0404D60
return self.parse_body(data[0x1c:], data[:0x1c])
if action_magic in magics_lm:
return self.parse_with_magic(action_magic, data[0x1c:], data[:0x1c])
return data
elif magic == magic_t_dll:
# CRPT
next_data = unshuffle(data)
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
elif magic == magic_6_dll:
# COMP
next_data = frombase64(data[:-1])[:after_data_size]
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
elif magic == magic_z_dll:
# COMP
next_data = inflate(data)[:after_data_size]
if next_data.startswith(p32(0x20170417)):
return self.parse_body(next_data)
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
elif magic == magic_x_dll: # hdrlen = 0x3c
# CRPT
iv = header[0x2c:0x34]
key = header[0x1c:0x2c]
key = [ u32(key[i:i+4], endianness="big") for i in range(0, len(key), 4) ]
key = ''.join([p32(x) for x in key])
next_data= xtea_decrypt(data, key, iv)[:after_data_size]
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
elif magic == magic_r_dll: # hdrlen = 0x34
# CRPT
iv = header[0x1c:0x2c]
next_data = swap_bytes_2(swap_bytes_1(iv), data)
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
elif magic == magic_m_dll: # hdrlen = 0x34
# CMD
offset, full_size, chunk_size = struct.unpack("<III", data[:0xc])
return data[0xc:]
elif magic == magic_b_dll: # hdrlen = 0x3c
# CRPT
key=header[0x1c:0x2c]
iv =header[0x2c:0x34]
next_data = blowfish_decrypt(key, data, iv)
if next_data.startswith(p32(0x20170417)):
return self.parse_body(next_data)
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
elif magic == magic_e_dll: # hdrlen = 0x28
# CRPT
iv = header[0x1c:0x20]
next_data = e_decrypt(iv, data)[:after_data_size]
if next_data.startswith(p32(0x20170417)):
return self.parse_body(next_data)
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
elif magic == magic_d_dll: # hdrlen = 0x44
# CRPT
key=header[0x1c:0x34]
iv=header[0x34:0x3c]
next_data = des_decrypt(key, data, iv)[:after_data_size]
hexdump(next_data[:0x50])
if next_data.startswith(p32(0x20170417)):
return self.parse_body(next_data)
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
elif magic == magic_c_dll:
# CRPT
key = header[0x1c:0x2c]
next_data=camellia_decrypt(key, data)[:after_data_size]
if next_data.startswith(p32(0x20170417)):
return self.parse_body(next_data)
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
elif magic == magic_a_dll:
# CRPT
next_data = aplib_deflate(data[:0x18], data[0x18:], before_data_size, after_data_size)
if next_data.startswith(p32(0x20170417)):
return self.parse_body(next_data)
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
elif magic == magic_l_dll:
# COMP
next_data = l_inflate(data, before_data_size, after_data_size)
if next_data.startswith(p32(0x20170417)):
return self.parse_body(next_data)
next_header_len = u32(next_data[:4])
next_header = next_data[:next_header_len]
next_data = next_data[next_header_len:]
next_magic = next_header[0xc:0x1c]
return self.parse_with_magic(next_magic, next_data, next_header)
return data
def parse_body(self, data, header=""):
arg0, arg1, arg2, arg2 = struct.unpack("<IIII", data[:0x10])
assert arg0 == 0x20170417
print("[*] body -> a1=0x{:x} a2=0x{:x} a3=0x{:x} a4=0x{:x}".format(arg0, arg1, arg2, arg2))
if arg1 == 0xe:
print("\t -> auth")
i = data[0x10:].find(magic_exe_value) + 0x10 + 0x10
print("[*] Value '%s'" % from_utf16(data[i:]))
elif arg1 == 0x2:
i = data[0x10:].find(string_delim_utf)
if i > -1:
print("[*] utf_string -> Value '%s'" % from_utf16(data[i+0x10+0x10:]))
elif arg1 == 0x3:
m = data[0x14:0x24]
if m in magics_lm:
return self.parse_with_magic(m, data[0x24:], data[:0x24])
i = data[0x10:].find(string_delim_ascii)
if i > -1:
print("[*] ascii_string -> Value '%s'" % from_utf16(data[i+0x10+0x10:]))
elif arg1 == 0x4:
m = data[0x10:0x20]
if m == magic_cryp:
body = data[0x34:]
offset, _, filesize, _, blocksize, _ = struct.unpack("<IIIIII", body[:24])
if len(data[0x18:]) < blocksize:
print("[*] writing %d to proxy" % (len(data[0x18:],)))
open("/tmp/proxy", "a+b").write(self.buf)
else:
fname = "g/crypfile-%.8x-%.8x" % (offset, blocksize)
print("[!] writing `%s` (len=%d off=%d filesize=%d len(msg)=%d)" % (fname, blocksize, offset, filesize, len(body[0x18:])))
open(fname, "wb").write(body[0x18:])
elif arg1 == 0x5:
print("[*] register_plugin")
elif arg1 == 0x6:
print("[*] recv_plugin")
elif arg1 == 0x7:
print("[*] run_plugin_function")
return data
def populate_directory_with_packets(fname, to_dir):
with open(fname) as fd:
i = 0
while True:
hdr = fd.read(0x14)
if not hdr:
break
pkt = Packet(hdr)
hdr += fd.read(pkt.header_size - 0x14)
data = fd.read(pkt.data_size)
open("%s/pkt-%d" % (to_dir, i, ), "wb").write(hdr + data)
print("[*] pkt-%d written" % i)
i += 1
return i
if __name__ == "__main__":
## step 0
# populate_directory_with_packets("./all-packets-client.raw", to_dir="packets-to-server/")
## step1
try: os.unlink("/tmp/proxy")
except: pass
for i in range(0, 743):
fname = "packets-to-server/pkt-%d" % i
if not os.path.isfile(fname): continue
print("-------- %s" % fname)
raw_data = open(fname).read()
Packet(raw_data).parse()
## step2
nb = populate_directory_with_packets("/tmp/proxy", "proxied-packets/")
for i in range(1,nb):
fname = "proxied-packets/pkt-%d" % i
print("-------- %s" % fname)
Packet( open(fname).read() ).parse()
import base64, sys, hashlib, struct
from Crypto import Random
from Crypto.Cipher import AES
from hexdump import hexdump
BLOCK_SIZE = 32
def p32(x):
return struct.pack("<I",x)
def u32(x):
return struct.unpack("<I",x)[0]
def decrypt(encrypted, passphrase, iv):
aes = AES.new(passphrase, AES.MODE_CBC, iv)
return aes.decrypt(encrypted)
if __name__ == "__main__":
data = open(sys.argv[1]).read()
# assert len(data) == 0x0089334, "file is 0x%x (expected 0x0089334)" % len(data)
print("[+] data_size = 0x%x" % len(data))
key = base64.b64decode("tCqlc2+fFiLcuq1ee1eAPOMjxcdijh8z0jrakMA/jxg=")
i = data.find("cryp")
i += 4
iv = data[i:i+0x10]
print("[+] iv: %s" % iv.encode('hex'))
i += 0x10
sha = data[i:i+0x20]
print("[+] sha: %s" % sha.encode('hex'))
i += 0x20
enc = data[i:]
if len(enc) % 16:
enc += '\x00' * (16-(len(enc) % 16))
dec = decrypt(enc, key, iv)
sz = u32(dec[:4])
filename = dec[4:4+sz]
filesize = u32(dec[4+sz:4+sz+4])
print("[+] filepath '%s'" % filename)
print("[+] filesize 0x%x" % filesize)
i = 4+sz+8
decrypted_file_content = dec[i:i+filesize]
print("[+] len(decrypted) 0x%x" % len(decrypted_file_content))
h = hashlib.sha256(decrypted_file_content).digest()
if h == sha:
print("[!!!] win ! dumping lab10.zip...")
open("lab10.zip", "wb").write(decrypted_file_content)
else:
print("[-] invalid sha256")
print("[-] decrypted_sha: %s" % h1)
print("[-] decrypted_sha: %s" % h2)
# password: infectedinfectedinfectedinfectedinfected919
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment