漏洞扫描系统
0x00 说明:这是一款基于主机的漏洞扫描工具,采用多线程确保可以快速的请求数据,采用线程锁可以在向sqlite数据库中写入数据避免database is locked的错误,采用md5哈希算法确保数据不重复插入。
本工具查找是否有公开exp的网站为shodan,该网站限制网络发包的速度,因而采用了单线程的方式,且耗时较长。
功能:
查找主机上具有的CVE
查找具有公开EXP的CVE
0x01 起因:因为需要做一些主机漏洞扫描方面的工作,因而编写了这个简单的工具。之前也查找了几款类似的工具,如下:
vulmap:
vulmon开发的一款开源工具,原理是根据软件的名称和版本号来确定,是否有CVE及公开的EXP。这款Linux的工具挺好用,但是对于Windows系统层面不太适用。
windows-exp-suggester:
这款和本工具的原理一样,尝试使用了之后,发现它的CVEKB数据库只更新到2017年的,并且没有给出CVE是否有公开的EXP信息。
基于以上所以写了这个简单的工具,该项目在https://github.com/chroblert/WindowsVulnScan
0x02 原理:1. 搜集CVE与KB的对应关系。首先在微软官网上收集CVE与KB对应的关系,然后存储进数据库中
2. 查找特定CVE网上是否有公开的EXP
3. 利用powershell脚本收集主机的一些系统版本与KB信息
4. 利用系统版本与KB信息搜寻主机上具有存在公开EXP的CVE
0x03 参数:# author: JC0o0l# GitHub: https://github.com/chroblert/可选参数: -h, –help show this help message and exit -u, –update-cve 更新CVEKB数据 -U, –update-exp 更新CVEEXP数据 -C, –check-EXP 检索具有EXP的CVE -f FILE, –file FILE ps1脚本运行后产生的.json文件0x04 示例:1. 首先运行powershell脚本KBCollect.ps收集一些信息
.KBCollect.ps12. 将运行后产生的KB.json文件移动到cve-check.py所在的目录
3. 安装一些python3模块
python3 -m pip install requirements.txt4. 运行cve-check.py -u创建CVEKB数据库
5. 运行cve-check.py -U更新CVEKB数据库中的hasPOC字段
6. 运行cve-check.py -C -f KB.json查看具有公开EXP的CVE,如下:
0x05 源码:KBCollect.ps1:
function Get-CollectKB(){ # 1. 搜集所有的KB补丁 $KBArray = @() $KBArray = Get-HotFix|ForEach-Object {$_.HotFixId} $test = $KBArray|ConvertTo-Json return $test}function Get-BasicInfo(){ # 1. 操作系统 # $windowsProductName = (Get-ComputerInfo).WindowsProductName $windowsProductName = (Get-CimInstance Win32_OperatingSystem).Caption # 2. 操作系统版本 $windowsVersion = (Get-ComputerInfo).WindowsVersion $basicInfo = “{“”windowsProductName””:””$windowsProductName””,””windowsVersion””:””$windowsVersion””}” return $basicInfo
}$basicInfo = Get-BasicInfo$KBList = Get-CollectKB$KBResult = “{“”basicInfo””:$basicInfo,””KBList””:$KBList}”$KBResult|Out-File KB.json -encoding utf8cve-check.py:
import requestsimport sqlite3import jsonimport hashlibimport mathimport reimport threadingimport timeimport argparsefrom pathlib import Path# 删除一些ssl 认证的warnging信息requests.packages.urllib3.disable_warnings()
ThreadCount=20DBFileName=”CVEKB.db”TableName=”CVEKB”insertSQL = []updateSQL = []lock = threading.Lock()KBResult = {}parser = argparse.ArgumentParser()parser.add_argument(“-u”,”–update-cve”,help=”更新CVEKB数据”,action=”store_true”)parser.add_argument(“-U”,”–update-exp”,help=”更新CVEEXP数据”,action=”store_true”)parser.add_argument(“-C”,”–check-EXP”,help=”检索具有EXP的CVE”,action=”store_true”)parser.add_argument(“-f”,”–file”,help=”ps1脚本运行后产生的.json文件”)args = parser.parse_args()
class CVEScanThread(threading.Thread): def __init__(self,func,args,name=””,): threading.Thread.__init__(self) self.func = func self.args = args self.name = name self.result = None
def run(self): print(“thread:{} :start scan page {}”.format(self.args[1],self.args[0])) self.result = self.func(self.args[0],) print(“thread:{} :stop scan page {}”.format(self.args[1],self.args[0]))class EXPScanThread(threading.Thread): def __init__(self,func,args,name=””,): threading.Thread.__init__(self) self.func = func self.args = args self.name = name self.result = None
def run(self): print(“thread:{} :start scan CVE: {},xuehao:{}”.format(self.args[1],self.args[0],self.args[2])) self.result = self.func(self.args[0],) print(“thread:{} :stop scan CVE: {}”.format(self.args[1],self.args[0])) def get_result(self): threading.Thread.join(self) try: return self.result except Exception: return “Error”def get_page_num(num=1,pageSize=100): url = “https://portal.msrc.microsoft.com/api/security-guidance/en-us” payload = “{“familyIds””:[]