ARM64架构下指针认证(PAC)与影子栈(SCS)安全机制解析
字数 1806 2025-12-23 12:13:22

ARM64架构下指针认证(PAC)与影子栈(SCS)安全机制解析

概述

本文详细解析ARM64架构下的两种重要安全机制:指针认证(Pointer Authentication, PAC)和影子栈(Shadow Call Stack, SCS)。这两种机制共同构成了现代ARM64系统的核心安全防护体系。

指针认证(PAC)机制

基本概念

指针认证是ARMv8.3及以上版本引入的硬件安全特性,其主要目的是防止指针篡改攻击。PAC通过对指针值进行加密签名和验证,确保指针的完整性。

技术原理

  1. 签名过程:使用特定的密钥对指针进行签名,生成认证码
  2. 验证过程:在执行指针使用前验证认证码的有效性
  3. 指令支持
    • paciza:对指针进行签名
    • autiza:验证指针签名

实现示例

void help() {
    void (*f)();
    for(int i = 0; i < 4; i++) {
        f = BUILTINS[i].fptr;
        __asm__("paciza %0\n" : "=r"(f) : "r"(f));
        printf("%8s: %p\n", BUILTINS[i].name, f);
    }
}

地址变换过程

假设原始地址:0x0000550000000b7c

经过paciza签名后变为:0xf123abcd00000b7c

  • 高16位:签名认证码
  • 低48位:原始地址

影子栈(SCS)机制

基本概念

影子栈是基于PAC实现的增强安全机制,专门用于保护函数返回地址不被篡改。

技术特点

  1. 依赖关系:SCS依赖于PAC功能实现
  2. 硬件要求:需要特定处理器架构支持
  3. 实现方式:使用X18寄存器存储影子栈指针

架构对比

项目 指针认证(PAC) 影子栈(SCS)
本质 ARM硬件安全机制 基于PAC的安全机制
作用 防止指针篡改 保护函数返回地址
依赖 硬件支持 依赖PAC功能
实现 paciza/autiza指令 编译器自动处理

实际应用分析

示例程序解析

分析一个具体的PAC演示程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char name[8];
    void (*fptr)();
} builtin_func;

// 功能函数定义
void ls() { system("ls"); }
void read64() { /* 读取内存 */ }
void write64() { /* 写入内存 */ }

builtin_func BUILTINS[4] = {
    { .name = "help", .fptr = help },
    { .name = "ls", .fptr = ls },
    { .name = "read64", .fptr = read64 },
    { .name = "write64", .fptr = write64 },
};

int main() {
    setvbuf(stdin, 0, 2, 0);
    setvbuf(stdout, 0, 2, 0);
    void (*fptr)() = NULL;
    
    puts("Welcome to pac shell v0.0.1");
    help();
    
    while(1) {
        printf("pacsh> ");
        scanf("%p", &fptr);
        __asm__("autiza %0\n" : "=r"(fptr) : "r"(fptr));
        (*fptr)();
    }
}

安全机制工作流程

  1. 初始化阶段:程序启动时显示各函数的签名指针
  2. 用户交互:接收用户输入的指针值
  3. 验证执行:使用autiza指令验证指针签名,然后执行

漏洞利用限制

由于PAC机制的存在,传统的漏洞利用技术受到严格限制:

  • 直接跳转到任意地址会被签名验证阻止
  • 需要正确的签名才能执行代码

跨架构对比

硬件支持要求

架构 PAC支持 SCS支持 实现基础
ARM64 ARMv8.3+ 基于PAC 硬件特性
x86_64 Intel CET 硬件特性
x86 (32位) 软件模拟
其他架构 依赖具体实现 依赖具体实现 可变

QEMU模拟限制

根据知识库信息,QEMU目前不支持PAC指令的模拟,因为PAC是硬件特性。这给相关安全研究带来了一定挑战。

ARM64架构安全特性

ASLR强制启用

  • ARM64架构设计时就将ASLR作为安全机制强制启用
  • 这是ARMv8-A架构的安全特性,无法通过系统设置禁用
  • 与x86架构不同,ARM64没有提供禁用ASLR的机制

汇编指令基础

函数调用规范

STP X29, X30, [SP, #-16]!    ; 保存现场
MOV X29, SP                   ; 设帧指针
; 函数体...
LDP X29, X30, [SP], #16       ; 恢复现场
RET                           ; 返回

关键指令分类

  1. 数据传送指令

    • MOV:寄存器间赋值/立即数加载
    • MVN:按位取反后传送
  2. 算术逻辑运算

    • ADD/SUB:加减法
    • AND/ORR/EOR:位运算
  3. 内存访问

    • LDR/STR:32位加载存储
    • LDRB/STRB:字节操作
    • LDRH/STRH:半字操作

开发与调试实践

编译选项

普通aarch64程序使用PAC功能时:

  • 编译时使用-mpac等选项
  • 编译器自动处理安全机制
  • 无需在代码中直接写paciza和autiza指令

调试技巧

# GDB调试命令
gdb-multiarch ./pacsh
target remote:1234

# 调试脚本示例
io = process(['qemu-aarch64', '-L', '/usr/aarch64-linux-gnu', '-g', '1234', file_name])

总结

指针认证(PAC)和影子栈(SCS)代表了现代处理器安全架构的发展方向。通过硬件级别的安全机制,有效防御了多种内存破坏攻击。理解这些机制对于二进制安全研究、漏洞挖掘和安全开发都具有重要意义。

核心要点回顾

  1. PAC是基础:提供指针完整性保护
  2. SCS是增强:基于PAC提供返回地址保护
  3. 硬件依赖:两种机制都需要特定硬件支持
  4. 开发透明:正常开发中由编译器自动处理
  5. 研究挑战:模拟环境支持有限,需要真实硬件环境

这些安全机制的普及标志着系统安全防护进入了新的阶段,对安全研究人员提出了更高的技术要求。

ARM64架构下指针认证(PAC)与影子栈(SCS)安全机制解析 概述 本文详细解析ARM64架构下的两种重要安全机制:指针认证(Pointer Authentication, PAC)和影子栈(Shadow Call Stack, SCS)。这两种机制共同构成了现代ARM64系统的核心安全防护体系。 指针认证(PAC)机制 基本概念 指针认证是ARMv8.3及以上版本引入的硬件安全特性,其主要目的是防止指针篡改攻击。PAC通过对指针值进行加密签名和验证,确保指针的完整性。 技术原理 签名过程 :使用特定的密钥对指针进行签名,生成认证码 验证过程 :在执行指针使用前验证认证码的有效性 指令支持 : paciza :对指针进行签名 autiza :验证指针签名 实现示例 地址变换过程 假设原始地址: 0x0000550000000b7c 经过paciza签名后变为: 0xf123abcd00000b7c 高16位:签名认证码 低48位:原始地址 影子栈(SCS)机制 基本概念 影子栈是基于PAC实现的增强安全机制,专门用于保护函数返回地址不被篡改。 技术特点 依赖关系 :SCS依赖于PAC功能实现 硬件要求 :需要特定处理器架构支持 实现方式 :使用X18寄存器存储影子栈指针 架构对比 | 项目 | 指针认证(PAC) | 影子栈(SCS) | |------|----------------|---------------| | 本质 | ARM硬件安全机制 | 基于PAC的安全机制 | | 作用 | 防止指针篡改 | 保护函数返回地址 | | 依赖 | 硬件支持 | 依赖PAC功能 | | 实现 | paciza/autiza指令 | 编译器自动处理 | 实际应用分析 示例程序解析 分析一个具体的PAC演示程序: 安全机制工作流程 初始化阶段 :程序启动时显示各函数的签名指针 用户交互 :接收用户输入的指针值 验证执行 :使用autiza指令验证指针签名,然后执行 漏洞利用限制 由于PAC机制的存在,传统的漏洞利用技术受到严格限制: 直接跳转到任意地址会被签名验证阻止 需要正确的签名才能执行代码 跨架构对比 硬件支持要求 | 架构 | PAC支持 | SCS支持 | 实现基础 | |------|---------|---------|----------| | ARM64 | ARMv8.3+ | 基于PAC | 硬件特性 | | x86_ 64 | 无 | Intel CET | 硬件特性 | | x86 (32位) | 无 | 无 | 软件模拟 | | 其他架构 | 依赖具体实现 | 依赖具体实现 | 可变 | QEMU模拟限制 根据知识库信息,QEMU目前不支持PAC指令的模拟,因为PAC是硬件特性。这给相关安全研究带来了一定挑战。 ARM64架构安全特性 ASLR强制启用 ARM64架构设计时就将ASLR作为安全机制强制启用 这是ARMv8-A架构的安全特性,无法通过系统设置禁用 与x86架构不同,ARM64没有提供禁用ASLR的机制 汇编指令基础 函数调用规范 关键指令分类 数据传送指令 MOV :寄存器间赋值/立即数加载 MVN :按位取反后传送 算术逻辑运算 ADD / SUB :加减法 AND / ORR / EOR :位运算 内存访问 LDR / STR :32位加载存储 LDRB / STRB :字节操作 LDRH / STRH :半字操作 开发与调试实践 编译选项 普通aarch64程序使用PAC功能时: 编译时使用 -mpac 等选项 编译器自动处理安全机制 无需在代码中直接写paciza和autiza指令 调试技巧 总结 指针认证(PAC)和影子栈(SCS)代表了现代处理器安全架构的发展方向。通过硬件级别的安全机制,有效防御了多种内存破坏攻击。理解这些机制对于二进制安全研究、漏洞挖掘和安全开发都具有重要意义。 核心要点回顾 PAC是基础 :提供指针完整性保护 SCS是增强 :基于PAC提供返回地址保护 硬件依赖 :两种机制都需要特定硬件支持 开发透明 :正常开发中由编译器自动处理 研究挑战 :模拟环境支持有限,需要真实硬件环境 这些安全机制的普及标志着系统安全防护进入了新的阶段,对安全研究人员提出了更高的技术要求。