PWN学习之格式化字符串漏洞

格式化输出函数

可变参数:https://blog.csdn.net/smstong/article/details/50751121 (C语言可变参函数的实现)

首先我们了解格式化字符串漏洞前,需要对格式化输出的函数进行一个了解,在C中格式化输出函数一共有如下:

fprintf()  "按照格式字符串将输出写入流中。三个参数分别是流、格式字符串和变参列表。"
printf() "等同于fprintf(),但是它的输出流为stdout。"
sprintf() "等同于fprintf(),但是它的输出不是写入流而是写入数组。在写入的字符串末尾必须添加一个空字符。"
snprintf() "等同于sprintf(),但是它指定了可写入字符的最大值size。超过第size-1的部分会被舍弃,并且会在写入数组的字符串末尾添加一个空字符。"
dprintf() "等同于fprintf(),但是它的输出不是写入流而是一个文件描述符fd。" "分别与上面的函数对应,但是它们将变参列表换成了va_list类型的参数。"
vfprint()、vprintf()、vsprintf()、vsnprintf()、vdprintf()

格式化字符串漏洞

格式化字符串漏洞从2000年左右开始流行起来,几乎在各种软件中都能见到它的身影,随着技术的发展,软件安全性的提升,如今它在桌面端已经比较少见了,但在物联网设备 IoT上依然层出不穷。

#include <stdio.h>
void main()
{
printf("%s %d %s %x %x %x %3$s","Hello World!",233,"\n");
}

我们输入的参数只有三个,但是格式化字符串中还有3个%x和一个%3$s,其中3个%x由于没有参数他会泄漏出栈的地址

接下来继续来看一个例子,其中fgets来接受用户输入的字符串,但是如果是hack他就会输入控制字符串来泄漏出栈地址,这点感觉和Web中的xss有点像,程序员没有过滤敏感字符导致被攻击。由此可以总结出,格式字符串漏洞发生的条件就是格式字符串要求的参数和实际提供的参数不匹配

#include <stdio.h>
void main()
{
char buf[50];
if(fgets(buf,sizeof buf,stdin) == NULL)
return;
printf(buf);
}

漏洞利用

对于格式化字符串漏洞的利用主要有:

  • 使程序崩溃
  • 栈数据泄露
  • 任意地址内存泄露
  • 栈数据覆盖
  • 任意地址内存覆盖

使程序崩溃

造成程序崩溃原因:printf需要在栈中取一个数字视为地址,然后打印出地址所指向的内存,知道出现空白字符;获取的某个数字可能并不是一个地址;获得的数组确实是一个地址,但改地址受保护。

在Linux中,存取无效的指针会使进程收到SIGSEGV信号。

printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s")

栈数据泄露

#include <stdio.h>
void main()
{
char format[128];
int arg1 = 0x00123456,arg2 = 0x11111111,arg3 = 0x22222222;
char arg4[4] = "ABCD";
scanf("%s",format);
printf(format,arg1,arg2,arg3,arg4);
printf("\n");
}
输入 %p-%p-%p-%p-%p

可以根据泄漏出来的栈的数据,然后挨个的计算出参数的位置,因为栈中的数据一般都是挨着的,可以看到在0xffffd484的下个数据就是字符串ABCD字符串的地址。

现在我们已经知道了如何按顺序泄露栈数据,那么如果想直接泄露指定的某个数据,则可以使用与下面类似的格式字符串,这里的n表示位于格式字符串后的第n个数据%n$p

%<arg#>$<format>
%n$x 分别获取arg3、arg1、arg2、arg2、arg4 以及栈上经跟参数的两个值
"%3$x-%1$p-%2$p-%2$p-%4$p-%5$p-%6$p"

任意地址内存泄漏

攻击者使用类似%s的格式规范就可以泄露出参数(指针)所指向内存的数据,程序会将它作为一个ASCII字符串处理,直到遇到一个空字符。所以,如果攻击者能够操纵这个参数的值,那么就可以泄露任意地址的内容。

AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p
AAAA代表地址

栈数据覆盖

#include <stdio.h>
void main()
{
int i;
char str[] = "hello";
printf("%s %n\n",str,&i);
printf("%d\n",i);
}

这个例子i被赋值成了6,因为遇到转换指示符之前一共写入了6个字符("hello"加上一个空格)。在没有长度修饰符时,默认写入一个int类型的值。有关详细内容可以参考:https://blog.csdn.net/FollowGodSteps/article/details/74115138

以下例子参考文章:c语言中对字段宽度的理解?

/*************************************************************************
> File Name: printf.c
> Author: Mr.Yang
> Purpose:演示printf的用法
> Created Time: 2017年05月21日 星期日 10时07分44秒
************************************************************************/ #include <stdio.h>
#include <stdlib.h> int main(void)
{
float i = 10000.123; printf("%5f\n",i);
printf("%10f\n",i);
printf("%15f\n",i);
printf("%20f\n",i);
printf("%25f\n",i); return 0;
}

输出内容:

10000.123047
10000.123047
10000.123047
10000.123047
10000.123047

回到一开始的程序,我们尝试将arg2的值更改为任意值(例如0x00000020,十进制32),于是构造格式字符串\x28\xcd\xff\xff%08x%08x%012d%13$n,其中\x28\xcd\xff\xff是arg2的地址,占4字节,“%08x%08x”表示两个8字符宽的十六进制数,占16字节,“%012d”占12字节,三个部分加起来共占4+16+12=32字节,也就是把arg2赋值为0x00000020。格式字符串最后一部分“%13$n”是最重要的一部分,表示格式字符串的第13个参数,即写入0xffffcd28的地方(0xffffcd58),printf()通过该地址找到被覆盖数据。

对比printf()执行前后的栈,可以看到其首先解析“%13$n”,从0xffffcd58找到地址0xffffcd28,然后将其数据覆盖为“0x00000020”。

任意地址内存覆盖

也许已经有人发现了问题,使用上面的方法,值最小只能是4,因为光地址就占去了4个字节,那么怎样覆盖比4小的值呢?利用整数溢出是一个方法,但是在实践中这样做很难成功。再想一下,前面的输入中,地址都位于格式字符串之前,这样做真的有必要吗,能否将地址放在中间呢?我们来试一下,使用格式字符串“AA%15\(nA"+"\x38\xd5\xff\xff”,开头的“AA”占2个字节,即将地址赋值为2,中间“%15\)n”占5个字节(这里不是%13$n,因为地址被放在了后面),是第15个参数,后面跟上一个“A”占用1个字节。于是前半部分总共占用2+5+1=8个字节,刚好是两个参数的宽度,这里的8字节对齐十分重要。最后,输入我们要覆盖的地址“\x38\xd5\xff\xff”,如下所示。

PWN学习之格式化字符串漏洞的更多相关文章

  1. [二进制漏洞]PWN学习之格式化字符串漏洞 Linux篇

    目录 [二进制漏洞]PWN学习之格式化字符串漏洞 Linux篇 格式化输出函数 printf函数族功能介绍 printf参数 type(类型) flags(标志) number(宽度) precisi ...

  2. Linux pwn入门教程——格式化字符串漏洞

    本文作者:Tangerine@SAINTSEC 原文来自:https://bbs.ichunqiu.com/thread-42943-1-1.html 0×00 printf函数中的漏洞printf函 ...

  3. CTF必备技能丨Linux Pwn入门教程——格式化字符串漏洞

    Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...

  4. 格式化字符串漏洞 format string exploit(一)

    本文系原创,转载请说明出处 本文为基于CTF WIKI的PWN学习 0x00 格式化字符串原理 先附一张经典的图,如下 其栈上布局如下: some value 3.14 123456 addr of ...

  5. Linux pwn入门教程(6)——格式化字符串漏洞

    作者:Tangerine@SAINTSEC 0x00 printf函数中的漏洞 printf函数族是一个在C编程中比较常用的函数族.通常来说,我们会使用printf([格式化字符串],参数)的形式来进 ...

  6. 格式化字符串漏洞利用实战之 0ctf-easyprintf

    前言 这是 0ctf 的一道比较简单的格式化串的题目. 正文 逻辑非常简单 do_read 可以打印内存地址的数据,可用来 泄露 got. leave 格式化字符串漏洞. printf(s) 直接调用 ...

  7. 格式化字符串漏洞利用实战之 njctf-decoder

    前言 格式化字符串漏洞也是一种比较常见的漏洞利用技术.ctf 中也经常出现. 本文以 njctf 线下赛的一道题为例进行实战. 题目链接:https://gitee.com/hac425/blog_d ...

  8. Linux下的格式化字符串漏洞利用姿势

    linux最早的漏洞防护机制nx-stack刚刚出现后就有人想出了突破方法.那就是只有栈是不可执行,而除了栈以外的其他地方还是可以执行的,只要把返回地址执行别的地方就可以. 一.格式化字符串漏洞 格式 ...

  9. 通过格式化字符串漏洞绕过canary

    1.1    canary内存保护机制 1.1.1    canary工作原理 canary保护机制类似于/GS保护机制,是Linux下gcc编译器的安全保护机制之一,在栈中的结构如下图所示: 在函数 ...

随机推荐

  1. PHP 7.4 checking for libzip 和 failed to open error_log 问题

    来源: https://hqidi.com/154.html 两个深坑,成年阿根廷龙踩出来的坑,网上都没找到解决方法,都是自己摸索出来的. 前面一切顺利: yum install -y libxml2 ...

  2. php 设计模式 --适配器

    1,目标:实现一个不同的类不同方法,符合一定的规范: 规范类 <?php interface Iplay{ function Attack(); function Defence(); } cl ...

  3. 配置 放上传文件的目录 apache(httpd)

    1. 确认服务器 开放8088端口 https://www.apachefriends.org/download.html 下载XAMPP for Windows,安装 2. 修改apache主配置文 ...

  4. python之jsonpath

    json 官方文档:http://docs.python.org/library/json.html JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使 ...

  5. 『Python』matplotlib常用图表

    这里简要介绍几种统计图形的绘制方法,其他更多图形可以去matplotlib找examples魔改 1. 柱状图 柱状图主要是应用在定性数据的可视化场景中,或是离散数据类型的分布展示.例如,一个本科班级 ...

  6. 如何实现Web视频聊天?

    在网页里实现文字聊天是比较容易的,但若要实现视频聊天,就比较麻烦了.这里,我们将实现一个简单的网页版视频聊天Demo,可以支持所有类型的浏览器. 本Demo除了视频聊天功能外,还包含以下功能: 1.上 ...

  7. 关于Postman你必须学会的技能

    关于Postman 工欲善其事,必先利其器,在了解了接口测试之后,就要选择一款适用的工具.之所以选择postman是因为它简单.容易上手.能覆盖大多数HTTP接口测试场景,性价比极高. Postman ...

  8. Matlab 速记

    链接:https://zhuanlan.zhihu.com/p/370259237 % 1.进度提醒 f = waitbar(0,'1','Name','进度'); set(f,'color','w' ...

  9. Sentry 监控 - Snuba 数据中台架构(Data Model 简介)

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  10. Serverless 如何在阿里巴巴实现规模化落地?

    作者 | 赵庆杰(卢令) 来源 | Serverless 公众号 一.Serverless 规模化落地集团的成果 2020 年,我们在 Serverless 底层基建上做了非常大的升级,比如计算升级到 ...