ROP对策 - PIE
PIE(Position Independent Executables)
.text区域的地址也进行随机化
所有的汇编代码中不包含绝对地址
全都使用相对地址
二进制文件被加载到内存时,基本是随机映射的
没有可以提前确定的固定地址
PIE绕过 – 多段memory leak + ret2libc等
看起来非常严格,因为完全没有固定地址,但如果能够多次利用漏洞,花费时间和精力也能够解决它
通过栈溢出之外的漏洞(例如格式化字符串(FSB),堆溢出)等泄漏的情况比较多
如果能够知道.text的地址,就能够知道其他例如.data , .bss,.plt,.got.plt 等
如果进一步从.got.plt读取内存,则可以识别libc地址。之后如果能够将其加载到stack上,或者能够重写GOT,就解决了。
Stack Canary
很早就出现的机制
- gcc编译后,stack上有一个canary值
- 进入函数时,canary被随机设置
- 退出该函数时(return 前),会验证canary没有被修改
- 根据之前已经提到的技术,很难突破这一层保护
Stack Canary攻略1 – brute force
在重新运行二进制文件之前,Stack Canary的值不会更改
对于fork-server类型,只要主进程没有重新启动,canary就是常量
逐个字节进行爆破的话,最多256*4次尝试就能够命中Stack Canary
- 如果是x64的话需要256*8次,但无论如何都是一个现实的数字
覆盖Stack Canary为正确的值,这样函数返回时,通过检查,正常返回
Stack Canary攻略2 – master canary forging
Stack Canary存储在TLS(Thread local storage)中
- x86是在gs:0x14,x64是在fs:0x28存在着值
如果能够重写该值,就能够使Stack Canary无效
- 将StackCanary修改为想要的值
- 使用任意内存读写,堆溢出等技术进行覆盖
potetisensei的相关paper
目前为止的技术总结
技术 | 推荐练习的问题 |
---|---|
nop-sled | CodeGate 2013 - pwn100 |
brute force | CodeGate 2013 - pwn100 |
ret2esp | CSAW CTF 2012 - pwn300 - 4842 |
stager | Hack.lu CTF 2012 - pwn300 - braincpy |
ret2plt | Plaid CTF 2013 - pwn200 - ropasaurusrex |
ret2pop | Plaid CTF 2013 - pwn200 - ropasaurusrex |
ret2libc | Plaid CTF 2013 - pwn200 - ropasaurusrex |
GOT overwrite | Plaid CTF 2013 - pwn200 - ropasaurusrex |
ROP | Hack.lu CTF 2012 - pwn300 – braincpy |
stack pivot | Hack.lu CTF 2012 - pwn300 – braincpy |
ret2dl_runtime_resolve | Hack.lu CTF 2014 – pwn400 - oreo |
_IO_jump_t overwrite | ED-CTF – pwn350 – Heap is a tomodachi of mine |
ld specific ptr overwrite | Plaid CTF 2015 – pwn550 - plaiddb |
canary brute force | 30c3 CTF 2014 - pwn400 - bigdata |
master canary forging | CodeGate 2014 – pwn600 - dodosandbox |