Linux漏洞分析入门笔记-CVE-2015-0235

Ubuntu 12.04 32位

ida 7.0

0x00:漏洞描述

1.glibc的__nss_hostname_digits_dots存在缓冲区溢出漏洞,导致使用gethostbyname系列函数的某些软件存在代码执行或者信息泄露的安全风险。

通过gethostbyname()函数或gethostbyname2()函数,将可能产生一个堆上的缓冲区溢出。经由gethostbyname_r()或gethostbyname2_r(),则会触发调用者提供的缓冲区溢出, 漏洞产生时至多sizeof(char* )个字节可被覆盖(因为char*指针的大小,即32位系统上为4个字节,64位系统为8个字节)。

0x01:漏洞分析

1.先静态分析glibc源码中的__nss_hostname_digits_dots函数流程,如图1所示。

          图1

图1代码大致流程就是在__nss_hostname_digits_dots中,计算了size_needed,当size_needed > buff_size时,会调用realloc重新申请size_needed的空间。

          图2

图2代码流程在计算size_need时,少加了一个sizeof(*h_alias_ptr),少算了4个字节,所以当name全为数字或者.号时,会将name拷贝到buff的hostname,造成一个指针大小字节的堆溢出。

所以要触发成功需要满足的条件为,size_need足够大,让其调用realloc重新分配。name全为数字或者.号。

2.选择一个受漏洞影响的程序clockdiff来调试分析,在IDA中对__nss_hostname_digits_dots下好断点,如图3所示:

          图3

F9运行,第一次断下无用不是处理我们自己输入的参数,直接跳过。第二次断下,发现gethostbyname的参数为我们输入的参数。Gethostbyname中调用__nss_hostname_digits_dots,其中缓冲区的大小默认为0x400。在调用realloc处下断点,此时buffer_size= 0x41B,刚好是输入参数的长度,因为size_need大于buffer_size所以须要重新分配空间。

          图4

通过上面的判断与计算空间大小后执行到stcpy处(溢出点),通过前面空间的计算,加上字符串结尾的空字节,刚好溢出了一个指针字节。

0x02:总结

1.产生漏洞的条件是当gethostbyname()函灵敏被调用时且满足下面两个条件。

a.size_need足够大,让其调用realloc重新分配。

b.name全为数字或者.号

posted @ 2019-01-04 14:38  我是小三  阅读(1116)  评论(0编辑  收藏  举报