├── data
├── __init__.py
└── param_blacklist.py
├── exploits
├── __init__.py
├── template.py
└── PUT.py
├── tornado_proxy
├── __init__.py
├── requirements.txt
├── setup_https_intercept.sh
├── LICENSE
├── README.md
├── .gitignore
├── filelock.py
├── timer.py
├── socket_wrapper.py
├── gen_cert.py
└── proxy.py
├── requirements.txt
├── stop.sh
├── README.md
├── templates
├── modal_style.html
├── show_detect.html
└── show_vul.html
├── LICENSE
├── proxy.pac
├── run.sh
├── config.py
├── AutoFill.user.js
├── .gitignore
├── install.sql
├── parser.py
├── httplog.py
├── zoneresolver.py
├── fuzzer.py
├── proxy.py
└── XSSHelper.user.js
/data/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data/param_blacklist.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/exploits/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tornado_proxy/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tornado_proxy/requirements.txt:
--------------------------------------------------------------------------------
1 | tornado
2 | pycurl
3 | pyopenssl
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | tornado
2 | requests
3 | pycurl
4 | pymysql
5 | flask
6 | dnslib
7 |
--------------------------------------------------------------------------------
/stop.sh:
--------------------------------------------------------------------------------
1 | cmd=$(which tmux) # tmux path
2 | session="zeroexploit"
3 |
4 | $cmd kill-session -t $session
--------------------------------------------------------------------------------
/tornado_proxy/setup_https_intercept.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | openssl genrsa -out ca.key 2048
4 | openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/CN=proxy2 CA"
5 | openssl genrsa -out cert.key 2048
6 | mkdir certs/
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ZeroExploit
2 | ultimate web vul hunter
3 |
4 | 前后端结合检测漏洞,正在开发中。。
5 | 是个大坑,并不知道什么时候能写完
6 |
7 | 代理设置成pac,路径见httplog.py
8 | tampermonkey加载XSS Helper.user.js并设置成页面加载完之后执行,方便自动填表单
9 |
10 | 设置XSS Helper.user.js里的作用域url和报告url
11 | 设置config.py里的各种信息
12 |
13 | 正常用要开3个脚本
14 |
15 | dns: zoneresolver.py
16 | httpserver: httplog.py
17 | proxyserver: proxy.py
18 |
19 | 浏览器加载XSS Helper.user.js
20 | 浏览器设置代理
21 |
22 | 就先这样吧
23 |
24 | ## TODO
25 |
26 | * onerror事件总是晚于某些js代码的执行,浏览器在页面最前方插入hook代码
27 | * 暂时不考虑伪静态
28 | * 目前只处理post query string的情况,对get请求没有参数不插数据库
--------------------------------------------------------------------------------
/exploits/template.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | author = 'md5_salt' # 可选
3 | timeout = 30 # 建议
4 | vtype = 'all' #value type: all/int/float/str/url/json/special/ special|json
5 |
6 |
7 | def exploit(request, response, method, key, is_array=False):
8 | info = "this is a test"
9 | return {'result': 'safe', 'info': info, 'hash': None} # result为('safe', 'vul', 'unknown', 'continue'), 第3个返回用于unknown时的延时判断
10 |
11 | if __name__ == '__main__':
12 | req = {'uri': '', 'body':'', 'headers': ''}
13 | rsp = {}
14 | method = 'GET'
15 | key = ''
16 | print exploit(req, rsp, method, key)
--------------------------------------------------------------------------------
/templates/modal_style.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
17 |
18 |
19 |
20 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/exploits/PUT.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import requests
3 | import os
4 | import config
5 | author = 'md5_salt' # 可选
6 | timeout = 5 # 建议
7 | vtype = 'all' #value type: all/int/float/str/url/json/special
8 | stype = 'java|asp|aspx'
9 |
10 | # https://paper.seebug.org/403/
11 | # https://mp.weixin.qq.com/s/uTiWDsPKEjTkN6z9QNLtSA
12 | # https://pivotal.io/security/cve-2017-8046
13 |
14 | def exploit(request, response, method, key, is_array=False):
15 |
16 | if config.dbconn().fetch_rows('result', condition="exploit='%s' and result != 'continue' and `host`='%s'" % (os.path.basename(__file__)[:-3], request['host']), order="id asc", limit="1", fetchone=True): return
17 | allow = requests.options(request['uri']).headers.get('Allow', '')
18 | if allow.find('PUT') != -1 or allow.find('PATCH') != -1:
19 | return {'result': 'vul', 'info': "Server support put/patch method", 'hash': None, 'level': "middle"}
20 | else:
21 | return {'result': 'safe', 'info': "Server does not support put/patch method", 'hash': None, 'level': "middle"}
22 |
23 | if __name__ == '__main__':
24 | pass
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 5alt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tornado_proxy/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 5alt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tornado_proxy/README.md:
--------------------------------------------------------------------------------
1 | # tornado-proxy
2 |
3 | tornado-proxy 是基于 tornado 实现的 HTTP/HTTPS 代理服务器,支持 python2 和 python3。
4 |
5 | 本程序在 owtf-proxy 的基础上修改而成,整合了 owtf-proxy 和 tornado-proxy 对 HTTPS 的两种不同方式的支持,参考 proxy2 中对请求和响应的拦截与处理方式。
6 |
7 | ## 特性
8 |
9 | * 支持对 HTTPS 请求的透明代理和动态伪造证书拦截流量两种方式
10 | * 高性能
11 | * 自定义对请求和响应的处理
12 | * 可配置此代理服务器的代理服务器
13 |
14 | ## 依赖
15 |
16 | * pyopenssl
17 | * tornado
18 | * pycurl
19 |
20 | `pip install -r requirements.txt`
21 |
22 | 在 osx 下 pip 安装 pycurl 报编译错误,加上环境变量 `archflags -arch x86_64` 即可。
23 |
24 | `sudo env ARCHFLAGS="-arch x86_64" pip install pycurl`
25 |
26 | ubuntu 下需先安装 `libssl-dev` 和 `libcurl4-openssl-dev`
27 |
28 | ## 开启 HTTPS 拦截
29 |
30 | 拦截 HTTPS 流量需要先生成私钥和CA证书。将生成的CA证书添加到浏览器的信任区域中。
31 |
32 | `$ ./setup_https_intercept.sh`
33 |
34 | 删除产生的证书以及私钥文件即不拦截 HTTPS 流量。
35 |
36 | ## 自定义功能
37 |
38 | 在 `ProxyHandler` 中有三个方法可以用来修改或者保存请求和响应信息。
39 |
40 | * request_handler: 在代理服务器向web服务器发送请求之前调用
41 | * response_handler: 在代理服务器向客户端返回响应之前调用
42 | * save_handler: 在客户端获取响应之后调用
43 |
44 |
45 | ## 参考资料
46 |
47 | https://github.com/tunnelshade/owtf-proxy
48 |
49 | https://github.com/senko/tornado-proxy
50 |
51 | https://github.com/inaz2/proxy2
52 |
--------------------------------------------------------------------------------
/proxy.pac:
--------------------------------------------------------------------------------
1 | function FindProxyForURL(url, host) {
2 | var proxy_host = '{{proxy_host}}'
3 | var proxy_port = {{proxy_port}}
4 |
5 | var whitelist_domain = {{included_host|safe}}
6 | var blacklist_domain = {{excluded_host|safe}}
7 | var blacklist_ext = {{filter_file|safe}}
8 |
9 | if (url.substring(0,5)!="http:" && url.substring(0,6)!="https:") return "DIRECT";
10 |
11 | if(blacklist_domain.length){
12 | for (var i = 0, len = blacklist_domain.length; i < len; i++) {
13 | if (host.endsWith(blacklist_domain[i]))
14 | return 'DIRECT';
15 | }
16 | }
17 |
18 | if(whitelist_domain.length){
19 | for (var i = 0, len = whitelist_domain.length; i < len; i++) {
20 | if (!host.endsWith(blacklist_domain[i]))
21 | return 'DIRECT';
22 | }
23 | }
24 |
25 | if(blacklist_ext.length){
26 | for (var i = 0, len = blacklist_ext.length; i < len; i++) {
27 | if (url.toLowerCase().split('?')[0].endsWith(blacklist_ext[i]))
28 | return 'DIRECT';
29 | }
30 | }
31 |
32 | return "PROXY "+proxy_host+":"+proxy_port+"; DIRECT";
33 |
34 | }
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | cmd=$(which tmux) # tmux path
2 | session="zeroexploit"
3 |
4 | if [ -z $cmd ]; then
5 | echo "You need to install tmux."
6 | exit 1
7 | fi
8 |
9 | $cmd has-session -t $session > /dev/null
10 |
11 | if [ $? != 0 ]; then
12 | $cmd new -d -n base-act -s $session ""
13 | $cmd splitw -v -t $session
14 | $cmd splitw -h -t $session
15 | $cmd splitw -v -t $session
16 | $cmd splitw -h -t $session
17 | #$cmd splitw -v -t $session
18 | $cmd select-layout -t $session tiled
19 |
20 | $cmd send-keys -t $session:0.0 'python httplog.py' C-m
21 | $cmd send-keys -t $session:0.1 'python proxy.py' C-m
22 | $cmd send-keys -t $session:0.2 'python parser.py' C-m
23 | $cmd send-keys -t $session:0.3 'python fuzzer.py' C-m
24 | #$cmd send-keys -t $session:0.4 'whoami' C-m
25 |
26 | #$cmd set-window-option synchronize-panes on
27 | #$cmd neww -n vim -t $session "zsh"
28 | #$cmd selectw -t $session:5
29 | fi
30 |
31 | $cmd att -t $session
32 |
33 | exit 0
34 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from lib.libmysql import MYSQL
3 |
4 | def ip():
5 | import socket
6 | return socket.gethostbyname(socket.gethostname())
7 |
8 | proxy_host = '127.0.0.1'#ip()
9 | proxy_port = 8888
10 |
11 | DNS_DOMAIN = 'd.5alt.me'
12 | SERVER_IP = '127.0.0.1'#ip()
13 |
14 | hash_pattern = r'[a-z0-9]{5}'
15 |
16 | filter_file = [".js", ".ico", ".flv", ".css", ".jpg", ".png", ".jpeg", ".gif", ".pdf", ".ss3", ".txt", ".rar", ".zip", ".avi", ".mp4", ".swf", ".wmi", ".exe", ".mpeg"] #host.endswith(item), '.html', '.htm',
17 | filter_code = r'4\d{2}' #re.match
18 | included_host = ['vulnweb.com'] #host.endswith(item)
19 | excluded_host = [".gov", "localhost", "127.0.0.1", "google.com", "gstatic.com", "cnzz.com", "doubleclick.com", "mil.cn", "gov.cn", "gov.com"] #host.endswith(item)
20 | filter_content_type = ['html', 'xml', 'json', 'javascript', 'plain']
21 |
22 | dbhost = 'localhost'
23 | dbuser = 'root'
24 | dbpwd = 'root'
25 | dbname = 'zeroexploit'
26 | dbcharset = 'utf8'
27 | unix_socket = None # for other platform
28 | #unix_socket = "/Applications/MAMP/tmp/mysql/mysql.sock" #for osx MAMP
29 |
30 | def dbconn():
31 | return MYSQL(dbhost, dbuser, dbpwd, dbname, dbcharset, unix_socket)
32 |
33 |
34 | max_save_size = 1024*1024 # 1M
35 |
36 | EXPLOITS_PATH = "./exploits/"
37 | EXPLOIT_TIMEOUT = 5
38 |
--------------------------------------------------------------------------------
/AutoFill.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name AutoFill
3 | // @version 0.1
4 | // @description XSS Helper
5 | // @exclude http://*.google.com/*
6 | // @exclude https://*.google.com/*
7 | // @grant none
8 | // @run-at document-idle
9 | // ==/UserScript==
10 |
11 |
12 | // @match http://*/*
13 | // @match https://*/*
14 |
15 | //md5_salt
16 |
17 | // auto fill forms
18 | (function() {
19 | document.all.constructor.prototype.forEach = Array.prototype.forEach;
20 | document.all.forEach(function(n){
21 | fuzz_mark_color = '#cfffdd';
22 | //fuzz_value = 'md5_salt23333\'"\\';
23 | //fuzz_textarea = 'md5_salt23333\'"\\