上周将W13Scan目录结构整理了一番,以为要深刻研究还得从代码层,因而尝试编写一下插件;框架自己已经集成了XSS扫描插件;php
本篇文章的XSS插件的编写单纯是为了学习这个框架,因此只支持GET型,了解插件的编写方法和原理便可。html
W13scan 是基于Python3的一款开源的Web漏洞发现工具,它支持主动扫描模式和被动扫描模式,能运行在Windows、Linux、Mac上。
在编写插件以前,咱们须要对框架自己的目录结构有必定了解,因为W13Scan自己的文档不是太详细,我本身整理了一下,目录结构图下所示python
├── api 经过API调用启动扫描 ├── certs HTTPS证书存放目录 ├── data html输出模板存放目录 ├── fingprints 指纹数据 │ ├── framework 框架 │ ├── os 操做系统 │ ├── programing │ └── webserver web服务 ├── lib 框架核心目录 │ ├── api │ ├── controller │ ├── core │ ├── helper │ ├── parse │ ├── proxy │ └── reverse ├── output 扫描结果输出目录 ├── scanners 扫描器插件 │ ├── PerFile 针对每一个文件,包括参数啥的 │ ├── PerFolder 针对url的目录,会分隔目录分别访问 │ ├── PerServer 对每一个domain的 ├── thirdpart │ ├── requests └── w13scan.py 启动入口
在上方目录结构中,咱们看到插件都放在scanners
目录中,入口文件则为w13scan.py
文件,所以这两个位置就是咱们须要重点所关注的;如今咱们须要去分析框架的运行流程。git
使用pycharm
编辑器打开文件 w13scan.py
,能够看到入口文件中的以下代码web
def main(): # 检查版本信息 version_check() # 获取绝对路径 root = modulePath() # 解析命令行参数 cmdline = cmd_line_parser() # 初始化执行 init(root, cmdline)
在上方代码中能够看到运行了初始化init(root,cmdline)
方法,按住ctrl
而后用鼠标点击跳转到方法详情,编辑器自动打开了文件 lib/core/option.py
,能够看到初始化的具体流程后端
def init(root, cmdline): cinit(autoreset=True) setPaths(root) # 指纹信息 banner() # 从config.py读取配置信息 _init_conf() # 从cmdline读取配置 _merge_options(cmdline) # 设置端口信息 _set_conf() initKb() # 加载插件 initPlugins() # 输出配置信息 _init_stdout() patch_all()
在上方代码中能够看到,里面有一个initPlugins()
方法,一样按住ctrl
而后点击方法名字,编辑器会自动打开文件 lib/core/option.py
,能够看到插件初始化的整个过程api
def initPlugins(): # 加载检测插件 for root, dirs, files in os.walk(path.scanners): # 获取插件下的文件列表 files = filter(lambda x: not x.startswith("__") and x.endswith(".py"), files) # 对每个文件进行处理 for _ in files: # 获取文件名 q = os.path.splitext(_)[0] # 判断插件白名单 if conf.able and q not in conf.able and q != 'loader': continue # 判断插件黑名单 if conf.disable and q in conf.disable: continue # 文件绝对路径 filename = os.path.join(root, _) # 加载该文件 mod = load_file_to_module(filename)
在上方代码中能够看到初始化插件,其实就是扫描了插件目录的文件列表,而后挨个加载文件。浏览器
为了证明这个猜测,我在遍历的位置进行了代码调试,加了print()
方法,来验证个人猜测,代码以下所示cookie
# 获取文件名 q = os.path.splitext(_)[0] print(q) print("\n") # 判断插件白名单 if conf.able and q not in conf.able and q != 'loader': continue
找了一个靶场系统,而后使用w13scan的扫描命令运行,执行命令以下所示框架
python w13scan.py -u "http://192.168.152.135:8888/home/index.php?m=tiezi&a=index&bk=6"
命令执行,在控制台看到以下信息
(w13scan) D:\mycode\tools\w13scan\W13SCAN>python w13scan.py -u "http://192.168.152.135:8888/home/index.php?m=tiezi&a=index&bk=6" ________________ < w13scan v2.1.0 > ---------------- \ \ ,__, | | (oo)\| |___ (__)\| | )\_ | |_w | \ | | || * Cower.... loader analyze_parameter backup_file ....插件列表,省略.... net_xss swf_files [11:23:49] [INFO] Load scanner plugins:29
在上方的信息中,看到scanners
目录下的文件列表,因此验证了个人猜测;
接下来我就能够正式编写插件了,为了防止编写过程当中对插件目录形成损坏,我将scanners
目录复制了一份,以下图所示
在上图中,我将scannsers
目录复制到当前目录的scannsers
目录,若是编写过程当中须要参考或者还原直接拷贝过来便可
接着我回到scanners
目录,在目录里面有29个插件,调试的时候不是太方便,我先将其余插件都删除,为了参考插件怎么编写的,我留下一个,以下图所示
在上图中,我只留下了一个backup_file.py
插件,用于编写本身的插件参考;同时我将这个插件改为本身插件的名字,以下图所示
在上图中,我将插件文件名子改成了xss_test.py
,再次运行,看看是否能正确运行,运行结果以下图所示
在上图中能够看到依然是能够运行的,同时插件名字也发生了变化,变成了xss_test
文件
如今咱们就开始编辑xss_test.py
插件,使用pycharm打开后,看到的代码以下图所示
在上图中能够看到插件代码里面有两个方法audit
和_check
,我作了下分析,audit
才是对外的方法,_check
方法是插件内部的方法,咱们不须要,直接删除便可;
接着咱们新建一个audit
方法,同时备份以前的audit
方法为audit_bak
做为参考,以下图所示
在上图中,我新建了一个audit
方法,并接收了请求头信息和要请求的URL地址,并给出了要实现XSS漏洞检测的三个步骤:
接着我就开始实现这三个步骤,首先去准备poc代码,以下代码所示
# 接收头信息 headers = self.requests.headers # 咱们不要URL地址中的参数部分 url = self.requests.netloc # 从这里单独接收参数,字典类型 params = self.requests.params # 这里备份一下字典,不要使用同一个内存地址 paramsBak = params.copy() # 1. 准备poc payloads = [ "1'\"()&%<acx><ScRiPt >prompt(915149)</ScRiPt>", "<svg/onload=alert(1)>", "\"><script>alert(document.cookie)</script>" ]
接着我须要将poc代码和URL地址结合,生成一个带有攻击参数的连接地址,代码以下所示
# 每个payloads都测试一遍 for payload in payloads: # 每个参数都须要测试 for key, val in params.items(): # 每次只测试一个参数,因此须要将以前的字典覆盖 params = paramsBak.copy() # 将字典里的值改变,而后放到另一个函数生成一个URL地址 params[key] = payload nUrl = self.createUrl(url, params)
生成以下URL地址:
http://192.168.152.135:8888/home/index.php?m=<svg/onload=alert(1)>&a=index&bk=6
或者以下:
http://192.168.152.135:8888/home/index.php?m=tiezi&a=<svg/onload=alert(1)>&bk=6
依次将poc代码替换到原有请求参数当中,接下来就是使用python去请求这个地址,并查看返回结果是否包含了poc代码,若是包含了poc代码说明后端没有作过滤处理,代码以下所示
# 2. 发送请求 r = requests.get(nUrl, headers=headers, allow_redirects=False) # 若是返回值是200,说明页面能够访问 if r.status_code == 200: # 3.判断返回数据里面是否包含了poc,包含了说明存在XSS if payload in r.text: # 将结果返回给框架,统一存储 result = self.new_result() result.init_info(nUrl, "XSS检测", VulType.BRUTE_FORCE) # 存储扫描结果 result.add_detail("payload请求", r.reqinfo, "请求返回结果", "插件备注信息", nUrl, "", PLACE.GET) self.success(result)
代码的含义在上面的备注信息中已经有说明,就再也不过多赘述了,接下来咱们再次运行W13Scan
,运行命令以下所示
python w13scan.py -u "http://192.168.152.135:8888/home/index.php?m=tiezi&a=index&bk=6"
命令运行以后,控制台输出的信息以下所示
在上图中能够看到咱们的插件已经成功运行,并检测到了XSS漏洞
接下来我复制其中一个带有poc的URL地址,放到浏览器去运行,以下图所示
在上图中能够看到浏览器触发了XSS代码,弹出了cookie值,至此编写XSS检测插件就完成了,固然这个插件还不够完善,有兴趣的能够本身再深刻研究~
完整的poc代码能够参考:
https://gitee.com/songboy/codes/kodyj714izqbpgv8cu2n390
做者:汤青松
日期:2020-12-08