基础知识——程序保护

阅读: 评论:0

基础知识——程序保护

基础知识——程序保护

我们先来看一个实例,使用pwntools的checksec对一个程序进行检测

RELRO(Relocation Read-Only):

 设置符号重定位表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对 GOT 攻击。

(1)No RELRO:

在这种模式下关于重定位并不进行任何保护。

(2)Partial RELRO:

1.这种模式是gcc编译的默认模式。

2.一些段 (包括.init_array .fini_array .jcr .dynamic .got) 在初始化后将会被标识为只读。

3.ELF 部分被重新排序,以便 ELF 内部数据部分(.got、.dtors 等)在程序的数据部分(.data 和 .bss)之前。

4.对于攻击者来说,由于linux的lazy bind机制,(.)段依然可写,只是(.got)段不在可写。

(3)FULL RELRO:

1.Full RELRO 不是默认编译器设置,因为它可以大大增加程序启动时间,因为必须在程序启动之前解析所有符号。在需要链接数千个符号的大型程序中,这可能会导致启动时间明显延迟。

2.将会继承Partial RELRO的所有功能。

3.lazy bind 将被禁用,所有导入的符号都在startup time被解析。

4.Full RELRO 使整个 GOT 成为只读的,其中一个函数的 GOT 地址不会被另一个函数或者通过ROP gadget 覆盖。
关于重定位与Lazy Bind机制会再以后讲到

Canary:

Canary 不管是实现还是设计思想都比较简单高效,就是插入一个值在 stack overflow 发生的高危区域的尾部。当函数返回之时检测 Canary 的值是否经过了改变,以此来判断 stack/buffer overflow 是否发生。

canary通常有三种类型

1.Terminator canaries

由于大多数缓冲区溢出攻击都是基于以某些字符结束符终结的字符串操作。Terminator canaries是由零终止子,CR,LF和FF构成的。因此,攻击者必须在写入返回地址之前写入空字符,以避免更改金丝雀。这将有效的限制了strcpy( )和其他空字符结束的攻击方法,但缺点也很明显,因为canary对攻击者来说是已知的,攻击者仍然可以采取手段覆盖canary,从而控制程序。

2.Random canaries

通常,随机金丝雀在程序初始化时生成,并存储在全局变量中。此变量通常由未映射的页面填充,因此尝试使用任何利用错误读取RAM的技巧来读取它都会导致分段错误,从而终止程序。如果攻击者知道金丝雀的位置,或者可以让程序从堆栈中读取,则仍然可以读取金丝雀。

Linux C 编译器 gcc,一般在ebp之前插入一段以/x00结尾的字节序,由于Intel处理器大多采用小端序,/x00其实位于字节序开头,对于字节序的其他部分将会由系统随机生成。当程序启用 Canary 编译后,在函数序言部分会取 fs 寄存器 0x28 处的值,存放在ebp之前。在函数返回之前,会将该值取出,并与 fs:0x28 的值进行异或。如果异或的结果为 0,说明 Canary 未被修改,函数会正常返回,这个操作即为检测是否发生栈溢出,否则将会执行 __stack_chk_fail错误回调函数,停止程序运行。

canary的值会在进程开始时生成,并在程序运行期间保持不变。进程的任何分支都将包含相同的canary值。这给我们提供了一些绕过的机会,我们看下面的示例。

该程序包含两个漏洞,一个printf,和一个任意写

可以看到这两个函数都存在canary,且由于canary相同,可以考虑printf将canary泄露出来,再使用read写入canary和返回地址。具体过程不再累述。

Linux C 编译器 gcc 目前包含 Stack Smashing 保护程序,如果 /dev/urandom 可用,它将引入一个Random canaries。在没有随机数据源的情况下,它将恢复为Terminator canaries。gcc 仅在特定情况下引入canary。缓冲区超过 8 个字节并调用 alloca()的函数(允许在堆栈上分配内存空间的函数)将受到金丝雀的保护。程序员可以使用 –fstack-protector-all 编译器标志为所有函数引入 canary,但这可能会妨碍程序的性能。

3.Random XOR canaries

Random XOR canaries是使用全部或部分控制数据进行异或加扰的Random canaries。这样一来,一旦canary或控制数据被破坏,canary的值就是错误的。
Random XOR canaries具有与Random canaries相同的漏洞,只是获取canary的“从堆栈读取”方法稍微复杂一些。攻击者必须获得canary、算法和控制数据,才能重新生成欺骗保护所需的原canary。

很多时候它将根据程序中的非静态值(通常是基本指针EBP)进行异或化。由于操作系统现在在激活地址空间布局随机化(ASLR)的情况下运行,因此EBP在程序运行期间不会是静态的。这为 Cookie 增加了一层额外的随机化,使得很难预测此值。
此外,Random XOR canaries可以防止某种类型的攻击,包括将结构中的缓冲区溢出到指针中,以将指针更改为指向一段控制数据。由于异或编码,如果控制数据或返回值发生变化,canary就会出错。由于指针,可以更改控制数据或返回值而不会溢出canary。

NX(No-eXecute):

NX即No-eXecute(不可执行)的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。

一个最简单的例子,我们通过向栈中写入shellcode,然后将返回地址设置为shellcode所在的栈地址,如果程序没有NX保护的话,就会执行我们写入的恶意代码。

接下来简要说明一下该保护的具体原理。

在Linux系统中,物理内存被划为三个层次来管理。

层次

描述

存储节点(Node)

CPU被划分为多个节点(node), 内存则被分簇, 每个CPU对应一个本地物理内存, 即一个CPU-node对应一个内存簇bank,即每个内存簇被认为是一个节点

管理区(Zone)

每个物理内存节点node被划分为多个内存管理区域, 用于表示不同范围的内存, 内核可以使用不同的映射方式映射物理内存

页面(Page)

内存被细分为多个页面帧, 页面是最基本的页面分配的单位

页面作为最基本的页面分配单位,适时的从虚拟内存转移的物理内存,在每个页面中都具有一定的结构,存储着状态信息和页面内容。而页面的保护信息是由页表管理的,操作系统为每一个进程创建了一个独立的页表,因而进程可以方便的对自己的数据进行保护,为每个页进行权限管理,如果一条指令违背了这些许可条件,CPU就会抛出一个异常。

而页表的权限设置,是在程序的装载过程中发生的。我们可以回想在ELF可执行文件中,有一个专门的数据结构叫做程序头表(Program Header Table)

typedef struct
{Elf32_Word	p_type;			/* Segment type */Elf32_Off	    p_offset;		/* Segment file offset */Elf32_Addr	p_vaddr;		/* Segment virtual address */Elf32_Addr	p_paddr;		/* Segment physical address */Elf32_Word	p_filesz;		/* Segment size in file */Elf32_Word	p_memsz;		/* Segment size in memory */Elf32_Word	p_flags;		/* Segment flags */Elf32_Word	p_align;		/* Segment alignment */
} Elf32_Phdr;

其中的p_flags记录了Segment的权限属性,例如R,W,X。

在IDA中我们可以看到程序各个段设置的权限。

由于NX保护只是栈数据没有执行权限,使用依然可以使用Return2lib,rop之类的攻击手段。

PIE(position-independent executable)

该技术是一个针对代码段(.text)、数据段(.data)、未初始化全局变量段(.bss)等固定地址的一个防护技术,如果程序开启了PIE保护的话,在每次加载程序时都变换加载地址,从而不能通过ROPgadget等一些工具来帮助解题。

未完待续。。。

参考:

Relocation Read-Only (RELRO) - CTF 101

程序保护的的机制 - 简书

二进制漏洞挖掘之栈溢出-开启RELRO_sp00f的博客-CSDN博客_partial relro

stack-overflow-at-runtime/

Instrumentation Options (Using the GNU Compiler Collection (GCC))

Stack Canaries – Gingerly Sidestepping the Cage | SANS Institute

Linux内存描述之内存页面page--Linux内存管理(四) - yooooooo - 博客园

本文发布于:2024-01-29 19:04:35,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170652628017600.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:基础知识   程序
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23