def create_task(self, id, pid, type, task_type, ip, port, attack_task_id_dict): """ 创建爆破子任务 :param pid: :return: """ try: portcrack = PortCrack() portcrack.id = pid if task_type == "create": PortCrackChild.objects.create(id=id, ip=ip, port=port, pid=portcrack, start_time=currenttime(), status="running", type=type, progress="0.00") return True, id elif task_type == "start": # 获取暂停任务的id id = attack_task_id_dict[ip + port] PortCrackChild.objects.filter(id=id, status="pause").update( pid=portcrack, status="running", end_time=currenttime()) return True, id except: print traceback.format_exc() return False, id
def update_main(self,poc_name,current_poc_size): if current_poc_size == 0: progress = "100" cms_poc_main.objects.filter(id=self.pid,locker="false").update(end_time=currenttime(),log="[%s]正在使用POC[%s]" % (progress+"%",poc_name),status="success",progress=progress,locker="true") # 计算进度 progress = 1-float(format(float(current_poc_size)/float(self.poc_size),'.4f')) progress = '%.2f' % (progress * 100) cms_poc_main.objects.filter(id=self.pid,locker="false").update(end_time=currenttime(),log="[%s]正在使用POC[%s]" % (str(progress)+"%",poc_name),progress=progress)
def __init__(self, urls, payload, threads, commond): self.payload = payload if type(urls) == str: self.targets = urls.split(",") elif type(urls) == list: self.targets = urls self.threads = threads self.commond = commond # target信息Queue self.target_queue = Queue.Queue(maxsize=len(self.targets)) self.target_queue_old_size = len(self.targets) try: for target in self.targets: self.target_queue.put(target) print self.target_queue.qsize() self.pid = str(uuid.uuid1()) self.parent = poc_main() self.parent.id = self.pid # 初始化数据库主数据 poc_main.objects.create(id=self.pid, start_time=currenttime(), status="running", commond=self.commond, threads=self.threads, progress="0.00") except: print traceback.format_exc()
def __init__(self, commond="", count=1000, tn="json", threads=10): self.commond = commond #rn——一页显示多少条,最大50 self.rn = 50 #pn—— pn = rn * (当前页数) 页数从0开始为第一页 self.pn = 0 self.tn = tn self.threads = threads self.id = str(uuid.uuid1()) # 计算所有要查询的http请求次数 self.pn_queue = Queue.Queue(maxsize=count / self.rn) # 保存搜集到的url self.targets_queue = Queue.Queue(maxsize=count) for i in range(0, count / self.rn): self.pn_queue.put(i * self.rn) print i * self.rn # 初始化数据库记录 poc_urls.objects.create(id=self.id, start_time=currenttime(), status="running", commond=self.commond, threads=self.threads, counts=0, log="【%s】正在采集【%s】相关网站" % (str(0), self.commond))
def cms_scan_stop(req): """ cms识别停止 :param req: :return: """ reload(sys) sys.setdefaultencoding('utf-8') data = json.loads(req.body) id_list = data.get("ids") result = {"status": True, "msg": "成功", "data": "", "success": "success"} log = "" try: for id in id_list: CmsInfo.objects.filter(id=id, locker="false", status="running").update( end_time=currenttime(), status="stop", locker="true") result["data"] = log except Exception: result = { "status": False, "msg": "CMS识别停止异常", "data": traceback.format_exc() } print traceback.format_exc() return HttpResponse(json.dumps(result, ensure_ascii=False))
def __init__(self,host,threads): self.threads = threads self.host = host self.id = "" self.cms_queue_oldsize = 0 self.cms = False # 初始化字典 cms_info_file = open(os.getcwd()+"/AnyScanUI/scanner/cms/"+'cms_info.json') # cms信息Queue cms_queue = Queue.Queue(maxsize = 10) try: cms_info_str = cms_info_file.read() cms_info = eval(cms_info_str) self.cms_queue = Queue.Queue(maxsize = len(cms_info)) self.cms_queue_oldsize = len(cms_info) for info in cms_info: self.cms_queue.put(info) id = str(uuid.uuid1()) self.id = id # 初始化数据库数据 CmsInfo.objects.create(id=id,start_time=currenttime(),status="running",host=self.host,threads=self.threads,progress="0.00") except: print traceback.format_exc() finally: cms_info_file.close()
def exploit(self): while True: if self.cms_queue.empty() is False: obj = CmsInfo.objects.get(id=self.id) if obj is None or obj.status == "stop": #print "任务【%s】被删除" % self.id break exp_info = eval(str(self.cms_queue.get())) # 不要忘记请求图片类型,无法获取content cms_name = exp_info.get("cms") version = exp_info.get("version") keyword = exp_info.get("keyword") cms_md5 = exp_info.get("md5") url = self.host + exp_info.get("url") http = Http('http', self.host, "") html_content,code = http.post_(url) # 计算进度 progress = 1-float(format(float(self.cms_queue.qsize())/float(self.cms_queue_oldsize),'.4f')) progress = '%.2f' % (progress * 100) # 实时日志 log = "【%s】正在测试【%s】" % (str(progress)+"%",str(url)) #print log CmsInfo.objects.filter(id=self.id,locker="false").update(end_time=currenttime(),status="running",progress=progress,log=str(log)) # 如果有关键字,就用关键字比较 if code == 200: md5 = self.get_md5_value(html_content) if cms_md5 == "" or cms_md5 is None: # 当md5为空时,比较关键字 if keyword in html_content: self.save(exp_info,keyword,cms_name,version) break if md5 == cms_md5: self.save(exp_info,md5,cms_name,version) break else: CmsInfo.objects.filter(id=self.id,locker="false").update(end_time=currenttime(),status="success",progress="100",log="【%s】检测完成" % self.host,locker="true") self.cms_queue.queue.clear() break
def save(self,exp_info,keyword,cms_name,version): """ 保存检测成功感的日志 :param exp_info: :param keyword: :param cms_name: :param version: :return: """ self.cms = True log = "【%s】检测成功,Payload为【%s】,CMS为【%s】,版本信息【%s】" % (self.host,exp_info.get("url"),cms_name,version) CmsInfo.objects.filter(id=self.id,locker="false").update(end_time=currenttime(),status="success",progress="100",log=str(log),locker="true",cms=cms_name,version=version,keyword=keyword,payload=exp_info.get("url")) self.cms_queue.queue.clear()
def init_scan(self, id, bugscan, poc_size): # 起始时间 start_time = currenttime() # 目标地址 target = self.__target__ # 线程数 threads = self.__threads__ # 状态 status = "running" cms_poc_main.objects.create(id=id, start_time=start_time, status="running", target=target, threads=threads, progress="0.00", poc_size=poc_size)
def stop(self, id_list): """ :param id_list: :return: """ try: log = "任务被手动停止" for id in id_list: cms_poc_main.objects.filter(~Q(status="stop"), ~Q(status="success"), id=id, locker="false").update( end_time=currenttime(), log=log, status="stop", locker="true") return True, "停止成功" except: print traceback.print_exc() return False, traceback.print_exc()
def exploit(self): """ exploit :return: """ try: while True: if self.target_queue.empty() is False: try: target = str(self.target_queue.get()) status = False keyword = "" try: code = compile(self.payload, '<string>', 'exec') runtime = {"target": target} exec code in runtime status = runtime.get("status") keyword = runtime.get("keyword") if status is None or keyword is None: status = False keyword = "" except: print traceback.format_exc() pass id = str(uuid.uuid1()) poc_chil.objects.create(id=id, pid=self.parent, commond=self.commond, vulnerable=status, host=target, keyword=keyword) # 计算进度 progress = 1 - float( format( float(self.target_queue.qsize()) / float(self.target_queue_old_size), '.4f')) progress = '%.2f' % (progress * 100) # log log = "【%s】正在测试【%s】" % (str(progress) + "%", target) poc_main.objects.filter(id=self.pid, locker="false").update( end_time=currenttime(), status="running", log=log, progress=progress) except: pass print traceback.format_exc() else: #print "空了" # 需要检测的目标为空了,更新主任务数据 poc_main.objects.filter(id=self.pid, locker="false").update( end_time=currenttime(), status="success", log="所有网站均已验证完成", locker="true", progress="100") break except: print traceback.format_exc()
def run(self): reload(sys) sys.setdefaultencoding('utf8') ip_ = str(self.param["ip"]) port_ = str(self.param["port"]) # 当前任务id id_ = str(self.param["id"]) # 当前任务爆破功能函数 callback = self.param["callback"] # 获取单个爆破线程 thread = self.__attackObject.getThreads() # 攻击类型 attack_type = self.param["attack_type"] portcrackchild = None while True: #print "正在破解" if self.__attackObject.locker.get(ip_ + port_) is True: # 清空队列 self.__attackObject.getAttack_queue_dict(ip_ + port_).queue.clear() PortCrackChild.objects.filter(id=id_, locker="false").update( end_time=currenttime(), status="success", progress=str("100"), log=self.__attackObject.getFinishLog((ip_, port_))) print "任务被停止1 %s" % ip_ break try: # 获取当前爆破任务的状态,如果已经是lock状态,那么任务暂停。 portcrackchild = PortCrackChild.objects.get(id=id_) # 如果任务不存在了,直接结束任务 except: # 将当前的字典queue对象保存到数据库,在下次启动是读取该queue进行爆破 crack_list = list( self.__attackObject.getAttack_queue_dict(ip_ + port_).queue) print "任务被停止2 %s" % ip_ break if portcrackchild.status == "pause": # 将当前的字典queue对象保存到数据库,在下次启动是读取该queue进行爆破 crack_list = list( self.__attackObject.getAttack_queue_dict(ip_ + port_).queue) # 保存当前任务的状态,主要是剩余的字典 if self.__attackObject.getAttack_queue_dict(ip_ + port_).qsize() > 0: __crack_list = json.dumps(crack_list) #print __crack_list PortCrackChild.objects.filter( id=id_, locker="false").update(attack_queue_list=__crack_list, end_time=currenttime(), threads=thread) print "任务被暂停3 %s" % ip_ # 清空队列 self.__attackObject.getAttack_queue_dict(ip_ + port_).queue.clear() break username_ = "" password_ = "" if self.__attackObject.getAttack_queue_dict( ip_ + port_).empty() is False: # 获取当前爆破字典queue up_ = self.__attackObject.getAttack_queue_dict(ip_ + port_).get() username_ = str(up_[0]) password_ = str(up_[1]) # 计算进度 c_size = self.__attackObject.getAttack_queue_dict( ip_ + port_).qsize() o_size = self.__attackObject.getAttack_queue_size_dict(ip_ + port_) progress = 1 - float( format(float(c_size) / float(o_size), '.4f')) progress = '%.2f' % (progress * 100) param = (ip_, port_, attack_type, progress + "%", username_, password_) print "正在爆破 %s:%s" % (ip_, port_) # 读取log日志 log = self.__attackObject.getLog(param) # 如果连接成功,说明用户名密码正确 if callback(ip_, username_, password_): # 清空队列 self.__attackObject.getAttack_queue_dict( ip_ + port_).queue.clear() self.__attackObject.locker[ip_ + port_] = True PortCrackChild.objects.filter( id=id_, locker="false").update( end_time=currenttime(), status="success", locker="true", username=username_, password=password_, progress=str("100"), log=self.__attackObject.getSuccessLog( (ip_, port_, attack_type, username_, password_))) print "破解成功,填充线程队列 %s" % self.__attackObject.threads_queue.qsize( ) for i in range(0, thread): self.__attackObject.threads_queue.put("") break else: # 更新日志数据 PortCrackChild.objects.filter( id=id_, locker="false").update(end_time=currenttime(), old_queue_size=o_size, type=attack_type, progress=str(progress), log=str(log), threads=thread) else: print "任务被停止4 %s" % ip_ # 如果字典队列空了,那么直接关掉跳出循环,更新为爆破完成,暂时为success if self.__attackObject.locker.get(ip_ + port_) != True: self.__attackObject.locker[ip_ + port_] = True PortCrackChild.objects.filter( id=id_, locker="false").update(end_time=currenttime(), status="success", progress=str("100"))
def exploit(self): while True: if self.pn_queue.empty() == False: try: reload(sys) sys.setdefaultencoding("utf-8") response = None content = None try: response = requests.get(self.target(), verify=True, timeout=10) if response.content is None: continue content = json.loads(response.content) except: print content continue response.close() entry = content.get("feed").get("entry") for en in entry: __title = en.get("title") __url = en.get("url") __pn = en.get("pn") __id = str(uuid.uuid1()) if __url is not None: __e = { "id": __id, "name": __title, "url": __url, "pn": __pn, "children": [{ "name": __url }] } print __e self.targets_queue.put(__e) # 先将数据取出来,定义一次,以防止其他线程干扰 __tmp_queue = self.targets_queue #__targets__ = self.format(repeat(list(__tmp_queue.queue))) __targets__ = list(__tmp_queue.queue) __len__ = __tmp_queue.qsize() poc_urls.objects.filter( id=self.id, locker="false").update( end_time=currenttime(), counts=__len__, log="【%s】正在采集【%s】相关网站" % (str(__len__), self.commond), urls=json.dumps(__targets__)) except Exception as e: poc_urls.objects.filter(id=self.id, locker="false").update( end_time=currenttime(), status="success", log="采集【%s】相关网站异常" % (self.commond)) print traceback.format_exc() print('获取百度内容失败,原因:%s' % e) return None else: poc_urls.objects.filter(id=self.id, locker="false").update( end_time=currenttime(), status="success", locker="true", log="采集完成【%s】相关网站" % (self.commond)) break
def update_task(self, pid): """ 更新总任务状态 :param pid: :return: """ while True: #print "正在执行" portcrack = None try: portcrack = PortCrack.objects.get(id=pid) except: print "任务id【%s】不存在了" % pid return if portcrack.status == "pause": return child_set = portcrack.portcrackchild_set.all() # 所有任务长度 all_length = len(child_set) # 未完成任务 not_success = child_set.filter( Q(status="running") | Q(status="pause")) # 已完成任务个数 success_num = all_length - len(not_success) now_progress = 0 log = "" # 在总进度中统计爆破成功的用户名密码[{"ip":"","port":"","username":"","password":""}] portcrack_success = [] # 统计总任务进度 for child in child_set: progress_ = self.formatnum(child.progress) now_progress = now_progress + progress_ # 统计日志 log = log + str(child.log) + "\n" if child.status == "success" and child.progress == "100": portcrack_success.append({ "ip": child.ip.encode("utf-8"), "port": child.port.encode("utf-8"), "username": child.username.encode("utf-8"), "password": child.password.encode("utf-8") }) # 计算总任务进度 progress = now_progress / (all_length) # 当所有的任务都不为running时说明都爆破完成了,无论是成功还是失败。 if success_num == all_length: PortCrack.objects.filter(id=pid).update( end_time=currenttime(), status="success", result=str(portcrack_success), progress="100", log="爆破结束,结果请看详情\n" + log) return else: PortCrack.objects.filter(id=pid).update( end_time=currenttime(), result=str(portcrack_success), progress=str(progress), log=log) # 每2秒轮询一次 time.sleep(2)
def portattack(req): """ 端口爆破 :param req: :return: """ data = json.loads(req.body) result = {"status": True, "msg": "成功", "data": "", "logid": ""} # id id = str(uuid.uuid1()) try: if data["type"] == "create": # 创建端口的爆破任务,存储数据库 # 爆破开始时间 start_time = currenttime() # 爆破状态 status = "running" # 爆破任务类型 type = "ALL" # 扫描进度 progress = "0.00" # 创建主任务数据 PortCrack.objects.create(id=id, start_time=start_time, status=status, type=type, progress=progress) attackObject = AttackObject() # 必须调用setThreads方法,里面有对queue的初始化 attackObject.setThreads(data["threads"]) print attackObject.attack_queue_dict attackObject.pid = id attackObject.usernames = "/Users/margin/PycharmProjects/AnyScan/AnyScanUI/port/ssh_username.txt" attackObject.passwords = "/Users/margin/PycharmProjects/AnyScan/AnyScanUI/port/ssh_password.txt" # 实时显示任务的id result["logid"] = id # 要爆破的ip,port attack_dict = data["attack_dict"] attacker = Attacker(attackObject) status = attacker.attack(attack_dict, attack_task_id_dict={}) if status == False: result["status"] == False result["msg"] == "任务添加异常,请查看日志" elif data["type"] == "start": id = data["id"] if id is None or id == "": result = {"status": False, "msg": "任务ID不可为空"} return HttpResponse(json.dumps(result, ensure_ascii=False)) # 判断任务id是否存在 portcrack = PortCrack.objects.get(id=id) if portcrack is None: result = {"status": False, "msg": "您所选的任务ID不存在"} return HttpResponse(json.dumps(result, ensure_ascii=False)) # 如果任务不是暂停状态就在启动任务 if portcrack.status != "pause": result = { "status": False, "msg": "您所选的任务不是【%s】,不能启动" % portcrack.status } return HttpResponse(json.dumps(result, ensure_ascii=False)) # 查询任务信息和子任务信息,组织数据给Attacker.py child_set = portcrack.portcrackchild_set.all() # 组织给Attacker.py的数据 attack_dict: {"ip":[80,3306],"ip2":[22]} attack_dict = {} # 搞一个字典{"ip+port":id},为了能让attacker正确的取出当前任务的id attack_task_id_dict = {} for child in child_set: __ip = attack_dict.get(child.ip) if __ip is None or __ip == "": attack_dict[child.ip] = [child.port] else: attack_dict[child.ip].append(child.port) attack_task_id_dict[child.ip + child.port] = child.id # 更新该任务状态 PortCrack.objects.filter(id=id).update(status="running", end_time=currenttime()) attackObject = AttackObject() # 当前攻击启动的类型 attackObject.type = "start" attackObject.pid = id attacker = Attacker(attackObject) status = attacker.attack(attack_dict, attack_task_id_dict) if status == False: result["status"] == False result["msg"] == "任务启动异常,请查看日志" except Exception: result = { "status": False, "msg": "任务添加异常", "data": traceback.format_exc(), "logid": "" } print traceback.format_exc() return HttpResponse(json.dumps(result, ensure_ascii=False))