本文主要介绍linux nx所指的相关知识。内容详实易懂,操作简单快捷,具有一定的参考价值。相信大家看完这篇关于linux nx所指的文章都会有所收获。让我们来看看。
Linux nx指的是“不执行”(No-eXecute),这是Linux中的一种保护机制,即数据是不可执行的,防止攻击者的shell代码因为程序运行中溢出而试图在数据区执行。
Linux程序中常用的一些保护机制
一、NX(Windows中的DEP)NX:不执行,DEP:数据执行阻止。
即数据是不可执行的,防止攻击者的外壳代码因为程序溢出而试图在数据区执行。
默认情况下,Gcc是打开的,选项有:
Gcc -o test test.c //默认情况下,NX保护开启。
Gcc -z execstack -o test test.c //禁用NX保护。
Gcc -z noexecstack -o test test.c //开启NX保护。
二、Pie (aslr) Pie:位置无关可执行,aslr:地址空间布局随机化。
Fpie/fpie:需要使用option -pie编译可执行文件,这样elf就有了共享库属性,可以在内存的任何地方加载运行。同样,还有fpic/fPIC,解释了https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html.
-fpic
如果目标机器支持,生成适合在共享库中使用的位置无关代码(PIC)。这种代码通过全局偏移表(GOT)访问所有常量地址。当程序启动时,动态加载器解析得到的条目(动态加载器不是GCC的一部分;它是操作系统的一部分)。如果链接的可执行文件的GOT大小超过了特定于机器的最大大小,那么链接器会显示一条错误消息,指出-fpic不起作用;在这种情况下,请改用-fPIC重新编译。(这些最大值在SPARC上是8k,在AArch74上是28k,在m68k和RS/6000上是32k。x86没有这样的限制。)
独立于位置的代码需要特殊的支持,因此只能在某些机器上工作。对于x86,GCC支持系统V的PIC,但不支持Sun 386i。为IBM RS/6000生成的代码总是与位置无关的。
设置该标志时,宏` __pic__ '和` __PIC__ '被定义为1。
-fPIC
如果目标机器支持,发出独立于位置的代码,适用于动态链接并避免对全局偏移表的大小的任何限制。此选项在AArch74、m68k、PowerPC和SPARC上发挥了重要作用。
独立于位置的代码需要特殊的支持,因此只能在某些机器上工作。
设置该标志时,宏` __pic__ '和` __PIC__ '被定义为2。
-fpie
-fPIE
这些选项类似于-fpic和-fPIC,但是生成的位置无关代码只能链接到可执行文件中。通常这些选项用于编译使用-pie GCC选项链接的代码。
-fpie和-fPIE都定义了宏“pie__”和“PIE__”。对于'-fpie ',宏的值为1,对于'-fPIE ',宏的值为2。
不同的是fpic/fPIC用于编译共享库,fpie/fpie是编译pie文件的选项。文档里说pic(位置无关代码)生成的共享库只能链接到可执行文件,然后根据自己编译简单的C程序,pie正常运行,也就是像网上很多文章说的,pie选项生成的位置无关代码在这个程序里可以假设,但是我看不出FPIE和FPIE有什么区别,除了宏定义只有1和2,好像是编译命令(PIE默认不打开):
Gcc -fPIE -PIE -o test test.c //打开pie。
Gcc -fPIE -PIE -o test test.c //打开PIE。
Gcc -fPIC -o test test.c //打开PIC。
Gcc -fPIC -o test test.c //打开PIC。
Gcc -no-PIE -o test test.c //关闭PIE。
ASLR(地址空间随机化)最初被设计用来随机化堆栈、库、堆和其他段的地址。ASLR的值存储在/proc/sys/kernel/randomize _ va _ space中,如下所示:
0-表示关闭进程地址空间的随机化。1-表示随机化mmap的基址、堆栈和vdso页。2-表示在1的基础上增加堆栈的随机化。(默认)
如何改变它的值:echo 0 >/proc/sys/kernel/randomize _ va _ space
虚拟动态共享对象;Mmap:即内存的映射。PIE负责可执行程序的随机基址。以下摘自维基:
独立于位置的可执行文件(PIE)为主可执行文件二进制文件实现了一个随机的基地址,自2003年就已经存在。它向主可执行文件提供了与共享库相同的地址随机性。
PIE是ASLR的一部分,ASLR是系统函数,PIE是编译选项。注意:堆分配中,有两种方式:mmap()和brk(),malloc()分配内存时调用,brk小的时候分配,否则mmap和128k不一样。
三、金丝雀(栈保护)金丝雀保护栈。每次执行该函数时,都会在堆栈上随机生成一个金丝雀值。之后在函数执行后返回时检测金丝雀值,如果不一致,系统会报告异常。
维基:
金丝雀或金丝雀字是放置在堆栈上的缓冲区和控制数据之间的已知值,用于监控缓冲区溢出。当缓冲区溢出时,第一个被破坏的数据通常是金丝雀,因此金丝雀数据的失败验证将警告溢出,然后可以例如通过使被破坏的数据无效来处理该溢出。不应将金丝雀值与哨兵值混淆。
如上所述,金丝雀值位于缓冲区和控制数据之间。当缓冲区溢出时,canary值被覆盖,这样就可以检测到它,以确定操作是否错误或受到攻击。减轻缓冲区溢出攻击。
编译选项:
Gcc -o test test.c //默认关闭。
gcc-fno-stack-protector-otest test . c//禁用堆栈保护。
gcc-f stack-protector-otest test . c//启用堆栈保护,但只在局部变量中插入带有char数组的函数的保护代码。
gcc-f stack-protector-all-otesttest . c//启用堆栈保护,并为所有函数插入保护代码。
4.RELRO(重定位只读)Linux中有两种RELRO模式:“部分RELRO”和“完全RELRO”。在Linux中,默认情况下启用Partical RELRO。
部分RELRO:
编译命令:gcc -o test test.c //打开gcc-wl,-z,relro-otesttest . c//打开RELROgcc -z lazy -o test test.c //部分打开。
ELF文件的一部分被重新排序。内部数据节(如。得到了,。dtors等。)放在程序数据段(program & # 39s数据段)(如。数据和。BSS);
没有plt指向的get是只读的;
得到的表是可以写的(应该和上面不一样)。
完全重置:
编译命令:gcc-wl,-z,relro,-z,now-otesttest . c//Open full relrogcc-znow-otesttest . c//全部打开。
支持部分模式的所有功能;
整个get表被映射为只读。
gcc-z No RELRO-o a . c//RELRO是封闭的,也就是No RELRO。
注意:
。dtors:当共享库与。已加载定义的dtors
在bss或数据溢出错误的情况下,部分和完全RELRO保护ELF中的数据段不被覆盖。但只有Full RELRO可以缓解get表覆盖攻击,但代价相对较大,因为程序启动前需要解析所有符号。
评论前必须登录!
注册