自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

黑客攻防:緩沖區(qū)溢出攻擊與堆棧保護(hù)

安全 應(yīng)用安全
當(dāng)函數(shù)返回時(shí)我們會(huì)再次拿fs:[0x28]處的值與棧上的“金絲雀”進(jìn)行對(duì)比,一旦發(fā)現(xiàn)這兩個(gè)值不同我們就可以認(rèn)為當(dāng)前的棧已經(jīng)被破壞了,由于棧上的數(shù)據(jù)已然不可信,因此我們必須及早撤離礦區(qū),也就是調(diào)用__stack_chk_fail函數(shù)提前終止進(jìn)程。

大家好,我是小風(fēng)哥。在上一篇文章《??進(jìn)程切換的本質(zhì)是什么???》中舉了一個(gè)示例,也就是這段代碼:

#include <stdio.h>
#include <stdlib.h>

void funcC() {
printf("jump to funcC !!!\n") ;
exit(-1) ;
}

void funcB() {
long *p = NULL ;
p = (long*)&p ;
*(p+2) = (long)funcC ;
}

void funcA() {
funcB();
}

int main() {
funcA() ;
return 0 ;
}

有同學(xué)在微信群里問不能在自己的機(jī)器上復(fù)現(xiàn),并給出了編譯后的機(jī)器指令:

00000000004005ee <funcB>:
4005ee: 55 push %rbp
4005ef: 48 89 e5 mov %rsp,%rbp
4005f2: 48 83 ec 10 sub $0x10,%rsp
4005f6: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
4005fd: 00 00
4005ff: 48 89 45 f8 mov %rax,-0x8(%rbp)
400603: 31 c0 xor %eax,%eax
400605: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp)
40060c: 00
40060d: 48 8d 45 f0 lea -0x10(%rbp),%rax
400611: 48 89 45 f0 mov %rax,-0x10(%rbp)
400615: 48 8b 45 f0 mov -0x10(%rbp),%rax
400619: 48 83 c0 10 add $0x10,%rax
40061d: ba d6 05 40 00 mov $0x4005d6,%edx
400622: 48 89 10 mov %rdx,(%rax)
400625: 90 nop
400626: 48 8b 45 f8 mov -0x8(%rbp),%rax
40062a: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
400631: 00 00
400633: 74 05 je 40063a <funcB+0x4c>
400635: e8 66 fe ff ff callq 4004a0 <__stack_chk_fail@plt>
40063a: c9 leaveq
40063b: c3 retq

仔細(xì)看這段代碼,有這樣一段可疑的指令:

mov    %fs:0x28,%rax
mov %rax,-0x8(%rbp)

這兩行指令將fs:[0x28] (段尋址的方式)處的值push到了調(diào)用棧上(%rbp偏移8字節(jié)),并在函數(shù)即將返回的時(shí)候又檢查了一遍該值有沒有被修改:

mov    -0x8(%rbp),%rax
xor %fs:0x28,%rax

接下來如果保存到棧上的值不等于fs:[0x28]處的值(xor指令進(jìn)行比較)那么跳轉(zhuǎn)到__stack_chk_fail函數(shù),我們的疑問是為什么要有這么一遍檢查呢?本質(zhì)上我們?cè)陂_頭給出的代碼相對(duì)于緩沖區(qū)溢出攻擊,做法是修改上一個(gè)棧幀的返回地址,將其修改為某個(gè)特定地址(黑客希望跳轉(zhuǎn)到的地方);

在開頭的這段代碼中本來funcA函數(shù)調(diào)用完funcB后需要返回funcA,但在我們的“精心”設(shè)計(jì)下調(diào)用完funcB后卻跳轉(zhuǎn)到了funcC,那么我們有沒有辦法防范這種攻擊呢?

答案是肯定的,這種方法要追溯到很久很久以前。在上世紀(jì)初,煤礦開采是一項(xiàng)很危險(xiǎn)的工作,因?yàn)槊旱V中的有毒氣體通常極難被人類察覺,這給礦工的生命帶來很大的威脅,而金絲雀對(duì)毒氣非常敏感,這樣礦工可以利用金絲雀來監(jiān)控礦區(qū),從而提早發(fā)現(xiàn)險(xiǎn)情。

這里也是一樣的道理,我們可以在棧區(qū)中放置一個(gè)“金絲雀”(fs:[0x28]處的值):

當(dāng)函數(shù)返回時(shí)我們會(huì)再次拿fs:[0x28]處的值與棧上的“金絲雀”進(jìn)行對(duì)比,一旦發(fā)現(xiàn)這兩個(gè)值不同我們就可以認(rèn)為當(dāng)前的棧已經(jīng)被破壞了,由于棧上的數(shù)據(jù)已然不可信,因此我們必須及早撤離礦區(qū),也就是調(diào)用__stack_chk_fail函數(shù)提前終止進(jìn)程。

而金絲雀也就是fs:[0x28]是隨機(jī)產(chǎn)生的(每次程序運(yùn)行時(shí)都不一樣),因此攻擊者很難提前知道該值是多少。

當(dāng)然我們也可以看到,添加堆棧保護(hù)功能需要增加額外的機(jī)器指令,這些也會(huì)稍稍對(duì)性能產(chǎn)生影響,代價(jià)就是需要額外多執(zhí)行一部分機(jī)器指令。

這就是編譯器的堆棧保護(hù)功能,當(dāng)然這個(gè)功能也是可以去掉的,編譯時(shí)添加-fno-stack-protector編譯選項(xiàng),這樣即可關(guān)閉堆棧保護(hù)功能,生成的代碼就可以復(fù)現(xiàn)上一篇文章《??進(jìn)程切換的本質(zhì)是什么???》中提到的效果了。

怎么樣,想成為黑客還是沒那么容易吧,就好比只有真正理解法律才能鉆空子一樣,只有真正理解計(jì)算機(jī)的工作原理才能hack它,當(dāng)然,想成為頂尖黑客只有對(duì)計(jì)算機(jī)的理解還不夠,你還需要有想象力。

責(zé)任編輯:武曉燕 來源: 碼農(nóng)的荒島求生
相關(guān)推薦

2010-10-09 14:45:48

2014-07-30 11:21:46

2010-09-29 15:10:58

2019-01-11 09:00:00

2009-09-24 18:16:40

2019-03-06 09:00:38

ASLRLinux命令

2010-09-08 15:43:18

2019-02-27 13:58:29

漏洞緩沖區(qū)溢出系統(tǒng)安全

2017-01-09 17:03:34

2011-11-15 16:00:42

2018-01-26 14:52:43

2009-05-13 09:21:48

2019-01-28 18:05:04

2019-02-13 13:31:42

2010-12-27 10:21:21

2012-07-26 09:39:01

2015-03-06 17:09:10

2020-08-10 08:37:32

漏洞安全數(shù)據(jù)

2011-03-23 12:39:44

2018-11-01 08:31:05

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)