最近看了一道题,write4的,里面有个很好的思路就是任意地址写:
一起看看吧:
64位的,堆栈不可写保护,栈溢出漏洞,栈大小是:
32+8 = 40(覆盖了ebp的)
找找system函数(plt)
找找“/bin/sh”,找不到哎:
这个不行哎,看来只能我们自己写/bin/sh了,这里介绍一种新技能!
就是任意地址写:举个例子:其中r1是要写入bss段的位置地址,r2是要写入的字符"/bin/sh\x00"(为了凑够8个字节),
pop r1 ; pop r2 ; ret(r1存地址,r2存信息)
mov ptr [r1] ,r2 ; ret
这样就成功写入了!r1和r2是随意的,所以自由!
接下来就是要找这两条指令!ROP走起:
找到了,接下来就是找找那个能执行system的函数了:
找到了,脚本可以写了:
好的,运行:
这里能get到一个新技能了~开心。
下面来个进阶版本的:fluff(64位)
栈溢出漏洞,堆栈不可写保护,栈大小为40(覆盖了ebp的),找system函数:
找字符串:
可见是无效的shell,需要自己写:以为和之前是一样的,试试看:
哦豁,完蛋,没有两个寄存器给我们能直接传,所以只能间接传,这里介绍一种放法:
间接传值法,首先看看一个知识点,异或实现传值:
A = A xor B,当A的值为0时,异或结果还是B,但是结果存到了A里面,就实现了间接传值。但是前提是A 的值为0,这里就可以用自身异或来实现:A xor A = 0,
所以又学到一个新技能:
A xor A = 0;A = A xor B(把B赋值给A),接下来就是实操了
上图:
解释的很清楚了,要实现r10和r11之间的操作,借助了下面的5条指令 ,3452的顺序实现了r10是bss地址值,第二次的345实现了r11是binsh,最后再用1的操作,实现mov,其中每一条指令不是都用上了,只是用其中的部分,所以其他的用junk(无用字符)填充,(还有xchg是交换两个寄存器内容的意思),这样实现了想要的功能,刚好1中有pop rdi,所以直接可以上bss参数和system了
在这里大家可能会有个疑问,为何pop r12的值会是0,不能其他的吗?这是个细节,因为在调用system函数前,还有句操作:
只有xor 0,r10的内容才不会变,所以为了保持一致性,只能填0,这个真的是靠细节的,发现了就很好!
接来下运行下:
可以,完成,总结就是学到新技巧,花式写地址注入/bin/sh(其实写/bin/bash(¥0)也可以),朝着下一关冲击!