About

Stack4 takes a look at overwriting saved EIP and standard buffer overflows.
Hints:
  • A variety of introductory papers into buffer overflows may help.
  • gdb lets you do "run < input"
  • EIP is not directly after the end of buffer, compiler padding can also increase the size.
This level is at /opt/protostar/bin/stack4

Source code

#include
#include
#include
#include

void win()
{
    printf("code flow successfully changed\n");
}

int main(int argc, char **argv)
{
    char buffer[64];

    gets(buffer);
}

这题开始有点意思,而且看上去跟Stack3的样子长得差不多。其实猜也能猜到是用gets(buffer)来构造溢出,经过微思考一番也容易知道在汇编的世界里,函数的末尾有个RET,显然需要通过溢出来修改RET地址。
首先第一步工作是找到Win()函数的地址,这个步骤跟Stack3里面的一样

第二步要是找到RET的地址在哪里,才能够把win的地址覆盖进去。。。这里有两种方法,一种是穷举法:
通过输入
1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9
根据两次报错地址容易算出RET的地址

二是利用gdb工具通过下断点可以算出RET地址:

得到的76意味着RET地址与buffer输入的第一个字符相隔76字节。因此可以得到。。。