为什麽会先说防御机制呢
因为在打 pwn 之前
要先对这些防御原理有基础才有办法知道你要怎麽打
在学习以下东西时
建议各位先去弄一台 linux 环境并且装上 pwntools
装好後有个指令叫做 checksec
可以检查这支程序有什麽样子的保护
名称 | 用处 |
---|---|
Arch | 架构 |
RELRO | read only relocation , 用来限制程序中重定向位置的可写区域, 通常 Partial RELRO 代表 GOT表 可写 |
Canary | stack 保护机制,利用 cookie 来确认是否被攻击,因为bof攻击通常会将整个 stack 改写而覆盖掉 cookie |
NX | No Execute(Win平台上称之为 DEP), 不能再stack上执行指令 |
PIE | Position Independent Code 或称 ASLR(address space layout randomization) , 记忆体地址随机化 |
从上面的表可以知道
这支程序 GOT 表可以被修改
没有随机记忆体区块
stack 上不能执行东西
大宗分为两大类
因为记忆体有两个大主体嘛 stack 跟 heap
今天只会提到 stack
在攻击手段中
通常叫做 overflow 攻击
原因是因为程序在输入区域变数时
没有加以限制导致过长的输入可以盖掉 ebp, ret 等之类的重要资料
导致精心加工的字串可以导致控制程序流程
如果你有学过 C 语言
不知道有没有老师曾经跟你说过 gets()
是个很危险的函数
没事不要乱用
其实就是因为该函数没有对输入的字元数做限制
导致如果有人输入过长就会导致程序崩溃
但这样 "输入过长就会导致程序崩溃" 其实在 pwn 的领域看来
就是我可以利用这支程序打下你主机拉~
以上这些都是对於 stack 的相关攻击手法
可以看到一堆 ret2
其实就是 return to(two)
的意思
那藉由这个字
我想前一篇为什麽说 ret位置是精随
应该不言而喻了吧
介绍个简单的例子带大家认识什麽是 pwn
就用最基础的 ret2text
来说吧
还记的 text 在记忆体中是什麽吗
是存放指令码的地方
意思就是我们要利用 ret 位址
跳到某个关键的程序码上去执行
利用上面讲防御保护的 bof_1
当例子
我们可以从原始码看出 win()
是我们要得结果
可是这支程序怎麽样都没有执行到阿
只有 vuln()
该怎麽办
这边要注意到刚刚说的 gets()
很危险
因为它可以输入任意长度导致覆盖 return
而使得改变流程
这边先厘清个思路
main()
call 了 vuln()
vuln()
的 return 位址会回到 main()
的 return 0;
那行vuln()
有 gets()
导致可以跳去任意地方vuln()
跳到 win()
吧这时候就得去看看程序的组语了
我们得算算 buf
这个变数离 ebp 多远才有办法盖到 ret
gets@plt
就是 call gets 的地方
那上面的 lea eax, [ebp-0x1c]
就是把 buf
变数的位址放进暂存器
所以可以知道 buf
离 ebp 有 0x1c
那麽远
接着来看一下 win()
在什麽位址开始
好的
0x080484eb
现在什麽都有了
构造一下 payload
灌进去程序当作输入
python -c "print 'a'*(0x1c+4)+'\xeb\x84\x04\x08'"|./bof_1
这边要注意ret地址在写的时候要倒着放
因为是 Little-Endien
+----------+ < buf (EBP - 0x1C)
| |
+----------+
| |
+----------+
| |
+----------+
| |
+----------+
| |
+----------+
| |
+----------+
| |
+----------+ < EBP
| old EBP |
+----------+
| ret |
+----------+
前面会先用随便一个东西填充满 0x1c 个来让我们到达 ebp
接着在放 4 个填充到达 ret 位置
+----------+ < buf (EBP - 0x1C)
| aaaa |
+----------+
| aaaa |
+----------+
| aaaa |
+----------+
| aaaa |
+----------+
| aaaa |
+----------+
| aaaa |
+----------+
| aaaa |
+----------+ < EBP
| aaaa |
+----------+
| ret |
+----------+
接着要写入我们所要跳转的位址去 ret
+----------+ < buf (EBP - 0x1C)
| aaaa |
+----------+
| aaaa |
+----------+
| aaaa |
+----------+
| aaaa |
+----------+
| aaaa |
+----------+
| aaaa |
+----------+
| aaaa |
+----------+ < EBP
| aaaa |
+----------+
|0x080484eb|
+----------+
所以当 vuln()
执行完之後就会 return 回我们指定的地方
也就是 win()
的位置
成功~
<<: 制作婚礼现场即时留言版- Azure SignalR Service II
>>: JavaScript 之旅 (28):Numeric Separators
既然昨天已经说了 http post 这件事,那今天就来说说 http get 这部份吧! 今天的资...
前言 目前为止我们都着重在解释作用域与变量的工作机制,有了这些基础後将进到下一步,首先我们要先探讨不...
Rails程序码整理(起步) 如何使用View Helper把这段逻辑藏起来: 使用View Hel...
前言 $emit 让我们可以发送出自订的事件,例如: 触发特定的事件(关闭 popup) 或是 子元...
设定完 VLAN 之後,来聊聊 PBR 吧 什麽是 PBR PBR 全名 Policy Based ...