- C和C++安全編碼(原書第2版)
- (美)Robert C.Seacord
- 1039字
- 2020-10-30 17:56:49
3.5 全局偏移表
Windows和Linux在庫函數(shù)的鏈接和控制轉(zhuǎn)移方面使用了類似的機制。從安全的角度來看,二者主要的區(qū)別在于Linux使用的方法是可被利用的,而Windows則不然。
Linux、Solaris2.x和SVR4使用的默認(rèn)二進制格式稱為可執(zhí)行和鏈接格式(Executable and Linking Format,ELF)。ELF最初由UNIX系統(tǒng)實驗室(UNIX System Laboratories,USL)作為二進制應(yīng)用程序接口(Application Binary Interface,ABI)的一個部分開發(fā)并發(fā)布。近來,工具接口標(biāo)準(zhǔn)(Tool Interface Standards,TIS) [1]委員會采納了ELF標(biāo)準(zhǔn),將其作為多種x86-32操作系統(tǒng)上的可移植目標(biāo)文件格式。
任何ELF的二進制文件的進程空間中,都包含一個稱為全局偏移表(Global Offset Table,GOT)的區(qū)。GOT存放絕對地址,從而使得地址可用,并且不會影響位置獨立性和程序代碼的可共享性。要使得動態(tài)鏈接的進程能夠工作,這個表是必不可少的。該表的實際內(nèi)容和形式取決于處理器的型號[TIS 1995]。
程序使用的每一個庫函數(shù)在GOT中都擁有一個入口項,GOT中包含有實際函數(shù)的地址。這使得很容易在進程內(nèi)存中對庫函數(shù)進行重定位。在程序首次使用一個函數(shù)之前,該入口項包含有運行時鏈接器(RunTime Linker,RTL)的地址。如果該函數(shù)被程序調(diào)用,則程序的控制權(quán)被轉(zhuǎn)移到RTL,然后函數(shù)的實際地址被確定且被插入到GOT中。接下來就可以通過GOT中的入口項直接調(diào)用函數(shù),而跟RTL就無關(guān)了。
在ELF可執(zhí)行文件中GOT入口項的地址是固定的。這就導(dǎo)致對任何可執(zhí)行進程映像而言GOT入口項都位于相同的地址。如例3.6所示,可以利用objdump命令查看某一個函數(shù)的GOT入口項的位置。為每一個R_386_JUMP_SLOT重定位記錄指定的偏移量,包含了指定函數(shù)(或RTL鏈接函數(shù))的地址。
例3.6 全局偏移表
% objdump --dynamic-reloc test-prog format: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 08049bc0 R_386_GLOB_DAT __gmon_start__ 08049ba8 R_386_JUMP_SLOT __libc_start_main 08049bac R_386_JUMP_SLOT strcat 08049bb0 R_386_JUMP_SLOT printf 08049bb4 R_386_JUMP_SLOT exit 08049bb8 R_386_JUMP_SLOT sprintf 08049bbc R_386_JUMP_SLOT strcpy
攻擊者可以利用任意內(nèi)存寫將一個函數(shù)的GOT入口項覆寫為外殼代碼的地址。這樣,當(dāng)程序調(diào)用對應(yīng)于被改寫的GOT入口項的函數(shù)時,程序的控制權(quán)就被轉(zhuǎn)移到外殼代碼。例如,每一個編寫良好的C程序最后都會調(diào)用exit()函數(shù),因此,只要覆寫了exit()的GOT入口項,就可以在exit()被調(diào)用時將程序的控制權(quán)轉(zhuǎn)移到指定的地址。ELF過程鏈接表(Procedure Linkage Table,PLT)具有類似的問題[Cesare 2000]。
Windows PE(Portable Executable,可移植的可執(zhí)行)文件格式扮演著與ELF格式相似的角色。PE文件中包含一個數(shù)據(jù)結(jié)構(gòu)數(shù)組,每一項對應(yīng)一個導(dǎo)入的DLL。每一項都包含有導(dǎo)入的DLL的名稱以及一個指向函數(shù)指針數(shù)組的指針(即導(dǎo)入地址表,Import Address Table,IAT)。每一個被導(dǎo)入的API在IAT中都有自己的保留槽,由Windows載入器為其填充導(dǎo)入函數(shù)的地址。一旦一個模塊被載入,IAT就保存了需要調(diào)用的導(dǎo)入函數(shù)的地址。IAT的入口項是寫保護的,因為它們在運行時無須修改。
- 工程軟件開發(fā)技術(shù)基礎(chǔ)
- PyTorch自動駕駛視覺感知算法實戰(zhàn)
- PostgreSQL Cookbook
- Web交互界面設(shè)計與制作(微課版)
- Practical Data Science Cookbook(Second Edition)
- 深入淺出DPDK
- 精通Python設(shè)計模式(第2版)
- Visual FoxPro程序設(shè)計習(xí)題集及實驗指導(dǎo)(第四版)
- 青少年信息學(xué)競賽
- Orleans:構(gòu)建高性能分布式Actor服務(wù)
- 軟件工程基礎(chǔ)與實訓(xùn)教程
- IBM Cognos TM1 Developer's Certification guide
- Java程序設(shè)計基礎(chǔ)(第6版)
- PyQt編程快速上手
- Web開發(fā)新體驗