No cON Name CTF Quals 2014 writeup

チームdodododoで参加。最近はよく自分(@akiym)とれっくす(@xrekkusu)の2人で参加している。
結果は7位。finalsの参加権が貰えるらしいが、会場はスペインでおそらく交通費はでないので破棄ということに。問題は開始時にすべてオープンされる形になっており、全部で10問。朝7:00から始め、途中で寝て、3:40に全完。miscとwebに足を引っぱられた。

f:id:akiym:20140915071230p:plain

以下は問題の解説。

inBINcible

golangが吐くバイナリ。strippedされていないため、読むのはそこまで苦ではない。
まず、argv[1]が16文字であるか調べる。次に16個のgoroutine(main.func.001を参照)を生成してそれぞれ1文字ずつ比較して、その結果channelに出力している。すべての結果が正しければ正解になり"Yeah!"、間違っていれば"Nope!"。

0x08049456         xor        ecx, eb

0x08049466         movzx      ebp, byte [ds:esi]

実は文字列の比較ルーチンはxorしているだけ。gdbで0x08049456と0x8049469にブレークポイントを仕掛け、ecxとebpの値を取ってくる。

my @a = (0x12,0x45,0x33,0x87,0x65,0x12,0x45,0x33,0x87,0x65,0x12,0x45,0x33,0x87,0x65,0x12);
my @b = (0x55,0x75,0x44,0xb6,0xb,0x33,0x6,0x3,0xe9,0x2,0x60,0x71,0x47,0xb2,0x44,0x33);

for my $i (0..15) {
    print chr($a[$i] ^ $b[$i]);
}
G0w1n!C0ngr4t5!!

NcN_ce71ba32ccf191cc3b62ae73c7ffd1acf5e2f296

cannaBINoid

実行ファイルの先頭128バイトと入力した文字列128バイトが一致していればいい。それだけ。

NcN_effaf80a641b28a8d8a750b99ef740593bb3dcbd

STEGOsaurus

オーディオファイルといえば、まずやるのはスペクトログラム表示。

f:id:akiym:20140915071236p:plain

これはモールス信号。

-. -.-. -. ...-- -.-. -... ..-. -.. -.-. -.-. ---.. -.. --... .- ..--- ..... --... -.. ---.. ----- -.... ..--- ..... -.... ----- . ---.. ---.. -.. -.. --... -.. --... ..-. -.. -.... ..... -.. -.-. -.... ....- --... .-
ncn3cbfdcc8d7a257d8062560e88dd7d7fd65dc647a

最初に解いたのでfirst blood獲得。

CRYPTonite

spanish-book.enc。スペイン語の換字暗号らしい。記号も含まれているので既存のソルバーが使えない。とりあえず記号部分をアルファベットに置き換えて Cryptogram Solver (http://rumkin.com/tools/cipher/cryptogram-solver.php) のSpanish辞書を使ってみる。先頭の1行は以下のように変換された。

XL UIZXIUGBG FURCLZG RGI YPUVGMX RX LC NCIQFC
↓
EL INGENIOSO HIDALGO DON QUIJOTE DE LA MANCHA

ドン・キホーテスペイン語の原文があるのでそれと比較して文字を置換していく。

https://gist.github.com/rekkusu/47e369c3f74342970c31

テキスト内をNCNで検索するとflagがある。置換できなかった文字があるが、これは_に該当する文字はないため。

NCN_DEADBEAFCAFEBADBABEFEEDDEFACEDBEDFADEDEC

MISCall

git stash pop

NCN4dd992213ae6b76f27d7340f0dde1222888df4d3

imMISCible

disを使うことで読みやすい形に直してくれる。

import dis
dis.dis(marshal.loads(bytecode.decode('base64')))

おおざっぱに見ると文字列のhashlibのsha1を計算している。そして最後にNCNをくっつけるような処理がある。hexがたくさんあるのでこれのsha1を計算してるのだろうと推測。

 57 68 61 74 20 69 73 20 74 68 65 20 61 69 72 2d
 73 70 65 65 64 20 76 65 6c 6f 63 69 74 79 20 6f
 66 20 61 6e 20 75 6e 6c 61 64 65 6e 20 73 77 61
 6c 6c 6f 77 3f
echo -n 'What is the air-speed velocity of an unladen swallow?' | shasum
NCN6ceeeff26e72a40b71e6029a7149ad0626fcf310

proMISCuous

ずっと悩んでいたが、れっくすが"t"を入力したときに若干遅くなることを発見。サイドチャネル攻撃のようだ。スクリプトを書こうと思ったが遅延が小さいのか、なぜかうまくいかず悩んでいたところれっくすが人力で求めた。1文字ずつリズムを刻みながら試せば遅延がわかるらしい。

tIMeMaTTerS

NcN_15d07db12cd83174f0d19ce7e8c65a7c5ffba7df

WEBster

test:testでログインすることができる。ファイル一覧の中にflag.txtがあるが、アクセス拒否される。
cookieに付加されるlocはページ内のLocationより"10.128.29.136"のMD5を計算したものだとわかる。locをf528764d624db129b32c21fbca0cb8d6(127.0.0.1)に変更することでflag.txtを見ることができる。

NCN_f528764d624db129b32c21fbca0cb8d6

MakeMeFeeWet^Hb

index.phpにアクセスしてhtmlのソースを見ると、<!-- vim: set ts=2 sw=2: -->と書かれている。わざわざphpのコメントとしてではなくhtmlに書いたのだから何か意味があるのだろう。index.php~, login.php~はないし、index.php.swp, login.php.swpもないので数時間悩んだが、生成されるswpファイルは先頭に.がつくことを忘れていた。カレントディレクトリにswpファイルを生成する設定にしてないので馴染みがなかった。
したがって、.login.php.swpにアクセスするとソースコードの一部が得られる。

b0VIM 7.4
/ncn/web1/login.php
3210#"!
@$data = unserialize(hex2bin(implode(explode("\\x", base64_decode($cookie)))));
if (isset($_COOKIE['JSESSIONID'])) {
if ($username == "p00p" && $password == "l!k34b4u5") {
$this->p = $_passwd;
$this->u = $_uname;
public function __construct($_uname, $_passwd) {
public $p;
public $u;
class Creds {

p00p:l!k34b4u5でログインしてみるが、NOPE. But good try :)と言われる。おそらくJSESSINIDに対して何かしらのデータを投げるのだろう。ここで何をすればいいか困っていたところ、れっくすが適当に試していたらflagが出てきたとのこと。問題の意図が分からない。

O:5:"Creds":2:{s:1:"p";s:9:"l!k34b4u5";s:1:"u";s:4:"p00p";}
POST /makemefeelweb/login.php HTTP/1.1
Host: ctf.noconname.org
Connection: keep-alive
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
Cookie: JSESSIONID=XHg0Zlx4M2FceDM1XHgzYVx4MjJceDQzXHg3Mlx4NjVceDY0XHg3M1x4MjJceDNhXHgzMlx4M2FceDdiXHg3M1x4M2FceDMxXHgzYVx4MjJceDcwXHgyMlx4M2JceDczXHgzYVx4MzlceDNhXHgyMlx4NmNceDIxXHg2Ylx4MzNceDM0XHg2Mlx4MzRceDc1XHgzNVx4MjJceDNiXHg3M1x4M2FceDMxXHgzYVx4MjJceDc1XHgyMlx4M2JceDczXHgzYVx4MzRceDNhXHgyMlx4NzBceDMwXHgzMFx4NzBceDIyXHgzYlx4N2Q=
NcN_778064be6556e64577517875a8710b0abeba1578

eXPLicit

fork型のサーバでポート7070で起動する。static linkされている。0-20の数字を入力せよと言われ、決められた数字に対して高いか低いかを教えてくれる。合っていれば終了する。

f:id:akiym:20140915071239p:plain

my_printf(sockfd, your_number);としているために入力した文字列に対してformat string bugの脆弱性が存在する。
NXが有効。static linkされているのでreturn2libcには持っていくことができないが、gadgetが豊富なので困ることはない。ゲーム回数の制限はないため、何度もfsbすることができるのでreturn addressの推測、書き換えができる。やるだけ。
注意したいのはfork型のサーバなので標準入出力をdup2する必要があること。

https://gist.github.com/akiym/c00a0a277c04e6432d85

$ cat /home/ch5/flag.txt
NcN_97740ead1060892a253be8ca33c6364a712b21d