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

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

先介绍一个很好用的yige wangzhan 贝壳风暴     Shell-Storm  更难一点的题目会用到

不光有大佬的博客,他还搭建了两个在线网站

一个是汇编反汇编器,还有一个是shellcode database,包含了各种各样的架构特性

在linux中一般攻击的架构是X86-64,X86

ret2libc2:

checksec一下

拖入ida中,这一题跟上一题很相似,可以先试着做一下

这题难度肯定比上一题有提高,没有bin/sh

可以先试着把第一题的攻击脚本放到第二题运行,由于没有bin/sh,就行不通,那么需要写一个bin/sh,

对于ROP,第一步将bin/sh写入程序中,第二步继续控制程序执行流,到system传进去,并且把刚刚写的地址传进去

回到main函数,需通过ROP写,我们需要思考怎样通过程序执行流读入我们自定义的字符串bin/sh,写到哪,要写到确定可写的区域,这样就会想到bss段,在buf2这个位置

接下来就是怎样通过ROP将bin/sh读入程序的buf2中呢,类似于ROP调用system函数

这个漏洞是gets触发,就ROP到gets函数,在gets函数读取bin并放入buf2,继续ROP控制执行流到system plt即可

构造payload:

第一种方法:

如图,填写一堆垃圾数据,覆盖到返回地址,控制程序执行的第一条指令,先是get plt,参数是向上数两个位置填写buf2,get完了就是system plt,参数向上数两个字长,填写bin/sh字符串,把地址当作参数传给system能执行system bin/sh

算出地址间的距离,填入数据,找其对应的地址,ida、pwntools、gdb都可以

以下就是构造payload的内容 

payload发过去之后会执行get函数,需要我们构造一些输入,把bin/sh发送给他,才能执行接下来的函数

新elf命令,获取buf2地址

下面是攻击本地,还要有get,system地址,构造垃圾数据,进行远程交互,获得shell

命令sendline是send后直接加一个换行符,send是不加换行符,get函数在读取用户输入时到换行符就结束,而read是都读取包括换行符

攻击远程

 第二种方法:

上面是调用两个和两个以下的,而这个是通用的。

在ROP过程中,每调用一次库函数后,就要使用特殊的gadget平衡栈,这里用pop ret

这是一个动态链接的程序,缺乏gadget,pop ret只要一个,满足弹出栈中数据,ret即可。以下是很有限的,但是能获得pop ret的,用来平衡栈

栈,从下往上,从低地址指向高地址

思路就是用完就扔,向buf2里读取bin/sh,向buf2中get字符串,而用完后,buf2还留在这里,需要清理,以便后面的进程,所以当get使用完buf2这个参数后,把栈清理掉

首先gets这个函数本身执行的时候主函数就有个ret来将它pop到eip,相当于已经清理了gets函数。gets函数下面的空白显然会由gets函数执行ret来清理。 

我们可以用pop|ret来清理。pop ebp有点不合适,ebp还有其他的用处(虽然已经被覆盖了),我们用pop ebx这样的通用寄存器来清理栈吧。

进入下一部分,system plt,同以上步骤一样

ret2libc3: 

checksec,看着好像跟上一题一样,但是增加了更多保护措施

ida反编译 

我的天,这看着就不那么妙了,它还有另一个可执行文件libc

看代码,输入了一些东西,如你想从内存中知道些什么吗。fflush函数是清理缓冲区,这里没有set buf函数。就是把上面一系列输入放入stout缓冲区里,使用ffliush函数将其输出到屏幕上,接下来read 0xA 到buf(A后面u表示无符号)。strtol将字符串转化为long型长整型,第一个参数是0,表示标准输入,标准输出是1,标准错误是2

补充:ida里一些快捷转换,右键,第一个转为十进制,第二个事八进制,第三个是字符,用R将字符转化为字符串,10对应换行符

u是unsigned int,后面会讲到整数溢出漏洞,下图看着就是个数字,但是这是错误的

想看地址为12对应的值,输入的并不是1100,而是一个字符串

如果输入12,得到的并不是12对应整数的值,而是对应ASCLL码的值,而strtol就可以转

回到正题,继续向下看有个see_something函数,跟进,它接收了一个指针,把指针对应的内容按指针格式打印了出来

继续回到主函数看有个v8,为了便于分辨将其改为address,按n键可以改,还有不想看到DWORD按 / 删去,int 64是8字节的int

下面代码和上面相似,就有个自定义的输出内容

找漏洞思路:

找栈溢出漏洞的技巧,在输入内容的地方输超长垃圾数据,如果栈溢出,就会进行控制覆盖,程序就会崩溃。但是无效地址也会崩溃,所以要用有效地址

一大堆j造成栈溢出,在代码中寻找。从第二个read,寻找漏洞位置,可以画栈结构,src与ebp距离0x10E,大于0x100,并不是这里。

栈帧: 

减的越多,离其越远,处于低地址位置。对于ida,写在最下方处于最高地址,从上到下逐渐增大

下图是main函数的栈帧中用来保存局部变量里的local viriable区域的数据分布,中间剩余的是src区域,0x100

找一下漏洞在哪,read没有溢出,继续向下看,puts,return肯定不会栈溢出,那么就在print_message

char后面与ebp相差0X38,dest起始值,将src地址里的内容复制给dest,src是0X100,dest是0X38,其实栈溢出漏洞就在这里

还原一下函数栈的工作过程(部分),将参数压栈,src的地址,看一下函数的汇编代码

第一行push ebp(main函数的) 

关于这题的续解:

之前已经知道栈溢出就在strcpy src 和 dest,下一步就要找后门函数,在之前的checksec中,并没有text段时可读可写可执行的,所以shellcode也不行。接下来是systemcall思路,用ROPgadget,也不行

接下来就是libc了,但是并没有本来的bin/sh,需要自己处理。左边栏plt里没有system函数。这就是这道题麻烦了

之前libc中不知道这个地方的system地址,它是在libc的动态链接库,地址被随机化,我们是用plt的地址来代替。就像之前讲的一样,终点就是system libc。但是连plt表象地址都没有

我们只有把libc system的真正地址找到填进去。 

plt是代码的填写者,got是代码的保存者

这道题并没有调用system,got表里没有,即使有也不行。got表填写的函数的真实地址第一次被调用之后才可以。got表里保存这个函数plt表象地址,泄露出来的就是elf自己保存的plt保存地址,而不是libc

断点打在第一个read

有一些填写libc里的,说明已经被执行了,可以利用这些地址获取libc里的地址。一般选用puts,因为它的使用次数比较高。输入要把十六进制转为十进制,注意ASLR是打开的,远程libc的地址是随机的,本地只能看出偏移量

那么这就要用到另一个文件找偏移量,根据put的真实地址,得到system的地址

用这道题实战一下:要分析两个elf文件,一个是libc3,一个是libc.so。接着获取puts地址,远程链接,接受数据并输入

得到一个值。

程序接收的是字符串,我们要发的是对应的ASCLL码,就会返回puts的值(注意地址随机化)

后三位是一样的。这里就是页(内存分配的最小单位)。大小是4KB。在虚拟内存中连续但在物理内存中不一定。 但是要页对齐

12个二进制位,12bit,0000 0000 0000,每四个可以转换为一个十六进制数。每1个bit有两种状态,12个就有2的12次方,也是能表示的地址数量,4KB

 puts函数在偏移141的位置,puts末三位000 140

知道了puts函数的真实地址,以及静态分析libc函数puts函数和system函数的距离,就能得出system地址。得看libc system和system函数分别的偏移

libc system在puts的低地址位置 

得到system函数的真实地址,接下来就是栈溢出,溢出的数据可以用来构造ROP链,整体形成payload。

不能用原来的地址,动态调试,把有效地址找出来。断点下在print_message

计算eax到ebp之间距离,看需要填入多少垃圾数据,接着从ebp构造ROP链,用gets将bin/sh读入到内存中,再system调用内存,进而获取shell。

还有一个重要的事情bin/sh要写到哪里。其实这道题虽然对应数据段没有sh,但是sh也能达到攻击效果。sh通过环境变量执行bin/sh,然后通过绝对地址再执行放在bin目录里的可执行程序。

即使sh段没有字符串,但是如图,例如fflush,是函数名,存在于程序中,是对应的ASCLL码的值,如果把sh截断传给bin/sh,就会向后读sh,0X0,最后就是system("sh") ,也能达到攻击效果。

只要能达到攻击效果,任何可以被我们利用的数据都可以使用的,甚至是函数名,像这题函数名字符串就可以为我们提供sh。

 

http://www.xdnf.cn/news/1213201.html

相关文章:

  • 洛谷刷题7.30
  • C++反射
  • 认识ansible(入门)
  • Javascript 基础总结
  • docker:将cas、tomcat、字体统一打包成docker容器
  • VS Code中如何关闭Github Copilot
  • 技术速递|GitHub Copilot 的 Agent 模式现已全面上线 JetBrains、Eclipse 和 Xcode!
  • 企业级WEB应用服务器TOMCAT
  • 【IDEA】JavaWeb自定义servlet模板
  • 工厂方法模式:从基础到C++实现
  • 华为昇腾NPU卡 文生视频[T2V]大模型WAN2.1模型推理使用
  • Kubernetes资源调优终极指南:从P95识别到精准配置
  • Kong API Gateway的十年进化史
  • Spring Cloud Gateway静态路由实战:Maven多模块高效配置指南
  • ‌CASE WHEN THEN ELSE END‌
  • YOLO-01目标检测基础
  • 【Rust多进程】征服CPU的艺术:Rust多进程实战指南
  • 力扣热题100-------74.搜索二维矩阵
  • SpringBoot 整合 自定义MongoDB
  • Flutter封装模板及最佳实践
  • CVAE 回顾版
  • STM32学习记录--Day3
  • gaussdb demo示例
  • 大语言模型(LLM)技术架构与工程实践:从原理到部署
  • 深入剖析 Spark Shuffle 机制:从原理到实战优化
  • 智能矿山综合管控平台
  • 非凸科技受邀出席第九届AIFOF投资创新发展论坛
  • 剧本杀系统 App 开发:科技赋能,重塑剧本杀游戏体验
  • forge篇——配置
  • SpringBoot+Three.js打造3D看房系统