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