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

ret2syscall:

先来回顾一下,这道题是静态链接

补充一下xor异或:

逻辑与:&& and 必须两个操作数全部都是1,才是1

逻辑或: || or 只要有一个是1答案就是1

汇编里异或就是xor 只要有一个不一样就是1,一样的是0

另:二进制中,当符号位为1时(即首个为1),表示的十进制数字为负数。

反码:正数反码 = 原码,负数反码 = 原码符号位不变,其余位取反。 如-5的反码为11111010。

补码:正数补码 = 原码,负数补码 = 反码 + 1

现在负数通常用补码表示,其表示简单,且在CPU里可以用加法实现减法运算

xor 相同寄存器(相同寄存器里村的数据是一样的)结果为0

重新回到这题

输入的地址在这里,需要更长的地址获得ebp在哪里

写入缓冲区与ebp距离为108,总共需要写112+return address

写脚本攻击,用到flat函数

gadget要和下面效果一样

需要用到以下指令

| 为管道符,是将前面的数据输出当作后面的输入

grep是把输入中含有后面字符串行输出

同样的要向ebx、ecx、edx,下面那行可以同时把三个包括

payload,运行获得shell

总体下来就是,先112长度的垃圾数据,后面就是gadget,需要用rop,发现两个gadget地址,每一个gadget后面对应的就是要传入的参数,传参之后,第二个gadget(3个参数)到第三个(int 80),send过去,就可以电泳interactive进行交互

系统调用:

其实对于PWN的知识,到现在我其实依旧云里雾里,需要不断地回想。这个老师讲的真的很好,这里正好重新讲了一遍。

Kenel空间操作系统内核的函数,只会给一个接口

一般函数调用:

C函数就是运行汇编,先传参数,再用call指令即可,这是用户自己写的,即Kenel下面用户空间。

直接call即可

系统调用:

int为中断指令

如果想用execve,要通过寄存器(对应eax)传参给call,eax保存系统调用号

sys_write为1 sys_execve为11,0xb

调用0x80要为系统调用传递参数

调用0x80得到bin/sh

回顾payload构造,就是陆续进行覆盖

程序在执行完main后就返回到pop_eax_ret,把eax下一个字长的数据弹到eax里,把下下爱一个字长的数据弹到eip里,进行execve系统调用,里面保存的值必须为0xb,把0xb弹出到eax中,ret,把紧邻的下一个地址弹出到eip里,执行地址里的代码。以次类推,分别pop数据到ebx,ecx,edx里。利用pwntools获得ebx(bin/sh)的地址,最后int 80

覆盖内容:

payload:

动态链接:

基于没有给gadget。中间过程由gcc完成

动态链接的代码在装载步骤可见,静态链接的代码的步骤在链接过程可见

改为静态链接

查看发现静态链接占的内存大很多

动态链接里的puts就像是一个表象(粉色底),没有函数体

而静态链接里的puts有函数体,还会调用其它函数体。函数都必须保存在各自内部

动态链接的相关结构:

.got是全局偏移量表,是变量地址,.got.plt是函数地址。

动态链接过程:

执行代码段需调用foo,不能直接跳到foo,需要代码中的PLT节,每一个动态链接库中的函数都会在PLT节中创建一个表项

call foo后会跳转到plt foo(进程首次调用foo)表项,.plt中的代码会立即跳转到.got.plt中记录的地址,但是got plt中还没有想要的地址,就会跳回到foo plt。接下来就是要找到foo函数的真实地址,并跳到foo

可以相当于plt是菜单,got是食物的位置

push index是一个参数,最终程序会push俩参数,jmp两次,也就是执行了4条汇编代码。

这里的一些地址其实我也不太懂

然后就可以跳到dl_resolve进行解析找到foo函数的实际地址。

第二次调用foo:

就相当于你第一次点外卖不知道每家店的电话号码(地址),动态链接相当于"懒人外卖系统",第一次需要查电话本,以后每次直接拨号(看人家比喻的)

找到foo地址后直接指向foo里的代码

整个过程:

查看plt:

检查对应地址中前20个的值,一个表项是16个字节

具体查看一下

汇编语言中,init用来初始化,接着就是plt

分别对应了pts,printf,exit表项,每一个表项的长度为0*10,16字节,也印证了之前的。包括内容也和之前的一样

往下滑(高地址),可以看到got表项,为8字节,高位为零可以省略不写

查看函数地址,并且反汇编,得到puts函数的真正代码

动调相关指令:

如果想返回上一条指令,程序调试时没有可以直接返回的指令。可以在上一条指令打一个断点,run起来,到点停下来。

gdb的一些功能:

b main 把断点下在main函数

r start运行至断点,如果没有main函数,就会停在程序入口start处

sn为步过,即跳过函数指令里的具体内容继续运行

s为步进,即进入对应函数指令里的具体内容运行,再继续运行

backtrace时显示函数调用栈的一个状态,呈现了函数调用的祖孙关系,如puts函数由main函数调用,以此类推

return直接回到main函数,而不是一行一行的运行到return

retlibc1:

通常也依赖于ROP gadget来创造执行shellcode的环境,但是目标是返回到libc system()函数

先看一下它的保护措施

反汇编猛一下看和上面那个没有任何区别,可以先利用上一题的思路

找一下gadget

可以发现这里的gadget很少,能用的更少。这题是动态链接

如果像ret2text那样找后门函数(长的比较奇怪,是程序员自己写的) ,但是并没有这样的功能

但是system为plt中添加了一些表项,它有什么用呢

向右拖可以发现显示的一些节的名字

而且要给system函数里传参,要用ROP,再栈溢出的同时用gadget直接布置到栈上,最后传到system

构造(后面会细讲为何):

传给system的是bin/sh的地址,在.rodata

这样可以达到system(bin/sh)的效果,为获取shell

详细的ret2libc解题过程请看下篇博客

相关推荐
IMPYLH1 小时前
Python 的内置函数 hasattr
笔记·python
moxiaoran57532 小时前
uni-app项目实战笔记17--获取系统信息getSystemInfo状态栏和胶囊按钮
笔记·uni-app
智者知已应修善业2 小时前
【51单片机2位数码管100毫秒的9.9秒表】2022-5-16
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
知青春之宝贵2 小时前
BEV感知-课程学习详细记录(自动驾驶之心课程)
学习
HeartException2 小时前
Spring Boot + MyBatis Plus + SpringAI + Vue 毕设项目开发全解析(源码)
人工智能·spring boot·学习
饕餮争锋2 小时前
设计模式笔记_创建型_单例模式
java·笔记·设计模式
teeeeeeemo2 小时前
Number.toFixed() 与 Math.round() 深度对比解析
开发语言·前端·javascript·笔记
蚊子不吸吸4 小时前
在Docker、KVM、K8S常见主要命令以及在Centos7.9中部署的关键步骤学习备存
linux·学习·docker·kubernetes·centos·k8s·kvm
谷雪_6584 小时前
学习华为 ensp 的学习心得体会
网络·学习·华为·网络工程·ensp
懒惰的bit5 小时前
STM32F103C8T6 学习笔记摘要(三)
笔记·stm32·学习