时间:2025-04-19 18:44
人气:
作者:admin
MOECTF24_no_more_gets WriteUp
(1) PWN 类型 linux环境
FLAG位置未知中。根据题目名称大概猜出这个题目的是提示不要再使用gets这种不安全的输入函数。
(2) 进入将给的文件用linux系统打开,大概判断一下文件类型(file并不能保证完全正确,它更多是基于文件中幻数来判断),编译信息:得出是一个ELF,使用arch:x86_64,OS:linux,编译选项没有对heap,stack保护,也没有PIE。那么可以进行栈溢出。

(3) 先试试这个程序是干什么的:
似乎是一个输入密码的程序,啊这,管你这哪的,先看看有没有对输入进行限定,一看溢出,没有保护,那完了。

(4) 用gdb打开一下看看有什么特别的函数,这一步也可以用nm快速去看文件有什么函数,链接库。

使用了gets()函数:

用nm查看程序信息
nm:

(5) 用IDA反编译看看这些函数要干什么,发现了内置的shell函数,那么直接通过栈溢出到这个函数即可,利用gets函数溢出,那么我们先去看看运行到gets时栈的情况,方便我们进行溢出





由以上两张图可知返回地址在rsp中,rdi(x86中,函数参数一般按照rdi,rsi,rdx,rcx,r8,r9传递,RX不够时再压栈)中是函数参数,即s2的地址,由于之前通过IDA得知它的内存大小是0x50,所以我们从rdi的地址开始写入0x50的数据还要写(0x90-0x38-0x50)=0x08B的数据,那么开始构造payload,写exploit.py
(6)构造payload

from pwn import *
context(os='linux',arch='amd64',log_level='debug')
# p = process('./lockedshell') # 本地测试
p = remote('IP',PORT) # 远程,IP,PORT填上的即可
address = 0x401176 + 1
payload = b'A' * (0x50 + 8) # 0x50 + 0x8
payload += p64(address)
p.sendlineafter('.\n',payload)
p.interactive()

成功调用my_shell。题目将exploit.py脚本中process改成IP,端口就行,flag就在当前目录。
1.使用了不安全的函数gets,由于在输入时不会因为变量大小而对输入进行要求,类似scanf,也有缓冲区溢出的问题,gets早就在C11就被弃用了,虽然还可以使用(要先声明,同时会被警告),同时也是因为没有对输入后的变量长度进行检查。
2.设置了不安全的shell函数,可以被调用。
3.在编译时没有使用栈保护,ASLR,PIE等保护措施。