文章是我之前发在吾爱破解论坛的,直接搬过来了。有问题大家可以直接提问。
最近刚刚接触漏洞调试逆向,希望能够将自己调试过程中的看法与大家分享,望大神们不要喷我。参考书籍就是有名的《0day》,作为想接触漏洞的新手非常适合。
言归正传GS机制:
GS会在函数调用前往函数栈帧内压入一个随机数(canary),然后等函数返回前,会对canary进行核查,判断canary是否被修改。因为canary的地址是(前栈帧EBP-4),所以如果溢出攻击想要覆盖返回地址,就会路过canary。系统检测到canary被修改之后,在函数返回前就会直接终止程序
GS流程:
- 程序启动时,读取.data节的第一个dword。
- 以这个dword为基数,通过和当前系统时间,进程ID,线程ID,性能计数器进行一系列加密运算(多次XOR)。
- 把加密后的种子再写入.data节的第一个dword。函数在执行前,把加密后的种子取出,与当前esp进行异或计算,结果存入“前EBP”的前面(低地址端)。函数主体正常执行。
- 函数返回前,把canary取出与esp异或计算后,调用__security_check_cookie函数进行检查,与.data节里的种子进行比较,如果校验通过则返回原函数继续执行。如果校验失败,则程序终止。
意思就是, .data第一个dword异或ebp后,存放到ebp低地址端,函数返回前,这个数再xor ebp,和.data中相比较。
GS突破的思路:
1、利用未被保护的内存突破GS
2、覆盖虚函数突破GS( wnagzihxain有讲到 )
3、攻击SEH突破GS
4、同时替换栈中和.data中的cookie突破GS( 同样讲到过 )
由于自己第一次发帖,刚好看到第四个突破技术,索性就记录下来以便交流
我们不看代码,试想一下,如果想要同时替换栈中和.data中的cookie,需要几步。需要什么条件。
攻击条件:
- 首先这个条件就很苛刻,正常情况下,我们是无法访问到.data段中的,只有当一个指针偏移没有作判断,能够为我们所用,将它指向.data的时候,才能够覆盖修改.data的第一个dword。代码中创造的条件是这样的,先申请一块堆区,再创建一个指针指向的地址是堆区+偏移(i),当i为我们恶意构造的负数的时候,就有可能指向.data段
- 其次,要有shellcode覆盖,代码中给了一个strcpy,我们喜闻乐见的一个函数。
代码如下(shellcode内容我们慢慢给出,这里先看程序):
[C] 纯文本查看 复制代码
0102030405060708091011121314151617181920void
test(
char
* str,
int
i,
char
* src)
{
char
dest[200];
if
(i<0x9995)
{
char
* buf=str+i;
*buf=*src;
*(buf+1)=*(src+1);
*(buf+2)=*(src+2);
*(buf+3)=*(src+3);
strcpy
(dest,src);
}
}
void
main()
{
char
* str=(
char