当前位置: 首页 > article >正文

PWN--格式化字符串

简介

‌格式化字符串‌是指在编程过程中,通过特殊的占位符将相关对应的信息整合或提取的规则字符串。格式化字符串包括格式化输入和格式化输出,其本质是程序员调用相关格式化字符串的操作协议规定。错误的或不当的信息配置可能导致程序运行失效或产生未定义行为

在PWN中,格式化字符串漏洞是常见的考察点,仅次于栈溢出漏洞。

格式化字符串漏洞成因:程序使用了格式化字符串作为参数,并且格式化字符串为用户可控。其中触发格式化字符串漏洞函数主要是printfsprintffprintfprin等C库中print家族函数

格式化说明符

%d - 十进制 - 输出十进制整数
%s - 字符串 - 从内存中读取字符串
%x - 十六进制 - 输出十六进制数
%c - 字符 - 输出字符
%p - 指针 - 指针地址
%n - 到目前为止所写的字符数

CPU利用ebp访问栈内东西
printf函数参数从右边向左入栈

补充:

EBP(Base Pointer)是栈帧基址指针寄存器,存放执行函数对应栈帧的栈底地址,用于C运行库访问栈中的局部变量和参数

举个栗子

#include <stdio.h>
int main viod{
    printf("My name is %s","Cyy");
    return 0;
}

输出为

My name is Cyy

漏洞

先来看一下正常的printf用法

#include <stdio.h>    //包含标准输入输出库
int main()    //主函数,程序的入口
{
  char str[100];    //定义一个字符数组str,长度为100,用于存储用户输入的字符串
  scanf("%s", str);    //使用scanf函数从标准输入读取一个字符串,并存储到str中
  printf("%s", str);    //使用printf函数将str中的字符串输出到标准输出
  return 0;    //程序正常结束,返回0
}

规定字符串的格式化说明符,规定参数的输出类型

补充:

字符串格式化说明符--用于规定输出数据的类型,也就是代码中的%s,从内存中读取字符串

接下来看一下错误版本

#include <stdio.h>
int main()
{
  char str[100];
  scanf("%s",str);
  printf(str);
  return 0;
}

程序将格式化字符串的输入权交给用户,printf函数并不知道参数个数,它的内部有个指针,用来索检格式化字符串。对于特定类型%,就去取相应参数的值,直到索检到格式化字符串结束。所以没有参数,代码也会将format string 后面的内存当做参数以16进制输出。这样就会造成内存泄露。

举个栗子

#include <stdio.h>

int main(void)
{
    char a[100];
    scanf("%s",a);
    printf(a);
    return 0;
}

假设输入为

AAAA%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x

输出为

AAAA61fe4c,61ffcc,76e4d250,70734fbf,fffffffe,76e473da,41414141,252c7825,78252c78,2c78252c,252c7825

可以看到打印出了地址

漏洞利用

主要利用有:使程序崩溃、栈数据泄露、任意地址内存泄露、栈数据覆盖、任意地址内存覆盖。

格式化字符串与malloc free有关的格式化字符串漏洞

malloc()、calloc()、realloc()分配堆中空间
alloca()来分配栈中的空间

scanf输入和printf输出的字符过多的时候,会调用malloc来处理,且结束之后都会调用free。
所以当输入或输出较多的时候,可以覆盖_free_hook或者_malloc_hook为其他函数地址来调用其他函数


http://www.kler.cn/a/531366.html

相关文章:

  • 安卓(android)饭堂广播【Android移动开发基础案例教程(第2版)黑马程序员】
  • 分析哲学:从 语言解剖到 思想澄清的哲学探险
  • nodejs:js-mdict 的下载、安装、测试、build
  • [HOT 100] 2824. 统计和小于目标的下标对数目
  • K8S集群部署--亲测好用
  • B+ 树的实现原理与应用场景
  • 100 ,【8】 buuctf web [蓝帽杯 2021]One Pointer PHP(别看)
  • UBX完成首轮代币销毁:1,755,874枚UBX永久退出流通
  • L31.【LeetCode题解】轮转数组
  • HTTP协议的无状态和无连接
  • HAO的Graham学习笔记
  • 想表示消息返回值为Customer集合
  • 实现数组的乱序输出、实现数组去重
  • Java编程范式与计算机系统基础
  • Vue 图片引用方式详解:静态资源与动态路径访问
  • webpack传输性能优化
  • 【Word快速设置论文公式居中编号右对齐】
  • Visual Basic语言的移动应用开发
  • 【LLM】Layer Norm 和 RMS Norm 的区别?
  • C#常用744单词
  • Baklib推动数字化内容管理解决方案助力企业数字化转型
  • 深度学习-98-大语言模型LLM之基于langchain的代理create_react_agent工具
  • 二叉树--链式存储
  • 无用知识研究:std::initializer_list的秘密
  • 模型蒸馏(ChatGPT文档)
  • npm知识