标签: buffer-overflow

C - 为什么有人要将argv字符串复制到缓冲区?

我今天正在学习缓冲区溢出,我遇到了许多易受攻击的程序示例.令我好奇的是,如果有任何理由使用这样的程序参数:

int main(int argc, char *argv[])
{
    char argument_buffer[100];
    strcpy(argument_buffer, argv[1]);

    if(strcmp(argument_buffer, "testArg") == 0)
    {
        printf("Hello!\n");
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

而不是简单地:

int main(int argc, char *argv[])
{
    if(strcmp(argv[1], "testArg") == 0)
    {
        printf("Hello!\n");
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意我知道strcpy等等的缺点- 这只是一个例子.我的问题是 - 是否有任何真正的理由使用临时缓冲区来存储来自argv的参数?我假设没有,但我很好奇,为什么它出现在溢出的例子中,而在现实中它从未被使用过?也许是因为纯理论.

c buffer-overflow argv

5
推荐指数
1
解决办法
2166
查看次数

什么是堆栈随机化,它如何防止缓冲区溢出攻击?

我从一本书中读到,缓冲区溢出可能用作注入将攻击系统的漏洞利用代码的方式。和堆栈随机化是防范此类攻击的有效途径之一。

我不明白什么是堆栈随机化及其如何防止这些攻击?

stack buffer-overflow

5
推荐指数
1
解决办法
5784
查看次数

缓冲区溢出漏洞利用:函数 ret 上的段错误到堆栈代码

我试图利用测试程序中的缓冲区溢出来执行任意代码。我在 NetBSD 6 i386 上。这是C代码:

int checkPassword(char *password)
{
  char                  savePassword[64] = {0};
  char                  *logMessage;
  int                   isUser = 0;
  int                   isAdmin = 0;
  int                   i;

  if (!strcmp(password, userPassword))
    isUser = 1;
  strcpy(savePassword, password);  
  for (i = 0; password[i]; ++i)
    password[i] ^= xorKey;
  if (!strcmp(password, adminPassword))
    isAdmin = 1;
  if (!(isAdmin | isUser)) {
    /* ... */
  }
  return isAdmin ? ADMIN : isUser ? USER : NOBODY; /* main.c:79 */
}
Run Code Online (Sandbox Code Playgroud)

我将代码插入savePassword缓冲区 (at %ebp - 0x58)。下面是 GDB …

c exploit buffer-overflow segmentation-fault netbsd

5
推荐指数
1
解决办法
1956
查看次数

可寻址存储器以及与缓冲区溢出的关系

阅读缓冲区溢出,我遇到了下面给出的示例代码: -

void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
}

void main() {
 function(1,2,3);
}
Run Code Online (Sandbox Code Playgroud)

这是来自着名的粉碎堆栈的乐趣和利润文章我猜.(参考:http://insecure.org/stf/smashstack.html)

文章说,要为buffer1和buffer2分配空间,需要20个字节(缓冲区1为8个字节,缓冲区2为12个字节),因为只能以字大小的倍数访问存储器地址(在这种情况下,1个字= 4个字节).

但我记得内存是字节可寻址的,即我可以从内存中一次访问1个字节.我将此与处理器的位数相关联.例如,32位处理器可以访问2 ^ 32个存储器位置,并且由于1个存储器位置保持1个字节(8位),因此32位处理器的总可寻址存储器等于(2 ^ 32)/(1024*1024*1024)= 4096 MB = 4GB.

因为在上面的例子中,buffer1和buffer2都是char类型,假设需要1个字节,为什么我们不能分别为buffer1和buffer2分配5个字节和10个字节?

为什么内存访问限制为字大小的倍数?

c memory-management buffer-overflow

5
推荐指数
1
解决办法
191
查看次数

计算 NOP 雪橇中的地址

我目前正在阅读计算机系统简介:程序员的视角(http://www.amazon.com/Computer-Systems-Programmers-Perspective-2nd/dp/0136108040/ref=sr_1_2?s=books&ie=UTF8&qid=1421029641&sr=1 -2&keywords=introduction+to+computer+systems)并尝试了解阻止缓冲区溢出的方法。

我理解为什么在使用地址随机化时我们需要 NOP 雪橇以及如何编写漏洞利用程序,但我很难理解书中给出的与 NOP 雪橇相关的地址计算。我在这里引用它:-

(假设程序在堆栈上的起始地址范围在32位系统上为2^23,在64位系统上为2^32)

“如果我们设置一个 256 字节的 NOP sled,那么可以通过枚举 2^15 个起始地址来破解 n=2^23 上的随机化,这对于坚定的攻击者来说是完全可行的。对于 64 位情况,尝试枚举 2^ 24个地址更令人畏惧。”

作者是如何分别为 32 位和 64 位情况得出数字 2^15 和 2^24 的?一个解释真的很有帮助。

buffer-overflow aslr no-op

5
推荐指数
1
解决办法
3462
查看次数

在缓冲区溢出时自动截断和空终止字符串缓冲区

我有以下代码,它可以从指定父窗口的所有子窗口加载文本。它工作正常,但有时,有一些父窗口(例如打开的带有很长 C++ 源文件的记事本)具有大量文本并导致缓冲区溢出。

BOOL CALLBACK EnumChildProc(__in HWND hWnd, __in LPARAM lParam) {

    LRESULT TEXT_LENGTH = NULL;
    WCHAR szText[32767];
    LPWSTR szWindowText;
    UINT nBuffer = NULL, nText = NULL;

    szWindowText = reinterpret_cast<LPWSTR>(lParam); szText[0] = L'\0';
    nBuffer = (UINT)wcslen(szWindowText);
    TEXT_LENGTH = SendMessage(hWnd, WM_GETTEXTLENGTH, NULL, NULL);

    if (TEXT_LENGTH > NULL)
    {
        SendMessage(hWnd, WM_GETTEXT, (WPARAM)32767, reinterpret_cast<LPARAM>(&szText));
        szText[TEXT_LENGTH] = L'\n'; szText[TEXT_LENGTH + 1] = L'\0';

        while ((nBuffer < 32766) && (szText[nText] != L'\0'))
        { szWindowText[nBuffer++] = szText[nText++]; }

        szWindowText[nBuffer] = L'\0';
    }
    return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

该行 …

c++ winapi truncate buffer-overflow

5
推荐指数
1
解决办法
334
查看次数

为什么我的缓冲区溢出漏洞利用只会打开用户外壳而不是根外壳?

我一直在关注一些有关缓冲区溢出利用的教程。但是我的问题是,我无法打开根外壳程序,而是总会得到一个普通的用户外壳程序。我检查了以下几点

我重新验证了以下各项,但仍然无法实现实际的root shell:

  • 我将二进制文件的所有者正确设置为root,还设置了s标志(检查)
  • 我已验证我使用的漏洞利用程序是否正常工作,使用了正确的system @ plt和exit @ plt地址,并且这些值已通过pop rdi; ret;正确加载到rdi中。段; 我毕竟得到了一个shell,但是没有得到预期的根shell;(校验)
  • 我听说如今破折号和bash确实放弃了特权,将/ bin / sh链接到/ bin / zsh会有所帮助,但这并没有帮助我;仍然获得非root shell(检查,方法对我不起作用)
  • 我还尝试在二进制文件中调用setuid(0)和seteuid(0)进行测试。仍然没有根壳;(检查,对我不起作用)
  • 我也看到有些人设置的/ proc / sys目录/内核/阎王/ ptrace_scope为0(见张贴在这里),看到张贴在这里,但事实并非如此,我(值设置为1,我从来没有感动)(支票,我的值设置为1,应该可以)
  • 我正在使用linux mint 18.1 serena,也许这里有一项附加的安全功能会丢弃特权并阻止root-shell?
  • 请参阅下面的我的C代码和利用python脚本以供参考(漏洞位于vuln()函数中);函数shell()仅具有对应@plt函数的地址可用(这仅用于练习和玩耍)
  • 我使用'gcc -fno-stack-protector -o ghost ghost.c'来编译二进制文件,以避免堆栈金丝雀

有人知道可能是什么问题吗?为什么我仍然无法获得root shell?

在此先感谢您的任何建议和提示。最好的Zaphoxx

易受攻击的C代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void shell(){
    system("/bin/sh");
    exit(0);
}
int vuln(){
    char buf[4];
    ssize_t l=0;
    printf("[+] input: ");
    l=read(0,buf,128);
    printf("[+] recv: ");
    write(1,buf,l);
    return 0;
}

int main(){
    //setbuf(stdout,0);
    setuid(0);
    seteuid(0);
    vuln();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

python利用脚本创建有效负载: …

c python exploit x86-64 buffer-overflow

5
推荐指数
1
解决办法
892
查看次数

重回 libc 攻击

我正在尝试使用格式字符串攻击向量对以下代码实施返回到 libc 攻击。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
   char a[10];
   scanf("%s",&a);  
   printf(a);
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

我想通了使用系统()的地址p system的命令gdb。通过使用 对堆栈帧的检查x/500s $esp,我计算出包含\bin\sh.

system: 0xf7e2cda0 
exit: 0xf7e209d0
\bin\bash: 0xffffd207
Run Code Online (Sandbox Code Playgroud)

有了这些东西,我构造了以下格式字符串:

python -c 'print "A"*14 + "\xbc\xcd\xff\xff" + "\xa0\xcd\xe2\xf7" + "\xd0\x09\xe2\xf7" + "\x07\xd2\xff\xff"' > inp
Run Code Online (Sandbox Code Playgroud)

其中0xffffcdbc - 0x4是包含系统地址0xf7e2cda0值的本地地址。

我使用编译程序gcc -m32 -fno-stack-protector -o sh sh.c并使用gdb sh. 执行后,在输入时r<inp,我得到以下输出

gdb_output

如上所示,显示了一些错误命令,我只有在r再次运行命令后才能进入 shell …

c linux libc buffer-overflow

5
推荐指数
1
解决办法
5799
查看次数

缓冲区溢出攻击和 ROP 攻击有什么区别?

我开始研究软件安全性,但我很难理解缓冲区溢出攻击和 ROP 攻击是什么。

据我了解,

缓冲区溢出攻击:

当缓冲区达到一定大小时,填充缓冲区并添加额外的代码,以便攻击者可以执行代码中的另一个函数或他/她自己的shellcode。

ROP攻击:

给出某个可以覆盖返回地址的输入,以便攻击者可以控制流量。

但两者之间的确切区别是什么?

我觉得两者都只是给出了过多的输入来覆盖不应该接近的区域。

例如,如果我有一个代码

  1 #include <stdio.h>
  2 
  3 void check(){
  4     printf("overflow occurs!\n");
  5 }
  6 
  7 int main(int argc, char* argv[]){
  8     char buffer[256];
  9     gets(buffer);
 10     printf("%s\n", buffer);
 11     return 0;
 12 }
Run Code Online (Sandbox Code Playgroud)

并尝试check()通过向函数提供特定输入来执行该函数gets()

这是 ROP 攻击还是缓冲区溢出攻击?

security assembly exploit buffer-overflow

5
推荐指数
1
解决办法
3087
查看次数

sprintf_s 和 snprintf 有什么区别?

我在编写需要该功能的程序时遇到了这个问题sprintf

在某些情况下,使用该sprintf函数可能会导致内存溢出并带来安全风险。因此,您可以使用snprintfsprintf_s函数来避免这些风险。

但这两个函数的定义是相同的。那么,为什么存在这两个函数而不是只有一个呢?

int sprintf_s(char *_DstBuf, size_t _DstSize, const char *_Format, ...);
int snprintf(char *__restrict__ __stream, size_t __n, const char *__restrict__ __format, ...);
Run Code Online (Sandbox Code Playgroud)

一开始,我认为该sprintf_s函数是Windows库特有的,我也认为该snprintf函数是POSIX特有的。但事实上,这两个函数都包含在<stdio.h>库中。

c printf buffer-overflow

5
推荐指数
1
解决办法
1657
查看次数