24-07-22
本周学习总结
感觉一周什么都没干…
全局常量声明:文章内容仅是由教程观点和自己总结获得,仅供参考。
一、字符串格式化漏洞–printf覆盖自己的返回地址
条件:
1、已知栈上的地址。
2、只有一次栈上的字符串格式化漏洞利用机会。
checksec:

除了PIE其他保护全开。
ida:
main:


不用想着去劫持变量w了,因为w是在字符串格式化漏洞完成后赋值为0的,也不能重新劫持返回地址到main或start执行,即使重新执行,w也不会变回0xFFFF。
这个时候就需要我们用一种超前的思想,用字符串格式化漏洞去修改还没有扩展出来的栈。
我们都知道函数执行都是创建栈的,printf函数也不意外,在知道栈地址的情况下我们可以提前预测printf的返回地址的位置,将该地址改为w赋值为0之前,也就是重新执行一遍read函数重新输入,顺便暴露栈上的libc地址,在第二次修改时修改返回地址为one_gadget来getshell。
exp:
1 | |
二、shellcode1–通过openat+sendfile获得flag
条件:
1.黑名单禁用write、writev和open
2.未禁用sendfile和openat
ida:
不用分析,输入完成后直接执行输入的shellcode。
openat:
rdi = -100(代表当前目录)
rsi = “flag”的地址
rdx= 0(只读方式打开)
rax= 257
sendfile:
rdi = 1 (输出流)
rsi = 3(文件流)
rdx = 0
r10 = 0x40(读取字节数)注:实际上可以用rcx控制–glibc2.35-3.8在作为函数调用时
rax = 40
exp:
1 | |
三、shellcode2–64位转32位程序执行
条件:
1.白名单允许fstat、read、write、mmap
2.程序未检查架构
ida:
不用分析,输入完成后执行输入的shellcode。
fstat在64位系统下的调用号是5,而在32位系统下5是open的调用号,我们可以转入32位模式执行open,然后跳回64位执行read和write。
同时我们也需要规划内存地址,因为32位下不能识别8字节地址,所以我们需要通过mmap创建几段可读可写的4字节地址。
exp:
1 | |
四、shellcode3–jmp的妙用–只允许j开头的汇编代码
条件:
1.shellcode无沙盒,限制输入为”j“开头的汇编代码且无法绕过
ida:
不用分析,输入完成后检查是否符合所有输入的汇编代码为“j”开头,然后执行输入的shellcode。
首先来说jmp的一个特殊语法:jmp $+0x??,这句的意思是跳转到rip+0x??执行汇编代码,因为在这道题中我们的汇编代码在栈上,所以rsp也在栈上。
通过一句jmp $+0x3我们可以跳转到可控的汇编代码中。因为jmp本身有3字节的固定位置,但是这些位置根据0x??会变化。
总结的规律就是0x??的数据在一字节的情况下需要+0x2,比如pop rsi是0x5e,那么此时我们就应该在jmp $+0x3后面写入jmp $+0x5e+0x2这样就会完美执行pop rsi并且能执行下一句汇编代码。而超过一字节就需要+0x5,比如sub rsp,0x50是0x50ec8348,对应的规则就是jmp $+0x50ec8348+0x5。
ps:非常好的思路,爱来自熊开泰学长。
exp:
1 | |
下周学习计划
| 应该要做的事情 |
学就完事了
学习感受
新生赛,好玩。