首页
社区
课程
招聘
[原创]pwnable.tw新手向write up(五) Silver Bullet-Off By One
发表于: 2020-5-9 14:32 9237

[原创]pwnable.tw新手向write up(五) Silver Bullet-Off By One

2020-5-9 14:32
9237

pwnable.tw新手向write up(一)
pwnable.tw新手向write up(二) 3×17-x64静态编译程序的fini_array劫持
pwnable.tw新手向write up(三) dubblesort-多重保护下的栈溢出
pwnable.tw新手向write up(四) hacknote-Use After Free

查看一下防护,开启了Full RELRO,那么GOT表是只读.还有NX也开着.

IDA看一下.

大概意思是程序要求我们用银子弹杀死狼人,分别提供了创建子弹,增强威力,和开枪这三个函数,这里我创建了一个狼人信息的结构体,如下:

接着进入create_bullet函数看一下:

子弹只能创建一次,而且这个函数并不存在漏洞,不过我们可以得知子弹的信息结构,如下:

接着是power_up函数:

首先判断子弹中的字符串长度是否大于47,不然就直接返回.假设我们的长度并没有超过47,那么程序会读取48-length长度的字节,然后用strncat函数将两个字符拼接在一起,之后更新子弹的长度信息.

乍一看可能很安全,因为使用了strncat而不是strcat,但是strcat在拼接完之后会在末尾加一个'\x00',根据保存子弹信息的结构体可知,我们在description输入48个字节后,会有一个\x00溢出到保存长度的length中.乍一看好像也没啥,才一个字节而已,但是不要忘记我们的计算机采用的是小端序,溢出的一个字节正好将length的值改成了0.溢出之后还会更新我们的length为0+fake_bullet->length.

beat函数首先用狼人的生命值减去子弹的长度,判断大小选择返回0或者1.main函数是用exit(0)来退出的,并不能执行return从而控制eip,所以我们在构造完栈上的数据之后要调用beat函数劫持控制流.

利用方法

唯一的溢出点在power_up函数之中的strncat函数,所以我们在创建子弹的时候不能超过0x2F,为了后面构造方便一点,我们创建一个0x2F长度的子弹.接着调用power_up函数,这个时候我们只能输入一个字节的内容,接着strncat从字符串之后的\x00所在处复制我们的输入,末尾会补一个\x00,此时,子弹的长度以及被覆盖为了0.但是还会对长度进行更新,0+fake_bullet->length = 1.这样,我们如果再调用一次power_up函数,那么我们就可以在48个字节+'\x01'之后输入2F个字节了,这就造成了栈溢出.

这个时候有两种解法,一种是比较麻烦的,先覆盖返回地址为puts函数来打印puts@got的值,接着计算出libc加载的基地址以及system函数和bin/sh字符串的地址,最后再覆盖返回地址为system函数来getshell.

另一种相对简单一点,我们可以考虑one_gadget:

exp-re2libc

exp-one_gadget

关于我

博客有我的联系方式,欢迎大家来玩,地址:https://www.0x2l.cn

  [0] % checksec silver_bullet
  [!] Couldn't find relocations against PLT to get symbols
  [*] '/home/dylan/ctfs/pwnable_tw/Silver_Bullet/silver_bullet'
      Arch:     i386-32-little
      RELRO:    Full RELRO
      Stack:    No canary found
      NX:       NX enabled
      PIE:      No PIE
  int __cdecl main(int argc, const char **argv, const char **envp)
  {
    int choice; // eax
    Werewolf wolf; // [esp+0h] [ebp-3Ch]
    bullet silver_bullet; // [esp+8h] [ebp-34h]

    init_proc();
    silver_bullet.length = 0;
    memset(&silver_bullet, 0, 0x30u);
    wolf.HP = 0x7FFFFFFF;
    wolf.name = "Gin";
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            menu();
            choice = read_int();
            if ( choice != 2 )
              break;
            power_up(&silver_bullet);
          }
          if ( choice > 2 )
            break;
          if ( choice != 1 )
            goto LABEL_16;
          create_bullet(&silver_bullet);
        }
        if ( choice == 3 )
          break;
        if ( choice == 4 )
        {
          puts("Don't give up !");
          exit(0);
        }
  LABEL_16:
        puts("Invalid choice");
      }
      if ( beat(&silver_bullet, &wolf) )
        return 0;
      puts("Give me more power !!");
    }
  }

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2020-8-12 20:23 被0x2l编辑 ,原因: 修改
上传的附件:
收藏
免费 2
支持
分享
最新回复 (2)
雪    币: 259
活跃值: (283)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
已阅
2020-5-10 21:15
0
雪    币: 1660
活跃值: (1487)
能力值: ( LV7,RANK:103 )
在线值:
发帖
回帖
粉丝
3
make
2020-6-25 17:06
0
游客
登录 | 注册 方可回帖
返回
//