B站pwn教程笔记-5

复习和回顾

首先复习一下ELF文件在内存和磁盘中的不同。内存只关注读写这权限,会合并一些代码段。

动态链接库只在内存中单独装在一份

 因为很多软件都要用动态链接库了,不可能一个个单独复制一份。但是在有的调试环境下会单独显示出来各一份。

ld.so是装载器。

为什么用栈来储存,因为函数都是后调用先返回,刚好符合栈的后进先出的特点。 

ebp指向先前EBP的字节的开头部分(默认小端序)返回地址上面紧跟的就是子函数参数,

为了绕过一些保护手段,攻击手段不断升级了

ret2libc

最后EIP地址改为libc库里面的位置

pwntools获取某函数在got表项地址。 

左图为64位地址空间,右边是32位。(没有开启pie)

1.右边长度长,高地址6字节。 

2.地址起始位置不一样,具体看图,64是400000,32是8048000。下面前半部分是关闭金丝雀,后面是关闭PIE

nop滑梯

nop的机器码是0x90。见下图,假如没有开启站保护,但是这虚拟内存有时候不断和内核有随机偏移量,因此我们无法得知shelllcode的具体地址,就可以溢出大量的nop,然后让eip指在大致的地方,不断执行nop最终到shellcode。

下图是 ret2shellcode和ret2libc的对比。

栈这样构造的原理

此时栈的返回地址已经被覆盖为system。这时候system函数就来找参数。但是需要注意他的长参数在他上方两个字长。exit函数同理。但其实exit并不是必须有,有的题只要拿到system就够了。

为啥会这样呢?正常情况而言应该如下图,调用函数的时候父函数保存的参数下方有ret addr和prev ebp,应该隔了俩东西,实际上上图他们的参数仅仅相隔一个东西。

一般子函数父函数分界线就是下图所示。

解释:大家看system函数的汇编部分。其实基本上一个子函数都是以push ebp开头的,也就是说call指令是提供了ret addr这部分,实际上的prev ebp是子函数自己汇编第一句话压入栈之中。我们溢出的时候是控制在一个字节,实际上执行到system栈自己就搞了一个ebp,并不矛盾。关键是不能错误地理解为call system执行的时候就已经会自动生成prev ebp了。

这里要特别注意,还是要从底层汇编代码入手开始分析。这里的两个字长是因为函数本身有push ebp这个指令,但不是所有的情况都是如此,还是要具体情况具体分析。比如调用多个函数,有时候还需要结合pop_ret等指令。如下图(通用结构)上面的是2个函数或以下的简化版本。


动态讲述栈执行过程 

下图就是我们构造出来的栈帧了。

首先eip指在system,执行system,函数自己压入栈帧一个rev ebp,栈结构变为下图。

不要忘记调用约定(32位)参数从右往左入栈,反之,函数找自己参数也是遵循这个规则。exit函数同理,不再赘述了。

如何得知system、exit函数地址 

就算手上有原来的libc文件,乍一看也肯定不知道。因为有ASLR地址随机化。

现在复习一下昨天的内容,也就是动态链接过程。最后都会指向libc的system。

也就是说,不管程序在什么地方引用过库函数,肯定在plt表就有对应的表项。如果没有,也有攻击手段,会通过泄露大量信息之类的拿到地址。,以后应该会学习到。

所以不难理解,直接让代码跳到system@plt,就等同于执行system,这也就解答了如何得知他的地址的疑问,我们只要让这个函数运行起来就可以了。

实战

漏洞还是很明显

一般情况下先要给“bin/sh”给read进内存空间中🤔

用这行代码直接找到system的plt地址

这行代码可以快速列出字符串,配合grep可以过滤

 

之前介绍过,可以找字符串的地址。next是迭代器。

 

PAYLOAD

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值