KPCTF-初赛wp
Sign_1n
签到题打开发现为Apache Tomcat/8.0.43在网上搜索会发现该版本存在后台弱口令+文件上传getshell
访问/manager/html路由tomcat/tomcat登陆
登陆后台会发现其存在war包上传
写一个蚁剑的shell.jsp压缩后,后缀改为war上传后在蚁剑连接
在根目录发现flag
How to get the flag
打开后查看index.php1
2
3
4
5
6
7
8
// flag in flag.php
show_source(__FILE__);
$file = $_GET['file'];
if (preg_match('/^[a-zA-Z0-9\/.]+$/', $file) && !preg_match('/(\.\.)|(\.\/)/', $file)) {
include '/tmp/'.$file;
}
我们会发现存在文件包含并且只能读取/tmp文件下的内容
扫描后台发现存在flag.php和phpinfo.php
仔细查看会发现其打开了Opcache
我们查一下会发现Opcache会将访问过的php文件进行缓存,该题的存储位置为/tmp
存储的结构为/tmp/system_id/var/www/html/xxx.php.bin
既然我们要读取flag.php的内容那么我们读取其缓存文件即可。那么我们的问题就变成了怎么得到这system_id
在php8版本system_id与这几个参数有光1
2
3PHP 版本号
Zend Extension
如果是dev版本的还与编译时间有关
该题的版本是8.0.30我们下载源码会发现其源码的Zend Extension和题目的Zend Extension 是一样的
即我们直接在本地的liunx编译这个版本的php并打开php.ini中的Opcache
开启php服务1
访问index.php
可以发现system_id
这样我们就得到了system_id
读取flag.php.bin文件
Bypass_it
1 |
查看源码我们会发现其明显存在一个原型链污染。
我们寻找merge函数会发现在登陆前使用了这个函数
而下面的/Access_Key_id
路由的登陆判断为cookie中的user的值为SECRETCOOKIE,或者req.user为admin,因为req.user的值是不存在的,那么我们就可以污染其原型的user为admin以此来绕过登陆验证
我们可以看到其污染位置过滤了`_proto我们可以使用
{“constructor”:{“prototype”:{}}}`来绕过
得到flag1
我们继续查看代码会发现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function Secret_Access_KeyController(req, res) {
let checkcode = req.body.checkcode ? req.body.checkcode : 1234;
console.log(req.body)
if (checkcode.length === 16) {
try {
checkcode = checkcode.toLowerCase()
if (checkcode !== "aGr5AtSp55dRacer") {
res.status(403).json({ "msg": "Invalid Checkcode1:" + checkcode })
}
} catch (__) { }
res.status(200).type("text/html").json({ "msg": "You Got Secret_Access_Key: " + Secret_Access_Key.toString().trim() })
} else {
res.status(403).type("text/html").json({ "msg": "Invalid Checkcode2:" + checkcode })
}
}
我们可以发现catch 处会抛出SK的值即flag2。那么我们只有让其在checkcode = checkcode.toLowerCase()处报错即可,我们直接令checkcode为数组并有16个元素即可
得到flag2
What’s_this
打开后扫目录会发现webshell.php代码如下
因为太长了所以我直接截图了如果复制的话转pdf会很难看
我们直接输出变量,并将eval只能的参数内容echo出来
会发现其套了娃,我们继续输出eval运行的参数
就这样重复的输出eval的参数会得到最后的shell的内容我们可以发现其参数为q
直接命令执行
calc
使用breakpoint()函数后即可随便执行命令