翼度科技»论坛 云主机 LINUX 查看内容

记一次有趣的 buffer overflow detected 问题分析

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
PS:要转载请注明出处,本人版权所有。

PS: 这个只是基于《我自己》的理解,

如果和你的原则及想法相冲突,请谅解,勿喷。

环境说明

  无
前言

  在我开发的一个实验和学习库中,在很久以前全面启用了编译器的sanitize功能。
  这次报错的程序,是我这个库中某个模块的单元测试模块。但是前面说的都不是重点。诡异的是本次出现的单元测试模块是很久未动的一个模块,而且在本地的单元测试过程中,是能够运行通过的,但是在github的ci上面出问题了。
  首先,报这个错误的原因肯定是我们的程序有问题,但是以前结合调试模式+sanitize功能基本能够把问题排除了,结合了github的ci出现问题,初步判断是由于GCC版本升级后,对于栈溢出的检查更加准确了。
  此外由于此报错是存在在一个release版本的模块,因此我们不能够采取通用的通过代码行来定位问题的方法。
问题初步定位

  首先gdb 初步分析定位,定位到如下地址:
  1. #4  0x00007ffff6a4db81 in __GI___fortify_fail (msg=msg@entry=0x7ffff6acf7e6 "buffer overflow detected") at fortify_fail.c:44
  2. #5  0x00007ffff6a4b870 in __GI___chk_fail () at chk_fail.c:28
  3. #6  0x00007ffff79c06fc in ?? () from ../lib/libylib.so.0
复制代码
从这里可以知道,我们在执行0x00007ffff79c06fc前面的一个指令的时候出现了"buffer overflow detected"。然后我们通过layout asm查看汇编指令,找到前面一行指令如下:
  1. 0x7ffff79c06f2:        b9 00 10 00 00               mov    $0x1000,%ecx
  2. 0x7ffff79c06f7:        e8 44 1e fe ff               callq  58540 <__memset_chk@plt>
  3. 0x7ffff79c06fc:        4c 89 e2                     mov    %r12,%rdx
复制代码
  其实到了这里,我们可以根据一些手段,可以查到是memset导致了我们的原因,如果要是可以进行源码调试的话,我们甚至马上就能够定位是哪一行导致的。
  但是今天这里提供一种方法,可以复杂定位(兼容一个库里面多个memset调用,兼容release版本调试等等)我们出错这行汇编在我们源码中的大概位置。




问题初步定位

  首先,我们查看一下当前我们这个so文件在内存中的映射位置:
  1.           Start Addr           End Addr       Size     Offset objfile
  2.       0x7ffff794a000     0x7ffff7bc2000   0x278000        0x0 /xxx/libylib.so.0.1.0
  3.       0x7ffff7bc2000     0x7ffff7dc2000   0x200000   0x278000 /xxx/libylib.so.0.1.0
  4.       0x7ffff7dc2000     0x7ffff7dcc000     0xa000   0x278000 /xxx/libylib.so.0.1.0
  5.       0x7ffff7dcc000     0x7ffff7dd1000     0x5000   0x282000 /xxx/libylib.so.0.1.0
复制代码
  首先我们可以分析出0x7ffff79c06f7是存在在内存映射0x7ffff794a000~0x7ffff7bc2000区段中的。此外,我们还知道了一个重要的消息是,当前我们关注的0x7ffff79c06f7在so中的偏移地址是0x7ffff79c06f7-0x7ffff794a000=0x766F7。
  这个时候,我们可以通过objdump -d对libylib.so.0.1.0进行反编译分析。注意,这里要往我们关注的0x766F7偏移前面去寻找,而且还要反复去寻找,直到找到类似函数的边界(这里我建议新手直接上ida,快速解决问题),一般来说就是找函数帧,如果对这个不熟悉,建议使用ida等工具进行分析,可能更加方便。
  1. libylib.so.0.1.0:     file format elf64-x86-64
  2. Disassembly of section .text:
  3. 00000000000764d0 <_ZNSt6vectorIhSaIhEE17_M_default_appendEm@@Base+0x2b0>:
  4.    764d0:        fe                           (bad)  
  5.    764d1:        fd                           std   
  6.    764d2:        ff 90 66 90 66 2e            callq  *0x2e669066(%rax)
  7.    764d8:        0f 1f 84 00 00 00 00         nopl   0x0(%rax,%rax,1)
  8.    764df:        00
  9. 00000000000764e0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base>:
  10.    764e0:        48 8b 05 81 b4 40 00         mov    0x40b481(%rip),%rax        # 481968 <_ZN4yLib6yShell10class_infoE@@Base-0x5058>
  11.    764e7:        c3                           retq   
  12.    764e8:        0f 1f 84 00 00 00 00         nopl   0x0(%rax,%rax,1)
  13.    764ef:        00
  14.    //注意这里开始
  15.    764f0:        41 57                        push   %r15
  16.    764f2:        41 56                        push   %r14
  17.    764f4:        49 89 fe                     mov    %rdi,%r14
  18.    764f7:        41 55                        push   %r13
  19.    764f9:        41 54                        push   %r12
  20.    764fb:        55                           push   %rbp
  21.    764fc:        48 89 d5                     mov    %rdx,%rbp
  22.    764ff:        53                           push   %rbx
  23.    76500:        48 81 ec a8 00 00 00         sub    $0xa8,%rsp
  24.    76507:        48 8b 56 08                  mov    0x8(%rsi),%rdx
  25.    7650b:        48 2b 16                     sub    (%rsi),%rdx
  26.    7650e:        64 48 8b 04 25 28 00         mov    %fs:0x28,%rax
  27.    76515:        00 00
  28.    76517:        48 89 84 24 98 00 00         mov    %rax,0x98(%rsp)
  29.    7651e:        00
  30.    7651f:        31 c0                        xor    %eax,%eax
  31.    76521:        48 8b 47 08                  mov    0x8(%rdi),%rax
  32.    76525:        48 2b 07                     sub    (%rdi),%rax
  33.    76528:        48 c1 fa 05                  sar    $0x5,%rdx
  34.    7652c:        48 c1 f8 05                  sar    $0x5,%rax
  35.    76530:        48 8d 7c 02 01               lea    0x1(%rdx,%rax,1),%rdi
  36.    76535:        48 89 f8                     mov    %rdi,%rax
  37.    76538:        48 c1 e8 3c                  shr    $0x3c,%rax
  38.    7653c:        0f 85 67 54 fe ff            jne    5b9a9 <fwrite@plt+0x1221>
  39.    76542:        48 c1 e7 03                  shl    $0x3,%rdi
  40.    76546:        49 89 f4                     mov    %rsi,%r12
  41.    76549:        48 89 cb                     mov    %rcx,%rbx
  42.    7654c:        e8 2f dc fd ff               callq  54180 <_Znam@plt>
  43.    76551:        49 8b 7e 08                  mov    0x8(%r14),%rdi
  44.    76555:        49 8b 14 24                  mov    (%r12),%rdx
  45.    76559:        49 89 c5                     mov    %rax,%r13
  46.    7655c:        49 8b 74 24 08               mov    0x8(%r12),%rsi
  47.    76561:        49 8b 06                     mov    (%r14),%rax
  48.    76564:        48 29 d6                     sub    %rdx,%rsi
  49.    76567:        48 29 c7                     sub    %rax,%rdi
  50.    7656a:        49 89 f9                     mov    %rdi,%r9
  51.    7656d:        49 89 f2                     mov    %rsi,%r10
  52.    76570:        49 89 f0                     mov    %rsi,%r8
  53.    76573:        48 01 c7                     add    %rax,%rdi
  54.    76576:        49 c1 f9 05                  sar    $0x5,%r9
  55.    7657a:        49 c1 fa 05                  sar    $0x5,%r10
  56.    7657e:        4b 8d 0c 11                  lea    (%r9,%r10,1),%rcx
  57.    76582:        49 c7 44 cd 00 00 00         movq   $0x0,0x0(%r13,%rcx,8)
  58.    76589:        00 00
  59.    7658b:        4c 89 e9                     mov    %r13,%rcx
  60.    7658e:        4d 85 c9                     test   %r9,%r9
  61.    76591:        74 19                        je     765ac <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xcc>
  62.    76593:        0f 1f 44 00 00               nopl   0x0(%rax,%rax,1)
  63.    76598:        48 8b 30                     mov    (%rax),%rsi
  64.    7659b:        48 83 c0 20                  add    $0x20,%rax
  65.    7659f:        48 83 c1 08                  add    $0x8,%rcx
  66.    765a3:        48 89 71 f8                  mov    %rsi,-0x8(%rcx)
  67.    765a7:        48 39 c7                     cmp    %rax,%rdi
  68.    765aa:        75 ec                        jne    76598 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xb8>
  69.    765ac:        4d 85 d2                     test   %r10,%r10
  70.    765af:        74 23                        je     765d4 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xf4>
  71.    765b1:        48 89 d0                     mov    %rdx,%rax
  72.    765b4:        4b 8d 54 cd 00               lea    0x0(%r13,%r9,8),%rdx
  73.    765b9:        4a 8d 34 00                  lea    (%rax,%r8,1),%rsi
  74.    765bd:        0f 1f 00                     nopl   (%rax)
  75.    765c0:        48 8b 08                     mov    (%rax),%rcx
  76.    765c3:        48 83 c0 20                  add    $0x20,%rax
  77.    765c7:        48 83 c2 08                  add    $0x8,%rdx
  78.    765cb:        48 89 4a f8                  mov    %rcx,-0x8(%rdx)
  79.    765cf:        48 39 f0                     cmp    %rsi,%rax
  80.    765d2:        75 ec                        jne    765c0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xe0>
  81.    765d4:        48 8b 7d 08                  mov    0x8(%rbp),%rdi
  82.    765d8:        48 2b 7d 00                  sub    0x0(%rbp),%rdi
  83.    765dc:        48 c1 ff 05                  sar    $0x5,%rdi
  84.    765e0:        48 83 c7 01                  add    $0x1,%rdi
  85.    765e4:        48 89 f8                     mov    %rdi,%rax
  86.    765e7:        48 c1 e8 3c                  shr    $0x3c,%rax
  87.    765eb:        0f 85 93 0a 00 00            jne    77084 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xba4>
  88.    765f1:        48 c1 e7 03                  shl    $0x3,%rdi
  89.    765f5:        e8 86 db fd ff               callq  54180 <_Znam@plt>
  90.    765fa:        48 8b 75 08                  mov    0x8(%rbp),%rsi
  91.    765fe:        48 89 c2                     mov    %rax,%rdx
  92.    76601:        48 89 44 24 08               mov    %rax,0x8(%rsp)
  93.    76606:        48 8b 45 00                  mov    0x0(%rbp),%rax
  94.    7660a:        48 29 c6                     sub    %rax,%rsi
  95.    7660d:        48 89 f1                     mov    %rsi,%rcx
  96.    76610:        48 01 c6                     add    %rax,%rsi
  97.    76613:        48 c1 f9 05                  sar    $0x5,%rcx
  98.    76617:        48 8d 3c ca                  lea    (%rdx,%rcx,8),%rdi
  99.    7661b:        48 c7 07 00 00 00 00         movq   $0x0,(%rdi)
  100.    76622:        48 85 c9                     test   %rcx,%rcx
  101.    76625:        74 1d                        je     76644 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x164>
  102.    76627:        66 0f 1f 84 00 00 00         nopw   0x0(%rax,%rax,1)
  103.    7662e:        00 00
  104.    76630:        48 8b 08                     mov    (%rax),%rcx
  105.    76633:        48 83 c0 20                  add    $0x20,%rax
  106.    76637:        48 83 c2 08                  add    $0x8,%rdx
  107.    7663b:        48 89 4a f8                  mov    %rcx,-0x8(%rdx)
  108.    7663f:        48 39 c6                     cmp    %rax,%rsi
  109.    76642:        75 ec                        jne    76630 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x150>
  110.    76644:        48 c7 07 00 00 00 00         movq   $0x0,(%rdi)
  111.    7664b:        48 8b 35 06 b2 40 00         mov    0x40b206(%rip),%rsi        # 481858 <_ZSt7nothrow@GLIBCXX_3.4>
  112.    76652:        bf 00 10 00 00               mov    $0x1000,%edi
  113.    76657:        e8 b4 2d fe ff               callq  59410 <_ZnamRKSt9nothrow_t@plt>
  114.    7665c:        48 8d 7c 24 28               lea    0x28(%rsp),%rdi
  115.    76661:        48 89 c5                     mov    %rax,%rbp
  116.    76664:        48 8b 05 5d 1c 1a 00         mov    0x1a1c5d(%rip),%rax        # 2182c8 <_ZTSNSt6thread11_State_implINS_8_InvokerISt5tupleIJMN4yLib11yThreadPoolEFvvEPS4_EEEEEE@@Base+0x4e8>
  117.    7666b:        48 89 44 24 28               mov    %rax,0x28(%rsp)
  118.    76670:        e8 fb 1c fe ff               callq  58370 <pipe@plt>
  119.    76675:        85 c0                        test   %eax,%eax
  120.    76677:        0f 88 69 03 00 00            js     769e6 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x506>
  121.    7667d:        e8 4e e5 fd ff               callq  54bd0 <fork@plt>
  122.    76682:        41 89 c4                     mov    %eax,%r12d
  123.    76685:        85 c0                        test   %eax,%eax
  124.    76687:        0f 88 08 07 00 00            js     76d95 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x8b5>
  125.    7668d:        0f 84 1d 01 00 00            je     767b0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x2d0>
  126.    76693:        8b 7c 24 2c                  mov    0x2c(%rsp),%edi
  127.    76697:        e8 24 3e fe ff               callq  5a4c0 <close@plt>
  128.    7669c:        48 8d 74 24 1c               lea    0x1c(%rsp),%rsi
  129.    766a1:        31 d2                        xor    %edx,%edx
  130.    766a3:        44 89 e7                     mov    %r12d,%edi
  131.    766a6:        e8 55 00 fe ff               callq  56700 <waitpid@plt>
  132.    766ab:        8b 44 24 1c                  mov    0x1c(%rsp),%eax
  133.    766af:        a8 7f                        test   $0x7f,%al
  134.    766b1:        0f 85 8a 07 00 00            jne    76e41 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x961>
  135.    766b7:        0f b6 cc                     movzbl %ah,%ecx
  136.    766ba:        f6 c4 ff                     test   $0xff,%ah
  137.    766bd:        0f 85 cd 03 00 00            jne    76a90 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x5b0>
  138.    766c3:        8b 7c 24 28                  mov    0x28(%rsp),%edi
  139.    766c7:        48 8d 35 52 cb 1c 00         lea    0x1ccb52(%rip),%rsi        # 243220 <_ZTSN4Json12RuntimeErrorE@@Base+0x60>
  140.    766ce:        e8 cd 0d fe ff               callq  574a0 <fdopen@plt>
  141.    766d3:        49 89 c4                     mov    %rax,%r12
  142.    766d6:        48 85 ed                     test   %rbp,%rbp
  143.    766d9:        0f 84 f1 02 00 00            je     769d0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x4f0>
  144.    766df:        4c 8d 74 24 70               lea    0x70(%rsp),%r14
  145.    766e4:        0f 1f 40 00                  nopl   0x0(%rax)
  146.    766e8:        31 f6                        xor    %esi,%esi
  147.    766ea:        ba 01 10 00 00               mov    $0x1001,%edx
  148.    766ef:        48 89 ef                     mov    %rbp,%rdi
  149.    766f2:        b9 00 10 00 00               mov    $0x1000,%ecx
  150.    766f7:        e8 44 1e fe ff               callq  58540 <__memset_chk@plt>
  151.    766fc:        4c 89 e2                     mov    %r12,%rdx
复制代码
  我们往此偏移往上查找,找到了764f0偏移的特殊指令,这里一看就是一个函数的开始位置(这里为啥是函数开始,主要是操作备份rbp,申请栈,操作rsp等等)。
  这里其实又有两个选择,我们在分析函数头的过程中,其实已经找到了足够多的我们想要找的函数特征:例如这里调用了fork/pipe/fdopen等等,如果情况是这样的,那么其实我们可以综合分析,找到我们源码对应出错的位置了。
  那如果我们的函数平平无奇,没有什么明显特征怎么搞呢?还是只有利用我们的函数头来判断,到底是我们写的哪个函数出问题了。
  于是我们拿着764f0偏移,通过readelf -s来查找符号,发现不是任何一个我们已知的符号,这尼玛就坑了啊。到了这里,其实现在不好搞啊。我们用gdb record / ida / objdump + grep 来综合分析,发现了跳转到当前地址的一个地方。下面是用readelf+objdump+grep来得到的一段片段:
  1.    764f0:        41 57                        push   %r15
  2.    77090:        e9 5b f4 ff ff               jmpq   764f0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x10>
复制代码
  我们再次用objdump和readelf查找77090这个偏移,终于在符号表查到了我们关心的这个偏移,如下:
  1.    559: 0000000000077090     5 FUNC    GLOBAL DEFAULT   12 _ZN4yLib6yShell7ExecuteERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EESB_SB_RS9_
复制代码
  到此,通过复原cxx函数名字,我们就知道了我们在哪个函数里面崩溃的,而且是在这个函数的memset的地方导致溢出崩溃的。




后记

  此问题的分析加深了我们对计算机的理解,使用了较多的二进制分析工具。
  结合我以前的调试和反调试经验,新手我还是建议直接上刑具ida进行分析,这样更棒哦。
参考文献





                    打赏、订阅、收藏、丢香蕉、硬币,请关注公众号(攻城狮的搬砖之路)               
    PS: 请尊重原创,不喜勿喷。

PS: 要转载请注明出处,本人版权所有。

PS: 有问题请留言,看到后我会第一时间回复。


来源:https://www.cnblogs.com/Iflyinsky/p/17780890.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具