ASLR如何保護Linux系統(tǒng)遠離緩沖區(qū)溢出攻擊?
譯文【51CTO.com快譯】地址空間布局隨機化(ASLR)是操作系統(tǒng)的一種保護內存的進程,旨在防范緩沖區(qū)溢出攻擊。它有助于確保與系統(tǒng)上運行中的進程關聯(lián)的內存地址不可預測,因此讓攻擊者更難利用與這些進程有關的缺陷或漏洞。
ASLR目前用于Linux、Windows和MacOS三大系統(tǒng)。2005年它首次實現(xiàn)在Linux上。2007年,這項技術部署在微軟Windows和MacOS上。雖然ASLR在這每一款操作系統(tǒng)上提供了一樣的功能,但它實現(xiàn)在每個操作系統(tǒng)上的方式都不一樣。
ASLR的效果取決于攻擊者仍然未知的全部地址空間布局。此外,只有編譯成位置獨立的可執(zhí)行程序(PIE)的可執(zhí)行文件才能從ASLR技術得到最大程度的保護,因為代碼的所有部分都將在隨機位置裝入。無論絕對地址如何,PIE機器碼都會正確執(zhí)行。
ASLR的局限性
盡管ASLR讓人更難利用系統(tǒng)漏洞,但其在保護系統(tǒng)方面的作用有限。了解ASLR的局限性很重要:
- 不解決漏洞,而是加大利用漏洞的難度
- 不跟蹤或報告漏洞
- 不為不支持ASLR而開發(fā)的二進制代碼提供任何保護
- 無法避免規(guī)避機制
ASLR的工作原理
ASLR加大了系統(tǒng)的控制流完整性,為此使內存布局中使用的偏移隨機化,從而讓攻擊者更難執(zhí)行成功的緩沖區(qū)溢出攻擊。
ASLR在64位系統(tǒng)上的效果要好得多,因為這類系統(tǒng)提供了大得多的熵(隨機化潛力)。
ASLR是否可以用在你的Linux系統(tǒng)上?
下列兩個命令中的任何一個都可以告訴你ASLR在你的系統(tǒng)上是否已啟用。
- $ cat /proc/sys/kernel/randomize_va_space
- 2
- $ sysctl -a --pattern randomize
- kernel.randomize_va_space = 2
上述命令中所示的值(2)表明,ASLR在完全隨機化模式下工作。顯示的值將是下列中的一個:
- 0 = 被禁用
- 1 = 保守隨機化
- 2 = 完全隨機化
如果你禁用ASLR并運行下列命令,會注意到下面ldd輸出中顯示的地址在隨后的ldd命令中都一樣。ldd命令的工作原理是,裝入共享的對象,并顯示它們最后出現(xiàn)在內存中的哪個位置。
- $ sudo sysctl -w kernel.randomize_va_space=0 <== disable
- [sudo] password for shs:
- kernel.randomize_va_space = 0
- $ ldd /bin/bash
- linux-vdso.so.1 (0x00007ffff7fd1000) <== same addresses
- libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007ffff7c69000)
- libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ffff7c63000)
- libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff7a79000)
- /lib64/ld-linux-x86-64.so.2 (0x00007ffff7fd3000)
- $ ldd /bin/bash
- linux-vdso.so.1 (0x00007ffff7fd1000) <== same addresses
- libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007ffff7c69000)
- libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ffff7c63000)
- libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff7a79000)
- /lib64/ld-linux-x86-64.so.2 (0x00007ffff7fd3000)
如果該值設回成2以啟用ASLR,你會發(fā)現(xiàn)每當你運行該命令,地址都會變化。
- $ sudo sysctl -w kernel.randomize_va_space=2 <== enable
- [sudo] password for shs:
- kernel.randomize_va_space = 2
- $ ldd /bin/bash
- linux-vdso.so.1 (0x00007fff47d0e000) <== first set of addresses
- libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f1cb7ce0000)
- libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1cb7cda000)
- libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1cb7af0000)
- /lib64/ld-linux-x86-64.so.2 (0x00007f1cb8045000)
- $ ldd /bin/bash
- linux-vdso.so.1 (0x00007ffe1cbd7000) <== second set of addresses
- libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007fed59742000)
- libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fed5973c000)
- libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fed59552000)
- /lib64/ld-linux-x86-64.so.2 (0x00007fed59aa7000)
試圖繞過ASLR
盡管ASLR有諸多優(yōu)點,但試圖繞過ASLR并不罕見,似乎屬于這幾類:
- 使用地址泄露
- 訪問與特定地址有關的數(shù)據
- 利用實現(xiàn)方面的薄弱環(huán)節(jié),熵很低或ASLR實現(xiàn)存在缺陷時,讓攻擊者得以猜出地址。
- 使用硬件操作的側通道
結束語
ASLR大有價值,尤其是在64位系統(tǒng)上運行、正確實現(xiàn)時。雖然無法避免規(guī)避機制,但它確實大大增加了利用系統(tǒng)漏洞的難度。這份參考資料(https://cybersecurity.upv.es/attacks/offset2lib/offset2lib-paper.pdf)更詳細地介紹了64位Linux上是完全ASLR的效果,而這篇論文(http://www.cs.ucr.edu/~nael/pubs/micro16.pdf)介紹了使用分支預測繞過ASLR的一種規(guī)避方法。
原文標題:How ASLR protects Linux systems from buffer overflow attacks,作者:Sandra Henry-Stocker
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】