ryy*_*yst 18 c buffer-overflow
我试图在Mac OS X 10.6 64位上使用C编写一个简单的缓冲区溢出.这是概念:
void function() {
char buffer[64];
buffer[offset] += 7; // i'm not sure how large offset needs to be, or if
// 7 is correct.
}
int main() {
int x = 0;
function();
x += 1;
printf("%d\n", x); // the idea is to modify the return address so that
// the x += 1 expression is not executed and 0 gets
// printed
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是main的汇编程序转储的一部分:
...
0x0000000100000ebe <main+30>: callq 0x100000e30 <function>
0x0000000100000ec3 <main+35>: movl $0x1,-0x8(%rbp)
0x0000000100000eca <main+42>: mov -0x8(%rbp),%esi
0x0000000100000ecd <main+45>: xor %al,%al
0x0000000100000ecf <main+47>: lea 0x56(%rip),%rdi # 0x100000f2c
0x0000000100000ed6 <main+54>: callq 0x100000ef4 <dyld_stub_printf>
...
Run Code Online (Sandbox Code Playgroud)
我想跳过movl指令,这意味着我需要将返回地址增加42 - 35 = 7(正确吗?).现在我需要知道返回地址的存储位置,以便我可以计算出正确的偏移量.
我已经尝试手动搜索正确的值,但是1被打印或者我得到abort trap- 是否有某种缓冲区溢出保护正在进行?
在我的机器上使用88的偏移量.我用Nemo的方法找出了返回地址.
Ben*_*son 12
这个32位示例说明了如何解决这个问题,请参阅下面的64位:
#include <stdio.h>
void function() {
char buffer[64];
char *p;
asm("lea 4(%%ebp),%0" : "=r" (p)); // loads address of return address
printf("%d\n", p - buffer); // computes offset
buffer[p - buffer] += 9; // 9 from disassembling main
}
int main() {
volatile int x = 7;
function();
x++;
printf("x = %d\n", x); // prints 7, not 8
}
Run Code Online (Sandbox Code Playgroud)
在我的系统上,偏移量是76.这是缓冲区的64个字节(记住,堆栈增长,因此缓冲区的起点远离返回地址)加上其他任何碎屑.
显然,如果你正在攻击现有的程序,你不能指望它为你计算答案,但我认为这说明了原理.
(另外,我们很幸运,+9没有执行到另一个字节.否则单字节增量不会设置返回地址我们的预期.如果你不满意返回地址,这个例子可能会中断main)
我以某种方式忽略了原始问题的64位. x86-64的等价物是8(%rbp)因为指针长度为8个字节.在这种情况下,我的测试构建恰好产生104的偏移量.在上面的代码中,8(%%rbp)使用double 替换输出程序集中的%%单个%.这在ABI文档中有所描述.搜索8(%rbp).
评论中的投诉与其他任意数字4(%ebp)一样神奇76.事实上,寄存器%ebp(也称为"帧指针")的含义及其与堆栈上返回地址位置的关系是标准化的.我快速用Google搜索的一个例子就在这里.该文使用术语"基指针".如果您想在其他体系结构上利用缓冲区溢出,则需要对该CPU的调用约定进行类似的详细了解.
| 归档时间: |
|
| 查看次数: |
9697 次 |
| 最近记录: |