64位Linux机器上的ELF可执行shellcode
我正在创建缓冲区溢出和堆栈/堆攻击的培训。 我正在使用Ubuntu 12.04 x86_64机器,并希望展示一些示例buggy程序以及可以利用这些漏洞的方式。
我试图从我迄今为止发现的最基本的shellcode开始,简单的退出调用,它应该退出程序溢出。
因此exitcall.asm :
;exitcall.asm
[SECTION .text]
global _start
_start:
xor ebx,ebx ; zero out ebx, same function as mov ebx,0
mov al, 1 ; exit command to kernel
int 0x80
然而,我从其他教程中获得了这个asm文件,它是为i386体系结构编写的。 接下来要做的是生成一个目标文件并将其设置为二进制可执行文件:
# nasm -f elf64 exitcall.asm
# ld -o exitcall exitcall.o
# file exitcall
exitcall: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
# strace ./exitcall
execve("./exitcall", ["./exitcall"], [/* 73 vars */]) = 0
write(0, NULL, 0 <unfinished ...>
+++ exited with 0 +++
# objdump -d exitcall
exitcall: file format elf64-x86-64
Disassembly of section .text:
0000000000400080 <_start>:
400080: 31 db xor %ebx,%ebx
400082: b0 01 mov $0x1,%al
400084: cd 80 int $0x80
正如你所看到的,二进制结果执行得很好(出口0用strace验证),不知怎的,给了我信心,asm文件也是正确的。 所以我现在应该做的是从它创建一个shellcode字符数组,所以我可以测试下面的示例shellprogram.c executor。 我刚刚从objdump中取得了HEX值,并开始从左到右,从上到下地读取,导致了以下测试:
char code[] = "x31xdbxb0x01xcdx80";
int main(int argc, char **argv) {
int (*exeshell)();
exeshell = (int (*)()) code;
(int)(*exeshell)();
}
当我编译这个文件并执行它时,我会遇到分段错误 ,但是:
# gcc shellprogram.c -o shellprogram
# file shellprogram
shellprogram: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=765bdf6201099b9784b63a0111dc16c1115118bb, not stripped
# strace ./shellprogram
execve("./shellprogram", ["./shellprogram"], [/* 73 vars */]) = 0
brk(0) = 0x602000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff8000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=134914, ...}) = 0
mmap(NULL, 134914, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7fd7000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "177ELF211 3 >