由段錯誤引申出的緩沖區(qū)溢出攻擊分析
前段時間在寫《段錯誤造成的常見詭異宕機(jī)情況總結(jié)(中)》時,分析到 程序中數(shù)據(jù)寫超時有可能寫到this指針?biāo)诘牡刂防锩妫瑢?dǎo)致最終詭異的宕機(jī)。其實網(wǎng)絡(luò)攻防里常用的緩沖區(qū)溢出攻擊也是這個道理,除了使用戶程序甚至計算機(jī)掛掉外,還有可能執(zhí)行攻擊者想執(zhí)行的任何程序,這篇文章主要詳細(xì)剖析一下第二種攻擊的方法以及現(xiàn)在Linux(包括各種修改版本,例如Android)、Windows下常使用的防范措施。話不多說,先貼一則小例子:
2 *\author peakflys
3 *\email peakflys@gmail.com
4 *\brief Buffer overflow attack
5 */
6 #include <iostream>
7 using namespace std;
8
9 void hack()
10 {
11 cout<<"hacked"<<endl;
12 }
13
14 void test()
15 {
16 char a[4];
17 int *ret = (int *)(a + 24);
18 *ret -= 0x48;
19 }
20
21 int main()
22 {
23 test();
24 return 0;
25 }
0000000000400814 <_Z4hackv>:
{
400814: 55 push %rbp
400815: 48 89 e5 mov %rsp,%rbp
cout<<"hacked"<<endl;
400818: be b8 09 40 00 mov $0x4009b8,%esi
40081d: bf 80 0d 60 00 mov $0x600d80,%edi
400822: e8 c1 fe ff ff callq 4006e8 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
400827: be 08 07 40 00 mov $0x400708,%esi
40082c: 48 89 c7 mov %rax,%rdi
40082f: e8 c4 fe ff ff callq 4006f8 <_ZNSolsEPFRSoS_E@plt>
400834: c9 leaveq
400835: c3 retq
}
0000000000400836 <_Z4testv>:
void test()
{
400836: 55 push %rbp
400837: 48 89 e5 mov %rsp,%rbp
char a[4];
int *ret = (int *)(a + 24);
40083a: 48 8d 45 f0 lea -0x10(%rbp),%rax
40083e: 48 83 c0 18 add $0x18,%rax
400842: 48 89 45 f8 mov %rax,-0x8(%rbp)
*ret -= 0x48;
400846: 48 8b 45 f8 mov -0x8(%rbp),%rax
40084a: 8b 00 mov (%rax),%eax
40084c: 8d 50 b8 lea -0x48(%rax),%edx
40084f: 48 8b 45 f8 mov -0x8(%rbp),%rax
400853: 89 10 mov %edx,(%rax)
400855: c9 leaveq
400856: c3 retq
}
0000000000400857 <main>:
int main()
{
400857: 55 push %rbp
400858: 48 89 e5 mov %rsp,%rbp
test();
40085b: e8 d6 ff ff ff callq 400836 <_Z4testv>
return 0;
400860: b8 00 00 00 00 mov $0x0,%eax
400865: c9 leaveq
400866: c3 retq
}
(gdb) p $rsp
(gdb) p $rbp
$2 = (void *) 0x7fffffffe2a0
(gdb) p /x *(0x7fffffffe2a8)
$3 = 0x400860
緩沖區(qū)溢出攻擊在平時的網(wǎng)絡(luò)攻擊中能占到50%的比例,上面test函數(shù)可以輕易的讓計算機(jī)崩潰,也可以輕易的執(zhí)行任何病毒或者木馬程序。
現(xiàn)在來分析一下防范措施。首先當(dāng)然是作為程序員的我們需要注意的:寫數(shù)據(jù)時,特別警惕數(shù)據(jù)邊界,嚴(yán)防存在數(shù)據(jù)寫溢出的情況,類似于strcpy等函數(shù)不要使用或者小心使用。其次當(dāng)然是通過其他方式的防范,上面我也提到了,shellcode中有兩個值是需要計算的,第一個是函數(shù)返回值地址,這個比較容易分析出來,因為編譯器是有固定的入棧壓棧規(guī)則的;第二個是兩個函數(shù)之間的偏移地址,函數(shù)地址在編譯階段就已經(jīng)在代碼段固定下來了,偏移 只需要根據(jù)反匯編出的片段地址猜解出來(如果能完全反匯編出來,就不用猜了……)。這兩個值只要增加任何一個的計算難度,都可以有效減少這種漏洞的攻擊。目前Linux (包括各種修改版本,例如Android) 、FreeBSD、Windows 等主流操作系統(tǒng)都已采用 ASLR(Address space layout randomization)技術(shù)(iOS系統(tǒng)自iOS 4.3以后也支持了ASLR技術(shù) ),這種技術(shù)就是通過對堆、棧、共享庫映射等線性區(qū)布局的隨機(jī)化來達(dá)到增加猜解出函數(shù)偏移的目的。當(dāng)然這種技術(shù)僅僅是減少而非杜絕緩沖區(qū)溢出攻擊。
世界上沒有完美的程序,只有暫時想不到的bug by peakflys
posted on 2012-10-24 16:51 peakflys 閱讀(2541) 評論(2) 編輯 收藏 引用 所屬分類: C++ 、服務(wù)器

