编写了一个简单的x86_64 shellcode:
BITS 64
xor rax, rax
push rax
push 0x68732f6e
push 0x69622f2f
mov rbx, rsp
push rax
mov rdx, rsp
push rbx
mov rcx, rsp
mov al, 221
int 0x80
通过缓冲区溢出,shellcode被发送到处理器。一切顺利,直到从末尾执行第三条指令(push rbx)为止。然后,程序将捕获SIGSEGV,并且永远不会到达所珍爱的中断-int 0x80。我以为堆栈可能溢出了,我在shellcode的开头插入了一些pop指令。结果,在同一条指令上,SIGSEGV更改为SIGILL-push rbx。根本没有想法。GDB:
=> 0x7fffffffea72: mov rdx,rsp
0x7fffffffea75: push rbx
0x7fffffffea76: mov rcx,rsp
0x7fffffffea79: mov al,0xdd
0x7fffffffea7b: int 0x80
0x7fffffffea7d: (bad)
0x7fffffffea7e: (bad)
0x7fffffffea7f: inc DWORD PTR [rax]
-----------------------------------------------------------------------------------------------------------------------------
0x00007fffffffea72 in ?? ()
gdb$ n
-----------------------------------------------------------------------------------------------------------------------[regs]
RAX: 0x0000000000000000 RBX: 0x00007FFFFFFFEA88 RBP: 0xFFFFFFFFFFFFFFFF RSP: 0x00007FFFFFFFEA80 o d I t s Z a P c
RDI: 0x00007FFFFFFFEA60 RSI: 0x0000555555556021 RDX: 0x00007FFFFFFFEA80 RCX: 0x60FFFFFFFFFFFFFF RIP: 0x00007FFFFFFFEA75
R8 : 0x0000000000000000 R9 : 0x00007FFFF7FE14C0 R10: 0xFFFFFFFFFFFFF8F5 R11: 0x00007FFFF7E54B60 R12: 0x0000555555555060
R13: 0x0000000000000000 R14: 0x0000000000000000 R15: 0x0000000000000000
CS: 0033 DS: 0000 ES: 0000 FS: 0000 GS: 0000 SS: 002B
-----------------------------------------------------------------------------------------------------------------------[code]
=> 0x7fffffffea75: push rbx
0x7fffffffea76: mov rcx,rsp
0x7fffffffea79: mov al,0xdd
0x7fffffffea7b: int 0x80
0x7fffffffea7d: (bad)
0x7fffffffea7e: (bad)
0x7fffffffea7f: inc DWORD PTR [rax]
0x7fffffffea81: add BYTE PTR [rax],al
-----------------------------------------------------------------------------------------------------------------------------
0x00007fffffffea75 in ?? ()
gdb$ n
Program received signal SIGSEGV, Segmentation fault.
-----------------------------------------------------------------------------------------------------------------------[regs]
RAX: 0x0000000000000000 RBX: 0x00007FFFFFFFEA88 RBP: 0xFFFFFFFFFFFFFFFF RSP: 0x00007FFFFFFFEA78 o d I t s Z a P c
RDI: 0x00007FFFFFFFEA60 RSI: 0x0000555555556021 RDX: 0x00007FFFFFFFEA80 RCX: 0x60FFFFFFFFFFFFFF RIP: 0x00007FFFFFFFEA76
R8 : 0x0000000000000000 R9 : 0x00007FFFF7FE14C0 R10: 0xFFFFFFFFFFFFF8F5 R11: 0x00007FFFF7E54B60 R12: 0x0000555555555060
R13: 0x0000000000000000 R14: 0x0000000000000000 R15: 0x0000000000000000
CS: 0033 DS: 0000 ES: 0000 FS: 0000 GS: 0000 SS: 002B
信息处理映射:
gdb$ info proc mappings
process 3025
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x555555554000 0x555555555000 0x1000 0x0 /home/yagur/Hacking.exploits.study/exploits/buffer_overflow.bin
0x555555555000 0x555555556000 0x1000 0x1000 /home/yagur/Hacking.exploits.study/exploits/buffer_overflow.bin
0x555555556000 0x555555557000 0x1000 0x2000 /home/yagur/Hacking.exploits.study/exploits/buffer_overflow.bin
0x555555557000 0x555555558000 0x1000 0x2000 /home/yagur/Hacking.exploits.study/exploits/buffer_overflow.bin
0x555555558000 0x555555559000 0x1000 0x3000 /home/yagur/Hacking.exploits.study/exploits/buffer_overflow.bin
0x7ffff7dbb000 0x7ffff7dbd000 0x2000 0x0
0x7ffff7dbd000 0x7ffff7de3000 0x26000 0x0 /usr/lib/libc-2.32.so
0x7ffff7de3000 0x7ffff7f30000 0x14d000 0x26000 /usr/lib/libc-2.32.so
0x7ffff7f30000 0x7ffff7f7c000 0x4c000 0x173000 /usr/lib/libc-2.32.so
0x7ffff7f7c000 0x7ffff7f7f000 0x3000 0x1be000 /usr/lib/libc-2.32.so
0x7ffff7f7f000 0x7ffff7f82000 0x3000 0x1c1000 /usr/lib/libc-2.32.so
0x7ffff7f82000 0x7ffff7f88000 0x6000 0x0
0x7ffff7fca000 0x7ffff7fce000 0x4000 0x0 [vvar]
0x7ffff7fce000 0x7ffff7fd0000 0x2000 0x0 [vdso]
0x7ffff7fd0000 0x7ffff7fd2000 0x2000 0x0 /usr/lib/ld-2.32.so
0x7ffff7fd2000 0x7ffff7ff3000 0x21000 0x2000 /usr/lib/ld-2.32.so
0x7ffff7ff3000 0x7ffff7ffc000 0x9000 0x23000 /usr/lib/ld-2.32.so
0x7ffff7ffc000 0x7ffff7ffd000 0x1000 0x2b000 /usr/lib/ld-2.32.so
0x7ffff7ffd000 0x7ffff7fff000 0x2000 0x2c000 /usr/lib/ld-2.32.so
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall]
gdb$
New question: Changed the shellcode to the following:
BITS 64
pop rax
pop rax
pop rax
pop rax
xor rax, rax
push rax
push 0x68732f6e
push 0x69622f2f
mov rbx, rsp
push rax
mov rdx, rsp
push rbx
mov rcx, rsp
mov al, 221
int 0x80
这样,可以防止我的shellcode被覆盖。因此:
gdb$ ni
--------------------------------------------------------------------------
---------------------------------------------[regs]
RAX: 0x0000000000000000 RBX: 0x00007FFFFFFFEAA8 RBP: 0xFFFFFFFFFFFFFFFF RSP:
0x00007FFFFFFFEAA0 o d I t s Z a P c
RDI: 0x00007FFFFFFFEA60 RSI: 0x0000555555556021 RDX: 0x00007FFFFFFFEAA0 RCX:
0x60FFFFFFFFFFFFFF RIP: 0x00007FFFFFFFEA79
R8 : 0x0000000000000000 R9 : 0x00007FFFF7FE14C0 R10: 0xFFFFFFFFFFFFF8F5 R11:
0x00007FFFF7E54B60 R12: 0x0000555555555060
R13: 0x0000000000000000 R14: 0x0000000000000000 R15: 0x0000000000000000
CS: 0033 DS: 0000 ES: 0000 FS: 0000 GS: 0000 SS: 002B
--------------------------------------------------------------------------
---------------------------------------------[code]
=> 0x7fffffffea79: push rbx
0x7fffffffea7a: mov rcx,rsp
0x7fffffffea7d: mov al,0xdd
0x7fffffffea7f: int 0x80
0x7fffffffea81: (bad)
0x7fffffffea82: (bad)
0x7fffffffea83: (bad)
0x7fffffffea84: (bad)
--------------------------------------------------------------------------------
---------------------------------------------
0x00007fffffffea79 in ?? ()
gdb$ ni
Program received signal SIGILL, Illegal instruction.
--------------------------------------------------------------------------
---------------------------------------------[regs]
RAX: 0xFFFFFFFFFFFFFFF7 RBX: 0x00007FFFFFFFEAA8 RBP: 0xFFFFFFFFFFFFFFFF RSP:
0x00007FFFFFFFEA98 o d I t s Z a P c
RDI: 0x00007FFFFFFFEA60 RSI: 0x0000555555556021 RDX: 0x00007FFFFFFFEAA0 RCX:
0x00007FFFFFFFEA98 RIP: 0x00007FFFFFFFEA81
R8 : 0x0000000000000000 R9 : 0x00007FFFF7FE14C0 R10: 0xFFFFFFFFFFFFF8F5 R11:
0x00007FFFF7E54B60 R12: 0x0000555555555060
R13: 0x0000000000000000 R14: 0x0000000000000000 R15: 0x0000000000000000
CS: 0033 DS: 0000 ES: 0000 FS: 0000 GS: 0000 SS: 002B
--------------------------------------------------------------------------
---------------------------------------------[code]
=> 0x7fffffffea81: (bad)
0x7fffffffea82: (bad)
0x7fffffffea83: (bad)
0x7fffffffea84: (bad)
0x7fffffffea85: (bad)
0x7fffffffea86: (bad)
0x7fffffffea87: (bad)
0x7fffffffea88: (bad)
--------------------------------------------------------------------------------
---------------------------------------------
0x00007fffffffea81 in ?? ()
gdb$
两个问题。
首先,你使用的是n
GDB命令,该命令应该转到下一个源代码行,可能有很多说明。(而且,当你执行的代码不是二进制文件的一部分时,行号无论如何都没有意义,并且n
无法可靠地工作。)你想使用它ni
,或者更好的做法是si
始终执行一条指令而无需尝试执行跳过子例程调用等。
确实,请注意段错误RIP
后寄存器转储中的值。这不是你的地址push rbx
,所以这不是错误的指令。相反,这是你原本打算成为的以下说明mov rcx, rsp
。
简单的寄存器移动如何引起段错误?因为它不再是寄存器移动-你只是重写了它。比较RSP和RIP的值。你正在从堆栈中执行代码,并将你的代码push rbx
存储到address 0x00007FFFFFFFEA78
,而则mov rcx, rsp
是从开始的三字节指令0x7fffffffea76
。因此,你只是改写了它的第三个字节。如果你再次执行此操作,disassemble
或x/i $rip
此时,你将看到最终执行的指令-我敢打赌它会访问内存。
实际上,mov rcx, rsp
被编码为48 89 e1
。rbx
is的低字节0x88
,并用88
产生的48 89 88 xx xx xx xx
is覆盖第三个字节mov [rax+disp], rcx
。
非常感谢您的回答!
谢谢你。我有一个新问题。我已经更改了shellcode,并且收到了SIGILL信号。我的问题中的新信息。
@СтаниславТимошко:可能仍然来自覆盖堆栈上的代码。
add rsp, -128
或者如果您的漏洞利用使RSP的代码在进入时低于RSP值,则可以将RSP移到新的空间。另请注意,如果以64位代码使用32位int 0x80 Linux ABI,会发生什么情况?-您不能int 0x80
与64位指针一起使用,并且堆栈指针始终在低32位之外。