天天看點

PLT , GOT 介紹及簡單 GOT 攻擊實驗

轉載修改自 http://blog.sina.com.cn/s/blog_70dd16910100r1gi.html

第一部分 過程連接配接表PLT

由于程式可以用共享庫的方式多次使用同一個函數,是以通過一張表來定義所有的函數是非常有用的。為了能利用這種手段,在編譯程式會使用一個專用區域,這個區域稱為“過程連接配接表(PLT)”。

PLT有許多調轉指令構成,每一個指令對應一個函數位址的指針。PLT猶如一個跳闆,每次需要調用某個函數時,控制權将由PLT傳遞。

例如下面的程式:

//got_vul.c
#include <stdio.h>
#include <string.h>

int bof(char *str)
{
char buffer[];
//The following statement has a buffer overflow problem
strncpy(buffer, str, sizeof(buffer)-);
printf(buffer);
   exit();
}


int main(int argc, char **argv)
{
   bof(argv[]);
   return ;
}
           

我們利用下面的指令把它編譯成SetUID root程式:

#gcc -fno-stack-protector got_vul.c -g -o got_vul
#chmod  got_vul
           

通過

$objdump –d –j .plt ./got_vul

我們可以檢視PLT的具體内容如下:

PLT , GOT 介紹及簡單 GOT 攻擊實驗

上面的這些指令中,我辨別的位址就是exit函數入口位址的指針。

看到這裡,我們自然就會有一種想法:

如果退出函數使用的調轉指令指向我們的shellcode,那麼我們就可以制造root shell漏洞了。

但是不幸的是,正如下圖所示PLT是隻讀的;

是以無法改變它的轉移指針。

PLT , GOT 介紹及簡單 GOT 攻擊實驗

但是上述調轉指針并不是直接指向某一指令,而是指向存放這個指令的記憶體區域首位址。

例如0x804a010指針指向存放exit函數所在的記憶體區域。更重要的是這個區域是可寫的,這一區域就是下面所說的全局轉移表GOT。

第二部分 全局轉移表(GOT)

正如上面所讨論的那樣,PLT中轉移函數的入口位址的指針存放在PLT表中(是隻讀的),但是這些函數的入口位址卻是存放在另一個可寫區域,我們把這個區域稱為全局轉移表(GOT)。

利用objdump –R ./got_vul我們可以檢視這些函數的轉移位址如下:

PLT , GOT 介紹及簡單 GOT 攻擊實驗

我們的想法:

把shellcode的位址放到環境變量中,并預知其實際位址。如果我們能在GOT表中用Shellcode的位址重0x0804a010所指向的區域,那麼當程式認為正在調用exit函數時,實際上卻是在調用我們的shellcode。

第三部分 攻擊 GOT

我們的攻擊過程如下:

  • 第一步:關閉記憶體位址随機化機制

    sudo sysctl -w kernel.randomize_va_space

  • 第二步:編譯got_vul.c為set-UID root程式,編譯時加上編譯選項-fno-protector
  • 第三步:在環境變量中存放shellcode
  • 第四步:利用下面函數編譯的程式擷取Shellcode 位址
//getenvaaddr.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
       char *ptr;
       if(argc < )
       {
              printf("Usage:%s<environment var> <target program name>\n",argv[]);
              exit();
       }
       ptr = getenv(argv[]);   
       ptr += (strlen(argv[]) - strlen(argv[])) * ;
//argv[0]:正在執行的程式名稱,本程式中:getenvaaddr
//argv[2]:即将執行的漏洞程式的名稱(包括路徑),本程式中:./got_vul
//Linux ubuntu 系統中已經驗證兩者名稱差一個字元,就會有兩個位元組的位址偏移
       printf("%s will be at %p\n", argv[], ptr);
       return ;
}
           
  • 第五步:改寫GOT并進行攻擊

    擷取位址

    PLT , GOT 介紹及簡單 GOT 攻擊實驗
    進行攻擊
    PLT , GOT 介紹及簡單 GOT 攻擊實驗

參考文獻:

Hacking: Chapter 0x300.EXPLOITATION.The Art of Exploitation, 2nd Edition ,by Jon Erickson.

繼續閱讀