[英]Is there a buffer overflow helloworld for c++?
我嘗試了這個問題提供的代碼,但它不起作用。
怎么設計溢出來包裹我的頭?
更新:
.file "hw.cpp"
.section .rdata,"dr"
LC0:
.ascii "Oh shit really bad~!\15\12\0"
.text
.align 2
.globl __Z3badv
.def __Z3badv; .scl 2; .type 32; .endef
__Z3badv:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl $LC0, (%esp)
call _printf
leave
ret
.section .rdata,"dr"
LC1:
.ascii "WOW\0"
.text
.align 2
.globl __Z3foov
.def __Z3foov; .scl 2; .type 32; .endef
__Z3foov:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl LC1, %eax
movl %eax, -4(%ebp)
movl $__Z3badv, 4(%ebp)
leave
ret
.def ___main; .scl 2; .type 32; .endef
.align 2
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
call __alloca
call ___main
call __Z3foov
movl $0, %eax
leave
ret
.def _printf; .scl 2; .type 32; .endef
您可以使用您發布的C示例。 它在C和C ++中的工作方式相同。
我能想到的最小可讀答案:
int main() {
return ""[1]; // Undefined behaviour (reading past '\0' in string)
}
將其他問題中的示例編譯為匯編將有助於您了解堆棧如何為給定的編譯器和處理器布局。 示例中的+8
可能不是您環境的正確數字。 您需要確定的是返回地址相對於存儲在堆棧中的數組存儲在堆棧中的位置。
順便說一下,這個例子對我有用。 我用Wing編譯了Cygwin,gcc版本4.3.4。 當我說它“有效”時,我的意思是它在bad()
函數中運行代碼,即使該函數從未被代碼調用過。
$ gcc -Wall -Wextra buffer-overflow.c && ./a.exe
Oh shit really bad~!
Segmentation fault (core dumped)
代碼實際上不是緩沖區溢出的示例,它是利用緩沖區溢出時可能發生的壞事的一個示例。
我對x86程序集不是很了解,但這是我對這個漏洞利用程序的解釋。
$ gcc -S buffer-overflow.c && cat buffer-overflow.s
_foo:
pushl %ebp ;2
movl %esp, %ebp ;3
subl $16, %esp ;4
movl LC1, %eax ;5
movl %eax, -4(%ebp) ;6
leal -4(%ebp), %eax ;7
leal 8(%eax), %edx ;8
movl $_bad, %eax ;9
movl %eax, (%edx) ;10
leave
ret
_main:
...
call _foo ;1
...
當main
調用foo
(1)時, call
指令將main中的地址推送到堆棧,以便在對foo
的調用完成后返回。 推入堆棧涉及減少ESP並在那里存儲值。
一旦進入foo
,舊的基指針值也被推入堆棧(2)。 當foo
返回時,這將被恢復。 堆棧指針被保存為該堆棧幀的基指針(3)。 堆棧指針遞減16(4),這會在此堆棧幀上為局部變量創建空間。
文字“WOW \\ 0”的地址被復制到堆棧上的局部變量overme
(5,6) - 這對我來說似乎很奇怪,難道不應該將4個字符復制到堆棧中分配的空間嗎? 無論如何,復制WOW(或指向它的指針)的位置是當前基指針下方4個字節。 所以堆棧包含這個值,然后是舊的基指針,然后是返回地址。
overme
的地址被放入EAX(7)中,並且在該地址(8)之外的8個字節處創建一個整數指針。 將bad
函數的地址放入EAX(9)中,然后將該地址存儲在由整數指針(10)指向的存儲器中。
堆棧看起來像這樣:
// 4 bytes on each row
ESP: (unused)
: (unused)
: (unused)
: &"WOW\0"
: old EBP from main
: return PC, overwritten with &bad
當你使用優化進行編譯時,所有有趣的東西都會被優化為“無用的代碼”(就是這樣)。
$ gcc -S -O2 buffer-overflow.c && cat buffer-overflow.s
_foo:
pushl %ebp
movl %esp, %ebp
popl %ebp
ret
像這樣的東西?
int main()
{
char arr[1];
arr[1000000] = 'a';
}
一個簡單的緩沖區溢出將是這樣的:
#include <stdio.h>
#include <string.h>
int main() {
char a[4] = {0};
char b[32] = {0};
printf("before: b == \"%s\"\n", b);
strcpy(a, "Putting too many characters in array a");
printf("after: b == \"%s\"\n", b);
}
可能的輸出:
before: b == "" after: b == " characters in array a"
程序的實際行為是未定義的 ,因此緩沖區溢出也可能導致不同的輸出,崩潰或根本沒有可觀察到的影響。
#define _WIN32_WINNT 0x0400
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
void process_msg(const char *pSrc)
{
char cBuff[5];
strcpy(cBuff, pSrc);
}
void main()
{
char szInput[] = "hello world!";
process_msg(szInput);
}
在調試模式下在Visual Studio 2008上運行此程序會顯示以下消息:
Run-Time Check Failure #2 - Stack around the variable 'cBuff' was corrupted.
在這個例子中,'cBuff'char數組被分配在堆棧上,它的大小為5個字節。 將給定指針的數據(pSrc)復制到該charrat(cBuff)會覆蓋堆棧幀的數據,這將導致可能的漏洞利用。
黑客使用這種技術 - 它們發送一個特制的字符數組,它將覆蓋堆棧上指向“返回”地址的指針,並將其更改為它們在內存中的所需位置。
因此,例如,他們可以將“返回”地址指向將打開端口或建立連接的任何系統/程序代碼,然后他們使用應用程序的權限(多次這意味着root / administrator)到達您的PC 。
以下文章更多地關注堆溢出:
這是從我的答案抄在這里 。
術語緩沖區溢出精確地意味着訪問緩沖區的末尾(也需要包括緩沖區下溢的想法)。 但是有一整類“內存安全問題”與緩沖區溢出,指針,數組,分配和釋放有關,所有這些都會在代碼中產生崩潰和/或利用機會。 請參閱此C另一個內存安全問題的示例(以及我們檢測它的方法)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.