前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >简单缓冲区溢出原理

简单缓冲区溢出原理

作者头像
Elapse
发布于 2020-08-17 03:42:48
发布于 2020-08-17 03:42:48
91500
代码可运行
举报
文章被收录于专栏:E条咸鱼E条咸鱼
运行总次数:0
代码可运行

本篇原创作者:Rj45

背景

什么是缓冲区溢出?这里我借某台栈溢出靶机里面的第一道题目来解释缓冲区溢出的原理。

可以看到靶机里面有两份权限不同的文件,而我目前拿到的shell是 level0

审计levelOne.c

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
    uid_t uid = geteuid();
    setresuid(uid, uid, uid);
    long key = 0x12345678;
    char buf[32];
    strcpy(buf, argv[1]);
    printf("Buf is: %s\n", buf);
    printf("Key is: 0x%08x\n", key);
    if(key == 0x42424242) {
        execve("/bin/sh", 0, 0);
    }
    else {
        printf("%s\n", "Sorry try again...");
    }
    return 0;
}

1、审计:可以看到,程序一开始声明并初始化了key=0x12345678, 并声明了32字节的buf, 然后通过strcpy函数将第一个参数拷贝到buf中, 接着判断key是否为0x42424242,如是则获得shell。(levelOne的权限为level1) key已经初始化为0x12345678,如何才能将其修改为0x42424242?

2、溢出:如何将key修改为0x42424242?--通过缓冲区溢出覆盖key值为0x42424242。什么是缓冲区溢出?在样例程序中声明了一段32字节的buf,此为缓冲区, 当通过strcpy函数将输入的函数第一个参数拷贝到缓冲区的时候,由于strcpy函数为危险函数,其不会对操作对象进行任何检查,故在输入数据不超过32个字节时不会发生任何情况, 但当输入的数据超过32个字节的时候,就会发生溢出,也即所谓的缓冲区溢出。

3、覆盖:根据前面我们学习到的内容,一个程序在载入内存后,其栈区会存在函数的各种变量、参数、栈针、返回地址等,并且各种数据是相邻分布的。这就意味着,一个存在缓冲区溢出的程序,在精准控制溢出范围的情况下,可以精准覆盖内存栈区中某些特殊位置的数据。这就为利用构造了条件,也即在本样例程序中的覆盖key值为0x42424242。

4、危险函数:显而易见,在缓冲区溢出的过程中,最关键的就是strcpy函数。那么还有哪些类似strcpy的危险函数呢?

可以看到这些危险函数集中为IO函数。

反汇编levelOne

1、命令

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
objdump -d levelOne -M intel

2、反汇编 下面为样例程序的反汇编情况:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
000011e9 <main>:
    11e9:    8d 4c 24 04             lea    ecx,[esp+0x4]
    11ed:    83 e4 f0                and    esp,0xfffffff0
    11f0:    ff 71 fc                push   DWORD PTR [ecx-0x4]
    11f3:    55                      push   ebp
    11f4:    89 e5                   mov    ebp,esp
    11f6:    56                      push   esi
    11f7:    53                      push   ebx
    11f8:    51                      push   ecx
    11f9:    83 ec 3c                sub    esp,0x3c
    11fc:    e8 ef fe ff ff          call   10f0 <__x86.get_pc_thunk.bx>
    1201:    81 c3 ff 2d 00 00       add    ebx,0x2dff
    1207:    89 ce                   mov    esi,ecx
    1209:    e8 42 fe ff ff          call   1050 <geteuid@plt>
    120e:    89 45 e4                mov    DWORD PTR [ebp-0x1c],eax
    1211:    83 ec 04                sub    esp,0x4
    1214:    ff 75 e4                push   DWORD PTR [ebp-0x1c]
    1217:    ff 75 e4                push   DWORD PTR [ebp-0x1c]
    121a:    ff 75 e4                push   DWORD PTR [ebp-0x1c]
    121d:    e8 0e fe ff ff          call   1030 <setresuid@plt>
    1222:    83 c4 10                add    esp,0x10     //调整栈帧
    1225:    c7 45 e0 78 56 34 12    mov    DWORD PTR [ebp-0x20],0x12345678  //声明并初始化了一个变量,地址为ebp-0x20,数据为0x12345678
    122c:    8b 46 04                mov    eax,DWORD PTR [esi+0x4]
    122f:    83 c0 04                add    eax,0x4
    1232:    8b 00                   mov    eax,DWORD PTR [eax]
    1234:    83 ec 08                sub    esp,0x8
    1237:    50                      push   eax
    1238:    8d 45 c0                lea    eax,[ebp-0x40]
    123b:    50                      push   eax
    123c:    e8 1f fe ff ff          call   1060 <strcpy@plt>        //将输入点数据拷贝到ebp-0x40
    1241:    83 c4 10                add    esp,0x10             //调整栈帧
    1244:    83 ec 08                sub    esp,0x8
    1247:    8d 45 c0                lea    eax,[ebp-0x40]
    124a:    50                      push   eax
    124b:    8d 83 08 e0 ff ff       lea    eax,[ebx-0x1ff8]
    1251:    50                      push   eax
    1252:    e8 e9 fd ff ff          call   1040 <printf@plt>
    1257:    83 c4 10                add    esp,0x10
    125a:    83 ec 08                sub    esp,0x8
    125d:    ff 75 e0                push   DWORD PTR [ebp-0x20]
    1260:    8d 83 14 e0 ff ff       lea    eax,[ebx-0x1fec]
    1266:    50                      push   eax
    1267:    e8 d4 fd ff ff          call   1040 <printf@plt>
    126c:    83 c4 10                add    esp,0x10
    126f:    81 7d e0 42 42 42 42    cmp    DWORD PTR [ebp-0x20],0x42424242      //判断ebp-0x20处的变量是否为0x42424242
    1276:    75 18                   jne    1290 <main+0xa7>     //如果相同则跳转到后门函数
    1278:    83 ec 04                sub    esp,0x4
    127b:    6a 00                   push   0x0
    127d:    6a 00                   push   0x0
    127f:    8d 83 24 e0 ff ff       lea    eax,[ebx-0x1fdc]         //将’/bin/sh’压入栈中,作为函数参数
    1285:    50                      push   eax              //将0压入栈中作为函数参数
    1286:    e8 05 fe ff ff          call   1090 <execve@plt>        //后门
    128b:    83 c4 10                add    esp,0x10
    128e:    eb 12                   jmp    12a2 <main+0xb9>
    1290:    83 ec 0c                sub    esp,0xc
    1293:    8d 83 2c e0 ff ff       lea    eax,[ebx-0x1fd4]
    1299:    50                      push   eax
    129a:    e8 d1 fd ff ff          call   1070 <puts@plt>
    129f:    83 c4 10                add    esp,0x10
    12a2:    b8 00 00 00 00          mov    eax,0x0
    12a7:    8d 65 f4                lea    esp,[ebp-0xc]
    12aa:    59                      pop    ecx
    12ab:    5b                      pop    ebx
    12ac:    5e                      pop    esi
    12ad:    5d                      pop    ebp
    12ae:    8d 61 fc                lea    esp,[ecx-0x4]
    12b1:    c3                      ret
    12b2:    66 90                   xchg   ax,ax
    12b4:    66 90                   xchg   ax,ax
    12b6:    66 90                   xchg   ax,ax
    12b8:    66 90                   xchg   ax,ax
    12ba:    66 90                   xchg   ax,ax
    12bc:    66 90                   xchg   ax,ax
    12be:    66 90                   xchg   ax,ax

栈中的情况如下图:

pwn

如此当填充满32个字节的数据后,在填充4个B,即达成利用条件,进入后门函数。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 E条咸鱼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 审计levelOne.c
  • 反汇编levelOne
  • pwn
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档