缓冲区溢出如何用于利用计算机?
我理解程序存储器的某些部分是被覆盖的,但是我不知道这会导致一个人执行自己的代码.此外,第三方的恶意代码必须用目标处理器汇编语言编写吗?
我正在尝试执行一个非常简单的缓冲区溢出攻击.我几乎是新手.所以,如果这个问题很愚蠢,请原谅:-)
代码:
#include<stdio.h>
#include<stdlib.h>
int i, n;
void confused(int i)
{
printf("**Who called me? Why am I here?? *** %x\n ", i);
}
void shell_call(char *c)
{
printf(" ***Now calling \"%s\" shell command *** \n", c);
system(c);
}
void victim_func()
{
int a[4];
printf("Enter n: "); scanf("%d",&n);
printf("~~~~~~~~~~~~~ values and address of n locations ~~~~~~~~~~");
for (i = 0;i <n ;i++)
printf ("\n a[%d] = %x, address = %x", i, a[i], &a[i]);
printf("\nEnter %d HEX Values \n", n);
// Buffer …Run Code Online (Sandbox Code Playgroud) 我在Linux(amd64)上玩过缓冲区溢出并试图利用一个简单的程序,但它失败了.我禁用了安全功能(使用sysctl -w kernel.randomize_va_space = 0和bios中的nx位进行地址空间布局随机化).它跳转到堆栈并执行shellcode,但它不会启动shell.execve系统调用成功,但之后它就会终止.知道什么是错的吗?运行shellcode独立工作正常.
额外问题:为什么在调用printf之前需要将rax设置为零?(见代码中的评论)
易受攻击的文件缓冲区:
.data
.fmtsp:
.string "Stackpointer %p\n"
.fmtjump:
.string "Jump to %p\n"
.text
.global main
main:
push %rbp
mov %rsp, %rbp
sub $120, %rsp
# calling printf without setting rax
# to zero results in a segfault. why?
xor %rax, %rax
mov %rsp, %rsi
mov $.fmtsp, %rdi
call printf
mov %rsp, %rdi
call gets
xor %rax, %rax
mov $.fmtjump, %rdi
mov 8(%rbp), %rsi
call printf
xor %rax, %rax
leave
ret
Run Code Online (Sandbox Code Playgroud)
shellcode.s
.text
.global …Run Code Online (Sandbox Code Playgroud) 我试图在Mac OS X 10.6 64位上使用C编写一个简单的缓冲区溢出.这是概念:
void function() {
char buffer[64];
buffer[offset] += 7; // i'm not sure how large offset needs to be, or if
// 7 is correct.
}
int main() {
int x = 0;
function();
x += 1;
printf("%d\n", x); // the idea is to modify the return address so that
// the x += 1 expression is not executed and 0 gets
// printed
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是main的汇编程序转储的一部分:
...
0x0000000100000ebe <main+30>: callq 0x100000e30 <function>
0x0000000100000ec3 <main+35>: …Run Code Online (Sandbox Code Playgroud) 我应该想出一个利用"返回libc缓冲区溢出"的程序.执行时,它会干净地退出并显示SHELL提示符.该程序在bash终端中执行.以下是我的C代码:
#include <stdio.h>
int main(int argc, char*argv[]){
char buffer[7];
char buf[42];
int i = 0;
while(i < 28)
{
buf[i] = 'a';
i = i + 1;
}
*(int *)&buf[28] = 0x4c4ab0;
*(int *)&buf[32] = 0x4ba520;
*(int *)&buf[36] = 0xbfffff13;
strcpy(buffer, buf);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用gdb,我已经能够确定以下内容:
我也知道,使用gdb,在我的缓冲区变量中插入32"A"会覆盖返回地址.因此,假设系统调用是4个字节,我首先填充28字节的内存"泄漏".在第28个字节,我开始我的系统调用,然后退出调用,最后添加我的"/ bin/sh"内存位置.
但是,当我运行程序时,我得到以下内容:
sh: B???: command not found
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)
我真的不确定我做错了什么......
[编辑]:我能够通过导出环境变量获得字符串"/ bin/sh":
export MYSHELL="/bin/sh"
Run Code Online (Sandbox Code Playgroud) 我被要求维护一个充满内存泄漏的大型C++代码库.在探索时,我发现我们有很多缓冲区溢出导致泄漏(它如何变坏,我不想知道).
我决定先从危险函数开始删除缓冲区溢出.哪些C/C++函数最常使用不正确并可能导致缓冲区溢出?
对于用于帮助查找缓冲区溢出的编译器和/或工具,我创建了另一个处理此问题的问题
今天,我从Elance.com上做了一个简短的"C++技能测试".一个问题如下:
以下代码行的安全漏洞是什么:
printf("%s", argv[1]);选项1:格式字符串
选项2:堆栈溢出 < - 这被Elance标记为正确答案
在最初几秒钟看到问题后(或自动使问题无效),用户被提供10秒钟来回答此问题.(还有另外两个明显不相关的答案,没有被Elance标记为正确答案.)
我正在寻找缓冲区溢出或缓冲区溢出作为选项.
我本能地不喜欢答案堆栈溢出,因为在我10秒内我精神上使用了我认为是"Stack Overflow"的标准定义:
在软件中,当堆栈指针超出堆栈限制时,会发生堆栈溢出.调用堆栈可能包含有限数量的地址空间,通常在程序开始时确定...
根据"Stack Overflow"的定义,在没有堆栈溢出的情况下完全可以实现缓冲区溢出 ; 只有当程序试图在调用程序的总堆栈分配之外写入时才会发生堆栈溢出(无论是由于缓冲区溢出,还是由于它是否是合法写入,例如为基于堆栈的变量分配内存过多而次).
我的10秒本能告诉我,"缓冲区溢出"是对上面有问题的代码行的更准确的描述 - 因为通常(根据我的经验),有足够的空字符('\0')通过RAM中的垃圾数据来填充,以避免在这种情况下实际的堆栈溢出,但实现中的缓冲区溢出似乎是合理可能的,甚至可能.(但是,这可能printf在这里读的垃圾可能会认为argc == 1,这样有是没有用户提供的argv[1];如果argv[1]存在,或许可以假设很可能是调用函数还没有插入NULL的这不是在问题陈述是否.argv[1]为当下.)
因为我想象这里可能存在缓冲区溢出问题,即使没有堆栈溢出,我回答了格式字符串,因为简单地通过传递不同的格式字符串"%.8s",问题可以大部分避免,所以它看起来像一个整体更通用,因此更好,回答.
我的回答被标记为错误.正确答案标记为"Stack Overflow".
现在我想到,如果假设argv[1]存在,那么唯一可能的缓冲区溢出是堆栈溢出,在这种情况下,堆栈溢出实际上可能是正确的答案.但是,即使在这种情况下,将这称为堆栈溢出也不会被认为是奇怪的吗?缓冲区溢出是否是描述此问题的更好方法,即使假设argv[1]存在?而且,如果argv[1]是不存在的,是不是非常不正确地指出,问题是 …
我对那些sscanf糟糕的建议有着模糊的回忆.我知道如果我使用字段宽度说明符,它不会溢出缓冲区,所以我的记忆只是在玩弄技巧吗?
对于这个问题的标题,我事先表示歉意,但是似乎没有比这更好的了。
这里的想法是argv在另一个变量中复制,本质上是复制它。因此,函数功能的基本思想是,malloc()用于为副本请求一些空间,然后遍历argv每个元素的副本进行迭代。
这是我正在使用的代码,开发环境现在是Visual Studio 2019(即使严格来讲不是C编译器...):
// Returns a copy of an array of strings (intended for argv, but should work with any of them):
wchar_t** copyArgv(size_t argc, wchar_t* argv[]) {
// Allocate space for the array of arguments:
wchar_t** argsCopy = malloc(((argc + 1) * sizeof(wchar_t*)));
if (!argsCopy)
return NULL;
// Copy each one of them:
for (size_t i = 0; i < argc; i++) {
argsCopy[i] = _wcsdup(argv[i]);
if (!argsCopy[i]) {
// Should …Run Code Online (Sandbox Code Playgroud) 编辑:请求完整的源代码.下面是一个准系统实现,以便复制该错误.删除内容枚举,但无论如何崩溃都会在第一个对象调用上发生.在这种情况下,WPD_DEVICE_OBJECT_ID对象.
链接到CPP(Bug从第103行开始)
链接到QMAKE.PRO(我正在使用Qt)
在我的项目中,我使用WPD API来读取移动设备的内容.我遵循API到tee并成功实现了内容枚举.
但是,如果连接了USB驱动器,WPD API有时也会将其检测为设备.无论如何,我的程序将继续进行内容枚举.我不希望这样.我只想枚举移动设备.
问题是在内容枚举期间,当我的程序试图检索USB驱动器上的对象的属性时,它会崩溃.以下是崩溃详情:
Problem Event Name: BEX
Application Name: UniversalMC.exe
Application Version: 0.0.0.0
Application Timestamp: 5906a8a3
Fault Module Name: MSVCR100.dll
Fault Module Version: 10.0.40219.325
Fault Module Timestamp: 4df2be1e
Exception Offset: 0008af3e
Exception Code: c0000417
Exception Data: 00000000
OS Version: 6.1.7601.2.1.0.768.3
Locale ID: 1033
Additional Information 1: 185e
Additional Information 2: 185ef2beb7eb77a8e39d1dada57d0d11
Additional Information 3: a852
Additional Information 4: a85222a7fc0721be22726bd2ca6bc946
Run Code Online (Sandbox Code Playgroud)
此次调用发生崩溃:
hr = pObjectProperties->GetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, &objectName);
Run Code Online (Sandbox Code Playgroud)
hr 返回FAILED然后我的程序崩溃.
经过一些研究,我发现异常代码c0000417意味着发生了缓冲区溢出?如果我错了,请纠正我,但这是WPD …