Linux内核中KASLR功能是什么?有什么作用?怎么破除?以及如何实操?(地址空间、layout random、kallsyms)

1. 背景

KASLR是一个什么技术点其实不重要,但重要的是有了KASLR这个功能后,造成内核中某个符号(函数 or 变量)在System.map中的地址和实际不一样了(实际: cat /proc/kallsyms),进一步带来了分析类似crash问题中的打印地址不准确问题。所以必须得知道这是什么?本文主要从实战层面来谈几个问题:

  1. KASLR是什么?
  2. KASLR如何开启?如何查看开启了?
  3. 破除KASLR的几个方法(有些奇技淫巧)
  4. 破除KASLR后再实战中有何作用?

2. 要点

  • KASLR:kernel address space layout randomization 内核地址空间布局随机化。是一个安全功能,本质是将链接的地址 mapping到 运行的地址多做了一个随机偏移。断句是:KAS LR,KAS的LR

  • 作者:Kees Cook,linux内核的安全工程师(Linux kernel security engineer),曾是Ubuntu Security Team的技术老大。更多参考链接: Cook的Linkedin 、 Cook的github仓库、Cook更多介绍
    在这里插入图片描述

  • ASLR:address space layout randomization地址空间布局随机化,是一种众所周知的技术,它通过将各种对象随机放置在而不是固定的地址上来增加攻击的难度。参考Wiki

  • ASLR首次提出:Linux PaX 项目首先创造了“ASLR”这个术语,并于 2001 年 7 月作为 Linux 内核的补丁发布了 ASLR 的第一个设计和实现。参考Wiki

  • 第一个默认支持 ASLR 的主流操作系统是 2003 年的 OpenBSD 3.4 版, 其次是 2005 年的 Linux。参考Wiki

  • ASLR是一种“统计防御”,因为一般可以使用暴力方法来克服它

  • 在一个完全不受限制的系统中,尤其是在本地不受信任的用户的系统中,KASLR 不会很有用。但是,在使用容器或具有大量包含进程的系统上,KASLR 可以提供帮助。参考链接

  • Linux 长期以来一直为用户空间程序提供 ASLR。参考链接

  • 在虚拟机内使用较多,提高虚拟机安全性

  • 让内核vmlinux在运行态的地址相比于编译的地址有一个偏移,具体偏移值通过DTS配置

  • 另外如果可以参数化,在bootloader中配置,可以动态设置每次每个设备都是不同的映射地址

  • Red Hat Enterprise Linux 7.5 and later开始引入,参考redhat 官网

  • 如何避免内核消息卸载:通过将 dmesg_restrict sysctl 设置为 1,防止非特权用户访问内核消息。此设置将 dmesg 访问限制为具有 CAP_SYSLOG 权限的用户。proc通过kptr_restrict sysctl 设置为 1。

3. 实操

3.1 查看是否打开:CONFIG_RANDOMIZE_BASE

内核编译是否配置 CONFIG_RANDOMIZE_BASE=y

cat /boot/config-$(uname -r) |grep CONFIG_RANDOMIZE_BASE

实操:
在这里插入图片描述

  • 在bootloader配置中关闭的方式,添加nokaslr的启动项
GRUB_CMDLINE_LINUX="rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet nokaslr"

nokaslr介绍

3.2 计算内核符号表和堆栈空间地址的偏移方法

可以随机找一个内核符号表假设是 kmalloc_info。
通过 /proc/kallsyms获取符号实际的加载地址 A d d r k a l l s y m s Addr_{kallsyms} Addrkallsyms
通过 /boot/System.map-$(uname -r) 获取链接后的地址 A d d r s y s t e m m a p Addr_{systemmap} Addrsystemmap
那么偏移的地址就是他们的delta
A d d r δ = A d d r k a l l s y m s − A d d r s y s t e m m a p Addr_\delta = Addr_{kallsyms} - Addr_{systemmap} Addrδ=AddrkallsymsAddrsystemmap

命令:

cat /boot/System.map-$(uname -r) |grep kmalloc_info
cat /proc/kallsyms |grep kmalloc_info
python3 -c 'print(hex(int("0xffffffff87fa04c0", 16) - int("0xffffffff831a04c0", 16)))'

实操:
获取链接地址和运行加载地址:在这里插入图片描述
计算delta:在这里插入图片描述
所以算出来是:0x4e00000
那么计算出这个delta之后有什么作用呢?对实战有什么帮助呢?

4. 实战作用

在实战中,主要是需要用gdb调试linux内核的时候,比如有qemu场景调试guest主机内核,或者host主机内核都可以。下面主要以gdb调试vmlinux为例子介绍:
gdb使用add-symbol-file 默认基地址就是二进制vmlinux中的各个段地址。如果开启了KASLR,那么这个地址寻找到某个变量的实际地址就不对了。需要加上刚才的偏移。才能正确的使用。

4.1 获取默认链接地址

比如gdb中加载符号地址默认是根据vmlinux二进制文件中的各个段地址进行加载基础地址的。比如选取某个vmlinux查看他的text段的地址:
在这里插入图片描述

4.2 获取偏移后的加载地址:

  • data段的基础地址就是:
    ffffffff82600000 + 0x4e00000 = 0xffffffff87400000
    在这里插入图片描述
  • text段的基础地址就是:
    ffffffff81000000 + 0x4e00000 = 0xffffffff85e00000在这里插入图片描述
    计算这两个段的地址以后在gdb加载的时候指定对应的地址就能正确的映射上去
    在这里插入图片描述
    验证正确性:使用gdb和crash分别查看一个内核全局变量vm_numa_stat中的值
    使用最新的加载地址的gdb获取地址:
    在这里插入图片描述
    使用crash作为正确性对比来源对比:
    在这里插入图片描述
    结论是:都是28872。说明通过随机地址偏移后计算新的地址正确。
    注意这里为什么vm_numa_stat不能直接使用kallsyms中直接使用他的地址?
    实际上是可以的,但是会带来两个问题:
  1. 每次都需要将gdb中符号地址转化
  2. 转化后需要使用地址实际使用
    使用加载时候指定每个段的基础地址这样gdb在使用具体符号(函数或者全局变量)的时候,就能从动态连接的符号表中获取到正确的地址偏移,最终获取到对应的正确数据。
    另外值得注意的是gdb在添加symbol的时候需要先清空表(symbol-file 命令),以及有些数据需要每次都add-symbol-file才会更新。
# 清空表
symbol-file 
#
add-symbol-file  /usr/lib/debug/lib/modules/4.18.0-372.9.1.an8.x86_64/vmlinux -s .data 0xffffffff87400000 -s .text 0xffffffff85e00000

综述

本文从KASLA的功能出发,介绍了基础概念,以及实战场景。
实战场景中以在systemmap中的链接地址和kallsyms中的实际地址进行计算,并且以vmlinux中的各个段基础地址加上偏移计算通用
本方法依赖掌握代码编译链接和动态加载的基础原理,以及gdb的基础流程和原理,详细细节可以多参考相关文档,并多琢磨多实践。

其他参考链接:

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_security_guide/sect-virtualization_security_guide-guest_security-kaslr
LWN介绍KASLR

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/541025.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM性能调优——GC日志分析

文章目录 1、概述2、生成GC日志3、Parallel垃圾收集器日志解析3.1、Minor GC3.2、FULL GC 4、G1垃圾收集器日志解析4.1、Minor GC4.2、并发收集4.3、混合收集4.4、Full GC 5、CMS垃圾收集器日志解析5.1、Minor GC5.2、Major GC5.3、浮动垃圾 6、日志解析工具6.1、GCeasy6.2、GC…

Java代码基础算法练习-自定义函数之求字符串长度-2024.04.13

任务描述: 写一函数,求一个字符串的长度(字符串长度不超过255),然后在主函数中调用该函数 实现求长度操作。 任务要求: 代码示例: package April_2024;import java.util.Scanner;public class …

Spark AQE(Adaptive Query Execution)机制

💐💐扫码关注公众号,回复 spark 关键字下载geekbang 原价 90 元 零基础入门 Spark 学习资料💐💐 AQE 的全称是 Adaptive Query Execution,翻译过来是“自适应查询执行”。它包含了 3 个动态优化特性&#…

Android适配平板屏幕尺寸

一、划分手机和平板 人为判断方法: 大于6英寸的就是平板。小于6英寸的都是手机 平板尺寸: 6英寸、7英寸、10英寸、14英寸… Android系统支持多配置资源文件,我们可以追加新的资源目录到你的Android项目中。命名规范: 资源名字-限制符 l…

Python代码识别minist手写数字【附pdf】

一、概述 对于人类而言,要识别图片中的数字是一件很容易的事情,但是,如何让机器学会理解图片上的数字,这似乎并不容易。那么,能否找出一个函数(模型),通过输入相关的信息&#xff0…

FourCastNet 论文解析

气象基础模型/气象大模型论文速递 论文链接基于arXiv Feb. 22, 2022版本阅读 几乎是第一篇气象大模型的工作,同时也是为数不多的对precipitation进行预测的模型。 文章目录 PerformanceStructureFourier transformToken mixing TrainingPrecipitation Model Ensembl…

科研学习|可视化——Origin绘制相关性系数矩阵

一、Origin软件版本 Origin2021版本 二、插件下载地址 CorrelationPlot.opx资源-CSDN文库 三、插件安装步骤 从上述链接下载插件将插件解压缩(最好是解压缩到orgin的安装目录)用origin打开插件(或者打开origin,将插件拖拽到origin…

Mysql主从复制安装配置

mysql主从复制安装配置 1、基础设置准备 #操作系统: centos6.5 #mysql版本: 5.7 #两台虚拟机: node1:192.168.85.111(主) node2:192.168.85.112(从)2、安装mysql数据库 #详细安装和卸载的步骤…

开源项目one-api的k8s容器化部署(上)-- 制作镜像及部署准备

一、背景 最近需要对开源项目one-api进行k8s容器化部署,主要分以下几个步骤: 制作docker镜像申请mysql和redis数据库docker-compose部署方式k8s部署方式 整个的篇幅比较长,将会分成上下两篇来阐述。 二、制作docker镜像 开源项目one-api…

Vue2 —— 学习(六)

一、Vue 脚手架 (一)介绍 Vue 脚手架是 Vue 官方提供的标准化开发工具 (开发平台) 脚手架版本最新版本 是 4.x 文档可以查看 http://cli.vuejs.org/zh/ 就是vue 官网文档中 的 vue.cli command line interface (…

ChatGPT深度科研应用、数据分析及机器学习、AI绘图与高效论文撰写

2022年11月30日,可能将成为一个改变人类历史的日子——美国人工智能开发机构OpenAI推出了聊天机器人ChatGPT3.5,将人工智能的发展推向了一个新的高度。2023年4月,更强版本的ChatGPT4.0上线,文本、语音、图像等多模态交互方式使其在…

开源!工厂数字化项目会用到的地理信息系统

软件介绍 QGIS(Quantum GIS)是一款免费、开源、跨平台的地理信息系统(GIS)软件,适用于Unix平台、Windows和MacOS。提供了强大且用户友好的功能,使其成为地理信息处理领域的热门选择。 功能特点 1.空间数据管…

DRF多表关联的序列化和反序列化

DRF多表关联的序列化和反序列化 目录 DRF多表关联的序列化和反序列化序列化定制字段source一对多的序列化 多表关联的序列化方式1:在表模型中定义方法方式2:定制返回格式SerializerMethodField方式3:子序列化 多表关联的反序列化反序列化保存…

Java---搭建junit4.x单元测试环境,并进行测试

搭建junit4.x单元测试环境 1.选择Project Structure 2.选择Modules,选择要加入测试环境的模块,选择Dependencies,可以看到当前模块都有哪些依赖。 3.点击 后选择第一个 4.找到你安装IDEA的文件夹,进入到IntelliJ IDEA 2018.3.4\lib目录下…

桥接模式:解耦抽象与实现的设计艺术

在软件设计中,桥接模式是一种结构型设计模式,旨在将抽象部分与其实现部分分离,使它们可以独立地变化。这种模式通过提供更加灵活的代码结构帮助软件开发人员处理不断变化的需求,特别是在涉及多平台应用开发时。本文将详细介绍桥接…

规则引擎之LiteFlow应用

官网地址&#xff1a;LiteFlow DEMO 整体结构 1.引入maven依赖 <dependency><groupId>com.yomahub</groupId><artifactId>liteflow-spring-boot-starter</artifactId><version>2.11.4.2</version> </dependency> 2. 配置yml …

Visual Studio code无法正常执行Executing task: pnpm run docs:dev

最近尝试调试一个开源的项目&#xff0c;发现cmd可以正常启动&#xff0c;但是在vs中会报错&#xff0c;报错内容如下 Executing task: pnpm run docs:dev pnpm : 无法加载文件 E:\XXXX\pnpm.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 http…

jmeter实验 模拟:从CSV数据到加密请求到解密返回数据再到跨越线程组访问解密后的数据

注意,本实验所说的加密只是模拟加密解密,您需要届时写自己的加解密算法或者引用含有加密算法的相关jar包才行. 思路: 线程组1: 1.从CSV文件读取原始数据 2.将读取到的数据用BeanShell预习处理器进行加密 3.HTTP提取器使用加密后的数据发起请求 4.使用BeanShell后置处理器…

外贸公司应该怎么选择企业邮箱?哪个企业邮箱最好?

外贸公司业务的特殊性需要他们频繁进行跨国的沟通交流&#xff0c;那么外贸公司应该如何选择适合的企业邮箱呢&#xff1f;首先&#xff0c;传输邮件的稳定安全是前提&#xff0c;另外由于沟通多是国外客户&#xff0c;邮件的翻译也成为外贸公司企业邮箱的刚需。小编今天就详细…

怎么用Vivado做覆盖率分析

关注公众号FPGA开源工坊获取更多内容。 在做仿真的时候往往会去做代码覆盖率和功能覆盖率的分析&#xff0c;来保证仿真是做的比较充分完备的。 在Vivado里面也支持我们做这项操作&#xff0c;现在就来看一下流程吧。 第一步&#xff1a;选择设置 第二步&#xff1a;在仿真选…