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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
0x0 介绍/ @) h# M' u; ^9 i$ b

1 n& W6 W9 j  {) S# R/ V本文记录软件安全课程一项实验内容,为”分析一款编译器的安全特性”,偷懒选了Linux下的gcc,网上有很多相关资料,这里做一实验总结,主要是测试该特性在当前版本Linux平台下是否工作,顺便比较和Windows平台的异同.# c3 A+ P: `% a' @5 X) D" Q
* H  }) _; o+ F' u+ O
另:有更多关于Windows平台下的安全保护机制,但由于windows平台编译器众多(特别是vs开头的),十分依赖编译器和操作系统的配合(虽然在linux平台的实验表明这种程度的安全措施只能依靠编译器和OS的配合,甚至于CPU提供相关的指令集)
1 c  T# m& b. |& ]) S! T) }
% p. R. L. s1 y8 \4 S! B  p本文分析和实验内容如下:
4 M5 B' I$ n$ t) D$ L1 D
  w" I- d8 E: z9 Fa) 分析gcc编译器对安全特性的支持。% b0 D$ ]& D9 b; Y) v3 r) B
4 i1 E" V" g* Q6 j
b) 写程序观察生成可执行代码的差异。
* B* r) A( P( N
* U' G! T5 Y' ?c) 分析这些安全特性和程序编写者、编译器、操作系统的关联。9 N/ _8 Q  v  |. {( A

  O& M0 K# w! R/ H5 s$ U. p) |实验环境: ubuntu 18.04 + gcc 7.3
. H6 {/ i( d2 r: p7 l& }* S
' o! t9 K1 ~* M9 v/ i经学习研究,Linux操作系统中gcc相关的安全保护机制有:栈Canaries保护、PIE机制、NX、fortity、relro机制。
: n. s- Y: `* y7 [, O+ R. Y! l: q7 D5 s# P- A) B1 N* l
0x1 Canaries3 T" M. H  |9 P4 Z- f$ g

# ]1 A+ _# }' s! R1 B! z  Q6 W在windows操作系统中,这一机制被称为gs机制。实现方式是类似的,即在函数的返回地址前加一个cookie检查,在linux中被称为Canaries。gcc在4.2版本中增加了-fstack-protector来使用这种保护方式,若要禁用栈保护,则应使用-fno-stack-protector。对栈空间的保护在gcc中是默认开启的。+ E6 p8 P0 w  v/ S/ U

1 M; R9 Q7 c7 ACanaries的产生方式是随机的,即从fs寄存器的0x28偏移处获取,而fs寄存器是被glibc定义存放tls信息的。如图是glibc定义的fs寄存器的数据结构:
, ^, m/ H0 d2 g" {
1 G$ i: Y. j3 T2 h/ S
! \7 ~2 l# h4 q. y3 {( S6 D! W8 B0 Q8 `
图1 fs寄存器的数据结构+ q! {/ X0 X4 N5 Z" W# H
- C5 G) }7 Q% O3 X! k2 t( `; C
可以发现,0x28处存放的即是stark_guard,canaries值。这个值是进程载入时初始化的,生成随机数的代码如下:# R1 L$ l4 ?& r" q, T
$ f7 n1 d8 t: [% @8 q

+ v) b( j" `8 z. J5 K- N% ]' ?4 n
图2 canaries的值初始化方式
" n6 z6 J4 n" s0 x* w+ V' l9 K, m) x' h7 K
可以看到,_dl_random是一个随机数,它由_dl_sysdep_start函数从内核获取的。_dl_setup_stack_chk_guard函数负责生成canary值,THREAD_SET_STACK_GUARD宏将canary设置到%fs:0x28位置。$ E# t/ j2 b5 a) m! p8 D  c

- P9 {, P$ m6 b: y1 r1 H' t+ j# {在实验中,我们编写了代码,使用调试程序查看其栈结构和机器码。下图是开启了栈保护的栈结构和机器码:
8 O! u+ m$ Z# P) G1 r, ]8 c, z! F: V0 t/ v

6 b4 i+ P& M$ L6 r; e8 Z: s7 g. r  ?" t8 a
图3 栈结构
6 _5 w- W& E! s4 K, S" H
: v& n8 ]& d, j+ Q& Y: B
0 X$ V0 D/ @# X: I6 S1 C( k: K9 d
图4 开启栈保护函数的执行代码$ Q0 `' _' \6 q1 @

. t" f! E, q! O2 s$ z可以看到,在初始化函数时。除了push rbp之外,在申请栈空间后又将fs[0x28]压入了栈中,即rbp-0x8。在函数结束前,又检查该处数值是否和fs[0x28]的大小相同,以此保证函数栈未被溢出。该检查如下图所示:
3 \- Q5 X. C* W. L
游客,如果您要查看本帖隐藏内容请回复

3 y& |$ H* \) r; C1 ~
; \3 h" j: \1 J7 ?% s0 d; \
2 g: u9 X5 V8 e

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-25 01:12 , Processed in 0.171875 second(s), 26 queries , Gzip On.

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

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

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