安全开发之w9scan扫描器源码学习
安全开发之w9scan扫描器源码学习
- 工作流程
- 信息搜集
- 子域名扫描
- w9scan中的子域名扫描实现
- 泛解析绕过
- cms指纹识别
- 插件加载
- 插件格式
- 加载过程
- 基于爬虫的漏洞扫描
- 线程调度
w9scan是一款全能型的网站漏洞扫描器,借鉴了各位前辈的优秀代码。内置1200+插件可对网站进行一次规模的检测,功能包括但不限于web指纹检测、端口指纹检测、网站结构分析、各种流行的漏洞检测、爬虫以及SQL注入检测、XSS检测等等,w9scan会自动生成精美HTML格式结果报告
工作流程
扫描器首先加载服务类型为www的插件,www插件中集合了信息搜集用到的各种脚本,对目标网站进行信息搜集,获取服务类型,端口,CMS等信息,加载对应的插件,进行漏洞扫描。
信息搜集
子域名扫描
w9scan中的子域名扫描实现
w9scan中子域名扫描以爆破的形式进行,利用已有的子域名字典进行爆破,若访问成功则子域名存在。但是子域名扫描时有可能会出现子域名泛解析的问题,这种情况下任何子域名均可访问到所指向的WEB地址。w9scan中首先设定了一个不可能存在的子域名进行访问,若访问成功则存在泛解析。
unable_pro = "sbsbsbsbforWebScannerunablepro"hostnames = unable_pro + "." + domainhostnames = hostnames.strip()try:l = socket.gethostbyname_ex(hostnames)except socket.error:l = 0if l != 0:security_info("域名存在泛解析 %s" % ("*." + domain), 'subdomain')returnfor pro in tlds:hostnames = pro + "." + domainhostnames = hostnames.strip()try:l = socket.gethostbyname_ex(hostnames)security_info(str(l),'subdomain')time.sleep(0.01)except socket.error:pass
泛解析绕过
我们可以利用泛解析时不存在的域名返回的页面是一样的这一原理来判断是否存在泛解析。首先访问一个不存在的子域名,对返回的html页面进行MD5加密获取泛解析特征。然后再进行子域名爆破,若返回html的MD5值与特征相同,则该子域名不存在。
unable_pro = “sbsbsbsbforw9scanunablepro”
hostnames = unable_pro + “.” + domain
hostnames = hostnames.strip()
try:l = socket.gethostbyname_ex(hostnames)
except socket.error:l = 0
if l != 0:security_info(“域名存在泛解析 %s” % (“*.” + domain), ‘subdomain’)m = get_html_md5(hostnames)
for pro in tlds:hostnames = pro + “.” + domainhostnames = hostnames.strip() try: if l==0: security_info(str(l),'subdomain') time.sleep(0.01) else:m1 =get_html_md5(hostnames) if m==m1: security_info(str(l), 'subdomain') time.sleep(0.01) except socket.error: pass
cms指纹识别
Cms识别的原理为收集各种cms的指纹特征,如特殊文件的MD5值,请求头与响应头的特殊关键字等特征,将目标网站与指纹库的指纹进行对比,判断网站cms类别。全面的cms指纹库在cms识别过程中起重要作用。
插件加载
插件格式
该插件模板借鉴了bugscan的设计,将脚本分为assign,audit,main三部分,assign用于验证任务指纹,aduit用于审计漏洞,main用于本地测试。若指纹符合则执行aduit函数检测漏洞是否存在。
加载过程
插件调用时系统会new一个模块出来,用exec函数执行插件代码并将执行的字节码加载进新建的模块,可以通过调用模块中的方法使用插件。首先用assign方法验证插件类型,若插件的任务指纹符合需求,则将该插件的扫描函数作为新的任务加入线程池等待执行。
基于爬虫的漏洞扫描
对于网页的常见漏洞等漏洞的发现是借助爬虫扫描实现的,爬虫采取了深度优先遍历的思想,即对目标url进行访问,对返回的报文进行分析获取相关链接,将爬到的新链接存入new_url列表,并同时对获取的url进行漏洞扫描,这些漏洞扫描脚本集中在spider_file模块中。Spider_file模块中包括许多常见的漏洞扫描脚本,如xss漏洞扫描,sql注入扫描,文件包含漏洞,文件上传漏洞的扫描。
def craw(self):self.urls.add_new_url(self.root)while self.urls.has_new_url() and self.maxdeep>self.deep and self.maxdeep > 0:new_url = self.urls.get_new_url()logger.debug("craw:" + new_url)try:html = until.w9_get(new_url)check(new_url,html)except:html = ''new_urls = self._parse(new_url, html)self.urls.add_new_urls(new_urls)self.deep = self.deep + 1
def check(url,html = ''):for k, v in w9_hash_pycode.iteritems():try:pluginObj = v["pluginObj"]service = v["service"]if(service == "spider_file"):pluginObj.audit(url,html)except Exception as errinfo:logger.error("spider plugin:%s errinfo:%s url:%s"%(k,errinfo,url))
线程调度
该扫描器利用了python的threading,queue,sleep等包实现了线程池调度,每次执行扫描任务时初始化线程池,设定线程工作函数及同时并行的最大线程值。遍历插件库,若插件符合要求则将其加入队列。然后使用编写的run方法,利用threading模块并行执行扫描线程,若执行线程数小于最大并行数,则等待。
# coding:utf-8
# 模拟一个进城池 线程池,可以向里面添加任务,import threading
import time
import traceback
from lib.core.data import logger
import Queue
import randomclass w8_threadpool:def __init__(self,threadnum,func_scan,Isjoin = False):self.thread_count = self.thread_nums = threadnumself.scan_count_lock = threading.Lock()self.thread_count_lock = threading.Lock()self.load_lock = threading.Lock()self.scan_count = 0self.isContinue = Trueself.func_scan = func_scanself.queue = Queue.Queue()self.isjoin = Isjoindef push(self,payload):self.queue.put(payload)def changeScanCount(self,num):self.scan_count_lock.acquire()self.scan_count += numself.scan_count_lock.release()def changeThreadCount(self,num):self.thread_count_lock.acquire()self.thread_count += numself.thread_count_lock.release()def run(self):th = []for i in range(self.thread_nums):t = threading.Thread(target=self.scan)t.setDaemon(True)t.start()th.append(t)# It can quit with Ctrl-Cif self.isjoin:for tt in th:tt.join()else:while 1:if self.thread_count > 0 and self.isContinue:time.sleep(0.01)else:breakdef stop(self):self.load_lock.acquire()self.isContinue = Falseself.load_lock.release()def scan(self):while 1:self.load_lock.acquire()if self.queue.qsize() > 0 and self.isContinue:payload = self.queue.get()self.load_lock.release()else:self.load_lock.release()breaktry:# POC在执行时报错如果不被处理,线程框架会停止并退出self.func_scan(payload)time.sleep(0.3)except KeyboardInterrupt:self.isContinue = Falseraise KeyboardInterruptexcept Exception:errmsg = traceback.format_exc()self.isContinue = Falselogger.error(errmsg)# self.changeScanCount(-1)self.changeThreadCount(-1)if __name__ == '__main__':def calucator(num):i = random.randint(1, 100)u = numa = i * uif (a % 6 == 0):for x in range(5):print "new thread"# p.push(x)p = w8_threadpool(3, calucator)for i in range(100000):p.push(i)p.run()
安全开发之w9scan扫描器源码学习相关推荐
- IOS开发之GitHub优秀源码分享/优秀第三方转载
来源博客:http://blog.treney.com/ 来源博客:http://blog.csdn.net/justinjing0612/article/details/42557303 开源项目源 ...
- iOS开发之Masonry框架-源码解析
Masonry是iOS在控件布局中经常使用的一个轻量级框架.Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让 ...
- iOS开发之Masonry框架源码解析
Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让 ...
- iOS开发之Masonry框架源码深度解析
Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让 ...
- linux驱动开发之spi-omap-100k.c源码分析
代码分析 对于linux的驱动代码来说,我们要从后往前分析: /** OMAP7xx SPI 100k controller driver* Author: Fabrice Crohas <fc ...
- 【安全工具】projectdiscover之naabu 端口扫描器源码学习
ProjectDiscovery组织开源了很多自动化扫描的内部工具和研究,它们都是基于Go语言编写,并且在实际渗透中有极大的作用.我非常喜欢这个组织开源的软件,它也是我学习Go语言的动力之一,所以计划 ...
- Firefox os 游戏开发之2048游戏源码
<2048 >是一款数字益智游戏,<2048>的初始数字则是由2+2组成的基数4.在操作方面的不同则表现为一步一格的移动,变成更为爽快的一次到底.相同数字的方况在靠拢.相撞时会 ...
- Masonry 源码学习整理
@(第三方库源码学习) [TOC] Masonry框架的类结构 学习一.Masonry采用了经典的组合设计模式(Composite Pattern). 1.定义 将对象组合成树状结构以表示" ...
- (0045) iOS 开发之MBProgressHUD 源码学习
(0045) iOS 开发之MBProgressHUD 源码学习 第一部分:学习所得和分析线程 1. 学习到了kvo 的使用 和屏幕方向的旋转判断. 2. 如果调起这个 HUD 的方法不是在主线程调 ...
最新文章
- 【异步爬虫】【aiohttp】不需要手动指定aiohttp中的encoding编码
- windows下安装RabbitMQ
- 包含目录、库目录、附加包含目录、附加库目录、附加依赖项之详解
- boost::mpl模块back相关的测试程序
- Solr 6.7学习笔记(04)-- Suggest
- 3G与4G到底有何区别?
- Struts2中的OGNL表达式
- 前端学习(848):为什么学习节点操作和节点简介
- 《Android开发卷——HTTP网络通信,HTTP网络连接》
- 《细说PHP》第四版 样章 第二章 PHP的应用与发展 1
- 我的大学生涯软件工程一年半
- python怎么设置为中文-python如何设置中文界面
- 简要介绍电源效率测试
- 心理学实验必备 | 脑电实验流程及注意事项
- jQuery 样式操作
- 开启memcached日志
- 阿里云视频点播解密DecryptKMSDataKeyRequest爬坑
- 冬至了,该盘点盘点2021年中国企业服务产业了
- nao机器人导入自己写的python程序_python程序控制NAO机器人行走
- 真真切切的100%新手向---安装Arch Linux(更新时间 2018/07-26)
热门文章
- 【wordpress】如何把wordpress从本地服务器迁移到网站主机上
- [已解决] Adding visible gpu devecies:
- input标签的value属性详解
- CListCtrl(clistctrl获取选中行数据)
- 数据存储:小端模式和大端模式——终于搞明白了!!!
- 幸福的指数 谁来定?
- hadoop Map 100% reduce 0% 问题
- 京东JData算法大赛-高潜用户购买意向预测(github源码)
- 笔记本电脑中浏览器无法连接网络。无法连接到代理服务器,错误代码 ERR_PROXY_CONNECTION_FAILED
- 通信网络单元定级报告怎么写?定级报告模板范文分享