Mac OS X x64 環境下覆蓋objective-c類結構並透過objc_msgSend獲得RIP執行shellcode

wyzsk發表於2020-08-19
作者: vvun91e0n · 2015/06/05 9:56

author vvun91e0n

0x00 前言


閱讀學習國外nemo大牛《Modern Objective-C Exploitation Techniques》文章的內容,就想在最新的OS X版本上除錯出作者給出的程式碼。控制rip。我根據自己的除錯,修改了原程式,才除錯成功。對大牛原程式的部分程式碼的意圖和計算方法難免理解不足,歡迎留言與我交流學習。本文主要簡要介紹下對objective-c類的覆蓋到控制rip的技術。是目前OS X平臺下,比較主流的一種溢位利用方式。

0x01 64位彙編知識及lldb簡單除錯命令


彙編知識主要是在除錯的時候使用,在64位平臺下除錯必不可少的知識。對此熟悉的讀者可直接跳過。下面簡要介紹下64位彙編。

RIP的就是64位的指令暫存器。

通用64位暫存器

RAX RBX RCX RDX RBP RSI RDI RSP

R8 --- R15

可以使用

  • EAX 訪問RAX的低32bits
  • AX 訪問RAX的低16bits
  • AL 訪問RAX的低8bist
  • AH 訪問RAX低16bits的高8bits

OS X 64位的彙編呼叫約定,可以參考AMD64 Application Binary Interface

x86-64 Function Calling convention:

  1. If the class is MEMORY, pass the argument on the stack.

  2. If the class is INTEGER, the next available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9 is used.

可以看到和32位彙編的透過push壓棧來傳遞引數不同,函式的引數傳遞基本是透過暫存器來完成的。順序如上。 32位彙編透過int 0x80來進行系統呼叫,64位彙編是透過syscall來呼叫的。

lldb是蘋果公司推出的用以替代gdb的偵錯程式。隨xcode一起安裝。是進行動態除錯的利器。除錯時必不可少。下面簡要介紹下會用到的一些基礎命令:

在命令列輸入lldb,就會進入除錯工具

(lldb)

help會顯示所有的命令,需要詳細瞭解可以用輸入help + 命令查詢

file命令載入需要除錯的程式

(lldb) file /Users/vvun91e0n/Desktop/OC64exploit
Current executable set to '/Users/vvun91e0n/Desktop/OC64exploit' (x86_64).

breakpoint set用來設定斷點

(lldb) breakpoint set --name length

breakpoint list可以用來檢視所有斷點 breakpoint disable 關閉斷點 breakpoint enable 啟用斷點 ni 單步步不執行指令

run或r啟動程式進行除錯

register read 讀取現在所有暫存器的值 想讀取特定的幾個暫存器,寫在後面就行,使用簡化命令如

(lldb) re r rdi r10 rsi
 rdi = 0x0000000100202fa0
 r10 = 0x0000000000000001
 rsi = 0x00007fff907bb509

memory read 可以讀取指定地址的記憶體資料,如下指定地址就是length字串。也可以使用gdb風格的x 0x00007fff907bb509命令來讀取記憶體資料。

(lldb) memory read 0x00007fff907bb509
0x7fff907bb509: 6c 65 6e 67 74 68 00 69 73 54 79 70 65 4e 6f 74  length.isTypeNot
0x7fff907bb519: 45 78 63 6c 75 73 69 76 65 3a 00 61 70 70 65 6e  Exclusive:.appen
(lldb) x 0x00007fff907bb509
0x7fff907bb509: 6c 65 6e 67 74 68 00 69 73 54 79 70 65 4e 6f 74  length.isTypeNot
0x7fff907bb519: 45 78 63 6c 75 73 69 76 65 3a 00 61 70 70 65 6e  Exclusive:.appen

continue 或者c 命令來繼續執行。 kill來結束程式。run來重新啟動。 其他如條件斷點,修改暫存器值等命令讀者可以使用help命令瞭解。

0x02 objective-c方法呼叫


你需要對objective-c語言有一定的基本的瞭解。特別是objc_msgSend函式的呼叫機制。可以參考:《The Objective-C Runtime: Understanding and Abusing》。這篇文章是nemo2009年發表在phrack上的。在32位系統基礎上講Objective-C Runtime溢位的文章。還是有閱讀價值的。特別是對後面64位溢位的理解。

下面簡要介紹下objective-c,先看看一個簡單的類實現和呼叫:

#!c
//  Talker.h
#import <Foundation/Foundation.h>
@interface Talker : NSObject        //定義一個類
- (void) say: (char *) str;         //宣告一個say方法
@end

//  Talker.m
#import "Talker.h"
@implementation Talker              //類的相關方法實現
- (void) say: (char *) phrase
{
    printf("%s\n",phrase);
}
@end

//main.m
#import "Talker.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        Talker *talker = [[Talker alloc] init];//分配記憶體,初始化
        [talker say: "Hello, World!"];          //呼叫say方法
    }
    return 0;
}

如上面程式碼所示,定義了一個Talker類,並在main函式中呼叫了say方法。 可以看出objective-c語言的方法呼叫語法為

[\

相關文章