IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> linux格式化字符串漏洞 -> 正文阅读

[系统运维]linux格式化字符串漏洞

格式化字符串漏洞

格式化字符串介绍

常见格式化字符串函数

函数基本介绍
printf输出到stdout
fprintf输出到指定FILE流
vprintf根据参数列表格式化输出到stdout
vfprintf根据参数列表格式化输出到FILE流
sprintf输出到字符串
snprintf输出指定字节数到字符串
vsprintf根据参数列表格式化输出到字符串
vsnprintf根据参数列表格式化输出指定字节到字符串

常用格式化字符串形式

%[parameter][flags][field width][.precision][length]type
  • parameter:n$,获取格式化字符串中的指定参数
  • field width:输出的最小宽度
  • precision:输出的最大长度
  • length,输出的长度
    • hh,输出一个字节
    • h,输出一个双字节
  • type
    • d/i,有符号整数
    • u,无符号整数
    • x/X,16进制
    • o,8进制
    • s,所有字节
    • c,char类型单个字符
    • p,void * 型,输出对应变量的值。printf("%p",a) 用地址的格式打印变量 a 的值,printf("%p", &a) 打印变量 a 所在的地址。
    • n,不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。

原理验证

示例程序:

#include<stdio.h>

int main() {
    char s[100] = "aaaa.%p.%p.%p.%p.%p.%p.%p";
    printf(s);
    return 0;
}

32位

编译命令:

gcc test.c -g -m32 -o test

输出结果:

aaaa.0xf7ffc988.0xffffcf2a.0x56555595.0xffffcf2a.0xf7ffc984.0x61616161.0x2e70252e

栈结构:

00:0000│ esp  0xffffcee0 —? 0xffffcef8 ?— 'aaaa.%p.%p.%p.%p.%p.%p.%p'
01:0004│      0xffffcee4 —? 0xf7ffc988 (_rtld_global_ro+136) ?— 0x8e
02:0008│      0xffffcee8 —? 0xffffcf2a ?— 0x0
03:000c│      0xffffceec —? 0x56555595 (main+24) ?— add    ebx, 0x1a3f
04:0010│      0xffffcef0 —? 0xffffcf2a ?— 0x0
05:0014│      0xffffcef4 —? 0xf7ffc984 (_rtld_global_ro+132) ?— 0x6
06:0018│ eax  0xffffcef8 ?— 'aaaa.%p.%p.%p.%p.%p.%p.%p'

自上而下依次是参数0~6,参数0为格式化字符串地址,而格式化字符串前4字节又作为参数6(由于栈结构不同,需要视情况而定)。因此如果将格式化字符串合适的位置设置为目标地址就可以对该地址的数据进行操作。

64位

编译命令:

gcc test.c -g -m64 -o test

输出结果:

aaaa.0x7fffffffde78.0x70.0x555555554770.0x7ffff7dced80.0x7ffff7dced80.0x2e70252e61616161.0x70252e70252e7025

寄存器:

 RAX  0x0
 RBX  0x0
 RCX  0x555555554770 (__libc_csu_init) ?— push   r15
 RDX  0x70
 RDI  0x7fffffffdd20 ?— 'aaaa.%p.%p.%p.%p.%p.%p.%p'
 RSI  0x7fffffffde78 —? 0x7fffffffe21b
 R8   0x7ffff7dced80 (initial) ?— 0x0
 R9   0x7ffff7dced80 (initial) ?— 0x0
 R10  0x0
 R11  0x0
 R12  0x5555555545a0 (_start) ?— xor    ebp, ebp
 R13  0x7fffffffde70 ?— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffdd90 —? 0x555555554770 (__libc_csu_init) ?— push   r15
 RSP  0x7fffffffdd20 ?— 'aaaa.%p.%p.%p.%p.%p.%p.%p'
 RIP  0x555555554747 (main+157) ?— call   0x555555554580

栈结构:

00:0000│ rdi rsp  0x7fffffffdd20 ?— 'aaaa.%p.%p.%p.%p.%p.%p.%p'
01:0008│          0x7fffffffdd28 ?— '%p.%p.%p.%p.%p.%p'
02:0010│          0x7fffffffdd30 ?— '.%p.%p.%p'
03:0018│          0x7fffffffdd38 ?— 0x70 /* 'p' */
04:0020│          0x7fffffffdd40 ?— 0x0

由于64位程序先使用rdi、rsi、rdx、rcx、r8、r9寄存器作为函数参数的前六个参数,多余的参数会依次压在栈上,因此前6个输出的为寄存器中的值(aaaa看做是格式化字符串参数),格式化字符串前8个字节作为参数6。

泄露内存

泄露栈变量内存

泄露栈变量的值

获取栈中被视为第 n + 1 n+1 n+1 个参数的值:%n$x

注意:%x其实只是%d的16进制输出,对应的是32位也就是4字节;在64位操作系统下,只会截区后32位;%p和系统位数关联没有问题,因此建议用%p。

泄露栈变量对应对应地址的内容

获取栈中被视为第 n + 1 n+1 n+1 个参数对应地址的内容:%n$s

泄露任意地址内存

获取地址addr对应的值(addr为第k个参数):addr%k$s

覆盖内存

注意:覆盖内存只能覆盖某地址对应的内存,而不是第几个参数,对于开启ASLR的程序覆盖栈上某个值要事先泄露栈地址。

pwntools生成payload

对于格式化字符串payload,pwntools也提供了一个可以直接使用的类Fmtstr,具体文档见http://docs.pwntools.com/en/stable/fmtstr.html,我们较常使用的功能是

fmtstr_payload(offset, {address:data}, numbwritten=0, write_size='byte')
  • offset表示格式化字符串的偏移
  • numbwritten表示已经输出的字符个数
  • write_size表示写入方式,是按字节(byte)、按双字节(short)还是按四字节(int),对应着hhn、hn和n,默认值是byte,即按hhn写。

注意:部分题目会限制时间,导致pwntools生成的payload失效。一般这一类题目可以通过仅修改低地址等操作减小输出长度,这时需要手动构造payload。

手动构造payload

覆盖小数字

对于小于机器字长的数字,如果把地址放在格式化字符串前面会使得已输出字符个数大于数字大小,因此要将地址放在后面。

以数字2为例:aa%k$n[padding][addr]

覆盖大数字

直接一次性输出大数字个字节来进行覆盖时间过长,因此需要把大数字拆分成若干个部分,分别进行覆盖。比如hhn按字节写或hn按双字写。

hhn写入32bit数为例,payload形式为:[addr][addr+1][addr+2][addr+3][pad1]%k$hhn[pad2]%(k+1)$hhn[pad3]%(k+2)$hhn[pad4]%(k+3)$hhn

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-02-05 22:03:22  更:2022-02-05 22:05:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 5:35:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码