linux怎汇编leave,Linux (x86) Exploit 开发系列教程之三(Off-By-One 漏洞 (基于栈))

(1)原理:

将源字符串复制到目标缓冲区可能会导致off by one。当源字符串长度等于目标缓冲区长度时,单个NULL字节将被复制到目标缓冲区上方。这里由于目标缓冲区位于堆栈中,所以单个NULL字节可以覆盖存储在堆栈中的调用者的EBP的最低有效位(LSB),这可能导致任意的代码执行。

(2)漏洞代码

#include

#include

void foo(char* arg);

void bar(char* arg);

void foo(char* arg) {

bar(arg); /* [1] */

}

void bar(char* arg) {

char buf[256];

strcpy(buf, arg); /* [2] */

}

int main(int argc, char *argv[]) {

if(strlen(argv[1])>256) { /* [3] */

printf("Attempted Buffer Overflow\n");

fflush(stdout);

return -1;

}

foo(argv[1]); /* [4] */

return 0;

}

编译文件

f61eb3cd28a19c0571de7e6b07b620d5.png

(2)漏洞代码的第[2]行是可能发生off by one溢出的地方。目标缓冲区长度为256,因此长度为256字节的源字符串可能导致任意代码执行。如果调用者的EBP位于目标缓冲区之上,则在strcpy之后,单个NULL字节将覆盖调用者EBP的LSB。反汇编漏洞代码并绘制它的堆栈布局

gdb-peda$ disassemble main

Dump of assembler code for function main:

0x08048497 :push ebp

0x08048498 :mov ebp,esp

0x0804849a :push edi

0x0804849b :sub esp,0x8

0x0804849e :mov eax,DWORD PTR [ebp+0xc]

0x080484a1 :add eax,0x4

0x080484a4 :mov eax,DWORD PTR [eax]

0x080484a6 :mov DWORD PTR [ebp-0x8],0xffffffff

0x080484ad :mov edx,eax

0x080484af :mov eax,0x0

0x080484b4 :mov ecx,DWORD PTR [ebp-0x8]

0x080484b7 :mov edi,edx

0x080484b9 :repnz scas al,BYTE PTR es:[edi]

0x080484bb :mov eax,ecx

0x080484bd :not eax

0x080484bf :sub eax,0x1

0x080484c2 :cmp eax,0x100

0x080484c7 :jbe 0x80484e9

0x080484c9 :mov DWORD PTR [esp],0x80485e0

0x080484d0 :call 0x8048380

0x080484d5 :mov eax,ds:0x804a020

0x080484da :mov DWORD PTR [esp],eax

0x080484dd :call 0x8048360

0x080484e2 :mov eax,0xffffffff

0x080484e7 :jmp 0x80484fe

0x080484e9 :mov eax,DWORD PTR [ebp+0xc]

0x080484ec :add eax,0x4

0x080484ef :mov eax,DWORD PTR [eax]

0x080484f1 :mov DWORD PTR [esp],eax

0x080484f4 :call 0x8048464

0x080484f9 :mov eax,0x0

0x080484fe :add esp,0x8

0x08048501 :pop edi

0x08048502 :pop ebp

0x08048503 :ret

End of assembler dump.

gdb-peda$ disassemble foo

Dump of assembler code for function foo:

0x08048464 :    push   ebp

0x08048465 :    mov    ebp,esp

0x08048467 :    sub    esp,0x4

0x0804846a :    mov    eax,DWORD PTR [ebp+0x8]

0x0804846d :    mov    DWORD PTR [esp],eax

0x08048470 :    call   0x8048477

0x08048475 :    leave

0x08048476 :    ret

End of assembler dump.

gdb-peda$ disassemble bar

Dump of assembler code for function bar:

0x08048477 :    push   ebp

0x08048478 :    mov    ebp,esp

0x0804847a :    sub    esp,0x108

0x08048480 :    mov    eax,DWORD PTR [ebp+0x8]

0x08048483 :    mov    DWORD PTR [esp+0x4],eax

0x08048487 :    lea    eax,[ebp-0x100]

0x0804848d :    mov    DWORD PTR [esp],eax

0x08048490 :    call   0x8048370

0x08048495 :    leave

0x08048496 :    ret

End of assembler dump.

a20ad0e82cb97125131e80e82a559f6f.png

(3)256字节的用户输入,用空字节可以覆盖foo的EBP的LSB。所以当foo的存储在目标缓冲区“buf”之上的EBP被一个NULL字节所覆盖时,ebp从0xbffff2d8变为0xbffff200。从堆栈布局我们可以看到堆栈位置0xbffff200是目标缓冲区“buf”的一部分,由于用户输入被复制到该目标缓冲区,攻击者可以控制这个堆栈位置(0xbffff200),因此他控制指令指针(eip )使用他可以实现任意代码执行。

测试:可覆盖返回地址。

097e70304b02f45108209b8958d2f676.png

(4)尝试找出ret_addr的值。

将断点下在Breakpoint 2, 0x08048495 in bar ()处。运行查看内存情况

49007af212d13d612e8da9ee2e50ac96.png

2d1b1feb0d4a90db298bc47ffa4a9cda.png

可以看到EBP 的值从0xbffff158被覆盖成0xbffff100。EIP指向的是0xbffff104地址。EIP所指地址与buf之间需要填充172个A。

cbd12ad39f4b0326fe600e0ef453d734.png

尝试找出ret_addr的地址。

2bd32025d946c2a74998ca2a19003604.png

aa7ec0c0ddc935f9a50116001b0c88d0.png

(5)攻击代码

064b7a1331a88595ec9404044a6c70b3.png

不知道为何,尝试运行攻击代码失败了。但是直接在调试界面输入,可以获得普通用户的shell权限。

cccc22e85c60de9a7da524bb1017b707.png

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值