이번 seccon은 연합팀 'KOREAN'으로 나가게 되어 최종 4위를 하였습니다. 하지만 명예 한국인 한 분도 계셨다는ㅋㅋ.

사실 조금 늦게 참여하였는데 운이 좋게 리버싱 한 문제를 풀 수 있었습니다. 

 

 

다음은 리버싱 문제였던 'flag' 풀이입니다.

문제 클릭시 웹 사이트로 리다이렉트되며 알맞는 플레그를 웹에서 체크하는 문제였습니다. 리버싱 태그로 나왔기 때문에 살펴보면 wasm 웹 어셈블리어 바이너리가 존재하는걸 볼 수 있습니다. 즉, 해당 문제에서 플래그 문자열을 입력하고 체크 버튼을 클릭시 내부적으로 웹 어셈블리어 바이너리에서 검증을 하게 되는겁니다.

 

웹 어셈블리어를 분석할 때는 유명한 팁이 존재합니다. 바로 wasm 바이너리를 디컴파일 후 다시 elf로 빌드해서 보는 것입니다. 사실 디컴파일 소스로 봐도 무방은 하나 IDA Pro 에서 만들어주는 의사코드에 익숙해져 있기 때문에...

 

이렇게 만들어진 웹 어셈블리어 바이너리를 IDA Pro로 로딩했을 때 특징들이 존재합니다.

 

 첫 번째로는 init이 존재한다는 점입니다. 여기서 전역 변수 설정 등 여러가지 초기화를 거치게 됩니다.

 

두 번째로는 다음과 같이 store, load 등이 존재합니다. 이렇게 생긴 함수들을 살펴보면 i32는 int32를 나타내는 것이며 'store' 저장하겠다. 인자 3개는 메모레, 위치, 값 이라고 생각하면됩니다.

 

즉, i32_store(memory, offset, value)는 offset에 value를 저장, i32_load(memory, offest, value)는 offset 값을 가져온다는 뜻으로 생각하시면 됩니다.

 

 

다시 문제 페이지의 자바 스크립트를 확인하면 다음과 같은 인자와 호출되는 함수를 확인할 수 있습니다.

flag.wasm 안의 check 함수를 실행하며 매번 똑같은 key값과 enc 값을 넘겨주는 것을 볼 수 있습니다. 그렇다면 이제부터 check 함수를 분석해보면 됩니다.

 

 

check 함수 초반 부분부터 enum 을 사용해서 분석하면 다음과 같이 인자로 받은 3개의 값을 저장 후 어떠한 루틴을 통해 결과를 내는 것을 볼 수 있습니다.

 

이것들을 분석한 뒤 Python으로 포팅한 결과입니다.

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
import sys
def w2c_f23(key, idx1, idx2, idx3, idx4):
    key[idx2] =  ((( ((key[idx4] + key[idx1]) & 0xff>> 7| (2 * ((key[idx4] + key[idx1]) & 0xff))) ^ key[idx2]) & 0xff
    key[idx3] = ((( ((key[idx1] + key[idx2]) & 0xff>> 6| (4 * ((key[idx1] + key[idx2]) & 0xff))) ^ key[idx3]) & 0xff
    key[idx4] = ((( ((key[idx2] + key[idx3]) & 0xff>> 5| (8 * ((key[idx2] + key[idx3]) & 0xff))) ^ key[idx4]) & 0xff
    key[idx1] = ((( ((key[idx3] + key[idx4]) & 0xff>> 4| (16 * ((key[idx3] + key[idx4]) & 0xff))) ^ key[idx1]) & 0xff
 
def reverse_w2c_f23(key, idx1, idx2, idx3, idx4):
    key[idx1] = ((( ((key[idx3] + key[idx4]) & 0xff>> 4| (16 * ((key[idx3] + key[idx4]) & 0xff))) ^ key[idx1]) & 0xff
    key[idx4] = ((( ((key[idx2] + key[idx3]) & 0xff>> 5| (8 * ((key[idx2] + key[idx3]) & 0xff))) ^ key[idx4]) & 0xff
    key[idx3] = ((( ((key[idx1] + key[idx2]) & 0xff>> 6| (4 * ((key[idx1] + key[idx2]) & 0xff))) ^ key[idx3]) & 0xff
    key[idx2] =  ((( ((key[idx4] + key[idx1]) & 0xff>> 7| (2 * ((key[idx4] + key[idx1]) & 0xff))) ^ key[idx2]) & 0xff
 
 
myinput = b"a"* 55 + b"}"
enc = b"6dbf84f73cf6a112268b09525ea550a665e21cb2e3e13af7e3ea0ecb52f5b9cda5b6522b1e978734553f1d7956d4af94bfc3f4d68c8fba9eeecf4035550b9106f70d57d1a6cdaf3211eaaa78d71a9038b71be621241e8b608a43b107f8860f543ab0189aa063800de4bae7d0b11045b8"
key = b"NekoPunch"
key = key[:8]
 
data_segment_data_1 = b"0123456789abcdef"
 
if len(key) >= 8 and bytes([myinput[-1]]) == b"}" and len(myinput) * 4 == len(enc):
    
    dup_key = bytearray(key[:8+ (0x10 - len(key)) * b"\x00")
 
    result = 0
    for loop in range(0len(myinput), 8):
 
        for idx1 in range(8):
            char = myinput[idx1+loop]
            dup_key[8+idx1] = char
 
        for idx2 in range(0x80):
            w2c_f23(dup_key, 04812)
            w2c_f23(dup_key, 59131);
            w2c_f23(dup_key, 101426);
            w2c_f23(dup_key, 153711);
            w2c_f23(dup_key, 0123);
            w2c_f23(dup_key, 5674);
            w2c_f23(dup_key, 101189);
            w2c_f23(dup_key, 15121314);
 
        print()
 
 
 
        for idx3 in range(16):
            tmp1 = enc[loop + idx3]
            tmp2 = dup_key[idx3] // 16
            value = (tmp1 != data_segment_data_1[tmp2]) | result
            result = value
 
            tmp1 = enc[loop + idx3 + 1]
            tmp2 = dup_key[idx3] % 16
            value = (tmp1 != data_segment_data_1[tmp2]) | result
            result = value
 
        print(result)
 
 
cs

 

여기서 알 수 있는 사실은 인자로 받은 enc는 역산이 가능한 인코딩된 플래그 값입니다.

 

비트연산을 역으로 짜서 다시 돌리게 되면 플래그를 도출해낼 수 있습니다.

 

 

 

 

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
import sys
def w2c_f23(key, idx1, idx2, idx3, idx4):
    key[idx2] =  ((( ((key[idx4] + key[idx1]) & 0xff>> 7| (2 * ((key[idx4] + key[idx1]) & 0xff))) ^ key[idx2]) & 0xff
    key[idx3] = ((( ((key[idx1] + key[idx2]) & 0xff>> 6| (4 * ((key[idx1] + key[idx2]) & 0xff))) ^ key[idx3]) & 0xff
    key[idx4] = ((( ((key[idx2] + key[idx3]) & 0xff>> 5| (8 * ((key[idx2] + key[idx3]) & 0xff))) ^ key[idx4]) & 0xff
    key[idx1] = ((( ((key[idx3] + key[idx4]) & 0xff>> 4| (16 * ((key[idx3] + key[idx4]) & 0xff))) ^ key[idx1]) & 0xff
 
def reverse_w2c_f23(key, idx1, idx2, idx3, idx4):
    key[idx1] = ((( ((key[idx3] + key[idx4]) & 0xff>> 4| (16 * ((key[idx3] + key[idx4]) & 0xff))) ^ key[idx1]) & 0xff
    key[idx4] = ((( ((key[idx2] + key[idx3]) & 0xff>> 5| (8 * ((key[idx2] + key[idx3]) & 0xff))) ^ key[idx4]) & 0xff
    key[idx3] = ((( ((key[idx1] + key[idx2]) & 0xff>> 6| (4 * ((key[idx1] + key[idx2]) & 0xff))) ^ key[idx3]) & 0xff
    key[idx2] =  ((( ((key[idx4] + key[idx1]) & 0xff>> 7| (2 * ((key[idx4] + key[idx1]) & 0xff))) ^ key[idx2]) & 0xff
 
enc = b"\x6D\xBF\x84\xF7\x3C\xF6\xA1\x12\x26\x8B\x09\x52\x5E\xA5\x50\xA6\x65\xE2\x1C\xB2\xE3\xE1\x3A\xF7\xE3\xEA\x0E\xCB\x52\xF5\xB9\xCD\xA5\xB6\x52\x2B\x1E\x97\x87\x34\x55\x3F\x1D\x79\x56\xD4\xAF\x94\xBF\xC3\xF4\xD6\x8C\x8F\xBA\x9E\xEE\xCF\x40\x35\x55\x0B\x91\x06\xF7\x0D\x57\xD1\xA6\xCD\xAF\x32\x11\xEA\xAA\x78\xD7\x1A\x90\x38\xB7\x1B\xE6\x21\x24\x1E\x8B\x60\x8A\x43\xB1\x07\xF8\x86\x0F\x54\x3A\xB0\x18\x9A\xA0\x63\x80\x0D\xE4\xBA\xE7\xD0\xB1\x10\x45\xB8"    
myinput = enc
 
key = b"NekoPunch"
key = key[:8]
 
 
data_segment_data_1 = b"0123456789abcdef"
flag = b""
dup_key = bytearray(key[:8+ (0x10 - len(key)) * b"\x00")
result = 0
for loop in range(0len(myinput), 16):
 
    for idx1 in range(16):
        char = myinput[idx1+loop]
        dup_key[idx1] = char
 
 
    for idx2 in range(0x80):
        reverse_w2c_f23(dup_key, 15121314);
        reverse_w2c_f23(dup_key, 101189);
        reverse_w2c_f23(dup_key, 5674);
        reverse_w2c_f23(dup_key, 0123);
        reverse_w2c_f23(dup_key, 153711);
        reverse_w2c_f23(dup_key, 101426);
        reverse_w2c_f23(dup_key, 59131);
        reverse_w2c_f23(dup_key, 04812)
    
    flag += dup_key[8:]
    print(flag)
 
cs

 

최종적으로 다음과 같은 결과를 얻을 수 있습니다.

 

 

b'SECCON{w'
b'SECCON{wh4ts_Ur_'
b'SECCON{wh4ts_Ur_r3c0mm3n'
b'SECCON{wh4ts_Ur_r3c0mm3nd3d_w4y_'
b'SECCON{wh4ts_Ur_r3c0mm3nd3d_w4y_2_d3c0mp'
b'SECCON{wh4ts_Ur_r3c0mm3nd3d_w4y_2_d3c0mp1l3_WASM'
b'SECCON{wh4ts_Ur_r3c0mm3nd3d_w4y_2_d3c0mp1l3_WASM?}\x00\x00\x00\x00\x00\x00'

'# write-up > - ctf' 카테고리의 다른 글

Codegate 2019 - The Matirx  (5) 2019.01.30
GoogleCTF 2017 - food  (1) 2017.06.19
HUST 2017 - Mystic Crypt  (0) 2017.06.06
[DEFCON 2017] - pegem  (2) 2017.05.10
[Plaid CTF 2017] zamboni  (0) 2017.05.02

얼마 전 'RC3 2016' CTF에서 재밌는 메모리 포렌식 문제가 나왔다. 


500pt로 포렌식 분야에서 배점이 가장 높았고 유일하게 못 푼 문제였다.


'TrueCrypt'에 관한 문제였는데, 목표를 잘 못 잡아 결국 풀지 못했다.



ddddh@siftworkstation:~/Desktop/CTF/rc3/forensics$ vol.py -f memdump.raw imageinfo

Volatility Foundation Volatility Framework 2.4

Determining profile based on KDBG search...


          Suggested Profile(s) : Win7SP0x64, Win7SP1x64, Win2008R2SP0x64, Win2008R2SP1x64

                     AS Layer1 : AMD64PagedMemory (Kernel AS)

                     AS Layer2 : FileAddressSpace (/home/sansforensics/Desktop/CTF/rc3/forensics/memdump.raw)

                      PAE type : No PAE

                           DTB : 0x187000L

                          KDBG : 0xf80002c0a0a0

          Number of Processors : 4

     Image Type (Service Pack) : 1

                KPCR for CPU 0 : 0xfffff80002c0bd00L

                KPCR for CPU 1 : 0xfffff880009ef000L

                KPCR for CPU 2 : 0xfffff88003169000L

                KPCR for CPU 3 : 0xfffff880031df000L

             KUSER_SHARED_DATA : 0xfffff78000000000L

           Image date and time : 2016-11-16 11:24:51 UTC+0000

     Image local date and time : 2016-11-16 06:24:51 -0500




메모리 포렌식을 할 때 가장 먼저 해야될 일은 'imageinfo'를 통해 KDBG 스캔을 하는 것이다.


결과를 통해 나온 Profile 중 하나를 지정해줘서 셋팅 해준다.



ddddh@siftworkstation:~/Desktop/CTF/rc3/forensics$ vol.py -f memdump.raw --profile=Win7SP0x64 pslist

Volatility Foundation Volatility Framework 2.4

Offset(V)          Name                    PID   PPID   Thds     Hnds   Sess  Wow64 Start                          Exit                          

------------------ -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------

0xfffffa8003c78b30 System                    4      0    111      531 ------      0 2016-11-16 11:00:14 UTC+0000                                 

0xfffffa8006239040 smss.exe                316      4      2       32 ------      0 2016-11-16 11:00:14 UTC+0000                                 

0xfffffa80058f95f0 csrss.exe               396    380      9      477      0      0 2016-11-16 11:00:15 UTC+0000                                 

0xfffffa800662d780 wininit.exe             440    380      3       78      0      0 2016-11-16 11:00:15 UTC+0000                                 

0xfffffa80066342e0 csrss.exe               464    452     12      409      1      0 2016-11-16 11:00:15 UTC+0000                                 

0xfffffa800677f5f0 services.exe            508    440      9      225      0      0 2016-11-16 11:00:15 UTC+0000                                 

0xfffffa80067819d0 lsass.exe               524    440      7      608      0      0 2016-11-16 11:00:15 UTC+0000                                 

0xfffffa8006787b30 lsm.exe                 532    440     10      159      0      0 2016-11-16 11:00:15 UTC+0000                                 

0xfffffa80067d2260 winlogon.exe            588    452      5      118      1      0 2016-11-16 11:00:15 UTC+0000                                 

0xfffffa8006790b30 svchost.exe             680    508      9      371      0      0 2016-11-16 11:00:15 UTC+0000                                 

0xfffffa800672e650 vmacthlp.exe            740    508      3       60      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa8006865b30 svchost.exe             780    508      9      293      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa80068a2060 svchost.exe             848    508     20      509      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa80068c0b30 svchost.exe             900    508     20      458      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa80068deb30 svchost.exe             944    508     40     1063      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa800695b320 svchost.exe             340    508      9      535      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa800698ab30 svchost.exe            1032    508     16      385      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa8006a47380 spoolsv.exe            1212    508     12      356      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa8006abb890 svchost.exe            1252    508     17      323      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa8006a1bb30 VGAuthService.         1404    508      3       89      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa8006c1f780 vmtoolsd.exe           1464    508      9      307      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa8006d0bb30 WmiPrvSE.exe           1724    680     12      226      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa8006c43060 dllhost.exe            1920    508     13      198      0      0 2016-11-16 11:00:16 UTC+0000                                 

0xfffffa8006dc0b30 msdtc.exe              2040    508     12      147      0      0 2016-11-16 11:00:17 UTC+0000                                 

0xfffffa8006d616c0 svchost.exe            1312    508      6       96      0      0 2016-11-16 11:00:17 UTC+0000                                 

0xfffffa8004c924f0 taskhost.exe           2324    508      8      194      1      0 2016-11-16 11:00:30 UTC+0000                                 

0xfffffa8005218890 GoogleCrashHan         2472   2448      5      103      0      1 2016-11-16 11:00:31 UTC+0000                                 

0xfffffa8005221b30 GoogleCrashHan         2480   2448      5       97      0      0 2016-11-16 11:00:31 UTC+0000                                 

0xfffffa800526db30 dwm.exe                2604    900      3       78      1      0 2016-11-16 11:00:32 UTC+0000                                 

0xfffffa8005284780 explorer.exe           2628   2592     34      947      1      0 2016-11-16 11:00:32 UTC+0000                                 

0xfffffa800528db30 vmtoolsd.exe           2716   2628      6      251      1      0 2016-11-16 11:00:32 UTC+0000                                 

0xfffffa8005289b30 StikyNot.exe           2724   2628     11      145      1      0 2016-11-16 11:00:32 UTC+0000                                 

0xfffffa8006ec7060 SearchIndexer.         2784    508     15      693      0      0 2016-11-16 11:00:32 UTC+0000                                 

0xfffffa8006ecbb30 RAMDisk.exe            2956   2628     25      729      1      0 2016-11-16 11:01:44 UTC+0000                                 

0xfffffa8005798430 svchost.exe            1044    508     10      158      0      0 2016-11-16 11:01:50 UTC+0000                                 

0xfffffa8006db2b30 wisptis.exe             704   2956      6      132      1      0 2016-11-16 11:01:52 UTC+0000                                 

0xfffffa8006fa5060 MappedDrives.e         1508   2956      0 --------      1      0 2016-11-16 11:01:54 UTC+0000   2016-11-16 11:01:54 UTC+0000  

0xfffffa8003eb4b30 chrome.exe              748   2628     28     1069      1      0 2016-11-16 11:01:59 UTC+0000                                 

0xfffffa8003ec3200 chrome.exe              936    748      6       85      1      0 2016-11-16 11:01:59 UTC+0000                                 

0xfffffa8003f93060 chrome.exe             1148    748      5      182      1      0 2016-11-16 11:01:59 UTC+0000                                 

0xfffffa8003f3a250 chrome.exe             1168    748     10      172      1      0 2016-11-16 11:01:59 UTC+0000                                 

0xfffffa80040449c0 chrome.exe             2672    748     16      214      1      0 2016-11-16 11:01:59 UTC+0000                                 

0xfffffa8006b4a060 chrome.exe             2952    748     10      154      1      0 2016-11-16 11:01:59 UTC+0000                                 

0xfffffa80041b9360 chrome.exe             3188    748     10      308      1      0 2016-11-16 11:02:00 UTC+0000                                 

0xfffffa800613d540 mscorsvw.exe           3620    508      7       90      0      1 2016-11-16 11:02:17 UTC+0000                                 

0xfffffa8004280780 mscorsvw.exe           3664    508      7       83      0      0 2016-11-16 11:02:17 UTC+0000                                 

0xfffffa8003fbab30 sppsvc.exe             3808    508      4      153      0      0 2016-11-16 11:02:17 UTC+0000                                 

0xfffffa8003fc3b30 svchost.exe            3848    508     12      333      0      0 2016-11-16 11:02:17 UTC+0000                                 

0xfffffa80041e2b30 chrome.exe             1068    748     13      261      1      0 2016-11-16 11:04:23 UTC+0000                                 

0xfffffa80068beaa0 audiodg.exe            3476    848      7      137      0      0 2016-11-16 11:17:42 UTC+0000                                 

0xfffffa8006af31b0 taskmgr.exe            3368   3760      8      131      1      0 2016-11-16 11:22:07 UTC+0000                                 

0xfffffa8006aec270 SearchProtocol         2032   2784      7      215      1      0 2016-11-16 11:24:31 UTC+0000                                 

0xfffffa8004252600 SearchFilterHo         3268   2784      5       97      0      0 2016-11-16 11:24:31 UTC+0000                                 

0xfffffa8006b0c450 DumpIt.exe             1536   2628      5       53      1      1 2016-11-16 11:24:41 UTC+0000                                 

0xfffffa8006ab81d0 conhost.exe            1220    464      2       51      1      0 2016-11-16 11:24:41 UTC+0000                                 




현재 실행 중인 프로세스 리스트를 출력해주는 플러그인이다.


우리가 평소에 흔히 접할 수 있는 'StikyNot.exe', 'chrome.exe'이 보이고 덤프는 'DumpIt.exe'으로 만든 것을 확인할 수 있다.



ddddh@siftworkstation:~/Desktop/CTF/rc3/forensics$ vol.py -f memdump.raw --profile=Win7SP0x64 screenshot -D ./Screenshot/

Volatility Foundation Volatility Framework 2.4

Wrote ./Screenshot/session_0.msswindowstation.mssrestricteddesk.png

Wrote ./Screenshot/session_0.Service-0x0-3e4$.Default.png

Wrote ./Screenshot/session_0.Service-0x0-3e5$.Default.png

Wrote ./Screenshot/session_0.WinSta0.Default.png

Wrote ./Screenshot/session_0.WinSta0.Disconnect.png

Wrote ./Screenshot/session_0.WinSta0.Winlogon.png

Wrote ./Screenshot/session_0.Service-0x0-3e7$.Default.png

Wrote ./Screenshot/session_1.WinSta0.Default.png

Wrote ./Screenshot/session_1.WinSta0.Disconnect.png

Wrote ./Screenshot/session_1.WinSta0.Winlogon.png

Wrote ./Screenshot/session_1.Service-0x0-63bca$.sbox_alternate_desktop_0x2EC.png







'screenshot' 플로그인은 덤프를 만들고 있던 당시의 화면을 확인할 수 있다. 


pslist의 결과에서 보았듯이, Stickynote와 chrome을 확인할 수 있다.




sansforensics@siftworkstation:~/Desktop/CTF/rc3/forensics$ vol.py -f memdump.raw --profile=Win7SP0x64 filescan




filescan 플러그 인으로 메모리 덤프안의 파일들을 리스트 형식으로 출력할 수 있다.


출력된 결과물을 확인하면 Sticknote를 확인할 수 있고, 'dumpfiles' 플러그인으로 뽑아내어 내용을 확인할 수 있다.


 0x000000013ceb23a0     17      1 RW-r-- \Device\HarddiskVolume2\Users\Donald Trump\AppData\Roaming\Microsoft\Sticky Notes\StickyNotes.snt'




ddddh@siftworkstation:~/Desktop/CTF/rc3/forensics$ vol.py -f memdump.raw --profile=Win7SP0x64 dumpfiles -Q 0x000000013ceb23a0 -D ./

Volatility Foundation Volatility Framework 2.4

DataSectionObject 0x13ceb23a0   None   \Device\HarddiskVolume2\Users\Donald Trump\AppData\Roaming\Microsoft\Sticky Notes\StickyNotes.snt



'True crypt container in evidence drive(E) and password in Lastpass'


라는 글을 확인할 수 있다.


또 한, 'chromesearchterms' 플러그인을 사용하여 크롬에 대한 정보를 얻을 수 있다.


ddddh@siftworkstation:~/Desktop/CTF/rc3/forensics$ vol.py -f memdump.raw --profile=Win7SP0x64 --plugins=/home/ddddh/v-plugins/ chromesearchterms

Volatility Foundation Volatility Framework 2.4

Row ID Keyword ID URL ID Lowercase                                                        Entered Text                                                    

------ ---------- ------ ---------------------------------------------------------------- ----------------------------------------------------------------

     9       5135     13 

                                                                

                                                               

    11          2     47 facebook                                                         facebook                                                        

    10          2     43 .net framework 4.5 offline installer                             .net framework 4.5 offline installer                            

     9          2     42 .net framework 4.5                                               .net framework 4.5                                              

     8          2     31 lastpass extension                                               lastpass extension                                              

     7          2     30 ramdisk filehippo                                                ramdisk filehippo                                               

     6          2     29 truecrypt                                                        truecrypt                                                       

     5          2     26 lastpass                                                         lastpass                                                        

     4          2     21 wireshark                                                        wireshark                                                       

     3          2     18 winrar                                                           winrar                                                          

     2          2     15 atom                                                             atom                                                            

     1          2     14 sysinternals                                                     sysinternals                                                    



출력된 결과를 보면 'lasspass', 'truecrypt' 두 가지를 발견할 수 있다.



lastpass 라는 플러그인으로 추출 후 복호화 하면 flag가 나온다. 

'# write-up > - ctf' 카테고리의 다른 글

[Plaid CTF 2017] no_mo_flo  (0) 2017.04.27
[ALEX CTF] RE5: packed movement  (0) 2017.02.07
[RC3 2016] - Reversing 200pt  (0) 2016.11.21
[RC3 2016] - Reversing 350pt  (0) 2016.11.21
[RC3 2016] - Reversing 100pt  (0) 2016.11.21


http://blog.naver.com/yheekeun/220867134574


같은 팀 yokkkkk님의 풀이




Reversing

 -f1ay.yokkkkk



[그림 1] main

 

main은 이렇게나 간단하다.. memcpy(flag, enc(입력값), 0x23) 해서 일치하면 정답이다.



 

[그림 2] enc 내부

 

내가 입력한 값을 d,a,d,?로 차례대로 암호화 시키는 것이다.

 

복호화 소스를 짜보자

 

[그림 3] 복호화 소스

 

 

[그림 4] sol

내가 찾고자하는 플레그가 아니라고 한다...

 

엄청난 삽질 끝에,

 

 

 

[그림 5] 바이너리 끝

 

FLAG가 뒤집혀 들어가있는 것을 알 수 있다그리고 문제이름도 elf의 반대인 fle이다.

바이너리를 뒤집어보자

 

[그림 6] 뒤집기

 

 

 

[그림 7] 수정

 

fix_fle 파일 내부인데 ELF 헤더 시그니쳐를 입력해주자

 

 

 

 

 

[그림 8] 정상 실행

 

제대로 된 바이너리 파일을 찾았단다.

 

 

[그림 9] syscall

syscall로 값을 입력을 받고 0x1F 길이를 비교한다즉 입력값이 0x1f

 

 

 

[그림 10] 연산 루틴

 

byte_8048000-0x8048000 부분에 내가 어떠한 바이너리와 내가 입력한 값을 xor연산하여 넣는다.

 

 

 

 

[그림 11] 체크 루틴

[그림 10]에서의 루틴이 완료 되면 왼쪽으로 넘어와서 체크루틴 sub_804804c 가 실행되고,

eax가 0이라면 offset word_80481c2 부분의 바이너리를 0x55와 xor하여 완성된 성공 구문을 출력 시켜준다.

 


[그림 12] sub_804804c 체크루틴

 

설명하자면 [그림 10]에서의 연산루틴을 거친 것과 비교를 하는 것을 알 수 있다.

동적분석을 통해 확인해보면 0x1d만큼 반복문을 돌리며 sub bl, [edx]에 의해 값이 같으면 eax에 0이 더해지고 다르면 eax의 값이 올라가므로 전부 일치하게되면 eax가 0이되어 correct문을 띄우게 된다.




[그림 13] 내가 입력한값과 연산

빨간색과 내가입력한 값이 xor연산되어 나중에 어떠한 바이너리값과 비교하게된다.

 



어떠한 바이너리값은 아래와 같다.(그림 11. 0x8049bcc-0x8048000의 file offset)


[그림 14] 바이너리

 

 

 

[그림 15] 복호화 소스

[출처] RC3 CTF - FLE (200)|작성자 헤헤

[출처] RC3 CTF - FLE (200)|작성자 헤헤

'# write-up > - ctf' 카테고리의 다른 글

[Plaid CTF 2017] no_mo_flo  (0) 2017.04.27
[ALEX CTF] RE5: packed movement  (0) 2017.02.07
[RC3 2016] 메모리 포렌식 - 500pt  (0) 2016.11.27
[RC3 2016] - Reversing 350pt  (0) 2016.11.21
[RC3 2016] - Reversing 100pt  (0) 2016.11.21

대회기간 : 토요일, 19 11월 2016, 02:00 UTC — 월요일, 21 11월 2016, 07:00 UTC 

대회명 : RC3

문제 : RC3Ciper - Reversing [350pt]

RC3Cipher



제일 고득점이지만 제일 쉬운 문제. 

아마 출제자의 의도는 이렇게 푸는게 아니였지 싶다...

CTF는 푸는 속도가 생명이기 때문에 풀이의 질이 다소 떨어질 수 있습니다.  <- 변명



1. 흐름 파악





바이너리를 IDA로 열어서 String 값을 확인 해보면 어떠한 Hash값과 "Your ciphertext is %s"가 보인다.

입력 값을 통해 연산된 cipher text를 출력해주는 것 같다.



  


flay_ddddh 를 인자로 넘겨 주었을 때 암호화 된 결과 값은 입력 길이의 2배다.

그리고 "Generic response one."을 출력 해준다. 아마  "Generic response two."를 출력해주도록 하는게 답일 것 같아 보인다.




2. 동적 분석


정적 분석은 생략한다. 동적 분석 짱짱맨





친절하게 functionone, functiontwo가 보인다. 물론 그 전에도 어떠한 연산이 있지만 푸는데 지장 없으므로 생략 합니다.







eax의 0x79 ('y')의 값을 rbp-44에 넣고 밑에서 0x79만큼 반복한다.







??????

-1 을 해주면서 00까지 채운다. 근데 왜 하필 0x79 ('y') 였을까 ....

파라미타 값이 'f1ay_ddddh'였다 ?!


그렇다... 파라미타 값 중 ASCII 값이 가장 큰 값 'y'가 들어간 것이다.






3. 노가다


딴 거 다 필요 없다... 입력 값 중 가장 큰 값을 통해서 연산을 하는 것을 확인한 이상 답은 쉽게 구할 수 있다.


문제를 풀면서 알아 낸 RC3의 FLAG FORMAT은 "RC3-2016-????"이다. 그러면 입력 해 보자.




음... IDA string값으로 확인 한 hash값이랑 맞지 않는다.


비교 값 : 1b65380f084b59016875513c6373131d2a6a327172753a2918243d7b181a051e5f1e104c32331c0842777b375f100113


즉, 이 다음부터 나의 ciphertext가 1b6538.. 이 되게 가장 큰 ASCII를 찾아주면 된다.




  

가장 큰 값은 'Y'인 걸 확인했고, 그다음 문자도 운이 좋게 'Y'다.

입력 가능 값은 '0x59' 보다 작아야되므로 수동으로 해도 빠르게 알아낼 수 있다.





FLAG : RC3-2016-Y0UR-KSA-IS-BAD-@ND-Y0U-SH0ULD-F33L-BAD



'# write-up > - ctf' 카테고리의 다른 글

[Plaid CTF 2017] no_mo_flo  (0) 2017.04.27
[ALEX CTF] RE5: packed movement  (0) 2017.02.07
[RC3 2016] 메모리 포렌식 - 500pt  (0) 2016.11.27
[RC3 2016] - Reversing 200pt  (0) 2016.11.21
[RC3 2016] - Reversing 100pt  (0) 2016.11.21

대회기간 : 토요일, 19 11월 2016, 02:00 UTC — 월요일, 21 11월 2016, 07:00 UTC 

대회명 : RC3

문제 : logmein - Reversing [100pt]

logmein






1. 흐름 파악




바이너리를 다운 받고 HxD로 열어보면 ELF파일임을 알 수 있다. 

64 bit ELF파일이었고 IDA를 통해서 정적 분석을 먼저 시도하였다. (RC3의 모든 Reversing는 64 bit / ELF 바이너리였다.)





String 값들을 확인해 보면 "Enter your guess"에서 Data를 넘겨주면 어떠한 연산을 거쳐 성공 분기점이 나눠지는 걸 알 수 있다.








2. 정적 분석




scanf로 입력 값을 받은 뒤 strlen으로 입력 길이를 체크 후 분기점으로 나뉘게 된다.

또 한, 중간중간 연산 결과값이 틀리면 INCORRECT 분기점으로 넘어가게 된다.






모든 연산을 정상적으로 마치면 CORRECT 문자열을 뛰어주는 콜 문을 실행해주게 된다.




3. 동적 분석





입력 값은 "f1ay_ddddh", 길이는 0xA 다.

즉, 입력 값 길이는 0x11이 되어야 한다. 일단 강제 패치 후 연산 부분으로 넘어간다.






[rbp - 0x32] - 0x3A, 0x22, 0x41, 0x4C, 0x5F, 0x52, 0x54, 0x5E, 0x4C, 0x2A, 0x2E, 0x3F, 0x2B, 0x36, 0x2F, 0x34, 0x36

[rbp - 0x40] - 0x68, 0x61, 0x72, 0x61, 0x6D, 0x62, 0x65


두 주소에서 값을 하나씩 가져와서 xor 연산을 해준 뒤, 밑의 cmp에서 입력했던 값이랑 비교하는 걸 확인할 수 있다.






4. 플래그 도출








'# write-up > - ctf' 카테고리의 다른 글

[Plaid CTF 2017] no_mo_flo  (0) 2017.04.27
[ALEX CTF] RE5: packed movement  (0) 2017.02.07
[RC3 2016] 메모리 포렌식 - 500pt  (0) 2016.11.27
[RC3 2016] - Reversing 200pt  (0) 2016.11.21
[RC3 2016] - Reversing 350pt  (0) 2016.11.21

+ Recent posts