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

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

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

环境说明

  无

前言


  在我开发的一个实验和学习库中,在很久以前全面启用了编译器的sanitize功能。

  这次报错的程序,是我这个库中某个模块的单元测试模块。但是前面说的都不是重点。诡异的是本次出现的单元测试模块是很久未动的一个模块,而且在本地的单元测试过程中,是能够运行通过的,但是在github的ci上面出问题了。

  首先,报这个错误的原因肯定是我们的程序有问题,但是以前结合调试模式+sanitize功能基本能够把问题排除了,结合了github的ci出现问题,初步判断是由于GCC版本升级后,对于栈溢出的检查更加准确了。

  此外由于此报错是存在在一个release版本的模块,因此我们不能够采取通用的通过代码行来定位问题的方法。

问题初步定位


  首先gdb 初步分析定位,定位到如下地址:

#4  0x00007ffff6a4db81 in __GI___fortify_fail (msg=msg@entry=0x7ffff6acf7e6 "buffer overflow detected") at fortify_fail.c:44
#5 0x00007ffff6a4b870 in __GI___chk_fail () at chk_fail.c:28
#6 0x00007ffff79c06fc in ?? () from ../lib/libylib.so.0

从这里可以知道,我们在执行0x00007ffff79c06fc前面的一个指令的时候出现了"buffer overflow detected"。然后我们通过layout asm查看汇编指令,找到前面一行指令如下:

0x7ffff79c06f2:	b9 00 10 00 00       	mov    $0x1000,%ecx
0x7ffff79c06f7: e8 44 1e fe ff callq 58540 <__memset_chk@plt>
0x7ffff79c06fc: 4c 89 e2 mov %r12,%rdx

  其实到了这里,我们可以根据一些手段,可以查到是memset导致了我们的原因,如果要是可以进行源码调试的话,我们甚至马上就能够定位是哪一行导致的。

  但是今天这里提供一种方法,可以复杂定位(兼容一个库里面多个memset调用,兼容release版本调试等等)我们出错这行汇编在我们源码中的大概位置。

问题初步定位


  首先,我们查看一下当前我们这个so文件在内存中的映射位置:

          Start Addr           End Addr       Size     Offset objfile
0x7ffff794a000 0x7ffff7bc2000 0x278000 0x0 /xxx/libylib.so.0.1.0
0x7ffff7bc2000 0x7ffff7dc2000 0x200000 0x278000 /xxx/libylib.so.0.1.0
0x7ffff7dc2000 0x7ffff7dcc000 0xa000 0x278000 /xxx/libylib.so.0.1.0
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等工具进行分析,可能更加方便。

libylib.so.0.1.0:     file format elf64-x86-64

Disassembly of section .text:

00000000000764d0 <_ZNSt6vectorIhSaIhEE17_M_default_appendEm@@Base+0x2b0>:
764d0: fe (bad)
764d1: fd std
764d2: ff 90 66 90 66 2e callq *0x2e669066(%rax)
764d8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
764df: 00 00000000000764e0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base>:
764e0: 48 8b 05 81 b4 40 00 mov 0x40b481(%rip),%rax # 481968 <_ZN4yLib6yShell10class_infoE@@Base-0x5058>
764e7: c3 retq
764e8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
764ef: 00
//注意这里开始
764f0: 41 57 push %r15
764f2: 41 56 push %r14
764f4: 49 89 fe mov %rdi,%r14
764f7: 41 55 push %r13
764f9: 41 54 push %r12
764fb: 55 push %rbp
764fc: 48 89 d5 mov %rdx,%rbp
764ff: 53 push %rbx
76500: 48 81 ec a8 00 00 00 sub $0xa8,%rsp
76507: 48 8b 56 08 mov 0x8(%rsi),%rdx
7650b: 48 2b 16 sub (%rsi),%rdx
7650e: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
76515: 00 00
76517: 48 89 84 24 98 00 00 mov %rax,0x98(%rsp)
7651e: 00
7651f: 31 c0 xor %eax,%eax
76521: 48 8b 47 08 mov 0x8(%rdi),%rax
76525: 48 2b 07 sub (%rdi),%rax
76528: 48 c1 fa 05 sar $0x5,%rdx
7652c: 48 c1 f8 05 sar $0x5,%rax
76530: 48 8d 7c 02 01 lea 0x1(%rdx,%rax,1),%rdi
76535: 48 89 f8 mov %rdi,%rax
76538: 48 c1 e8 3c shr $0x3c,%rax
7653c: 0f 85 67 54 fe ff jne 5b9a9 <fwrite@plt+0x1221>
76542: 48 c1 e7 03 shl $0x3,%rdi
76546: 49 89 f4 mov %rsi,%r12
76549: 48 89 cb mov %rcx,%rbx
7654c: e8 2f dc fd ff callq 54180 <_Znam@plt>
76551: 49 8b 7e 08 mov 0x8(%r14),%rdi
76555: 49 8b 14 24 mov (%r12),%rdx
76559: 49 89 c5 mov %rax,%r13
7655c: 49 8b 74 24 08 mov 0x8(%r12),%rsi
76561: 49 8b 06 mov (%r14),%rax
76564: 48 29 d6 sub %rdx,%rsi
76567: 48 29 c7 sub %rax,%rdi
7656a: 49 89 f9 mov %rdi,%r9
7656d: 49 89 f2 mov %rsi,%r10
76570: 49 89 f0 mov %rsi,%r8
76573: 48 01 c7 add %rax,%rdi
76576: 49 c1 f9 05 sar $0x5,%r9
7657a: 49 c1 fa 05 sar $0x5,%r10
7657e: 4b 8d 0c 11 lea (%r9,%r10,1),%rcx
76582: 49 c7 44 cd 00 00 00 movq $0x0,0x0(%r13,%rcx,8)
76589: 00 00
7658b: 4c 89 e9 mov %r13,%rcx
7658e: 4d 85 c9 test %r9,%r9
76591: 74 19 je 765ac <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xcc>
76593: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
76598: 48 8b 30 mov (%rax),%rsi
7659b: 48 83 c0 20 add $0x20,%rax
7659f: 48 83 c1 08 add $0x8,%rcx
765a3: 48 89 71 f8 mov %rsi,-0x8(%rcx)
765a7: 48 39 c7 cmp %rax,%rdi
765aa: 75 ec jne 76598 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xb8>
765ac: 4d 85 d2 test %r10,%r10
765af: 74 23 je 765d4 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xf4>
765b1: 48 89 d0 mov %rdx,%rax
765b4: 4b 8d 54 cd 00 lea 0x0(%r13,%r9,8),%rdx
765b9: 4a 8d 34 00 lea (%rax,%r8,1),%rsi
765bd: 0f 1f 00 nopl (%rax)
765c0: 48 8b 08 mov (%rax),%rcx
765c3: 48 83 c0 20 add $0x20,%rax
765c7: 48 83 c2 08 add $0x8,%rdx
765cb: 48 89 4a f8 mov %rcx,-0x8(%rdx)
765cf: 48 39 f0 cmp %rsi,%rax
765d2: 75 ec jne 765c0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xe0>
765d4: 48 8b 7d 08 mov 0x8(%rbp),%rdi
765d8: 48 2b 7d 00 sub 0x0(%rbp),%rdi
765dc: 48 c1 ff 05 sar $0x5,%rdi
765e0: 48 83 c7 01 add $0x1,%rdi
765e4: 48 89 f8 mov %rdi,%rax
765e7: 48 c1 e8 3c shr $0x3c,%rax
765eb: 0f 85 93 0a 00 00 jne 77084 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0xba4>
765f1: 48 c1 e7 03 shl $0x3,%rdi
765f5: e8 86 db fd ff callq 54180 <_Znam@plt>
765fa: 48 8b 75 08 mov 0x8(%rbp),%rsi
765fe: 48 89 c2 mov %rax,%rdx
76601: 48 89 44 24 08 mov %rax,0x8(%rsp)
76606: 48 8b 45 00 mov 0x0(%rbp),%rax
7660a: 48 29 c6 sub %rax,%rsi
7660d: 48 89 f1 mov %rsi,%rcx
76610: 48 01 c6 add %rax,%rsi
76613: 48 c1 f9 05 sar $0x5,%rcx
76617: 48 8d 3c ca lea (%rdx,%rcx,8),%rdi
7661b: 48 c7 07 00 00 00 00 movq $0x0,(%rdi)
76622: 48 85 c9 test %rcx,%rcx
76625: 74 1d je 76644 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x164>
76627: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
7662e: 00 00
76630: 48 8b 08 mov (%rax),%rcx
76633: 48 83 c0 20 add $0x20,%rax
76637: 48 83 c2 08 add $0x8,%rdx
7663b: 48 89 4a f8 mov %rcx,-0x8(%rdx)
7663f: 48 39 c6 cmp %rax,%rsi
76642: 75 ec jne 76630 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x150>
76644: 48 c7 07 00 00 00 00 movq $0x0,(%rdi)
7664b: 48 8b 35 06 b2 40 00 mov 0x40b206(%rip),%rsi # 481858 <_ZSt7nothrow@GLIBCXX_3.4>
76652: bf 00 10 00 00 mov $0x1000,%edi
76657: e8 b4 2d fe ff callq 59410 <_ZnamRKSt9nothrow_t@plt>
7665c: 48 8d 7c 24 28 lea 0x28(%rsp),%rdi
76661: 48 89 c5 mov %rax,%rbp
76664: 48 8b 05 5d 1c 1a 00 mov 0x1a1c5d(%rip),%rax # 2182c8 <_ZTSNSt6thread11_State_implINS_8_InvokerISt5tupleIJMN4yLib11yThreadPoolEFvvEPS4_EEEEEE@@Base+0x4e8>
7666b: 48 89 44 24 28 mov %rax,0x28(%rsp)
76670: e8 fb 1c fe ff callq 58370 <pipe@plt>
76675: 85 c0 test %eax,%eax
76677: 0f 88 69 03 00 00 js 769e6 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x506>
7667d: e8 4e e5 fd ff callq 54bd0 <fork@plt>
76682: 41 89 c4 mov %eax,%r12d
76685: 85 c0 test %eax,%eax
76687: 0f 88 08 07 00 00 js 76d95 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x8b5>
7668d: 0f 84 1d 01 00 00 je 767b0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x2d0>
76693: 8b 7c 24 2c mov 0x2c(%rsp),%edi
76697: e8 24 3e fe ff callq 5a4c0 <close@plt>
7669c: 48 8d 74 24 1c lea 0x1c(%rsp),%rsi
766a1: 31 d2 xor %edx,%edx
766a3: 44 89 e7 mov %r12d,%edi
766a6: e8 55 00 fe ff callq 56700 <waitpid@plt>
766ab: 8b 44 24 1c mov 0x1c(%rsp),%eax
766af: a8 7f test $0x7f,%al
766b1: 0f 85 8a 07 00 00 jne 76e41 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x961>
766b7: 0f b6 cc movzbl %ah,%ecx
766ba: f6 c4 ff test $0xff,%ah
766bd: 0f 85 cd 03 00 00 jne 76a90 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x5b0>
766c3: 8b 7c 24 28 mov 0x28(%rsp),%edi
766c7: 48 8d 35 52 cb 1c 00 lea 0x1ccb52(%rip),%rsi # 243220 <_ZTSN4Json12RuntimeErrorE@@Base+0x60>
766ce: e8 cd 0d fe ff callq 574a0 <fdopen@plt>
766d3: 49 89 c4 mov %rax,%r12
766d6: 48 85 ed test %rbp,%rbp
766d9: 0f 84 f1 02 00 00 je 769d0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x4f0>
766df: 4c 8d 74 24 70 lea 0x70(%rsp),%r14
766e4: 0f 1f 40 00 nopl 0x0(%rax)
766e8: 31 f6 xor %esi,%esi
766ea: ba 01 10 00 00 mov $0x1001,%edx
766ef: 48 89 ef mov %rbp,%rdi
766f2: b9 00 10 00 00 mov $0x1000,%ecx
766f7: e8 44 1e fe ff callq 58540 <__memset_chk@plt>
766fc: 4c 89 e2 mov %r12,%rdx

  我们往此偏移往上查找,找到了764f0偏移的特殊指令,这里一看就是一个函数的开始位置(这里为啥是函数开始,主要是操作备份rbp,申请栈,操作rsp等等)。

  这里其实又有两个选择,我们在分析函数头的过程中,其实已经找到了足够多的我们想要找的函数特征:例如这里调用了fork/pipe/fdopen等等,如果情况是这样的,那么其实我们可以综合分析,找到我们源码对应出错的位置了。

  那如果我们的函数平平无奇,没有什么明显特征怎么搞呢?还是只有利用我们的函数头来判断,到底是我们写的哪个函数出问题了。

  于是我们拿着764f0偏移,通过readelf -s来查找符号,发现不是任何一个我们已知的符号,这尼玛就坑了啊。到了这里,其实现在不好搞啊。我们用gdb record / ida / objdump + grep 来综合分析,发现了跳转到当前地址的一个地方。下面是用readelf+objdump+grep来得到的一段片段:

   764f0:	41 57                	push   %r15
77090: e9 5b f4 ff ff jmpq 764f0 <_ZN4yLib6yShell16yLibGetClassInfoEv@@Base+0x10>

  我们再次用objdump和readelf查找77090这个偏移,终于在符号表查到了我们关心的这个偏移,如下:

   559: 0000000000077090     5 FUNC    GLOBAL DEFAULT   12 _ZN4yLib6yShell7ExecuteERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EESB_SB_RS9_

  到此,通过复原cxx函数名字,我们就知道了我们在哪个函数里面崩溃的,而且是在这个函数的memset的地方导致溢出崩溃的。

后记


  此问题的分析加深了我们对计算机的理解,使用了较多的二进制分析工具。

  结合我以前的调试和反调试经验,新手我还是建议直接上刑具ida进行分析,这样更棒哦。

参考文献


打赏、订阅、收藏、丢香蕉、硬币,请关注公众号(攻城狮的搬砖之路)

PS: 请尊重原创,不喜勿喷。

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

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

记一次有趣的 buffer overflow detected 问题分析的更多相关文章

  1. ubuntu 14.04 ns2.35 ***buffer overflow detected **: ns terminated解决办法

    1.按照如下教程安装 Install With Me !: How to Install NS-2.35 in Ubuntu-13.10 / 14.04 (in 4 easy steps) 2.运行一 ...

  2. 异常之*** buffer overflow detected ***

    *** buffer overflow detected *** 是sprintf()超出buff大小

  3. BUFFER OVERFLOW 10 Vulnerability & Exploit Example

    SRC= http://www.tenouk.com/Bufferoverflowc/Bufferoverflow6.html THE VULNERABLE AND THE EXPLOIT     W ...

  4. Kingsoft Office Writer 2012 8.1.0.3385 - (.wps) Buffer Overflow Exploit (SEH)

    #!/usr/bin/python # Exploit Title: Kingsoft Office Writer v2012 8.1.0.3385 .wps Buffer Overflow Expl ...

  5. ORA-20000:ORU-10027:buffer overflow,limit of 2000 bytes.

     ORA-20000:ORU-10027:buffer overflow,limit of 2000 bytes.  这是因为在过程中用到了dbms_output.put_line()在服务器端输出信 ...

  6. Buffer Overflow Study

    -- These days I learned and studied buffer overflow. I like to write on the paper and it can keep sy ...

  7. buffer overflow

    Computer Systems A Programmer's Perspective Second Edition We have seen that C does not perform any ...

  8. buffer overflow vulnerabilitie

    Computer Systems A Programmer's Perspective Second Edition Avoiding security holes.For many years,bu ...

  9. ORA-20000:ORU-10027:buffer overflow,limit of 10000 bytes错误4

    今天再测试一个存储过程时,用DBMS_OUTPUT.PUT_LINE输出时,报 ORA-20000:ORU-10027:buffer overflow,limit of 10000 bytes SQL ...

  10. ORA-20000: ORU-10027: buffer overflow, limit of 10000 bytes

        要用dbms_output.put_line来输出语句,遇到以下错误: ERROR 位于第 1 行: ORA-20000: ORU-10027: buffer overflow, limit ...

随机推荐

  1. 行行AI人才直播第7期:奇计AI创始人左晟《AI时代的商业挑战和机遇》

    行行AI人才是博客园和顺顺智慧共同运营的AI行业人才全生命周期服务平台,是园子商业化努力的一个重要方向. 行行AI人才直播希望以直播的方式让大家更多了解AI行业的现状与未来可能的发展方向. 随着人工智 ...

  2. 计算机COM口数据测试

    计算机COM口数据测试一.基本使用流程 程序需要以管理员身份运行,COM口回路测试需短接2,3pin,测试时候使用控制台,配置测试相关路径,并在测试完成后 1.测试配置路径D:\bigdata\INI ...

  3. Istio 入门(三):体验 Istio、微服务部署、可观测性

    本教程已加入 Istio 系列:https://istio.whuanle.cn 目录 3,快速入门 书店微服务 预先准备 details 应用 ratings 应用 reviews v1/v2/v3 ...

  4. 现代C++(Modern C++)基本用法实践:三、移动语义

    概述 移动 移动(move)语义C++引入了一种新的内存优化,以避免不必要的拷贝.在构造或者赋值的时候,如果实参是右值(或者左值由std::move转换成右值),便会匹配移动语义的函数调用如下述举例的 ...

  5. C# Task 实现任务超时取消、超时取消然后重试 超过重试最大次数就结束。

    任务超时取消 示例 public static async Task TimeoutCancelTask() { CancellationTokenSource cts = new Cancellat ...

  6. study the docker network of macvlan

    Introduce: 在 Macvlan 出现之前,我们只能为一块以太网卡添加多个 IP 地址,却不能添加多个 MAC 地址,因为 MAC 地址正是通过其全球唯一性来标识一块以太网卡的,即便你使用了创 ...

  7. JVM篇(一) 什么是JVM,它有什么用

    一.JVM的组成 1. JVM由那些部分组成,运行流程是什么? 从图中可以看出 JVM 的主要组成部分 ClassLoader(类加载器) Runtime Data Area(运行时数据区,内存分区) ...

  8. 零基础入门——从零开始学习PHP反序列化笔记(一)

    靶场环境搭建 方法一:PHPstudy搭建 GitHub地址 https://github.com/mcc0624/php_ser_Class 方法二:Docker部署 pull镜像文件 docker ...

  9. 在 ubuntu 中安装或升级最新版本的 Elasticsearch

    1. 安装 java 8 首先最新版本的elasticsearch需要java8的支持,那先来安装一下. $ sudo add-apt-repository -y ppa:webupd8team/ja ...

  10. [mysql]安全加固

    前言 因等保安全的要求,需要对MySQL用户密码和登录策略进行安全加固,以满足以下需求: 密码至少8位,包含大小写字母.数字和特殊字符. 当密码登录失败一定次数后锁定账户. 密码90天过期 本文使用的 ...