新的目标:Capture The Flag

  承蒙前来宣讲前辈们的指引和各种震天响的牛逼,决定接下来一段时间把CTF一搞起。

  然后百度了下各个方向,打算直接搞pwn(听说搞过ACM的上手会快一点?),环境弄好后开始上手,研究一下pwn要怎么搞。

  First step 

  栈溢出原理从入门到放弃

       参考资料:www.blog.csdn.net/DRondong/article/details/94500556

  简单尝试了一个栈溢出原理:

  

#include<stdio.h>
 
int fun1()
{
    int a;
    gets((char *)&a);
    return 0;
}
 
int fun2()
{
    printf("stackflow success!\n");
    return 0;
}
 
int main(int argc, char *argv[])
{
    fun1();
 
    return 0;
}

我们向栈中写入了超出限定长度的数据,溢出的数据会覆盖栈中其它数据,从而影响程序的运行。

所以,如果我们计算好溢出的长度,编写好溢出数据,让我们想要的地址数据正好覆盖到函数返回地址,那么被调函数调用完返回主函数时,就会跳转到我们覆盖的地址上。

gets()它不进行边界检查,我们可以利用它达成目的。在我们的例子中,a是int型只有4字节大小的空间,所以当输入的字符大于4字节时,就会发生溢出。而我们的目标就是,让我们的溢出数据覆盖fun1函数的返回地址,具体就是覆盖为fun2函数的地址,使程序的流程跳转到fun2函数去执行。

按照上链的方法,用gcc对这段代码进行编译: 

gcc -z execstack -fno-stack-protector -o stackflow-example ./stackflow-example.c

(其中-z execstack开启堆栈可执行机制,-fno-stack-protector关闭堆栈保护机制)

用gdb进行调试,可以直接在gets()函数下断点,也可以使用next、step指令快速调试到gets()函数这,在输入AAA后,查看堆栈数据。

在执行完gets()函数并输入AAA后,程序的栈分布情况如下所示,0x00007fffffffe110即是上一函数(调用者main函数)的ebp,0x4005b4是fun1函数的返回地址。

在输入AAAAA后呢,溢出的数据就会存在0x00007fffffffe0f0开始的栈上

所以,我们只需要输入AAAA+AAAAAAAA(覆盖上一函数ebp)+fun2地址(覆盖返回地址),就可以达到我们的目标。

新的目标:Capture The Flag

 

 (开启了新世界的大门)

静待更新。。。。。。

上一篇:C# wpf 委托调用的方法


下一篇:JS:函数的实参可以是任何值及函数返回值的类型