本教程操作环境:linux5.9.8系统、Dell G3电脑。
linux nx是什么?
Linux程序常见用的一些保护机制
一、NX(Windows中的DEP)
NX:No-eXecute、DEP:Data Execute Prevention
- 也就是数据不可执行,防止因为程序运行出现溢出而使得攻击者的shellcode可能会在数据区尝试执行的情况。
- 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:Position-Independent Excutable、ASLR:Address Space Layout Randomization
- fpie/fPIE:需要和选项
-pie
一起使用开启pie选项编译可执行文件使得elf拥有共享库属性,可以在内存任何地方加载运行。与之相似的还有fpic/fPIC,关于其说明https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
-fpic Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. Such code accesses all constant addresses through a global offset table (GOT). The dynamic loader resolves the GOT entries when the program starts (the dynamic loader is not part of GCC; it is part of the operating system). If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error message from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead. (These maximums are 8k on the SPARC, 28k on AArch64 and 32k on the m68k and RS/6000. The x86 has no such limit.) Position-independent code requires special support, and therefore works only on certain machines. For the x86, GCC supports PIC for System V but not for the Sun 386i. Code generated for the IBM RS/6000 is always position-independent. When this flag is set, the macros `__pic__` and `__PIC__` are defined to 1. -fPIC If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table.This option makes a difference on AArch64, m68k, PowerPC and SPARC. Position-independent code requires special support, and therefore works only on certain machines. When this flag is set, the macros `__pic__` and `__PIC__` are defined to 2. -fpie -fPIE These options are similar to -fpic and -fPIC, but the generated position-independent code can be only linked into executables. Usually these options are used to compile code that will be linked using the -pie GCC option. -fpie and -fPIE both define the macros `__pie__` and `__PIE__`. The macros have the value 1 for `-fpie` and 2 for `-fPIE`.
登录后复制
- 区别在于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
中,如下:
vDSO:virtual dynamic shared object;
mmap:即内存的映射。PIE
则是负责可执行程序的基址随机。
以下摘自Wiki:
PIE为ASLR的一部分,ASLR为系统功能,PIE则为编译选项。
注: 在heap分配时,有mmap()
和brk()
两种方式,由malloc()
分配内存时调用,分配较小时brk,否则mmap,128k区别。
三、Canary(栈保护)
Canary对于栈的保护,在函数每一次执行时,在栈上随机产生一个Canary值。之后当函数执行结束返回时检测Canary值,若不一致系统则报出异常。
- Wiki:
- Canaries or canary words are known values that are placed between a buffer and control data on the stack to monitor buffer overflows. When the buffer overflows, the first data to be corrupted will usually be the canary, and a failed verification of the canary data will therefore alert of an overflow, which can then be handled, for example, by invalidating the corrupted data. A canary value should not be confused with a sentinel value.
如上所述,Canary值置于缓冲区和控制数据之间,当缓冲区溢出,该值被覆写,从而可以检测以判断是否运行出错或是受到攻击。缓解缓冲区溢出攻击。
- 编译选项:
gcc -o test test.c //默认关闭 gcc -fno-stack-protector -o test test.c //禁用栈保护 gcc -fstack-protector -o test test.c //启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码 gcc -fstack-protector-all -o test test.c //启用堆栈保护,为所有函数插入保护代码
登录后复制
四、RELRO(RELocation Read Only)
在Linux中有两种RELRO模式:”Partial RELRO“
和 ”Full RELRO“
。Linux中Partical RELRO默认开启。
Partial RELRO:
- 编译命令:
gcc -o test test.c // 默认部分开启
gcc -Wl,-z,relro -o test test.c// 开启部分RELRO
gcc -z lazy -o test test.c // 部分开启 - 该ELF文件的各个部分被重新排序。内数据段(internal data sections)(如.got,.dtors等)置于程序数据段(program's data sections)(如.data和.bss)之前;
- 无 plt 指向的GOT是只读的;
- GOT表可写(应该是与上面有所区别的)。
Full RELRO:
- 编译命令:
gcc -Wl,-z,relro,-z,now -o test test.c // 开启Full RELRO
gcc -z now -o test test.c // 全部开启 - 支持Partial模式的所有功能;
- 整个GOT表映射为只读的。
Note:
- .dtors:当定义有.dtors的共享库被加载时调用;
- 在bss或数据溢出错误的情况下,Partial和Full RELRO保护ELF内数据段不被覆盖。 但只有Full RELRO可以缓解GOT表覆写攻击,但是相比较而言开销较大,因为程序在启动之前需要解析所有的符号。
- 相关推荐:《Linux视频教程》
以上就是linux nx是什么的详细内容,更多请关注Work网其它相关文章!