首页
社区
课程
招聘
[原创]Linux平台OffByOne(基于栈)漏洞
发表于: 2017-7-5 17:16 8743

[原创]Linux平台OffByOne(基于栈)漏洞

2017-7-5 17:16
8743

前一段时间在看雪上看到hackyzh翻译的《Linux (x86) Exploit 开发系列教程之三(Off-By-One 漏洞 (基于栈))》 文章,后面又查看了英文原文,https://sploitfun.wordpress.com/2015/06/07/off-by-one-vulnerability-stack-based-2/,发现原文作者的exp跑不通,并且部分地方讲解的不利于理解,所以按照自己的理解,重新整理了offbyone基于栈的漏洞,同时附上相关exp。

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

         漏洞演示环境:Ubuntu 12.04-32

漏洞代码:

#include <stdio.h>

#include <string.h>

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;

}

在编译时,先切换到root,关闭Linux的地址随机化(ASLR)特性,命令如下:

echo 0 > /proc/sys/kernel/randomize_va_space

(恢复)开启ASLR命令如下

echo 2 > /proc/sys/kernel/randomize_va_space

编译命令如下:

gcc -fno-stack-protector -z execstack -mpreferred-stack-boundary=2 -o vuln -g   offbyone.c

 编译命令的详细解释,放到了3.1章节中。

上述漏洞代码的第[2]行可能是发生off by one溢出的地方。目标缓冲区长度时256,因为长度为256字节的源字符串可能导致任意代码执行。

漏洞利用:

我们来看一下上述代码的堆栈布局,确定调用者的EBP是否位于目标缓冲区至上,也就是strcpy之后,单个NULL字节是否覆盖调用者的EBPLSB

Main函数

.text:08048497 ; int __cdecl main(int   argc, const char **argv, const char **envp)

.text:08048497                 public main

.text:08048497 main            proc near               ; DATA XREF: _start+17o

.text:08048497

.text:08048497 var_8           = dword ptr -8

.text:08048497 argc            = dword ptr  8

.text:08048497 argv            = dword ptr  0Ch

.text:08048497 envp            = dword ptr  10h

.text:08048497

.text:08048497                 push    ebp

.text:08048498                 mov     ebp, esp

.text:0804849A                 push    edi

.text:0804849B                 sub     esp, 8

.text:0804849E                 mov     eax, [ebp+argv]

.text:080484A1                 add     eax, 4

.text:080484A4                 mov       eax, [eax]

.text:080484A6                 mov     [ebp+var_8], 0FFFFFFFFh

.text:080484AD                 mov     edx, eax

.text:080484AF                 mov     eax, 0

.text:080484B4                 mov     ecx, [ebp+var_8]

.text:080484B7                 mov     edi, edx

.text:080484B9                 repne scasb

.text:080484BB                 mov     eax, ecx

.text:080484BD                 not     eax

.text:080484BF                 sub     eax, 1

.text:080484C2                 cmp     eax, 100h

.text:080484C7                 jbe     short loc_80484EA

.text:080484C9                 mov     eax, offset format ; "attepted   buffer overflow"

.text:080484CE                 mov     [esp], eax      ; format

.text:080484D1                 call    _printf

.text:080484D6                 mov     eax, ds:stdout@@GLIBC_2_0

.text:080484DB                 mov     [esp], eax      ; stream

.text:080484DE                 call    _fflush

.text:080484E3                 mov     eax, 0FFFFFFFFh

.text:080484E8                 jmp       short loc_80484FF

.text:080484EA ;   ---------------------------------------------------------------------------

.text:080484EA

.text:080484EA loc_80484EA:                            ; CODE XREF:   main+30j

.text:080484EA                 mov     eax, [ebp+argv]

.text:080484ED                 add     eax, 4

.text:080484F0                 mov     eax, [eax]

.text:080484F2                 mov     [esp], eax      ; src

.text:080484F5                 call    foo

.text:080484FA                 mov     eax, 0

.text:080484FF

.text:080484FF loc_80484FF:                            ; CODE XREF:   main+51j

.text:080484FF                 add     esp, 8

.text:08048502                 pop     edi

.text:08048503                 pop     ebp

.text:08048504                 retn

.text:08048504 main            endp

foo函数:

.text:08048464 ; int __cdecl foo(char   *src)

.text:08048464                 public foo

.text:08048464 foo             proc near               ; CODE XREF: main+5Ep

.text:08048464

.text:08048464 src             = dword ptr  8

.text:08048464

.text:08048464                 push    ebp


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
看看
2017-7-5 21:45
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
看看
2017-7-5 21:45
0
游客
登录 | 注册 方可回帖
返回
//