2020年12月3の21:30 - 12月4日21:30 で行われていた、Shakti CTF 2020の [Web] 分野のwriteupです。
※ まとめはこちら tech.kusuwada.com
AuthEN
Ada is important to the world, she is important for a reason
リンクを踏むと、こんなログイン画面
ソースを見てみると、怪しいところが。
if(username == “admin” && password == String.fromCharCode(115, 104, 97, 107, 116, 105, 99, 116, 102, 123, 98, 51, 121, 48, 110, 100, 95, 112, 117, 114, 51, 95, 99, 52, 108, 99, 117, 108, 97, 116, 105, 48, 110, 115, 125))
もうすでにflagになってそう。
arr = [115, 104, 97, 107, 116, 105, 99, 116, 102, 123, 98, 51, 121, 48, 110, 100, 95, 112, 117, 114, 51, 95, 99, 52, 108, 99, 117, 108, 97, 116, 105, 48, 110, 115, 125] for a in arr: print(chr(a), end='')
実行結果
$ python solve.py shaktictf{b3y0nd_pur3_c4lculati0ns}
Ador
Ada was born on 10 December 1815 not 12, identification change makes a difference
urlを訪れるとこんなページ
Welcome user, secrets only for admin
これが気になる。
cookieとhtmlソースを確認。ソースに
use
name
for user
的なコメントが書いてあるのも気になる。
色々いじったりUAを変えてみたりしたけどわからなかったので、上の文言からなんとなくurlのparameterクエリに?name=admin
を入れたらflagが出た。
Biscuits
Ada Lovelace used to love eating french biscuits during her work
これはタイトルからcookie関連かな?と想像。
cookie見たらそのまんまフラグが書いてあった。
THE_FLAG_IS
:
shaktictf%7Bc00k13s_m4k3_phr3n0l0gy%26m3sm3r15m_3asy%7D
url decodeして
shaktictf{c00k13s_m4k3_phr3n0l0gy&m3sm3r15m_3asy}
Machine
Babbage was impressed by Lovelace's intellect and analytic skills that he called her a humanoid
topページはこんな感じ。
Humanoid robot of maths
これは robots.txt
問の予感。
http://34.72.245.53/Web/Machine/robots.txt
にアクセスしてみると
User-agent: * Allow: /var/www/html/ Disallow: /mkiujnbhytgbvfr.html
ほうほう。このdisallowのページにアクセスできれば良さそう。
何も考えずに
http://34.72.245.53/Web/Machine/mkiujnbhytgbvfr.html
にアクセスするとFlagがありました。
flag: shaktictf{7h3_3nch4n7r355_0f_Nu3b3r}
Doors
Ada Loves to travel to places, London-Paris-Spain and discover more
topはこんな感じ
ここから飛べるサイトは特にflagのヒントなし。
flag.txt
, flag.php
, file0.php
, file4.php
などをpathトラバーサルしたりしてみたがヒットせず。
index.phpのソースコードに
<!-- ?page -->
というコメントがあたので、?page=hogehoge
みたいな感じでクエリを投げられそうなことがわかる。
?page=file1.php
とすると、file1の内容が表示される。
?page=index.php
とすると、fileの表示に使われている関数が表示された。
この関数には PHP: file_get_contents - Manual のとおり何でも突っ込めるので、上記試したようなファイルを推測して色々試してみたが特にめぼしい成果はなし。
どういう問題が出されるんだろうな?とfile_get_contents ctf
的な感じでぐぐってみるとnoisyさんのDEFCONのwriteupを発見。
DefCamp CTF Qualification 2017 writeup - Qiita
/etc/passwd
にflagがあった、とある!
easy問題にしては推測部分が多いから違うかもな?と思いつつ ?page=/etc/passwd
を入れると、flagがいました!
PharAway
Explaining the Analytical Engine's function was a difficult task, bypass the basic php to see what she tried to explain
index.php
が配布されます。
<?php include('flag.php'); $a=$_GET['flag0']; if(strlen($a)>3){ } if($a>900000000){ echo "<h1>".$flag[0]."</h1>"; } #------------------------------------------------------------------------------------------------------------------ $_p = 1337; $_l = 13; $l = strlen($_GET['secret']); $_i = intval($_GET['secret']); if($l !== $_l || $_i !== $_p) { die("bye"); } echo "<h1>".$flag[1]."</h1>"; #----------------------------------------------------------------------------------------------------------------------- if (isset($_GET['a']) and isset($_GET['b'])) { if ($_GET['a'] === $_GET['b']) print 'Your password can not be your dog\'s name.'; else if (sha1($_GET['a']) === sha1($_GET['b'])) echo "<h1>".$flag[2]."</h1>"; else print '<p class="alert">Invalid password.</p>'; } #----------------------------------------------------------------------------------------------------------------------------- if (!isset($_GET["md4"])) { die(); } if ($_GET["md4"] == hash("md4", $_GET["md4"])) { echo "<h1>".$flag[3]."</h1>"; } else { echo "bad"; } #----------------------------------------------------------------------------------------------------------------------------- if (isset($_GET['abc'])){ if (!strcasecmp ($_GET['abc'], $flag[4])){ echo $flag[4];}} ?>
flag0
クエリが用意されていて、これが900000000より大きいと一つ目のflagが表示されるっぽい。
でた。format部分だ。
次は?secret
。文字列の長さが13で、intval
の値が1337になっていると通るみたい。なんとか進数で表したら良さそう。...と思ったけど、頭に0
つけるだけでいいや。
次はa
とb
。
sha1が衝突する別の値を入れれば良さそう。
Googleが2017年に発表した SHAttered を使って攻撃しようと思ったんだけど、もう手動実行の限界だ。スクリプトに移行しよう。
で、スクリプトで組んで、urlクエリにshattered-1
のPDF載せて送りつけてやろうと思ったんだけど、HTTP status response 414(too long)。ですよねー。。。
csictf 2020 Writeup - CTF フラxxグゲット
こちらのサイトに sha1 衝突の話が出ていて、値も短かったので良し!と思ったんだけど invalid password のまま。なんで?
var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));
$ echo -n 'aaroZmOk' | shasum -a 1 0e66507019969427134894567494305185566735 - $ echo -n 'aaK1STfY' | shasum -a 1 0e76658526655756207688271159624026011393 -
確かに違うな。
ここで競技終了。ここから復習。
競技環境は閉じてしまっている & localで再現するコードの配布もされていないので、writeupを見て復習。
これによると、sha1の衝突の件はarrayを突っ込むことで回避できたらしい。
&a[0]=asd&b[1]=dsf
asd,dsf
は適当で良さそう。
次のmd4
パラメータは、入力値とhashが一致したらOK。
このチェックの回避方法は、まさに
Magic Hashes | WhiteHat Security
で説明されているやつで、PHPの"0e"から始まって通じが続く文字列 (e.g. 0e134545364535464
) の==
演算子による比較が、0
として評価されてしまうため、中身によらず常に真と判定されてしまうことを利用する。
これを利用したMagic Hash
的な問題は前に解いたことがあったが(どれか見つけられなかった)、今回はHash前の値(左辺の$_GET["md4"]
)が0
と評価されれば良いので、Hash化後に0e{dddd}
になる値を探さなくてよく、単に0e{dddd}
をそのままmd4
に突っ込めば良い。
&md4=0e12345
最後のチェックはstrcasecmp
を使っているので、またarrayを突っ込めば良い。
&abc[]=xxx
これでflagが全部回収でき、くっつけたらOKのはず。残念ながら実際にペイロードを送って検証はできないが、次に出てきたときに役に立ちそう。
感想
XSSやSQL injection問題とかあると嬉しかったなー。
競技中に解けなかった PharAway が面白そうなので、是非復讐したい。sha1の一致のところで詰まってしまった。 -> 復習した。arrayで回避とは思ったより初歩的な解法であった…。