def add_task(task_id=None): name = request.values.get('task_name') scheme = request.values.get('task_scheme') domain = request.values.get('task_domain') source_ip = request.values.get('source_ip') path = request.values.get('task_path') cookie = request.values.get('task_cookie') spider_type = request.values.get('spider_type') task_policy = request.values.get('task_policy') urls = request.values.get('urls') target = request.values.get('target') multiple_task = True if request.values.get('multiple_task') else False run_now = True if request.values.get('run_now') else False run_time = request.values.get('run_time') rules = request.values.get('rules') scan_key = request.values.get('scan_key') try: # 从接口提交的扫描任务,如果是全面扫描则扫描所有规则 if scan_key: if not (name and urls and run_time and task_policy): raise Exception user_id = verify_scan_key(scan_key).id if task_policy == '509': rules = db.session.query(func.group_concat(WebVulFamily.id)).filter(WebVulFamily.parent_id != 0).first()[0] spider_type = 2 else: username = current_user.name user_id = db.session.query(User).filter(User.name == username).first().id except Exception, e: logger.exception(e) return jsonify(dict(status=False, desc='添加更新失败'))
def report_list(): scan_key = request.values.get('scan_key') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id user = db.session.query(User).filter(User.id == user_id).first() admin_id = db.session.query(Group).filter(Group.name == 'ADMIN').first().id if str(admin_id) in user.groups.split(','): tasks = db.session.query( Task.id, Task.name, Task.target, Task.start_time, Task.end_time).filter(Task.state == 3).order_by(Task.id).all() else: tasks = db.session.query(Task.id, Task.name, Task.target, Task.start_time, Task.end_time).filter( Task.user_id == user_id, Task.state == 3).order_by(Task.id).all() reports = [ dict(id=task.id, name=task.name, target=task.target, start_time=datetime.strftime(task.start_time, '%Y-%m-%d %H:%M:%S'), end_time=datetime.strftime(task.end_time, '%Y-%m-%d %H:%M:%S')) for task in tasks ] return jsonify(reports)
def report_model_delete(): model_id = request.values.get('model_id') scan_key = request.values.get('scan_key') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id user = db.session.query(User).filter(User.id == user_id).first() admin_id = db.session.query(Group).filter(Group.name == 'ADMIN').first().id if str(admin_id) in user.groups.split(','): model = db.session.query(ReportModel).filter(ReportModel.model_id == model_id).first() else: model = db.session.query(ReportModel).filter(ReportModel.user_id == user_id & ReportModel.model_id == model_id).first() if not model: logger.error(model_id) abort(403) old_filename = model.logo_filename file_path1 = '%s%s' % (basedir, PDF_LOGO_PATH1) file_path2 = '%s%s' % (basedir, PDF_LOGO_PATH2) try: if os.path.exists(os.path.join(file_path1, old_filename)): os.remove(os.path.join(file_path1, old_filename)) if os.path.exists(os.path.join(file_path2, old_filename)): os.remove(os.path.join(file_path2, old_filename)) except Exception, e: return jsonify(dict(status=False, desc='logo文件删除失败' + str(e)))
def report_list(): try: scan_key = request.values.get('scan_key') search_msg = request.values.get('search_msg', '') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id user = db.session.query(User).filter(User.id == user_id).first() admin_id = db.session.query(Group).filter(Group.name == 'ADMIN').first().id if str(admin_id) in user.groups.split(','): query = db.session.query(Task).join(ApJobsTaskRef, ApJobsTaskRef.task_id == Task.id). \ filter(ApJobsTaskRef.job_status == 3, ApJobsTaskRef.parent_id == None).order_by(Task.id.desc()) else: query = db.session.query(Task).join(ApJobsTaskRef, ApJobsTaskRef.task_id == Task.id). \ filter(ApJobsTaskRef.job_status == 3, ApJobsTaskRef.parent_id == None, Task.user_id == user_id).order_by(Task.id.desc()) if search_msg: like_msg = '%%%s%%' % search_msg query = query.filter(or_(Task.id.like(search_msg), Task.name.like(like_msg), Task.target.like(like_msg))) page, per_page, offset, search_msg = get_page_items() tasks = query.limit(per_page).offset(offset).all() total = query.count() pagination = get_pagination(page=page, per_page=per_page, total=total, # record_name="server", format_total=True, format_number=True # search=True, # search_msg=search_msg ) taskids = [task.id for task in tasks] reportList = db.session.query(ModelReport.job_id, ModelReport.task_id).filter(ModelReport.task_id.in_(taskids)).order_by( ModelReport.id.desc()).all() reports = {} for report in reportList: if not reports.has_key(report.task_id): reports[report.task_id] = report for task_id in taskids: if not reports.has_key(task_id): reports[task_id] = ('', task_id) except Exception, e: logger.exception(e) return render_template('error-not-safe.html')
def tasks_list(): scan_key = request.values.get('scan_key') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id user = db.session.query(User).filter(User.id == user_id).first() admin_id = db.session.query(Group).filter(Group.name == 'ADMIN').first().id if str(admin_id) in user.groups.split(','): task_jobs = db.session.query(Task).filter(Task.state != 3) # task_jobs = db.session.query(ApJobsTaskRef, Task).join(Task, ApJobsTaskRef.task_id == Task.id).\ # filter(ApJobsTaskRef.job_status != 3, ApJobsTaskRef.parent_id == None) else: # task_jobs = db.session.query(ApJobsTaskRef, Task).join(Task, ApJobsTaskRef.task_id == Task.id).\ # filter(ApJobsTaskRef.job_status != 3, ApJobsTaskRef.parent_id == None, Task.user_id == user_id) task_jobs = db.session.query(Task).filter(Task.state != 3, Task.user_id == user_id) return render_template('tasks_list.html', task_jobs=task_jobs, level_one='task', level_two='list_task')
def tasks_list_api(): scan_key = request.values.get('scan_key') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id user = db.session.query(User).filter(User.id == user_id).first() admin_id = db.session.query(Group).filter(Group.name == 'ADMIN').first().id if str(admin_id) in user.groups.split(','): task_jobs = db.session.query(ApJobsTaskRef, Task).outerjoin(Task, ApJobsTaskRef.task_id == Task.id). \ filter(ApJobsTaskRef.job_status != 3, ApJobsTaskRef.parent_id == None) else: task_jobs = db.session.query(ApJobsTaskRef, Task).outerjoin(Task, ApJobsTaskRef.task_id == Task.id). \ filter(ApJobsTaskRef.job_status != 3, ApJobsTaskRef.parent_id == None, Task.user_id == user_id) res_data = [dict(task_id=row.Task.id, task_name=row.Task.name, run_time=datetime.strftime(row.ApJobsTaskRef.run_time, '%Y-%m-%d %H:%M:%S'), status=get_job_task_status(row.ApJobsTaskRef.job_status)) for row in task_jobs.all()] return jsonify(dict(resp=res_data))
def report_model_edit(model_id): ''' 供内部工作人员调用,自定义PDF报告模板 ''' scan_key = request.values.get('scan_key') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id user = db.session.query(User).filter(User.id == user_id).first() admin_id = db.session.query(Group).filter(Group.name == 'ADMIN').first().id if str(admin_id) in user.groups.split(','): model = db.session.query(ReportModel.model_id, ReportModel.model_name, ReportModel.company, ReportModel.title, ReportModel.footer).filter(ReportModel.model_id == model_id).first() else: model = db.session.query(ReportModel.model_id, ReportModel.model_name, ReportModel.company, ReportModel.title, ReportModel.footer).filter(ReportModel.user_id == user_id & ReportModel.model_id == model_id).first() if model: return render_template('report_modify_model.html', model=model)
def report_output(task_id): scan_key = request.values.get('scan_key') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id user = db.session.query(User).filter(User.id == user_id).first() admin_id = db.session.query(Group).filter(Group.name == 'ADMIN').first().id if str(admin_id) in user.groups.split(','): tasks = db.session.query(Task).filter(Task.state == 3).order_by( Task.id).all() task_id_list = [task.id for task in tasks] else: tasks = db.session.query(Task).filter( Task.user_id == user_id, Task.state == 3).order_by(Task.id).all() task_id_list = [task.id for task in tasks] if int(task_id) not in task_id_list: abort(403) rep = Report() dictData = rep.formatResult(task_id) return jsonify(dictData)
def add_task(task_id=None): name = request.values.get('task_name') name = escape(name.decode('utf-8')) # scheme = request.values.get('task_scheme') # domain = request.values.get('task_domain') source_ip = request.values.get('source_ip') if source_ip and not re.match('^(\d{1,3}\.){3}\d{1,3}$', source_ip): return jsonify(dict(status=False, desc='添加失败, 源IP格式错误')) patch_no = request.values.get('patch_no') cookie = request.values.get('task_cookie') spider_enable = request.values.get('spider_enable') task_policy = request.values.get('task_policy') rep_model_id = request.values.get('rep_model') urls = request.values.get('urls') target = request.values.get('target') # multiple_task = True if request.values.get('multiple_task') else False run_now = True if request.values.get('run_now') else False run_time = request.values.get('run_time') rules = request.values.get('rules') scan_key = request.values.get('scan_key') try: if not rep_model_id: rep_model_id = db.session.query(ReportModel).filter(or_(ReportModel.company == '上海云盾信息技术有限公司', ReportModel.model_name == '盾眼默认模板')).first().model_id # 从接口提交的扫描任务,如果是全面扫描则扫描所有规则 if scan_key: if not (name and urls and task_policy): raise Exception user_id = verify_scan_key(scan_key).id # if task_policy == '509': # rules = db.session.query(func.group_concat(WebVulFamily.id)).filter(WebVulFamily.parent_id != 0).first()[0] else: username = current_user.name user_id = db.session.query(User).filter(User.name == username).first().id except Exception, e: logger.exception(e) return jsonify(dict(status=False, desc='添加更新失败'))
def report_download(reportid=None): scan_key = request.values.get('scan_key') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id report = db.session.query(ModelReport).filter(ModelReport.id == reportid).first() user = db.session.query(User).filter(User.id == user_id).first() admin_id = db.session.query(Group).filter(Group.name == 'ADMIN').first().id if str(admin_id) in user.groups.split(','): tasks = db.session.query(Task).filter(Task.state == 3).order_by(Task.id).all() task_id_list = [task.id for task in tasks] else: tasks = db.session.query(Task).filter(Task.user_id == user_id, Task.state == 3).order_by(Task.id).all() task_id_list = [task.id for task in tasks] if int(report.task_id) not in task_id_list: abort(403) file_dir = WEBROOT + STRSPIT + "app" + STRSPIT + "static" + STRSPIT + "pdf" + STRSPIT if os.path.isfile(os.path.join(file_dir, report.pdf)): return send_from_directory(file_dir, report.pdf) else: abort(404)
def report2(): scan_key = request.values.get('scan_key') job_id = request.values.get('job_id') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id user = db.session.query(User).filter(User.id == user_id).first() admin_id = db.session.query(Group).filter(Group.name == 'ADMIN').first().id mReport = db.session.query( ModelReport.id, ModelReport.task_id, ModelReport.job_id, ModelReport.domain, ModelReport.json_raw).filter(ModelReport.job_id == job_id).first() if not mReport: result = { "status": "failed", "error": "task is not exists", "data": {} } return jsonify(result) task_id = mReport.task_id if str(admin_id) in user.groups.split(','): tasks = db.session.query(Task).order_by(Task.id).all() task_id_list = [task.id for task in tasks] else: tasks = db.session.query(Task).filter( Task.user_id == user_id).order_by(Task.id).all() task_id_list = [task.id for task in tasks] if int(task_id) not in task_id_list: abort(403) report = Report() result = report.jsonRaw2Report2(json.loads(mReport.json_raw)) return jsonify({"status": "success", "error": "", "data": result})
def report_model_modify(model_id): scan_key = request.values.get('scan_key') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id user = db.session.query(User).filter(User.id == user_id).first() admin_id = db.session.query(Group).filter(Group.name == 'ADMIN').first().id if str(admin_id) in user.groups.split(','): model = db.session.query(ReportModel).filter(ReportModel.model_id == model_id).first() else: model = db.session.query(ReportModel).filter(ReportModel.user_id == user_id & ReportModel.model_id == model_id).first() if not model: logger.error(model_id) abort(403) model_name = request.values.get('model_name') title = request.values.get('title') company = request.values.get('company') footer = request.values.get('footer') logo_file = request.files.get('logo_file') if not model_name or not title or not company or not footer: return jsonify(dict(status=False, desc='必选字段不能为空')) if len(model_name) > 100: return jsonify(dict(status=False, desc='模板名称太长')) if len(title) > 100: return jsonify(dict(status=False, desc='模板标题太长')) if len(company) > 100: return jsonify(dict(status=False, desc='单位名称太长')) if len(footer) > 200: return jsonify(dict(status=False, desc='页脚太长')) if len(logo_file.read()) > 2 * 1024 * 1024: return jsonify(dict(status=False, desc='Logo文件太大,仅支持2MB以下')) # 对异常字符进行HTML编码,防XSS攻击 new_model_name = escape(model_name.decode('utf-8')) new_title = escape(title.decode('utf-8')) new_company = escape(company.decode('utf-8')) new_footer = escape(footer.decode('utf-8')) try: model.model_name = new_model_name model.title = new_title model.company = new_company model.footer = new_footer if not logo_file: # 不更新logo db.session.commit() else: # 更新logo filename = secure_filename(logo_file.filename) if not re.match('^.{1,50}\.(?:png|jpg)$', filename, re.I): return jsonify(dict(status=False, desc='图片文件只支持.jpg或.png格式')) time_stamp = time() salt = '18f7fc1b0a37c7f023462249c1c1fc36' m = md5() m.update('%s%s%f' % (salt, filename, time_stamp)) postfix = filename.rsplit('.', 1)[1].lower() if postfix == 'jpg': new_filename = m.hexdigest() + '.jpg' elif postfix == 'png': new_filename = m.hexdigest() + '.png' else: return jsonify(dict(status=False, desc='图片文件只支持.jpg或.png格式')) file_path1 = '%s%s' % (basedir, PDF_LOGO_PATH1) file_path2 = '%s%s' % (basedir, PDF_LOGO_PATH2) try: im = Image.open(logo_file) im.save(os.path.join(file_path1, new_filename), quality=99) # 压缩后质量为原图的99%, 高保真 if os.path.exists(file_path2): im.save(os.path.join(file_path2, new_filename), quality=99) else: logger.debug("路径%s不存在,文件仅保存一份;如果在本地或测试环境,属于正常情况" % file_path2) except Exception, e: logger.error("文件保存失败, error:%s" % str(e)) return jsonify(dict(status=False, desc='提交失败')) old_filename = model.logo_filename model.logo_filename = new_filename db.session.commit() # 移除旧文件 try: if os.path.exists(os.path.join(file_path1, old_filename)): os.remove(os.path.join(file_path1, old_filename)) if os.path.exists(os.path.join(file_path2, old_filename)): os.remove(os.path.join(file_path2, old_filename)) except Exception, e: logger.error("文件删除失败, error:%s" % str(e)) return jsonify(dict(status=True, desc='新logo提交成功,旧logo删除失败'))
def report_model_create(): scan_key = request.values.get('scan_key') if scan_key: user_id = verify_scan_key(scan_key).id else: user_id = current_user.id model_name = request.values.get('model_name') title = request.values.get('title') company = request.values.get('company') footer = request.values.get('footer') logo_file = request.files.get('logo_file') if not model_name or not title or not company or not footer: return jsonify(dict(status=False, desc='必选字段不能为空')) if len(model_name) > 100: return jsonify(dict(status=False, desc='模板名称太长')) if len(title) > 100: return jsonify(dict(status=False, desc='模板标题太长')) if len(company) > 100: return jsonify(dict(status=False, desc='单位名称太长')) if len(footer) > 200: return jsonify(dict(status=False, desc='页脚太长')) if len(logo_file.read()) > 2 * 1024 * 1024: return jsonify(dict(status=False, desc='Logo文件太大,仅支持2MB以下')) # 对异常字符进行HTML编码,防XSS攻击 model_name = escape(model_name.decode('utf-8')) title = escape(title.decode('utf-8')) company = escape(company.decode('utf-8')) footer = escape(footer.decode('utf-8')) try: if not logo_file: new_filename = '' model = ReportModel(model_name=model_name, title=title, company=company, logo_filename=new_filename, footer=footer, user_id=user_id) db.session.add(model) db.session.commit() return jsonify(dict(status=True, desc='提交成功')) else: filename = secure_filename(logo_file.filename) if not re.match('^.{1,50}\.(?:png|jpg)$', filename, re.I): return jsonify(dict(status=False, desc='图片文件只支持.jpg或.png格式')) time_stamp = time() salt = '18f7fc1b0a37c7f023462249c1c1fc36' m = md5() m.update('%s%s%f' % (salt, filename, time_stamp)) postfix = filename.rsplit('.', 1)[1].lower() if postfix == 'jpg': new_filename = m.hexdigest() + '.jpg' elif postfix == 'png': new_filename = m.hexdigest() + '.png' else: return jsonify(dict(status=False, desc='图片文件只支持.jpg或.png格式')) file_path1 = '%s%s' % (basedir, PDF_LOGO_PATH1) file_path2 = '%s%s' % (basedir, PDF_LOGO_PATH2) try: im = Image.open(logo_file) im.save(os.path.join(file_path1, new_filename), quality=99) # 压缩后质量为原图的99%, 高保真 if os.path.exists(file_path2): im.save(os.path.join(file_path2, new_filename), quality=99) else: logger.debug("路径%s不存在,文件仅保存一份;如果在本地或测试环境,属于正常情况" % file_path2) except Exception, e: logger.error("文件保存失败, error:%s" % str(e)) try: # 文件上传失败,则删除已上传的部分文件 if os.path.exists(os.path.join(file_path1, new_filename)): os.remove(os.path.join(file_path1, new_filename)) if os.path.exists(os.path.join(file_path2, new_filename)): os.remove(os.path.join(file_path2, new_filename)) except Exception, e: logger.error("文件删除失败, error:%s" % str(e)) return jsonify(dict(status=False, desc='提交失败')) model = ReportModel(model_name=model_name, title=title, company=company, logo_filename=new_filename, footer=footer, user_id=user_id) db.session.add(model) db.session.commit() return jsonify(dict(status=True, desc='提交成功'))