设为首页 加入收藏

TOP

二进制炸弹(第二次实验)(二)
2016-04-27 17:25:30 】 浏览:858
Tags:二进制 炸弹 第二 实验

x /&b/ 8048bad: lea -0xc(%ebp),%eax 8048bb0: push %eax /&a/ 8048bb1: push $0x80497de /format/ 8048bb6: push %edx /input/ 8048bb7: call 8048860

同样用gdb可以知道format的值是”%d %c %d”,因此调用了sscanf(input,”%d %c %d”,&a,&b,&c),之后同样比较其返回值,如果小于3就引爆,接着:

08048b98 
   
    : 8048bc9: cmpl $0x7,-0xc(%ebp) 8048bcd: ja 8048c88 
    
      8048bd3: mov -0xc(%ebp),%eax /c/ 8048bd6: jmp *0x80497e8(,%eax,4) /case 0,1,2,3,4,5,6,7/ ...
    
   
 8048c88:       mov    $0x78,%bl
 8048c8a:       call   80494fc 
   
     /default/
   

这里可以看到这是一个switch语句,用gdb查看跳转表:

(gdb) x/8x 0x80497e8
0x80497e8:  0x08048be0  0x08048c00  0x08048c16  0x08048c28
0x80497f8:  0x08048c40  0x08048c52  0x08048c64  0x08048c76

其中,从上到下,从左到右依次为a=0,1,..7时跳转地址,以a=0时为例:

08048b98 
   
    : 8048be0: mov $0x71,%bl /bl=”q”/ 8048be2: cmpl $0x309,-0x4(%ebp) /比较777和c/ 8048be9: je 8048c8f 
    
      /c==777/ 8048bef: call 80494fc 
     
       /c!=777/ ... 8048c8f: cmp -0x5(%ebp),%bl /比较b和”q”/ 8048c92: je 8048c99 
      
        /b==”q”/ 8048c94: call 80494fc 
       
         /b!=”q”/ 8048c99: mov -0x18(%ebp),%ebx /return/ 8048c9c: mov %ebp,%esp 8048c9e: pop %ebp 8048c9f: ret
       
      
     
    
   

由此可知,当a=0时,b=”q”且c=777才不会引爆,其余情况类似。
C语言等价代码为:

void phase_3(char *input)
{
    int a,c;
    char b;
    int eax=sscanf(input,"%d %c %d",&a,&b,&c);
    if (eax<=2)
        explode_bomb();
    switch (a){
    case 0:
        if (c!=777||b!="q")
            explode_bomb();
    case 1:
        if (c!=214||b!="b")
            explode_bomb();
    case 2:
        if (c!=755||b!="b")
            explode_bomb();
    case 3:
        if (c!=251||b!="k")
            explode_bomb();
    case 4:
        if (c!=160||b!="o")
            explode_bomb();
    case 5:
        if (c!=458||b!="t")
            explode_bomb();
    case 6:
        if (c!=780||b!="v")
            explode_bomb();
    case 7:
        if (c!=524||b!="b")
            explode_bomb();
    default:explode_bomb();
    }
}

由此可知,阶段三字符串必须是以0q777,1b214,2b755,3k251,4o111,5t458,6v780,7b524中的一个为开头且后续字符串不能以数字为开头的字符串。

阶段四

08048ce0 
   
    : 8048ce3: sub $0x18,%esp 8048ce6: mov 0x8(%ebp),%edx /input/ 8048ce9: add $0xfffffffc,%esp 8048cec: lea -0x4(%ebp),%eax /&x/ 8048cef: push %eax /&x/ 8048cf0: push $0x8049808 /format/ 8048cf5: push %edx /input/ 8048cf6: call 8048860 
    
      ... 8048cfe: cmp $0x1,%eax 8048d01: jne 8048d09 
     
       ... 8048d09: call 80494fc 
       
      
     
    
   

同前分析可知,这里调用了sscanf(input,”%d”,&x),并且读到的数据个数不为1时,引爆,如果读入了一个数据:

08048ce0 
   
    : ... 8048d03: cmpl $0x0,-0x4(%ebp) /比较x和0/ 8048d07: jg 8048d0e 
    
      /x>0/ 8048d09: call 80494fc 
     
       /x<=0/ 8048d0e: add $0xfffffff4,%esp 8048d11: mov -0x4(%ebp),%eax /x/ 8048d14: push %eax/x/ 8048d15: call 8048ca0 
      
        8048d1a: add $0x10,%esp 8048d1d: cmp $0x37,%eax /比较func4(x)和55/ 8048d20: je 8048d27 
       
         /func4(x)==55,return/ 8048d22: call 80494fc 
        
       
      
     
    
   

可以看出,如果读入值x<=0,引爆,如果读入值>0,比较func4(x)和55的大小,如果不相等,引爆,接下来分析func4:

08048ca0 
   
    : ... 8048cab: cmp $0x1,%ebx /比较x和1/ 8048cae: jle 8048cd0 
    
      /x<=1,return 1/ 8048cb0: add $0xfffffff4,%esp 8048cb3: lea -0x1(%ebx),%eax 8048cb6: push %eax /push x-1/ 8048cb7: call 8048ca0 
     
       /func4(x-1)/ 8048cbc: mov %eax,%esi /esi=func4(x-1)/ 8048cbe: add $0xfffffff4,%esp 8048cc1: lea -0x2(%ebx),%eax 8048cc4: push %eax /push x-2/ 8048cc5: call 8048ca0 
      
        /func4(x-2)/ 8048cca: add %esi,%eax /return func4(x-1)+func4(x-2)/ 8048ccc: jmp 8048cd5 
       
         8048cce: mov %esi,%esi 8048cd0: mov $0x1,%eax ...
       
      
     
    
   

可以发现func4首先比较x和1,如果x<=1返回1,否则返回func4(x-1)+func4(x-2;
C语言等价代码为:

int func4(int x)
{
    if (x<=1)
        return 1;
    else
        return func4(x-1)+func4(x-2);
}
void phase_4(char *input)
{
    int x;
    int eax=sscanf(input,"%d",&x);
    if (eax!=1)
        explode_bomb();
    if (x<=0)
        explode_bomb();
    if (func4(x)!=55)
        explode_bomb();
}

可知这是一个斐波拉契数列:
x 0 1 2 3 4 5 6 7 8 9
func4 1 1 2 3 5 8 13 21 34 55
由此可知,阶段4的正确输入是以9为开头,后续字符串以非数字开头的字符串,关于隐藏关是什么,我们留到最后分析。

阶段五

08048d2c 
   
    : ... 8048d3a: push %ebx /input/ 8048d3b: call 8049018 
    
      8048d40: add $0x10,%esp 8048d43: cmp $0x6,%eax 8048d46: je 8048d4d 
     
       8048d48: call 80494fc 
      
        ...
      
     
    
   

可以知道这里比较input的长度,如果不是6,引爆,接着:

08048d2c 
   
    : 8048d4d: xor %edx,%edx /edx=0/ 8048d4f: lea -0x8(%ebp),%ecx /ecx=&s[0]/ 8048d52: mov $0x804b220,%esi /esi=&p[0]/ .loop 8048d57: mov (%edx,%ebx,1),%al /al=input[edx]/ 8048d5a: and $0xf,%al /al&=0xf/ 8048d5c: movsbl %al,%eax /eax=(int)al/ 8048d5f: mov (%eax,%esi,1),%al /al=p[eax]/ 8048d62: mov %al,(%edx,%ecx,1) /s[edx]=al/ 8048d65: inc %edx 8048d66: cmp $0x5,%edx 8048d69: jle 8048d57 
    
      goto .loop
    
   

同样用gdb可以知道p的值是”isrveawhobpnutfg”,上述循环的功能是令
s[edx]=p[(int)(input[edx]&0xf)],接着:

08048d2c 
   
    : ... 8048d6b: movb $0x0,-0x2(%ebp) /s[7]=0/ ... 8048d72: push $0x804980b /pattern/ 8048d77
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇OpenCV实践之路――行人检测 下一篇C++学习笔记之四 复合类型1

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

最新文章

热门文章

C 语言

C++基础

windows编程基础

linux编程基础

C/C++面试题目