CTFshow pwn03
因为是第一次尝试pwn,见谅..
下载得到一个stack1文件
已知(萌新):做pwn一般是根据所给的程序,于IDA进行反汇编,经过一系列逆天操作获得/bin/bash的地址,然后进行EXP的书写,最后pwn!!!,成功执行命令,拿到flag
当然这道题先跟着WP进行学系~
got与plt表关系(ret2libc)
简单检索一下(我看懵了这就是pwn吗):
PLT与GOT表均为动态链接过程中的重要部分
GOT: Global Offset Table, 全局偏移表,包含所有需要动态链接的外部函数的地址(在第一次执行后)
PLT: Procedure Link Table, 过程链接表,包含调用外部函数的跳转指令(跳转到GOT表中),以及初始化外部调用指令(用于链接器动态绑定dl_runtime_resolve)
Linux虚拟内存分段映射中,一般会分出三个相关的段:
.plt: 即上文提到的过程链接表,包含全部的外部函数跳转指令信息
.got.plt: 即下文将要表达的GOT表,与PLT表搭配使用,包含全部外部函数地址
简单来说,PLT表存放跳转相关指令,GOT表存放外部函数(符号)地址点到为止,继续就听不懂了
延迟绑定实现
一大堆的东西,看不懂就删了吧
https://blog.51cto.com/u_16356440/8601071
这位大佬写的过程很详解了,直观看到动态链接前后的变化,以下内容也来自于这篇博客~
收获:
首先libc中的地址默认开启随机,但是这种随机只是加载到程序时基地址随机,libc内部所有函数的相对位置没有变化。
做题时分两种情况
1.我们已经获得了题目给的libc文件
2.没有libc文件
这两种其实再exp写起来思路是差不多的,都需要泄露一个libc库里函数的地址才能用得了库里面别的我们需要的函数,如system。
所以无论如何我们得先泄露一个函数的真实地址。在根据具体libc库的版本得知所有函数的偏移情况如何,就可以调用我们心心念念的system函数了。
1.这里最好的方法就是泄露已经调用过的函数的地址。因为其地址已经被写入got表了。这里我选择泄露read。
2.如何让程序把got表里的东西写出来呢,我们这里直接调用像puts,write,printf这样的函数就行。看这段payload,题目里其实还有write函数,但是puts函数只需要一个参数,比较方便,不需要找一大堆popret。
1 |
|
将函数的地址绑定推迟到第一次调用该函数
checksec各个值的意义
位置无关可执行文件(PIE)
位置无关可执行文件(Position-Independent Executable)(PIE),顾名思义,它指的是放置在内存中某处执行的代码,不管其绝对地址的位置,即代码段、数据段地址随机化
NX(堆栈禁止执行)
NX 代表 不可执行(non-executable)。它通常在 CPU 层面上启用,因此启用 NX 的操作系统可以将某些内存区域标记为不可执行。通常,缓冲区溢出漏洞将恶意代码放在堆栈上,然后尝试执行它。但是,让堆栈这些可写区域变得不可执行,可以防止这种攻击。
RELRO(GOT 写保护)
RELRO 代表 “重定位只读(Relocation Read-Only)”。可执行链接格式(ELF)二进制文件使用全局偏移表(GOT)来动态地解析函数。启用 RELRO 后,会设置二进制文件中的 GOT 表为只读,从而防止重定位攻击
开始:
使用IDA反汇编打开stack1,看到main函数
1 |
|
有一个pwnme()
1 |
|
**fgets:C 库函数 char *fgets(char str, int n, FILE stream) 从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
发现只有9个字节大小,但是fgets了100个字节内容,存在栈溢出漏洞
栈溢出题目,基本上不需要调试,ida本身提供的栈空间数据就可以实现偏移的计算。
覆盖返回地址然后执行/bin/sh
第一,找到覆盖返回地址的偏移量,即pwnme这个函数的返回地址
返回地址:当前fgets函数结束后,程序下一步要到达的地方
第二,找到/bin/bash在哪里,例如,如果题目有一个函数shell里面有system(“/bin/bash”),即找到这个shell函数的调用地址
附上一个简单的payload
1 |
|
payload = 填充字符 + system地址(ret中eip的位置)
尝试gdb stack1再run不行,存在nc(checksec最初发现了nc开启)
手动添加chmod +x stack1
理一下思路,现在我们发现了栈溢出,代码中没有system也没有/bin/sh,都要在动态库里找,而且要找到返回地址的偏移量
32位的程序,通常情况加4个字节覆盖到返回地址
或者
1 |
|
运行cyclic 生成随机字符串;获取溢出地址,通过 -l 计算偏移
工具pade也可以很方便的计算出偏移量
但是问题是关于另一个通过动态链接获取到/bin/bash还是没太看懂…
1 |
|
成功~
纪念一下自己做出的最简单的exp
1 |
|
哈哈
https://www.toutiao.com/i6978232161929331214/
https://blog.csdn.net/Zheng__Huang/article/details/119484353