找回密码
 注册
关于网站域名变更的通知
查看: 336|回复: 1
打印 上一主题 下一主题

GCC安全保护机制,你了解多少?

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-9-16 17:49 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
0x0 介绍/ c; b/ B- ^- C5 c2 D! G# F
7 I! k. F! N% f3 j/ i1 O
本文记录软件安全课程一项实验内容,为”分析一款编译器的安全特性”,偷懒选了Linux下的gcc,网上有很多相关资料,这里做一实验总结,主要是测试该特性在当前版本Linux平台下是否工作,顺便比较和Windows平台的异同.$ Q7 Z. J8 v% ]2 ~2 E
6 t7 x5 J0 ^$ X( d' J* d: `
另:有更多关于Windows平台下的安全保护机制,但由于windows平台编译器众多(特别是vs开头的),十分依赖编译器和操作系统的配合(虽然在linux平台的实验表明这种程度的安全措施只能依靠编译器和OS的配合,甚至于CPU提供相关的指令集)" h, ~) }$ Z) y
) K; c% b2 N- j2 ^9 }
本文分析和实验内容如下:
9 j: g8 l. a# t9 i' P5 X% J6 O) V! f0 b0 @
a) 分析gcc编译器对安全特性的支持。
- V) u- \# ?  m! T& @+ B+ g4 s2 y8 C; }! z$ G3 ]% c
b) 写程序观察生成可执行代码的差异。
. e% b9 o4 M) n8 S" P$ o( T' A& q, g( R9 H% s
c) 分析这些安全特性和程序编写者、编译器、操作系统的关联。
: V3 M1 _8 P: d4 s! w; s% r
% g( N( o7 x. _& O: G实验环境: ubuntu 18.04 + gcc 7.38 ?; U! d2 W0 q, w* g* [/ \8 h

( j2 p5 @) u( k& j经学习研究,Linux操作系统中gcc相关的安全保护机制有:栈Canaries保护、PIE机制、NX、fortity、relro机制。
5 L  s% k: U$ `  O0 J3 w8 @) d. O% h- Y+ s
0x1 Canaries
. `/ z7 I% X7 p* ^. w/ C7 e
% I6 {* P, q$ e  g& n* X
在windows操作系统中,这一机制被称为gs机制。实现方式是类似的,即在函数的返回地址前加一个cookie检查,在linux中被称为Canaries。gcc在4.2版本中增加了-fstack-protector来使用这种保护方式,若要禁用栈保护,则应使用-fno-stack-protector。对栈空间的保护在gcc中是默认开启的。
; x6 U8 o# i6 f4 p1 a
4 T$ S1 R- {' }$ {/ HCanaries的产生方式是随机的,即从fs寄存器的0x28偏移处获取,而fs寄存器是被glibc定义存放tls信息的。如图是glibc定义的fs寄存器的数据结构:$ f- v& K: M% v* z- }9 s

8 F# z" w7 p& u0 W+ I( L
4 w8 E) u6 o2 @2 l; m/ x* O7 Z/ F7 W" C2 Y. q: X. H" R: c% P8 ?
图1 fs寄存器的数据结构
0 R3 A) r3 b! g( Q2 D" y
# {3 c. b2 `3 ?( D可以发现,0x28处存放的即是stark_guard,canaries值。这个值是进程载入时初始化的,生成随机数的代码如下:
$ `! w: c2 t. F# A0 Z- P2 T& j2 H9 m) ?
8 _/ l' o, V/ }9 V1 A
  g8 \' A& g% O/ w8 l
图2 canaries的值初始化方式
: F/ p, K5 w- r5 T% m+ c/ e. c" L
可以看到,_dl_random是一个随机数,它由_dl_sysdep_start函数从内核获取的。_dl_setup_stack_chk_guard函数负责生成canary值,THREAD_SET_STACK_GUARD宏将canary设置到%fs:0x28位置。
: P# M) X& r( h/ L; t9 }  K( g
2 [7 E' i! L$ S, _在实验中,我们编写了代码,使用调试程序查看其栈结构和机器码。下图是开启了栈保护的栈结构和机器码:
' d- H( R0 s$ V
% B- v2 l$ a( t: z1 X ! N# e# M  A$ w

3 n& N  D/ H9 L% V图3 栈结构
% T  s& R/ d0 U) E1 N9 Y( ]( U9 }- b
' |  k. d8 Y$ p9 ^/ b

6 p0 X0 o6 E6 U图4 开启栈保护函数的执行代码
2 v( _' i$ n) {% R2 B+ [6 I. t: e" D
可以看到,在初始化函数时。除了push rbp之外,在申请栈空间后又将fs[0x28]压入了栈中,即rbp-0x8。在函数结束前,又检查该处数值是否和fs[0x28]的大小相同,以此保证函数栈未被溢出。该检查如下图所示:6 l' u$ G9 }  C1 P; W1 [
游客,如果您要查看本帖隐藏内容请回复
) n3 e" S" ^6 B1 T

9 u9 W. A9 S! P9 I3 |: k- m1 d4 g7 Y7 p$ S8 d6 X; Z  d) Y: v3 g

该用户从未签到

2#
发表于 2019-9-17 20:51 | 只看该作者
GCC安全保护机制,你了解多少?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-8-23 22:14 , Processed in 0.140625 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表