├── .gitignore
├── LICENSE
├── README.md
├── advancedModelFile.html
├── communityModelFile.html
├── config.py
├── images
├── screen.png
├── screen2.png
├── screen3.png
├── screen4.png
├── screen5.png
└── screen6.png
├── pppXray.py
├── requirements.txt
├── target.txt
└── test.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | .idea
7 | # C extensions
8 | *.so
9 |
10 | # Distribution / packaging
11 | .Python
12 | venv/
13 | migrations/
14 | build/
15 | develop-eggs/
16 | dist/
17 | downloads/
18 | eggs/
19 | .eggs/
20 | lib/
21 | lib64/
22 | parts/
23 | sdist/
24 | var/
25 | wheels/
26 | pip-wheel-metadata/
27 | share/python-wheels/
28 | *.egg-info/
29 | .installed.cfg
30 | *.egg
31 | MANIFEST
32 |
33 | # PyInstaller
34 | # Usually these files are written by a python script from a template
35 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
36 | *.manifest
37 | *.spec
38 |
39 | # Installer logs
40 | pip-log.txt
41 | pip-delete-this-directory.txt
42 |
43 | # Unit test / coverage reports
44 | htmlcov/
45 | .tox/
46 | .nox/
47 | .coverage
48 | .coverage.*
49 | .cache
50 | nosetests.xml
51 | coverage.xml
52 | *.cover
53 | *.py,cover
54 | .hypothesis/
55 | .pytest_cache/
56 |
57 | # Translations
58 | *.mo
59 | *.pot
60 |
61 | # Django stuff:
62 | *.log
63 | local_settings.py
64 | db.sqlite3
65 | db.sqlite3-journal
66 |
67 | # Flask stuff:
68 | instance/
69 | .webassets-cache
70 |
71 | # Scrapy stuff:
72 | .scrapy
73 |
74 | # Sphinx documentation
75 | docs/_build/
76 |
77 | # PyBuilder
78 | target/
79 |
80 | # Jupyter Notebook
81 | .ipynb_checkpoints
82 |
83 | # IPython
84 | profile_default/
85 | ipython_config.py
86 |
87 | # pyenv
88 | .python-version
89 |
90 | # pipenv
91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
94 | # install all needed dependencies.
95 | #Pipfile.lock
96 |
97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
98 | __pypackages__/
99 |
100 | # Celery stuff
101 | celerybeat-schedule
102 | celerybeat.pid
103 |
104 | # SageMath parsed files
105 | *.sage.py
106 |
107 | # Environments
108 | .env
109 | .venv
110 | env/
111 | venv/
112 | ENV/
113 | env.bak/
114 | venv.bak/
115 |
116 | # Spyder project settings
117 | .spyderproject
118 | .spyproject
119 |
120 | # Rope project settings
121 | .ropeproject
122 |
123 | # mkdocs documentation
124 | /site
125 |
126 | # mypy
127 | .mypy_cache/
128 | .dmypy.json
129 | dmypy.json
130 |
131 | # Pyre type checker
132 | .pyre/
133 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 潘一二三
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pppXray
2 | **作用:**
3 |
4 | Xray批量化自动扫描
5 |
6 | **使用方法:**
7 |
8 | 一,在target.txt里按行放置待扫描URL,如图:
9 |
10 | 
11 |
12 | 二,将Xray所在文件夹配置到电脑环境变量里
13 |
14 | 三,然后运行pppXray.py即可
15 |
16 | **运行截图:**
17 |
18 | 
19 |
20 | 关于[Xray高级版破解](https://www.cnblogs.com/Cl0ud/p/13884206.html)
21 |
22 |
23 |
24 | ### 2021/2/20更新
25 |
26 | 添加命令行参数与自定义`xray`插件用法,可通过 `--help`查看
27 |
28 | 
29 |
30 | `-r,--readfile`参数指定批量读取文件名,默认文件名为`target.txt`
31 |
32 | 
33 |
34 | `--plugins`参数指定xray插件
35 |
36 | 如图:
37 |
38 | 输入 `python3 pppXray.py --plugins cmd_injection -r target.txt`,使用注入插件进行检测
39 |
40 | 
41 |
42 |
43 |
44 | ### 2021/5/5更新
45 |
46 | 看到了黑白某道的公众号文章,这么菜的脚本也能水文章了,xs
47 |
48 | 但为了方便初学安全的小伙伴更方便使用`xray`,参考之前[花溪九尾](https://github.com/Cl0udG0d/HXnineTails)的经验,在脚本中兼容专业版和社区版,以及添加分类的功能,大伙儿就不用点开每个漏洞报告看了,因为有部分类型的漏洞会被忽略,节省查看报告时间
49 |
50 | 使用前记得`pip install -r requirements.txt` (没科学上网的自主换源)
51 |
52 | 
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 |
4 | RootPath = os.path.dirname(os.path.abspath(__file__))
5 | saveDir = "{}\\save".format(RootPath)
6 | # saveXrayReport = '{}\\save\\xrayReport'.format(RootPath)
7 |
8 | targetFileName=""
9 | plugins=""
10 |
11 | def logo():
12 | logo='''
13 | _ __ _ __ _ __
14 | | '_ \| '_ \| '_ \
15 | | |_) | |_) | |_) |
16 | | .__/| .__/| .__/
17 | | | | | | |
18 | |_| |_| |_|
19 | __ __
20 | \ \ / /
21 | \ V / _ __ __ _ _ _
22 | / \| '__/ _` | | | |
23 | / /^\ \ | | (_| | |_| |
24 | \/ \/_| \__,_|\__, |
25 | __/ |
26 | |___/
27 | v1.2
28 | author:springbird
29 | '''
30 | return logo
--------------------------------------------------------------------------------
/images/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cl0udG0d/pppXray/cb19836cf200da934b66edfdf8db874a7ca18943/images/screen.png
--------------------------------------------------------------------------------
/images/screen2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cl0udG0d/pppXray/cb19836cf200da934b66edfdf8db874a7ca18943/images/screen2.png
--------------------------------------------------------------------------------
/images/screen3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cl0udG0d/pppXray/cb19836cf200da934b66edfdf8db874a7ca18943/images/screen3.png
--------------------------------------------------------------------------------
/images/screen4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cl0udG0d/pppXray/cb19836cf200da934b66edfdf8db874a7ca18943/images/screen4.png
--------------------------------------------------------------------------------
/images/screen5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cl0udG0d/pppXray/cb19836cf200da934b66edfdf8db874a7ca18943/images/screen5.png
--------------------------------------------------------------------------------
/images/screen6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cl0udG0d/pppXray/cb19836cf200da934b66edfdf8db874a7ca18943/images/screen6.png
--------------------------------------------------------------------------------
/pppXray.py:
--------------------------------------------------------------------------------
1 | import hashlib
2 | import re
3 | import time
4 | import os
5 | import click
6 | import config
7 |
8 | @click.command()
9 | @click.option('-r', '--readfile',default='target.txt',help='xray批量扫描读取文件名,按行读取',type=str)
10 | @click.option('--plugins',help='自定义xray插件 plugins')
11 | def init(readfile,plugins):
12 | """pppXray : xray 批量扫描\n
13 | https://github.com/Cl0udG0d/pppXray
14 | """
15 | try:
16 | if not os.path.exists(config.saveDir):
17 | os.makedirs(config.saveDir)
18 | config.targetFileName=readfile
19 | if plugins:
20 | config.plugins=plugins
21 | click.echo("读取文件 {} ".format(readfile))
22 | except Exception as e:
23 | print(e)
24 | pass
25 |
26 |
27 | def advancedMergeReport(tempTypeResult,bugTypeSet):
28 | pattern2 = re.compile(r'"plugin":"(.*?)"')
29 | tempType = pattern2.findall(tempTypeResult)[0]
30 | path = os.path.join(config.saveDir, tempType)
31 | context = ""
32 | if tempType not in bugTypeSet:
33 | bugTypeSet.add(tempType)
34 | os.makedirs(path)
35 | with open("{}\\advancedModelFile.html".format(config.RootPath), 'r', encoding='utf-8') as f:
36 | context += f.read()
37 | result = "".format(tempTypeResult)
38 | context += result
39 | with open("{}\\{}.html".format(path, tempType), 'w', encoding='utf-8') as f:
40 | f.write(context)
41 | else:
42 | result = "".format(tempTypeResult)
43 | context += result
44 | with open("{}\\{}.html".format(path, tempType), 'a+', encoding='utf-8') as f:
45 | f.write(context)
46 |
47 |
48 |
49 | def communityMergeReport(tempTypeResult,bugTypeSet):
50 | pattern2 = re.compile(r'"plugin":"(.*?)"')
51 | tempType = pattern2.findall(tempTypeResult)[0]
52 | path = os.path.join(config.saveDir, tempType)
53 | context = ""
54 | if tempType not in bugTypeSet:
55 | bugTypeSet.add(tempType)
56 | os.makedirs(path)
57 | with open("{}\\communityModelFile.html".format(config.RootPath), 'r', encoding='utf-8') as f:
58 | context += f.read()
59 | result = "".format(tempTypeResult)
60 | context += result
61 | with open("{}\\{}.html".format(path, tempType), 'w', encoding='utf-8') as f:
62 | f.write(context)
63 | else:
64 | result = "".format(tempTypeResult)
65 | context += result
66 | with open("{}\\{}.html".format(path, tempType), 'a+', encoding='utf-8') as f:
67 | f.write(context)
68 | return
69 |
70 |
71 |
72 | def assortReport():
73 | '''
74 | 对 save 文件夹下的漏洞文件进行分类
75 | 依托 "plugin"
76 | :return:
77 | '''
78 | bugTypeSet=set()
79 | bugReportList=os.listdir(config.saveDir)
80 | pattern = re.compile(r'')
81 | # pattern2 = re.compile(r'"plugin":"(.*?)"')
82 | for tempReport in bugReportList:
83 | tempReportPath=os.path.join(config.saveDir,tempReport)
84 | with open(tempReportPath,'r',encoding='utf-8') as f:
85 | temp=f.read()
86 | result=pattern.findall(temp)
87 | tempResult = eval(result[0])
88 | if 'snapshot' in tempResult["detail"]:
89 | for tempTypeResult in result:
90 | communityMergeReport(tempTypeResult, bugTypeSet)
91 | else:
92 | for tempTypeResult in result:
93 | advancedMergeReport(tempTypeResult, bugTypeSet)
94 |
95 |
96 | def xrayScan(targeturl,outputfilename="test"):
97 | scanCommand = "xray.exe webscan {} --basic-crawler {} --html-output {}\\{}.html".format('--plugins {}'.format(config.plugins) if config.plugins else '',targeturl, config.saveDir,
98 | outputfilename)
99 | print(scanCommand)
100 | os.system(scanCommand)
101 | return
102 |
103 |
104 | def pppGet():
105 | f = open(config.targetFileName)
106 | lines = f.readlines()
107 | pattern = re.compile(r'^http')
108 | for line in lines:
109 | try:
110 | if not pattern.match(line.strip()):
111 | targeturl="https://"+line.strip()
112 | else:
113 | targeturl=line.strip()
114 | print(targeturl.strip())
115 | outputfilename=hashlib.md5(targeturl.encode("utf-8"))
116 | xrayScan(targeturl.strip(), outputfilename.hexdigest())
117 | # print(type(line))
118 | except Exception as e:
119 | print(e)
120 | pass
121 | f.close()
122 | print("Xray Scan End~")
123 | return
124 |
125 | def main():
126 | try:
127 | print(config.logo())
128 | init.main(standalone_mode=False)
129 | pppGet()
130 | assortReport()
131 | except Exception as e:
132 | print(e)
133 | pass
134 | return
135 |
136 | if __name__ == '__main__':
137 | main()
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | click==7.1.2
2 | urllib3==1.25.8
3 |
--------------------------------------------------------------------------------
/target.txt:
--------------------------------------------------------------------------------
1 | http://127.0.0.1
--------------------------------------------------------------------------------
/test.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | pattern2 = re.compile(r'"plugin":"(.*?)"')
4 | str2='web.com/guestbook.php"},"identifier":"","plugin":"xss",'
5 | result=pattern2.findall(str2)
6 | print(result)
--------------------------------------------------------------------------------