哪一组GCC选项可提供最佳保护,以防止内存损坏漏洞(如缓冲区溢出和指针悬空)? GCC是否提供任何类型的ROP链缓解措施?是否有性能方面的担忧或其他问题会阻止此GCC选项在关键任务应用程序上使用?

我正在看《 Debian Hardening Guide》以及GCC Mudflap。我正在考虑以下配置:

-D_FORTIFY_SOURCE=2
-fstack-protector --param ssp-buffer-size=4
-fPIE -pie
-Wl,-z,relro,-z,now (ld -z relro and ld -z now)


对这组选项是否可以进行任何改进?

最担心保护WebKit的问题。

评论

gcc -x ada。认真地说,如果您不想要可利用的程序,请先使用一种不会竭力让程序员编写可利用的代码的编程语言。

@Gilles cool在ada中编写浏览器时让我知道。

有一个用Objective Caml编写的Web浏览器,但是该项目已停滞了十多年(因此在实践中无法使用):pauillac.inria.fr/mmm

还有Java中最新的Lobo。

Mozilla社区正在开发一个用Rust编写的浏览器引擎,该引擎应该提供比C更好的安全级别。(尽管我承认我无法将它与ADA进行比较,因为我对ADA一无所知。) >

#1 楼

我不为gcc编写代码,因此希望其他人可以对此进行添加或更正。我将使用回复对其进行编辑。其中某些方法并非在所有情况下都适用。


-Wall -Wextra打开所有警告以帮助确保基础代码安全。
-Wconversion -Wsign-conversion警告取消符号/符号转换。
-Wformat-security警告有关表示可能存在安全问题的格式函数的使用。
-Werror将所有警告转换为错误。
-arch x86_64编译为64位以采用地址空间的最大优势(对于ASLR来说很重要;在使布局随机化时可以选择更多的虚拟地址空间)。
-mmitigate-rop尝试在没有意外返回地址的情况下编译代码,从而使ROP变得更难一点。
-mindirect-branch = thunk -mfunction-return = thunk
启用retpoline(返回蹦床)以减轻Spectre V2的某些变体。由于分支目标缓冲区易受攻击,因此在Skylake +上第二个标志是必需的。
-fstack-protector-all -Wstack-protector --param ssp-buffer-size = 4您选择的“ -fstack-保护器”并不保护所有功能(请参阅注释)。您需要-fstack-protector-all以确保将防护措施应用于所有功能,尽管这可能会导致性能下降。将-fstack-protector-strong考虑为中间立场。
这里的-Wstack-protector标志会为所有不需要保护的功能发出警告。
-fstack-clash-protection击败一类称为堆栈冲突的攻击。<​​br /> -pie -fPIE获得ASLR的全部安全优势。
-ftrapv生成有符号溢出的陷阱(当前在gcc中已错误,可能会干扰UBSAN)。
-D_FORTIFY_SOURCE = 2缓冲区溢出检查。另请参阅= 2和= 1之间的差异。
-Wl,-z,relro,-z,现在
RELRO(只读重定位)。一起指定的选项relronow被称为“完全RELRO”。您可以通过省略now标志来指定“部分RELRO”。
RELRO将各种ELF内存节标记为只读(例如GOT)。

-Wl,-z,noexecstack
不可执行的堆栈。此选项将堆栈标记为不可执行,可能与许多代码不兼容,但针对任何可能的代码执行提供了很大的安全性。 (https://www.win.tue.nl/~aeb/linux/hh/protection.html)


-fvtable-verify = [std | preinit | none]
Vtable指针验证。通过它,可以在运行时针对每个虚拟调用验证通过该vtable指针进行的调用对于该对象的类型有效,并且未被破坏或覆盖。如果在运行时检测到无效的vtable指针,则会报告错误并立即停止执行程序。(https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html)


-fcf-protection = [完整|分支|返回|无]
通过检查控制流传输指令的目标地址(例如,等)来启用控制流传输的代码检测,以提高程序安全性。作为间接函数调用,函数返回,间接跳转)是有效的。仅在具有Intel CET的x86(_64)上可用。 (https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html)


如果在Windows上编译,请使用Visual Studio而不是GCC,作为对Windows的一些保护(例如SEHOP)不是GCC的一部分,但是如果必须使用GCC:



-Wl,dynamicbase告诉链接器使用ASLR保护。

-Wl,nxcompat告诉链接器使用DEP保护。


评论


启用警告无助于防止损害正在运行的系统。另外,如果没有-fstack-protector-,则所有Canary仅添加到可能导致基于堆栈的溢出的函数中,该溢出包含大于4个字节的数组(按照ssp-buffer-size = 4)。并非所有功能都需要使用金丝雀来保护,这只是浪费。另外,我使用的是32位系统。因此,本文并未更改我的构建选项。

–rook
2012年12月2日19:39



@RJFalconer编译为X86_64可为应用程序提供更多的虚拟地址空间。这样,由于随机化时有更多地址可供选择,因此ASLR更加有效。

–user7610
2014年4月25日在20:33

显然,对于Windows 8和HiASLR,您可能还希望指定-Wl​​,highentropyva,除了-Wl,dynamicbase之外,以确保获得HiASLR(高熵ASLR)的全部好处。我不能告诉您是否/何时真正需要此标志。向可能偶然发现此问题的其他人提及此为公共服务。

– D.W.
2014年6月4日在18:34

如果您正在使用clang,请不要忘记CFI!

–亚伦
17年9月21日在18:20

@Avamander当然,这就是为什么我只在评论中提到这一点。您可以让CFI在GCC上工作(无需CET),但是它不像使用Clang那样容易和无缝。

–森林
19年3月11日在10:43

#2 楼

这些是不错的选择,但是您需要注意自己的源代码。
在处理用户输入时,请确保使用安全功能,对它们进行过滤,以及在使用诸如strncpy()之类的东西时,请尽量不要留出足够的空间来防止某些攻击。
OS本身提供安全性,即DEP(NX),ASLR和Canary来保护堆栈,但是您不能一直依赖它们。是的,以上是我的建议。希望对您有所帮助,并且您还可以使用源代码审核工具。
祝你好运!