- C和C++安全編碼(原書第2版)
- (美)Robert C.Seacord
- 784字
- 2020-10-30 17:56:41
2.3.9 返回導向編程
返回導向編程攻擊技術(shù)與弧注入是類似的,但漏洞利用代碼不是返回函數(shù),而是返回跟在return指令后的指令序列。任何這樣的可使用的指令序列都稱為小工具(gadget)。對于x86架構(gòu),一個小工具的圖靈完備集合已可以允許用返回導向語言編寫任意程序。圖靈完備的代碼庫小工具使用Solaris的libc片段,為構(gòu)建返回導向漏洞的通用的編程語言和編譯器也已經(jīng)被開發(fā)出來[Buchanan 2008]。因此,存在一個假設(shè)的返回導向編程漏洞的風險,對其他架構(gòu)也可能是有效的。
返回導向編程語言,由一組小工具組成。每個小工具指定要放置在棧中的某些值,供代碼段中的一個或多個指令序列使用。小工具執(zhí)行良好定義的操作,如裝載、加法或跳轉(zhuǎn)。
返回導向編程由執(zhí)行所需操作的小工具共同組成。小工具由return指令與棧指針所指的小工具地址來執(zhí)行。
例如,指令序列
pop %ebx; ret
形成一個小工具,它可以用于加載一個常數(shù)到ebx寄存器,如圖2.16所示。
圖2.16 用返回導向編程構(gòu)建的小工具
圖2.16的左邊顯示把常量$0xdeadbeef復制到ebx寄存器所需的x86-32匯編語言的指令,并在右側(cè)顯示了等效的小工具。使用指向小工具的棧指針,CPU執(zhí)行返回指令。由此導致小工具從棧中彈出該常數(shù),并返回執(zhí)行棧上的下一個小工具。
返回導向編程也支持有條件的和無條件的分支。在返回導向編程中,棧指針代替指令指針來控制執(zhí)行流。一個無條件跳轉(zhuǎn)需要簡單地改變棧指針的值以指向一個新的小工具。這很容易使用如下指令序列來完成:
pop %esp; ret
圖2.17對無條件分支的x86-32位匯編語言編程和返回導向編程的慣用語法進行了對比。
圖2.17 無條件分支在x86-32位匯編語言(左)和返回導向編程的慣用語法
無條件分支可以用于棧上的一個較早的小工具,從而產(chǎn)生一個無限循環(huán)。有條件的迭代可以由一個條件分支跳出循環(huán)實現(xiàn)。
Hovav Shacham發(fā)表的“The Geometry of Innocent Flesh on the Bone”[Shacham 2007]包含返回導向編程的一個更完整的教程。雖然返回導向編程可能看起來很復雜,但這種復雜性可以被編程語言和編譯器抽象和隱藏,使得它成為一種可行的編寫利用代碼的技術(shù)。
- Learning Cython Programming(Second Edition)
- Dependency Injection in .NET Core 2.0
- Learning SQLite for iOS
- INSTANT CakePHP Starter
- Hands-On Enterprise Automation with Python.
- Working with Odoo
- 常用工具軟件立體化教程(微課版)
- Python從入門到精通(第3版)
- RocketMQ實戰(zhàn)與原理解析
- Mastering OAuth 2.0
- 用Python動手學統(tǒng)計學
- 從零開始學Unity游戲開發(fā):場景+角色+腳本+交互+體驗+效果+發(fā)布
- Learning ROS for Robotics Programming
- C#程序設(shè)計基礎(chǔ)與實踐
- TypeScript High Performance