【问题标题】:achieve stack smashing with executable file用可执行文件实现栈粉碎
【发布时间】:2013-12-30 20:04:31
【问题描述】:

当我只有可执行文件时,我尝试实现堆栈粉碎。 我使用 objdump 来获取此源代码的汇编代码:

#include<stdio.h>
#include<string.h>
void func(char *str) { 
char buffer[24]; 
int *ret; 
strcpy(buffer,str); 
}
int main(int argc, char **argv) { 
int x; 
x = 0; 
func(argv[1]); 
x = 1; 
printf("%d\n”,x); 
} 

在运行时。操作说明。 在到达包含 fun() 返回地址的位置之前,我有 40 个字节。

08048444 <func>:
8048444:    55                      push   %ebp
8048445:    89 e5                   mov    %esp,%ebp
8048447:    83 ec 48                sub    $0x48,%esp
804844a:    8b 45 08                mov    0x8(%ebp),%eax
804844d:    89 45 d4                mov    %eax,-0x2c(%ebp)
8048450:    65 a1 14 00 00 00       mov    %gs:0x14,%eax
8048456:    89 45 f4                mov    %eax,-0xc(%ebp)
8048459:    31 c0                   xor    %eax,%eax
804845b:    8b 45 d4                mov    -0x2c(%ebp),%eax
804845e:    89 44 24 04             mov    %eax,0x4(%esp)
8048462:    8d 45 dc                lea    -0x24(%ebp),%eax
8048465:    89 04 24                mov    %eax,(%esp)
8048468:    e8 eb fe ff ff          call   8048358 <strcpy@plt>
804846d:    8b 45 f4                mov    -0xc(%ebp),%eax
8048470:    65 33 05 14 00 00 00    xor    %gs:0x14,%eax
8048477:    74 05                   je     804847e <func+0x3a>
8048479:    e8 fa fe ff ff          call   8048378 <__stack_chk_fail@plt>
804847e:    c9                      leave  
804847f:    c3                      ret    

08048480 <main>:
8048480:    55                      push   %ebp
8048481:    89 e5                   mov    %esp,%ebp
8048483:    83 e4 f0                and    $0xfffffff0,%esp
8048486:    83 ec 20                sub    $0x20,%esp
8048489:    c7 44 24 1c 00 00 00    movl   $0x0,0x1c(%esp)
8048490:    00 
8048491:    8b 45 0c                mov    0xc(%ebp),%eax
8048494:    83 c0 04                add    $0x4,%eax
8048497:    8b 00                   mov    (%eax),%eax
8048499:    89 04 24                mov    %eax,(%esp)
804849c:    e8 a3 ff ff ff          call   8048444 <func>
80484a1:    c7 44 24 1c 01 00 00    movl   $0x1,0x1c(%esp)
80484a8:    00 
80484a9:    b8 90 85 04 08          mov    $0x8048590,%eax
80484ae:    8b 54 24 1c             mov    0x1c(%esp),%edx
80484b2:    89 54 24 04             mov    %edx,0x4(%esp)
80484b6:    89 04 24                mov    %eax,(%esp)
80484b9:    e8 aa fe ff ff          call   8048368 <printf@plt>
80484be:    b8 00 00 00 00          mov    $0x0,%eax
80484c3:    c9                      leave  
80484c4:    c3                      ret    
80484c5:    90                      nop
80484c6:    90                      nop

如果我插入 00 将其视为 (31) ASCII 的问题。我如何插入十六进制值。

...我希望阙清楚

objdump -w -Mintel:

08048444 <func>:
8048444:    55                      push   ebp
8048445:    89 e5                   mov    ebp,esp
8048447:    83 ec 48                sub    esp,0x48
804844a:    8b 45 08                mov    eax,DWORD PTR [ebp+0x8]
804844d:    89 45 d4                mov    DWORD PTR [ebp-0x2c],eax
8048450:    65 a1 14 00 00 00       mov    eax,gs:0x14
8048456:    89 45 f4                mov    DWORD PTR [ebp-0xc],eax
8048459:    31 c0                   xor    eax,eax
804845b:    8b 45 d4                mov    eax,DWORD PTR [ebp-0x2c]
804845e:    89 44 24 04             mov    DWORD PTR [esp+0x4],eax
8048462:    8d 45 dc                lea    eax,[ebp-0x24]
8048465:    89 04 24                mov    DWORD PTR [esp],eax
8048468:    e8 eb fe ff ff          call   8048358 <strcpy@plt>
804846d:    8b 45 f4                mov    eax,DWORD PTR [ebp-0xc]
8048470:    65 33 05 14 00 00 00    xor    eax,DWORD PTR gs:0x14
8048477:    74 05                   je     804847e <func+0x3a>
8048479:    e8 fa fe ff ff          call   8048378 <__stack_chk_fail@plt>
804847e:    c9                      leave  
804847f:    c3                      ret    

08048480 <main>:
8048480:    55                      push   ebp
8048481:    89 e5                   mov    ebp,esp
8048483:    83 e4 f0                and    esp,0xfffffff0
8048486:    83 ec 20                sub    esp,0x20
8048489:    c7 44 24 1c 00 00 00 00     mov    DWORD PTR [esp+0x1c],0x0
8048491:    8b 45 0c                mov    eax,DWORD PTR [ebp+0xc]

8048494:    83 c0 04                add    eax,0x4
8048497:    8b 00                   mov    eax,DWORD PTR [eax]
8048499:    89 04 24                mov    DWORD PTR [esp],eax
804849c:    e8 a3 ff ff ff          call   8048444 <func>
80484a1:    c7 44 24 1c 01 00 00 00     mov    DWORD PTR [esp+0x1c],0x1
80484a9:    b8 90 85 04 08          mov    eax,0x8048590
80484ae:    8b 54 24 1c             mov    edx,DWORD PTR [esp+0x1c]
80484b2:    89 54 24 04             mov    DWORD PTR [esp+0x4],edx
80484b6:    89 04 24                mov    DWORD PTR [esp],eax
80484b9:    e8 aa fe ff ff          call   8048368 <printf@plt>
80484be:    b8 00 00 00 00          mov    eax,0x0`

【问题讨论】:

  • 你用什么工具来编辑二进制文件?
  • (你能用objdump -w -Mintel吗?为了我的眼睛?)
  • 不,他正在学习粉碎藏匿处。他也没有编辑二进制文件,他只是使用objdump 来获取程序集。
  • 不,我不是...... :P 我没有编辑任何东西,只是在运行时依赖 CLI 的值
  • 您如何插入值 00(或尝试...)?

标签: c buffer-overflow stack-smash


【解决方案1】:

您可以使用 ./a.out $(perl -e "print '\x97';") 并将 \x97 替换为您要使用的十六进制。

【讨论】:

  • perl ??我可以将它与多个字符一起使用 >
  • @Haboosh 你可以,在第一个之后放更多的 \x00 。 Perl 是最常用的编写 shellcode 的工具。
  • 我做了以下事情:我重复“打印'\x00';”六次,代码工作正常,推第七次给我错误“堆栈粉碎”......它表明我在 ret addr 存储的位置正确吗?
【解决方案2】:

如果是 C,则字符串字符的结尾是 0x00(如果您愿意,也可以是 '\0')。因此,如果您使字符串长度正好为 39 个字符,那么第 40 个字符将是零 - 它会在正确的位置。无法在 C 字符串中复制多个零 - 除非您使用 strcpy 以外的函数(例如,memcpy)。但是,如果您依靠argv[1] 作为零的来源,那么这是唯一的方法。你当然可以在处理之前从字符串中减去一些东西 - 如果你愿意,你可以这样做

L = strlen(argv[1]);
for(int ii = 0; ii < L; ii++) if(argv[1][ii] == '0') argv[1][ii] = '\0';

这会将每个'0' 变成'\0'。但是你不能做一个简单的strcpy,你必须做memcpy

而且你必须希望你不会因为写入不属于你的内存而出现段错误……

【讨论】:

  • 那么你需要一个正好是 39 个字符的字符串作为你的参数,你会在第 40 个位置写一个nul
  • 我之前考虑过,但有没有机会将 null 视为普通字符串,因为我处理的是 char * argv
猜你喜欢
  • 2020-05-16
  • 1970-01-01
  • 2014-06-26
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多