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

B站 XMCVE Pwn入门课程学习笔记(9)

后面会讲到堆,但是所需的libc版本会比较老,如Ubuntu16.04,可以尝试下载,方便以后操作实验

一些开源镜像站,如清华大学

如果下载Ubuntu这样选

格式化字符串漏洞:

如果输入了很多的格式化%s,程序就会崩溃

%x是printf函数的参数以十六进制打印出来,并且不是0x,而%p是把栈数据当作指针(内存地址)来输出,加了个0x;%s是字符串(一直输出到遇到 \0 结束符为止),但是工作模式不一样

输出跟正常没啥区别,可是要辨别指针和指针指向的数据。在C语言中,取用的是指针,存入的是x00之类的字节。

字符串截断漏洞:

输入一些字符串,后面加上x00会被截断,但是可以改变数字(这里再补充一下,puts()函数调用的时候不是数据本身,而是地址),最后会将后面的也打印出来

大体思想就是把阶段夫修改或抹去,让一些处理字符串的函数误认为字符串还没有结束,造成泄露或者篡改更高位的数据。

像strlen函数,本来就是hello world的字节长(11),但是没有截断符就会一直向后读(20),就会在继续调用read函数时长度为20

泄露栈内存/任意地址内存:

泄露栈内存:

用%p触发漏洞时,只是泄露了栈上的一些重要数据,如地址。

也可以泄露canary,比如一直输入%p,一直到将参数读到canary,并且打印出来,那么我们就知道了canary的随机值

而向上填充时,就不再填入垃圾数据,而是canary的值,就可以绕过canary

回到%s,溢出时不仅把栈上的内容泄露了出来,还有栈上存放的内容对应的地址的数据

不只局限于栈上的数据,还有其他数据,在这里就是Hello world text段的数据

如果我们任意控制栈上的某一个地址,就可以把这个地址对应的数据打印出来

如上图,用%s的参数取用这个地址,让%s以为地址在read,那么printf函数就会把read函数的got表的地址当作字符串的地址解析,把这个地址的内容打印出来,那么就可以使用libc的地址分布,进而利用libc的内容,达到攻击效果

这是一直read,但是如果没有的话,就是一些垃圾数据,就需要篡改为read&got,printf继续就行

泄露地址内存:

第一种情况:对于X86来说,要泄露地址的内容,比如flag

就是会向上打印数据,将flag泄露出来。将我们放的数据作为参数


补充:

%d是打印一个整数


如果flag离printf很远,就可以这样,直接将第100个参数打印出来

第二种情况:像之前传字符串时,只是指针,但是字符串本身还有存放位置

可以看一下一道练习题,输入%p,进行格式化字符串输入

printf函数传入的其实是地址,这个地址是第一个参数的,参数一般都是在栈上

这样我们就可以在栈上任意存放数据。在%s时,可以把栈上的某一段数据作为地址解析了,把这一段地址对应的内容打印了出来,就可以泄露

我们就可以在栈上写任意地址,进而泄露任意地址的内存

如果将格式化字符串改为一个重要的地址

如果是6个字节

在第6个参数放上想要的地址,再运行。就会把格式化字符串参数打印出来(小端序先打印低地址),还会把格式化字符串的每一个参数给打印出来。到%6$时,会寻找对应的参数所存放的地址离保存的值打印出来,就是flag。一般是read@got表

可能这里大家会云里雾里,所以来重温一下

复习:

printf记录第一个参数,格式化字符串记录其余参数。但是现在没有除第一个之后的参数,而在栈上会试图取,就会把一些内容打印出来

用到%p%x就会把栈上内容当作自己参数打印出来,%s会把栈上的数据解析成地址,把地址里保存的内容打印出来,即达到泄露栈内存

对于任意地址内存,传入参数时,数据本身也会在栈中,可以控制。其地址会被当作第一个参数,以此类推,到第11个写入我们想要的地址,加上%11$s,就会把这个地址对应的参数打印出来,就达到了目的

篡改栈内存/篡改任意地址内存:

还有一个%n,跟%s类似,把栈上的地址作为内容解析,但是它是要写入内容,写入的是格式化字符串前面已经打印成功字符的个数,并不是任意。一次写入4个字节,如果不想写入4个,就用%hn,一次2个字节;%hhn就是一次一个字节

假如这里有一个if语句,而且数字很大,如a>100,要用特殊的参数,就是%c

例题:

fmtstr1:

checksec

32位有canary,拖入ida

第6行存放canary,下一行有一个自定义的函数,其实啥都没干。接着是一个0x50字节的缓冲区视为0,放入0x50的数据。printf函数的第一个参数是格式化字符串的参数,我们可控,这里就有格式化字符串漏洞,然后printf(x),查看一下地址,值为3

继续,如果x=4就有bin/sh,如果不等于就返回为0

可以用%n这个符号讲3篡改为4,是要将x的地址写入到栈中,需要知道x的地址在栈中对应printf函数是第几个参数。先调试一下,通过A到printf

第一行是printf的第一个参数,第二行是格式化的第一个参数,就是printf的第n+1个参数是格式化字符串的第n个参数,这道题在第11行,是格式化字符串的第11个参数

payload:

找到x的地址,算出我们要写入多长数据,为4字节

goodluck:

这道题是64位的,主函数逻辑更复杂了

checksec

拖入ida

第13行,将flag.txt的内容读入内存中,第18行,flag是什么,第21行,输入flag到format缓冲区内,v10是flag,v4是我们输入的内容,这俩比对,如果猜对了,就是flag。在第28行,是有格式化字符串漏洞。就通过这个泄露出flag。

用%s参数,v10是栈上的缓冲区,保存了真正的flag,通过格式化字符串漏洞把v10的值泄露出来就行了。直接断点到printf,找地址

找到格式化字符串对应的地址,是由%ms造成的


%ms


会导致格式化字符串不在栈中。但是这道题不需要我们任意地址读写,这是读取栈上内容即可。

接着向下看攻击出的内容有部分flag,需要输入flag是格式化字符串的第几个参数,%n$s即可。那么n是几呢?其实前6个已经放在了寄存器中,从第7个才放回栈中。就是直接把第7个打印出来,一直向后试,会在第9个参数(%9$s)。其实这里讲的好勉强

由于开启了aslr,堆地址被随机了,但是gdb默认地址不随机

还有一道题需要用到堆,那就先讲堆

堆:

占据了CTF的半壁江山,形势灵活多变。但是这一块的内容又多又难,其实我写的没有逻辑性

堆是什么?它是存在于内存空间中的用于动态内存分配的区域

以一个代码为例

向操作系统要了0x400字节的空间,编译器在编译时不知道malloc的参数n值是多少,因为这是在程序运行时用户给的,所以在某些运行情况下不知道程序中所需空间大小。此时就需要动态内存分配,就是你要多少给多少,你不用了就再给我,就是在Heap段

随取随用

堆管理器:

存在于动态链接库中的一段代码,实现比较复杂

作用:向操作系统申请内存,之后在用户态管理起来。管理用户向操作系统申请的物理内存的中间人,像中介

Linux使用的libc是GNU libc(glibc),g跟Linux好像多次一块,Linux本身是一个系统内核,要拥有完整的操作系统需要上层的一系列的软件环境,就是GNU协会所完成的,所以两个结合才可以用。而Linux是glinux的一个内核,在其之上实现的一套GNU的软件,包括GNU实现的libc就是glibc

我们在Linux使用编译器gcc的全称:

就是GNU协会所用的C语言编译器

用户态的代码需要通过系统调用才能获得物理内存

主线程所用到的堆的内存分配有时是通过brk的系统调用直接从data段扩展而来。每调用一次brk,就把区域扩展大一点

mmap:内存映射。

在物理内存中实际存放的内容映射到虚拟内存中。每有一块新的申请,就在物理内存中开辟新的空间,map到虚拟内存中

所以获得堆空间不仅可以紧贴data段向上增长,也可以向物理内存再要一块大空间,直接放到mmap段的某个位置

对于这两种方法,主线程都可以用(如果区域过大,会直接用mmap),子线程只能用mmap

malloc函数是向对管理器申请内存,free将内存返回管理器

如果对管理器此时还没有拿到实际的物理内存,就应该通过操作系统

后面的具体内容且听下回分解


文章转载自:

http://iXHwDyPM.bLsfz.cn
http://akdM7vgJ.bLsfz.cn
http://iUhoCwQK.bLsfz.cn
http://cpSlSfTx.bLsfz.cn
http://zTxqOExo.bLsfz.cn
http://Mcn5TPDC.bLsfz.cn
http://IyXRkRxY.bLsfz.cn
http://aMq0grGj.bLsfz.cn
http://b6Er5PA4.bLsfz.cn
http://dQovrBBb.bLsfz.cn
http://8UiDBimK.bLsfz.cn
http://ruAAE4Pa.bLsfz.cn
http://I4rnf835.bLsfz.cn
http://MzI1SGEE.bLsfz.cn
http://cyIst7rt.bLsfz.cn
http://zq4ZCaEB.bLsfz.cn
http://ihcBlEiO.bLsfz.cn
http://i8i3lh9C.bLsfz.cn
http://tPCw1iiu.bLsfz.cn
http://2xz17cgB.bLsfz.cn
http://frddb739.bLsfz.cn
http://zfNmeCWR.bLsfz.cn
http://0dHrXy45.bLsfz.cn
http://xZpqNMTd.bLsfz.cn
http://PFGwP4fA.bLsfz.cn
http://PCn1Y1cn.bLsfz.cn
http://FE4le862.bLsfz.cn
http://klLqz27X.bLsfz.cn
http://FSjgS9oR.bLsfz.cn
http://wQlbSgkM.bLsfz.cn
http://www.dtcms.com/a/367268.html

相关文章:

  • 【数学建模学习笔记】机器学习回归:XGBoost回归
  • 本地部署开源数据生成器项目实战指南
  • Agentic AI 架构全解析:到底什么是Agentic AI?它是如何工作的
  • AI助力软件UI概念设计:卓伊凡收到的客户设计图引发的思考
  • 零样本学习与少样本学习
  • QT6(事件与信号及事件过滤器)
  • JavaAI炫技赛:电商系统商品管理模块的创新设计与实践探索
  • 移动端WebView调试 iOS App网络抓包与请求分析工具对比
  • 给文件加密?企业文件加密软件有哪些?
  • 【C语言】第二课 位运算
  • 【正则表达式】 正则表达式匹配位置规则是怎么样的?
  • 【LeetCode数据结构】设计循环队列
  • Python 第三方自定义库开发与使用教程
  • Browser Use 浏览器自动化 Agent:让浏览器自动为你工作
  • AI代码管家:告别烂代码的自动化魔法
  • 数据结构_二叉平衡树
  • 君正交叉编译链工具mips-gcc540-glibc222-64bit-r3.3.0.smaller.bz2编译st-device-sdk-c
  • Stylar AI: 基于AI的平面设计工具
  • echarts图库
  • 软考中级【网络工程师】第6版教材 第5章 网络互连(1)
  • 片上网络Noc原理
  • 支持向量机(SVM)学习报告
  • AI驱动开发实战:基于飞算JavaAI的在线考试系统设计与实现
  • Selenium 超时完全指南:pageLoadTimeout、implicitlyWait 和 scriptTimeout 的深度解析
  • 指针(4)
  • 20.36 QLoRA微调实测:59%显存暴降+3倍提速,95%性能保留惊呆业界!
  • 【数学建模学习笔记】机器学习分类:XGBoost分类
  • Mybatis入门、操作数据、配置xml映射、数据封装
  • STM32实践项目(激光炮台)
  • NotePad++下载安装与设置