pwnable.kr(2)
布教用兼確認の2記事目
col
2つ目の問題。
col@ubuntu:~$ ls -l total 16 -r-sr-x--- 1 col_pwn col 7341 Jun 11 2014 col -rw-r--r-- 1 root root 555 Jun 12 2014 col.c -r--r----- 1 col_pwn col_pwn 52 Jun 11 2014 flag
MD5って書いてあったから多分、ソースコードcol.cのlongのハッシュコードがMD5なんだと思う。16バイト(128ビット)だし。MD5のアルゴリズムとは何にも関係なさそう。
ソースコードを見てみると、プログラムの引数に値を渡すタイプだって事がわかる。長さは20じゃないとダメ。
if(strlen(argv[1]) != 20){ printf("passcode length should be 20 bytes\n"); return 0; }
長さが20でもcheck_passwordの戻り値と定数hashcodeが同じじゃないとダメ。
check_passwordは20バイトの文字列を先頭から4バイトずつリトルエンディアンの整数として5回足すというもの。
unsigned long check_password(const char* p){ int* ip = (int*)p; int i; int res=0; for(i=0; i<5; i++){ res += ip[i]; } return res; }
この戻り値をhashcodeに合わせれば良い。合わせるパターンはいくらでもあるけど、¥x00(ヌル文字)とかは文字列が終了して使えなかったり、アラームとかも使えないんじゃないかって思ったりするので、そういうところは気をつける。
今回は、hashcodeを5で割って最後のにオフセットをつける。hashcodeは0x21DD09ECっていうことを踏まえて、算出する。python3のインタプリターで。
>>> from struct import pack >>> pack('i',0x21DD09EC//5) b'\xc8\xce\xc5\x06' >>> pack('i',0x21DD09EC//5+0x21DD09EC%5) b'\xcc\xce\xc5\x06'
これで準備は整った。
ぶち込んでやるぜぇ。
col@ubuntu:~$ ./col `python -c 'print "\xc8\xce\xc5\x06"*4+"\xcc\xce\xc5\x06"'`
おしまい。