看板 C_and_CPP 關於我們 聯絡資訊
抱歉我是原PO 改了個標題 因為我上網找了一些嵌入shellcode的資料感覺很奇怪 我不太了解為什麼可以用一堆輸入去塞爆buffer和stack 就可以讓程式去執行shellcode 假如是用shellcode去改變pointer還可以理解 但是只用輸入一堆machine code去讓buffer overflow的話 不是應該會造成程式錯誤嗎?? 還是說如果把存reeturn address 的記憶體位址蓋掉 就可以讓程式去執行放進buffer & stack 裡面的machine code ======================================================================= #include <stdio.h> #include <stdlib.h> #include <unistd.h> //BEGIN:A program to illustrate buffer overflow //vulnerability void func(char *str) { char buffer[24]; int *ret; strcpy(buffer,str); } int main(int argc, char **argv) { int x; x = 0; func(argv[1]); x = 1; printf("x is 1\n"); printf("x is 0\n"); } //END 這支是用來CALL上面的程式 #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { char shellcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"; //如果放進夠長的machine code 是否就可以讓程式去執行呢?? execl("./vuln.exe", "test",shellcode,"test",NULL); return 0; } 我現在的想法是 我在shellcode裡面放進一些code例如可以修改return address或是jmp之類的code 之後用NOP去把buffer 和 stack灌爆 不過我剛剛測試了一下 即使塞一大堆的NOP在buffer裡面,似乎沒有影響到stack上的情況 我是想說如果用NOP把stack上面的東西都蓋掉 -----------------------------------------> ---------------------------------------- jmp NOP NOP NOP NOP NOP NOP NOP ---------------------------------------- 因為stack上的東西不見了 所以他就順著NOP執行回去 但是NOP沒做事情 所以就一路碰到jmp -----------------------------------------> ---------------------------------------- jmp NOP NOP NOP NOP NOP NOP NOP ---------------------------------------- 是不是就能達到利用buffer overflow去修改return address的值呢? 麻煩大家給我一點意見 謝謝 ================================================================== 我剛剛查了一下NOP是不是不佔空間只會消耗CPU的CLOCK 謝謝大家 -- 我不是宅 我只是比較居家 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 128.238.252.164
loveflames:NOP只有在buffer裡? 12/16 02:46
loveflames:你要做的是把func的ret addr改成buffer位址 12/16 02:50
loveflames:然後在buffer裡的shellcode的最後放jmp回main的指令 12/16 02:51
loveflames:shellcode可能會需要在一開始補上操作stack的指令 12/16 02:52
loveflames:以前在測試插入hello world的時候,印象中需要補上 12/16 02:53
我比較好奇的是 如果放進buffer的東西太多造成overflow 應該有可能會蓋到func的reture address 這樣不會造成程式中止嗎?? 我現在用程式去call vuln.exe 然後送shellcode去buffer裡面 我還是不知道為什麼系統會去執行buffer裡面的值 除非我們能用input 的 shellcode把pointer指到我們放shellcode的地方?? 感覺一整個很模糊 感覺不出為什麼可以讓程式去執行buffer裡面的shellcode 可以在跟我說一下嗎 拜託你了 謝謝 ※ 編輯: rock1985 來自: 128.238.252.164 (12/16 05:24)
loveflames:"為什麼可以讓程式去執行buffer裡面的shellcode" 12/16 05:53
loveflames:因為函數最後的ret指令,會自動把eip設成ret addr 12/16 05:54
loveflames:蓋到func的ret addr不會造成程式中止 除非該位址不合法 12/16 05:56
loveflames:不過那也是執行ret之後的事,在func裡不會當掉 12/16 05:57
所以假如stack的狀態是 | | | | | | |ret addr| ----- | | | | | | | | | | | | | | | | | | | | 44 byte | | (我做第一題 | | 的時候buffer和ret addr的距離) | | | | | | | | | | | | | | | buffer | ----- | | | | | | 如果我的shellcode剛好大概44byte 蓋掉 ret address | | | | | | | new ret| ----- | shell | | | shell | | | shell | | shell | | shell | | shell | | shell | | shell | | shell | 44 byte | shell | (我做第一題 | shell | 的時候buffer和ret addr的距離) | shell | | shell | | shell | | shell | | shell | | | shell | | | buffer | ----- | | 這樣是不是就可以改變return的位址 假設就讓他跳到shellocode裡面的某一行?? 我測試的時候有試過放進去很長的NOP 不過好像沒有影響 不會蓋到ret addr 這是因為放進去的是NOP嗎? 假如shellcode過長 應該有會導致出錯囉? 非常的感謝你 ※ 編輯: rock1985 來自: 108.6.66.40 (12/16 10:33)
loveflames:放NOP時的stack內容讓我看一下吧 12/16 10:44
我好像成功用NOP把buffer 塞到爆開了 stack的內容 3f3f3f3f3f3f3f3f 3f3f3f3f3f3f3f3f 3f3f3f3f3f3f3f3f 3f3f3f3f3f3f3f3f 3f3f3f3f3f3f3f3f 3f3f3f3f3f3f3f3f 3f3f3f3f3f3f3f3f 3f3f3f3f3f3f3f3f 3f3f3f3f3f3f3f3f 3f3f3f3f3f3f3f3f ffffff003635343f 75e48cd50028ff58 fffffffebe8b5dfc 75e315a075e3161e 06118d800000000 7efde00075e32811 04011480028ff88 000000000000001 000000000000000 000000000000000 測試程式 vuln.c #include <stdio.h> #include <stdlib.h> //BEGIN:A program to illustrate buffer overflow //vulnerability void func(char *str) { char buffer[24]; int *ret; long long int *seek_ptr = (long long int *)(buffer+24); strcpy(buffer,str); //puts(buffer); int i; printf("%d %d\n",sizeof(ret),sizeof(seek_ptr)); for(i=0;i<20;i++) { printf("%015llx\n", *seek_ptr); seek_ptr++; } } int main(int argc, char **argv) { int x; x = 0; func(argv[1]); //func("12345678987654321"); //func("12345678987654321"); x = 1; printf("x is 1\n"); printf("x is 0\n"); } //END main.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { char shellcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"; execl("./vuln.exe", "123",shellcode,"456",NULL); return 0; } 所以我現在是必須讓shellcode剛好蓋到ret addr的地方 改變ret addr的值 shellcode裡面則是可能要有某些運算 例如讓新的ret addr指到shellcode的某一行 那一行可能是一個jmp指令 可以跳到x is 0那一行 是這個意思嗎?? 感覺要非常熟悉機器碼和記憶體的狀態 才有辦法修改的樣子 ※ 編輯: rock1985 來自: 108.6.66.40 (12/16 12:10)
rock1985:結果好怪 我今天測試的時候就沒有把stack 塞爆 12/17 13:37
rock1985:越來越搞不懂要怎麼做了 = =a 12/17 13:38