def add(self, taskid, poc, task_name, poc_name, status, target, app, result=""): if taskid and poc and task_name and poc_name and status and target and app: inserted_id = mongo[self.table].insert_one({ "taskid": taskid, "poc": poc, "task_name": task_name, "poc_name": poc_name, "status": status, "target": target, "app": app, "result": result, "date": self.localtime, }).inserted_id return str(inserted_id) else: logger.warning("pocsuite scan result insert failed: invalid data") raise DatabaseError("invalid data")
def SubdomainScan(rootdomain, project, freq): global company logger.info("[*] 开始找寻 {} 的子域名".format(rootdomain)) tmpid = str(uuid.uuid1()) TaskDB.add(taskid=tmpid, project=project, rootdomain=rootdomain, subdomain_count=0, portcount=0, flag=0, freq=int(freq)) one = OneForAll(target=rootdomain) one.format = "json" one.brute = True one.req = True one.run() oneres = one.datas logger.info("[*] 子域名入库") # ICP查询 # res = os.popen("curl https://api.66mz8.com/api/icp.php?domain={}".format(rootdomain)).read() domainkey = "" try: res = requests.get( 'http://apidata.chinaz.com/CallAPI/Domain?key={0}&domainName={1}}'. format(domainkey, rootdomain), verify=False) if json.loads(res.text)['StateCode'] == 1: company = json.loads(res.text)['Result']["CompanyName"] logger.info(company) except: logger.warning("查询域名的key失效") company = "Vulcan" with open("{0}/oneforall/results/{1}.json".format(plugindir, str(rootdomain))) as f: lines = f.read() tmp = json.loads(lines) subcount = len(tmp) ipcount = 0 logger.info("[+] 找到{0}的子域 {1} 个".format(rootdomain, (len(tmp)))) # 先获取所有子域名ip for i in range(0, len(tmp)): ip = tmp[i]["content"] if ip: ipcount += 1 flagnum = 0 for i in range(0, len(tmp)): ip = tmp[i]["content"] if ip: # print(ip) ip = tmp[i]["content"].split(',')[0] # 入库信息 flagnum += 1 tmpres = "%.2f%%" % ((flagnum / ipcount) * 100) subdomain = tmp[i]["subdomain"].strip("\n") logger.info("[+]Scanning subdomain: " + subdomain + "--IP: " + ip) main_scan.delay(tmpid, ip, project, subdomain, company, subcount, ipcount, tmpres) return project + "=====Subdomain Scanning!======="
def notice(contents, info="Wing"): ddheaders = {"Content-Type": "application/json; charset=utf-8"} try: data = '{ "markdown": { "title": "' + info + '!", "text": "' + \ contents + 'By IceWing" }, "msgtype": "markdown" }' resp = requests.post( url="https://oapi.dingtalk.com/robot/send?access_token=", data=data.encode('utf-8'), headers=ddheaders) except Exception as e: logger.warning(e)
def add(self, ip, referrer, data): if ip and data and referrer: inserted_id = mongo[self.table].insert_one({ "ip": ip.strip(), "data": data, "referrer": referrer, "date": int(time.time()) }).inserted_id return str(inserted_id) else: logger.warning("http request log insert failed: invalid data") raise DatabaseError("invalid data")
def main_scan(tmpid, ip, project, subdomain, company, subcount, ipcount, flagnum): queue = Queue() try: data = [ip, subdomain, subcount, company, tmpid, project] queue.put(data) threads = [] thread_count = 1 for i in range(thread_count): threads.append( PortScan(queue, tmpid, project, ipcount, flagnum=flagnum)) for t in threads: t.start() for t in threads: t.join() # f.close() return "=====分布式扫描中=====" except Exception as e: logger.warning(e)
def Title(self, scan_url_port, service_name, port): try: r = requests.get(scan_url_port, timeout=10, verify=False) r.encoding = 'utf-8' title = get_title(r.text) self.final_domains.append({ "url": scan_url_port, "title": title, "server": service_name, "port": port }) except Exception as e: logger.warning(e) self.final_domains.append({ "url": scan_url_port, "title": "空", "server": service_name, "port": port })
def add(self, domain, title, url, server, project, company_name, taskid, port=None, ip=None, icp=None): if domain: insert_id = mongo[self.table].insert_one({ "taskid": str(taskid), "domain": domain.strip(), "url": url, "ip": str(ip), "title": str(title), "server": str(server), "date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), "project": str(project), "company_name": str(company_name), "port": str(port), "icp": str(icp) }).inserted_id print(insert_id) return str(insert_id) else: logger.warning('入库error') raise DatabaseError("invalid data")
def Scan(self, scan_ip): nm = nmap.PortScanner() try: if len(self.ports) == 0: self.final_domains.append({ "url": "http://" + scan_ip, "title": "空", "server": "空", "port": 0 }) else: for port in self.ports: ret = nm.scan(scan_ip, port, arguments='-Pn,-sS') service_name = ret['scan'][scan_ip]['tcp'][int( port)]['name'] logger.info('[*]主机 ' + scan_ip + ' 的 ' + str(port) + ' 端口服务为:' + service_name) if service_name or service_name == 'sun-answerbook': if service_name == 'https' or service_name == 'https-alt': scan_url_port = 'https://' + scan_ip + ':' + str( port) self.Title(scan_url_port, service_name, port) else: scan_url_port = 'http://' + scan_ip + ':' + str( port) self.Title(scan_url_port, service_name, port) else: self.final_domains.append({ "url": "http://" + scan_ip + ":" + str(port), "title": "空", "server": service_name, "port": port }) # return final_domains except Exception as e: logger.warning(e)
def Portscan(host, ports, projectid, threads): try: ip = socket.gethostbyname(host) try: res = requests.get( 'https://api.tx7.co/icp.php?url={0}'.format(host), timeout=3) company_name = json.loads(res.text)["主办名称"] logger.warning(message=company_name) except Exception as e: logger.warning(message=e) company_name = "snowing" portserver = dict() singleportdetail = {} np = nmap.PortScanner() np.scan(hosts=ip, ports=ports, arguments="-Pn -sT") if 'tcp' in np[ip].all_protocols(): for port in np[ip]["tcp"].keys(): if np[ip]["tcp"][port]["state"] == "open": pattern = re.compile( '(php)|(aspx?)|(jsp)|(python)|(go?)|(ruby)', re.I) match = pattern.search(np[ip]["tcp"][port]["extrainfo"]) if match: codes = match.group().lower() else: codes = "" # host = host port = port server = np[ip]["tcp"][port]["name"] product = np[ip]["tcp"][port]["product"] state = np[ip]["tcp"][port]["state"] extrainfo = np[ip]["tcp"][port]["extrainfo"] codes = codes version = np[ip]["tcp"][port]["version"] url = "http://{0}:{1}".format(host, port) try: res = requests.get(url=url, timeout=5) res.encoding = 'utf-8' soup = BeautifulSoup(res.text, 'lxml') title = soup.find('title').text except: title = "" # 指纹识别 try: resp = requests.get( url= "http://api.yunsee.cn/fingerApi/?token=&id\=191&url\={0}:{1}\&level\=2" .format(host, port), timeout=5) temp = json.loads(resp.text) if temp['data']['cms']: finger = temp['data']['server'][0]['name'] + " " + temp['data']['cms'][0]['name'] + \ temp['data']['cms'][0]['version'] else: finger = server except: finger = server # 目录扫描 dirscan = webdir(str(url), int(threads)) dirscan.work() path = dirscan.output() # return path singleportdetail[str(port)] = { "port": port, "finger": finger, "title": title, "product": product, "state": state, "extrainfo": extrainfo, "codes": codes, "version": version, "path": path } portserver.setdefault("portserver", singleportdetail) # print(portserver) VulnScanDB.AddVulScan(projectid=projectid, host=host, ip=ip, portserver=portserver, company_name=company_name) return portserver except Exception as e: print(e) return "[!]" + str(e) + "[======]PortScan Error!"
def celery_pocscan(pid, flag): from app.api.common.utils.utils import target_parse, poc_config_init from app.api.common.utils.pocsuite_api import pocsuite_scanner try: items = PocscanTask.find_by_id(pid) taskname = items['name'] target_list = target_parse(items["target"]) poc_list = items["poc"] thread = items['thread'] if flag == 1: PocscanTask.update_by_id( pid, { "status": "Running", "end_date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) }) else: PocscanTask.update_by_id(pid, {"status": "Running"}) count = 0 for poc_id in poc_list: poc_item = PocsuiteDB.get_detail_by_id(poc_id) if not poc_item: continue _poc_config = poc_config_init( target_list=target_list, poc_str=poc_item['poc_content'].replace('\\ufeff', ''), threat=thread) _scan_items = pocsuite_scanner(_poc_config) for _item in _scan_items: try: result = _item['result'] if _item['result'] else _item[ 'error_msg'][1] if _item['status'] == "success": PocsuiteVuln.add(taskid=pid, poc=poc_id, task_name=taskname, poc_name=poc_item['name'], status=_item['status'], target=_item['target'], app=poc_item['app'], result=result) contents = "### PocScan \n" + \ "目标: {domain} \n\n".format(domain=_item['target']) + \ "漏洞名称: {title} \n\n".format(title=poc_item['name']) + \ "app: {company} \n\n".format(company=poc_item['app']) notice(contents=contents, info="任务" + taskname + "[+]" + _item['target'] + "!!发现高危漏洞!!") count += 1 except Exception as e: logger.warning("save poc result failed: {}".format(e)) # Update task information update_data = { "status": "Success", "vul_count": count, "end_date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), } notice(contents=taskname + " 扫描完成!^_^", info=taskname + " 扫描完成!^_^") PocscanTask.update_by_id(tid=pid, data=update_data) logger.success("poc task completed: {}".format(pid)) return taskname + " 扫描完成!^_^" except Exception as e: logger.warning("poc scan failed: {}".format(e))
def save_data(self): # print(self.final_domains) flag = TaskDB.get_by_id(self.tmpid) for i in flag: self.tmpres = i["flag"] self.portnum = i["portcount"] if self.tmpres == "100.00%": self.tmpres = "100.00%" else: self.tmpres = self.flagnum print("进度:" + str(self.tmpres)) for res in self.final_domains: port = int(res["port"]) if port != 0: server = res["server"] url = res["url"].replace(self.scan_ip, self.subdomain) title = res["title"] db_query = mongo['Subdomain'].find({ "domain": "{}".format(self.subdomain), "project": str(self.project), "port": str(port) }) count = db_query.count() for j in db_query: if j: _id = str(j["_id"]) self.portnum = self.portnum + 1 tmp_data2 = { "subdomain_count": self.subcount, "portcount": int(self.portnum), "flag": self.tmpres, "date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) } TaskDB.update(taskid=self.tmpid, data=tmp_data2) if count == 0: pid = DBSubdomain.add(taskid=self.tmpid, domain=self.subdomain, url=str(url), ip=str(self.scan_ip), title=str(title), server=str(server), project=self.project, company_name=self.company, port=port) msg = "子域名{0} 入库成功----> pid:{1}".format( self.subdomain, pid) contents = "### 子域名信息 \n" + \ "子域名: {domain} \n\n".format(domain=self.subdomain) + \ "标题: {title} \n\n".format(title=title) + \ "公司: {company} \n\n".format(company=self.company) + \ "端口: {port} \n\n".format(port=port) + \ "服务: {server} \n\n".format(server=server) notice(contents=contents, info="新的子域名:" + self.subdomain) logger.success(msg) elif count == 1: domain_update = { "ip": str(self.scan_ip), "server": str(server), "title": str(title), "port": port, "date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) } pid = DBSubdomain.update_by_id(tid=_id, data=domain_update) msg = "子域名{0} 更新成功".format(self.subdomain) contents = "### 子域名数据更新 \n" + \ "子域名: {domain} \n\n".format(domain=self.subdomain) + \ "标题: {title} \n\n".format(title=title) + \ "公司: {company} \n\n".format(company=self.company) + \ "端口: {port} \n\n".format(port=port) + \ "服务: {server} \n\n".format(server=server) # if len(self.final_domains) != 0: # self.final_domains.pop(0) notice(contents=contents, info="子域名数据更新:" + self.subdomain) logger.success(msg) else: logger.warning("[+] 未发现域名 [{0}] 存在开放端口,继续扫描.".format( self.subdomain)) if self.tmpres == "100.00%": tmp_data = { "flag": self.tmpres, "date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) } TaskDB.update(taskid=self.tmpid, data=tmp_data) # os.system("rm {0}/oneforall/results/*".format(plugindir)) # os.remove("/Users/wing/evilwing/pentesting/OneForAll/oneforall/results/{0}.json".format(rootdomain)) notice(contents="[+] " + self.project + " <----> Subdomain Scan Complete") logger.success(self.project + "=====Subdomain Scan Complete!=======") return self.project + "=====Subdomain Scan Complete!======="