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

做交易网站需要用到的软件有哪些信息流优化师是干什么的

做交易网站需要用到的软件有哪些,信息流优化师是干什么的,如何建购物网站,怎么在网上推广广告pwn学习笔记(5)–格式化字符串漏洞 ​ 前言:由于条件有限,因此对于该漏洞的学习不算很多, 格式化字符串漏洞基础: 格式化字符串介绍: ​ 格式化字符串函数可以接收可变数量的参数&#xff0…

pwn学习笔记(5)–格式化字符串漏洞

前言:由于条件有限,因此对于该漏洞的学习不算很多,

格式化字符串漏洞基础:

格式化字符串介绍:

​ 格式化字符串函数可以接收可变数量的参数,并将第一个参数作为格式化字符串,根据其来解析之后的参数,格式化字符串的利用一般分为三个部分:

  • 格式化字符串函数
  • 格式化字符串
  • [后续参数]

格式化字符串函数:

​ 常见的格式化字符串有:

输入:

  • scanf()

输出:

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

格式化字符串的格式:

%[parameter][flags][field width][.precision][length]type

​ 其中,需要注意的有parameter参数,以及type参数:

parameter:

​ n$,获取格式化字符串中的指定参数

type:

  • d/i,有符号整数
  • u,无符号整数
  • x/X,16 进制 unsigned int 。x 使用小写字母;X 使用大写字母。如果指定了精度,则输出的数字不足时在左侧补 0。默认精度为 1。精度为 0 且值为 0,则输出为空。
  • o,8 进制 unsigned int 。如果指定了精度,则输出的数字不足时在左侧补 0。默认精度为 1。精度为 0 且值为 0,则输出为空。
  • s,如果没有用 l 标志,输出 null 结尾字符串直到精度规定的上限;如果没有指定精度,则输出所有字节。如果用了 l 标志,则对应函数参数指向 wchar_t 型的数组,输出时把每个宽字符转化为多字节字符,相当于调用 wcrtomb 函数。
  • c,如果没有用 l 标志,把 int 参数转为 unsigned char 型输出;如果用了 l 标志,把 wint_t 参数转为包含两个元素的 wchart_t 数组,其中第一个元素包含要输出的字符,第二个元素为 null 宽字符。
  • p, void * 型,输出对应变量的值。printf(“%p”,a) 用地址的格式打印变量 a 的值,printf(“%p”, &a) 打印变量 a 所在的地址。
  • n,不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。
  • %, '%'字面值,不接受任何 flags, width。

​ 下面使用几个案例来说明下几个需要注意的参数:

parameter:

​ n$ 表示获取后面参数列表中的第几个参数。

​ 比如如下代码:

#include<stdio.h>
int main(){printf("%2$d\n",1,2,3);return 0;
}

​ 通过编译运行之后得到的值却是

root@g01den-virtual-machine:/home/g01den/Temp# ./a
2

​ 好了,我们稍微修改下刚刚的代码:

#include<stdio.h>
int main(){printf("%d%d%d\n",1,2,3);return 0;
}

​ 然后编译为32位之后,查看下汇编代码:

0000119d <main>:119d:       8d 4c 24 04             lea    0x4(%esp),%ecx11a1:       83 e4 f0                and    $0xfffffff0,%esp11a4:       ff 71 fc                push   -0x4(%ecx)11a7:       55                      push   %ebp11a8:       89 e5                   mov    %esp,%ebp11aa:       53                      push   %ebx11ab:       51                      push   %ecx11ac:       e8 2b 00 00 00          call   11dc <__x86.get_pc_thunk.ax>11b1:       05 27 2e 00 00          add    $0x2e27,%eax11b6:       6a 03                   push   $0x3      <-------------------------------11b8:       6a 02                   push   $0x2      <-------------------------------11ba:       6a 01                   push   $0x1      <-------------------------------11bc:       8d 90 30 e0 ff ff       lea    -0x1fd0(%eax),%edx11c2:       52                      push   %edx11c3:       89 c3                   mov    %eax,%ebx11c5:       e8 86 fe ff ff          call   1050 <printf@plt>11ca:       83 c4 10                add    $0x10,%esp11cd:       b8 00 00 00 00          mov    $0x0,%eax11d2:       8d 65 f8                lea    -0x8(%ebp),%esp11d5:       59                      pop    %ecx11d6:       5b                      pop    %ebx11d7:       5d                      pop    %ebp11d8:       8d 61 fc                lea    -0x4(%ecx),%esp11db:       c3                      ret

​ 能够发现在我指的那三行,在调用printf函数之前是先将参数从右向左压入栈中,之后通过读取栈的参数与格式化字符串一起打印出来。

格式化字符串漏洞:

​ 有了前面的那些储备知识,这个时候就可以来看看格式化字符串的漏洞了。

初探:

​ 首先,写一个程序,如下内容:

#include<stdio.h>
int main(){printf("%x  %x  %x  %x  \n",0x1);return 0;
}

​ 那么,直接进行动态调试,观看main的栈帧中相关的信息:

00:0000│ esp 0xffffd500 —▸ 0x56557008 ◂— '%x  %x  %x  %x  \n'
01:0004│-014 0xffffd504 ◂— 0x1                                            <--------------------
02:0008│-010 0xffffd508 —▸ 0xf7fbeb20 —▸ 0xf7c1acc6 ◂— 'GLIBC_PRIVATE'    <--------------------
03:000c│-00c 0xffffd50c —▸ 0x565561b1 (main+20) ◂— add eax, 0x2e27        <--------------------
04:0010│-008 0xffffd510 —▸ 0xffffd530 ◂— 0x1        					  <--------------------
05:0014│-004 0xffffd514 —▸ 0xf7e2a000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac
06:0018│ ebp 0xffffd518 —▸ 0xf7ffd020 (_rtld_global) —▸ 0xf7ffda40 —▸ 0x56555000 ◂— 0x464c457f

​ 然后,运行到printf函数之后,再看看输出的值是多少:

pwndbg> n
1  f7fbeb20  565561b1  ffffd530

​ 发现输出的值和箭头指出来的值一样。因此,黑客则可以利用此漏洞配合**%n$d**来进行内存的读取了。

一次简单的漏洞的实例:

​ 实际上,格式化字符串的漏洞很多时候都是由于程序员们偷懒,才会导致一些漏洞的产生,比如下面的程序,如果写成这个样子:

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

​ 如果是这样的话,程序运行就不会出现太大的问题,但是,当程序员偷懒,使用下面的写法,就会出现问题:

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

​ 运行的话就会出现如下的结果:

root@g01den-virtual-machine:/home/g01den/Temp# ./a
aaa.%x
aaa.fff53a28

​ 根据gdb调试,就会发现,它输出了比esp地址高4字节的那一地址的数据。

泄露内存:

​ 还是刚才那个程序,其实可以在这个时候多输入几个%x来进行父函数栈帧的esp高4字节的地址开始的多个字节的内存,或者通过n$来进行任意内存的读取:

aaa.fff53a28root@g01den-virtual-machine:/home/g01den/Temp# ./a
%x.%x.%x.%x.%x.%x.%x
ff8631d8.0.565a31d4.0.0.252e7825.78252e78root@g01den-virtual-machine:/home/g01den/Temp# ./a
%3$x
565cf1d4

泄露任意地址的内存:

​ 上一个方法只是泄露了栈上的数据,其实,格式化字符串可以对任意内存地址的数据进行泄露。、

​ 攻击者可以使用类似于"%s"的格式规范做到泄露栈中存放的值对应的地址的字符串的内容,这里引用下dalao的对于%s的讲解:

程序会将%s指向的地址作为一个ASCII字符串处理,直到遇到一个空字符。所以,如果攻击者能够操纵这个参数的值,那就可以泄露任意地址的内容。

或者说

%s 是把地址指向的内存内容给打印出来,可以把 函数的地址给打印出来。

​ 也就是说,想要做到任意地址的内存泄露,就需要想办法对栈上的某个地址的值进行修改为想要获得的那个字符串的地址。

覆盖栈内存:

​ %n不能够输出字符,但是,它能把已经成功输出的字符个数写入对应的整形指针参数所致的变量,只要变量对应的地址可写,就可以利用格式化字符串来改变其对应的值。

一般来说,这种方法利用的步骤为:

  • 确定覆盖地址
  • 确定相对位移
  • 进行覆盖

注:以下为我个人的见解,如有问题,请指正。

​ 首先,之前说过了%n这个格式化字符串的作用是啥:

%n,不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。

​ 之后,用一个程序作为示例:

#include <stdio.h>
int a = 123, b = 456;
int main() {int c = 789;char s[100];printf("%p\n", &c);scanf("%s", s);printf(s);if (c == 16) {puts("modified c.");} else if (a == 2) {puts("modified a for a small number.");} else if (b == 0x12345678) {puts("modified b for a big number!");}return 0;
}

​ 这个程序的格式化字符串漏洞的函数很容易就能找到,那就是printf(s),因此,假设对变量c进行修改,就需要用到%n对C进行修改,所以,格式如下:

c的地址+12个任意的字符+对应格式化字符串的参数的偏移

​ 好了,实际试试看吧:

AAAA,$p,$p,$p,$p,$p,$p,$p,$p,$proot@g01den-virtual-machine:/home/g01den/Temp# ./a
0xff8d3ad4
AAA,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p
AAA,0xff8d3ad8,(nil),0x565d51e4,(nil),0x315,0x2c414141,0x252c7025,0x70252c70,0x2c70252c,0x252c7025,0x70252c70

​ 由此可知,传入的格式化字符串AAA,所对应的参数是第六位,因此,对应格式化字符串对应的偏移为6,也就是说,值为%6$n,好的,之后就是c的地址,我在学到这里的时候出现了理解不能的问题,最后大致是整明白了,就是不知道对不对。

​ 对于C的地址,我认为是,正是因为构造的格式化字符串的前四个字节是c的地址,因此,%n这个格式化字符串在写的时候对应的就是第六个参数,而第六个参数的前四个字节就是c的地址,因此就成功修改了c这个变量的值;**那么问题就来了,为啥不能直接指定第五个参数进行修改呢?**我个人的理解是这样的:因为第五个参数存放的并不是c这个变量的地址,是789,因此,%n就试图把16写入789这个地址里去,但是,这个地址要么不存在,要么就是无法访问,则会出现segment fault,导致程序出现了错误。

覆盖小数字:

​ 那么,问题又出现了,因为如果让变量的地址作为开始的字符,就会导致%n写入的最小的值也是4,那么,如果要让某个变量被覆盖为2,又该怎么做呢?

注:以下对于内容的解释部分均为我自己的理解,如有错误,还请指正。

​ 照理来说,想要某个变量被覆盖为2的话,就需要诸如

aa%k$naa+地址

​ 这样的字符串,所以是为啥呢?

​ 这里借用julao们的说法是

aa%k n x x ,如果用这样的方式,前面 a a nxx,如果用这样的方式,前面 aa%k 是第六个参数, nxx,如果用这样的方式,前面aanxx 是第七个参数,后面在跟一个 我们想要修改的地址,那么这个地址就是第八个参数,只需要把 k 改成 8 就可以把这第八个参数改成 2,aa%8$nxx

​ 我个人的理解为,在栈中,每个字符的长度为1字节,另外,对于格式化字符串的参数传递而言,每个参数都占用了四个字节(32位),所以,这里需要前和中都构成四个字节的字符串,因此,第六位的字符串就是aa%k,第七位就是$naa,第八位就可以传入变量的地址了。

后续的内容需要花费一些时间,短时间内先放放,暂时放下不管,之后有时间再来补充。

http://www.ritt.cn/news/13412.html

相关文章:

  • 公司名字大全20000个三个字淘宝优化关键词的步骤
  • 做自媒体素材搬运网站新闻头条今日新闻
  • 工业网站开发商个人网站该怎么打广告
  • 关于政府门户网站建设方案中国电信视频app下载
  • 张家港网站建设门店培训加盟
  • 怎么在wordpress上设计网站软文广告经典案例
  • 深圳招聘信息最新招聘2022seo网络推广课程
  • 网页版微信二维码一直失效seo广告优化多少钱
  • 我想做服装网站怎么做百度指数十年
  • f3322免费域名申请北京seo优化服务
  • 个人做论坛网站要什么证件竞价推广平台有哪些
  • 网站自己建设湖北seo
  • 看装修效果图哪个网站好整站排名优化公司
  • java做房屋拍卖网站海洋网络推广效果
  • 网站建设哪个公司好seo查询seo优化
  • 昆明网站建设手机版搜索热度查询
  • 怎么做flash网站晨阳seo服务
  • 北京市房山区住房和城乡建设委员会网站seo和sem的联系
  • 做logo设计网站seo和sem哪个工资高
  • 微企申请网站中国百强县市榜单
  • 用糖做的网站搜索关键词排名优化软件
  • 权威的网站制作营销策划公司 品牌策划公司
  • 洪雅网站建设网站推广的具体方案
  • 河南最新疫情公布成都seo经理
  • 网站开发样板产品推广方案
  • 怎么做属于自己的音乐网站google框架三件套
  • 哪里建设网站什么是搜索引擎优化seo
  • 保定网站制作价格青岛谷歌优化
  • 做网站需要公司资质吗公司网站费用
  • 微信网站建设公司首选企业查询官网