逆向分析中的密码学---tea

0x01 简介

TEA全称Tiny Encrypt Algorithm。在CTF逆向分析中经常会出现Tea或者魔改了DELTA的TEA算法。

0x02 算法原理

明文长度分组为64位(8字节),密钥长度为128位(16字节),明文和密钥进入32轮循环,得到最后的64位密文。其中magic number DELTA是由黄金分割点得到。
算法比较简单源码如下

#include<stdio.h>
#include<stdint.h>
#define DELTA 0x9981abcd

void tea_encrypt(unsigned int* v, unsigned int* key) {
  unsigned int l = v[0], r = v[1], sum = 0;
  for (size_t i = 0; i < 32; i++) { //进行32次迭代加密,Tea算法作者的建议迭代次数
    l += (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
    sum += DELTA; //累加Delta的值
    r += (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]); //利用多次双位移和异或将明文与密钥扩散混乱,并将两个明文互相加密
  }
  v[0] = l;
  v[1] = r;
}

void tea_decrypt(unsigned int* v, unsigned int* key) {
  unsigned int l = v[0], r = v[1], sum = 0;
  sum = DELTA * 32; //32次迭代累加后delta的值
  for (size_t i = 0; i < 32; i++) {
    r -= (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]);
    sum -= DELTA;
    l -= (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
  }
  v[0] = l;
  v[1] = r;
}


int main(int argc, char const *argv[])
{
    unsigned int key1[4]={0xa3eeb7be,0x50e7de9a,0x6dbcc2bc,0x78591fad};//key1
    unsigned int key2[4]={0x78591fad,0x6dbcc2bc,0xa3eeb7be,0x50e7de9a};//key2
    unsigned int v1[2] = {0x556E2853,0x4393DF16};
    unsigned int v2[2] = {0x1989FB2B,0x83F5A243};
    
    //encrypt(v1,key1);
    //printf("tea_encrypt:%x %x\n",v1[0],v1[1]);
    //encrypt(v2,key2);
    //printf("tea_encrypt:%x %x\n",v2[0],v2[1]);
    tea_decrypt(v1,key1);
    printf("tea_decrypt:%x %x\n",v1[0],v1[1]);
    tea_decrypt(v2,key2);
    printf("tea_decrypt:%x %x\n",v2[0],v2[1]);
    return 0;
}

//tea_decrypt:c0cacd59 38bb7623
//tea_decrypt:8757d16 a520cece
}

0x03 逆向分析识别tea算法

这次我在windows上用gcc tea.c -o tea.exe编译生成对应的程序。
利用PEiD的插件KANAL识别,能够识别出存在tea算法
在这里插入图片描述
下面用ida pro来识别一下tea算法。能够识别到tea中的常数,DELTA,
在这里插入图片描述
tea_encrypt
tea算法最关键的是要找到DELTA值和128位的key。
key明显是传进来的参数a2,当然程序的key不是参数传入,(4i64 * (v4 & 3) + a2) 可以知道a2是一个int数组,就是key
DELTA的识别,分析成的v4 -= 0x61C88647而不是我们源码中的sum += DELTA; ,通过简单计算可以得到v4 -= 0x61C88647v4 += 0x9e3779b9 是等价的
在这里插入图片描述

0x04 逆向分析识别魔改tea算法

tea算法可以魔改的地方主要是DELTA值,很多时候都会将这个值修改,让很多加密算法识别软件失效。下面就将DELTA魔改为0x1234567。
利用PEiD的插件KANAL识别,因为DELTA被修改了所以无法识别
在这里插入图片描述
ida pro也没有识别出来
在这里插入图片描述
tea_encrypt
关键还是DELTA和key的识别。有对源码的了解可以很容易的识别出DELTA为0x1234567,key为a2

0x05 总结

如果tea没有魔改,通过插件就能识别到对应的。
如果tea被魔改过,可以通过算法的结构找到DELTA和key

参考
《加密与解密第四版》

<think>好的,用户想了解CTF比赛中关于AES加密的逆向分析方法。首先,我需要回忆一下AES的基本原理和常见模式,因为在逆向分析中,识别加密算法是关键。AES有多个步骤,比如字节代替、行位移、列混淆和轮密钥加,这些步骤在代码中可能会有特定的特征。 接下来,用户提到的参考资料里提到了一些关键点,比如S盒和密钥扩展。逆向分析时,查找S盒的使用可能有助于识别AES的存在。S盒是固定的置换表,如果在反汇编代码中看到大量固定的256字节数组,那可能是S盒或逆S盒。此外,密钥扩展过程生成轮密钥,这也是一个特征点。 然后,考虑加密模式。比如ECB模式每个块独立加密,而CBC需要IV。在逆向时,查找IV的存储位置或生成方式很重要。例如,IV可能硬编码在程序中,或者通过某种算法生成,这会影响如何构造解密脚本。 还要注意反调试和SMC(自修改代码)技术,这些在CTF题中常用来保护AES的实现。例如,程序可能在运行时解密关键代码,干扰静态分析。这时候需要动态调试,或者识别出SMC的触发点,手动提取解密后的代码。 另外,密钥的存储方式也很重要。密钥可能被分成多个部分,隐藏在代码的不同位置,或者通过某种运算动态生成。逆向时需要跟踪密钥的生成过程,可能需要将各个部分拼接起来,或者逆向生成算法。 还有,如果题目使用了自定义的S盒或修改了AES的某些步骤,比如改变行位移的方向,这就需要分析具体的实现细节。这时候对比标准AES的流程,找出差异点,才能正确解密。 最后,编写解密脚本时,可能需要利用现有的加密库,如PyCryptodome,但要确保模式、填充方式、密钥和IV都正确匹配。如果遇到问题,需要检查每一步的参数是否正确,特别是字节序和填充的处理。 总结一下,逆向AES的步骤大致是:识别算法特征,确定模式和密钥,处理反调试/SMC,分析密钥生成,编写解密脚本。同时结合动态分析和静态分析,逐步拆解保护措施,最终提取关键参数进行解密。</think>### CTF中AES加密逆向分析技巧 #### 1. **识别AES算法特征** - **S盒与逆S盒**:AES的核心组件是固定的$256$字节S盒(SubBytes)和逆S盒。在逆向分析中,若发现程序代码中存在固定的$256$字节数组(例如`0x63, 0x7c, 0x77...`),极可能是S盒或逆S盒[^3]。 - **密钥扩展**:AES需要生成轮密钥(Round Keys),密钥扩展过程包含循环左移、S盒置换等操作。逆向时需关注密钥生成逻辑,尤其是对初始密钥的多次变换。 - **加密轮数**:根据密钥长度(如AES-128为$10$轮),可通过循环结构或轮密钥数量判断具体类型。 #### 2. **分析加密模式与参数** - **模式识别**:AES常见模式包括ECB、CBC、CTR等。例如,CBC模式需要初始向量(IV),逆向时需查找IV存储位置或生成方式(如硬编码、动态计算)[^1]。 - **填充方式**:PKCS#7填充是常见方案,需在解密后验证填充合法性。若程序包含填充校验逻辑(如检查最后一个字节的值),可辅助确认填充类型。 #### 3. **定位关键数据** - **密钥与IV提取**:密钥可能被分割存储或动态生成。例如,密钥可能由多个字符串拼接后经过哈希处理生成,需跟踪内存操作或调试提取。 - **密文定位**:密文通常以字节数组形式存储在数据段,或通过文件/网络输入。若程序包含加密函数调用,可通过参数传递路径定位密文[^4]。 #### 4. **对抗反调试与SMC** - **反调试绕过**:部分题目会通过`except_handler`或`IsDebuggerPresent`检测调试器,需使用插件(如ScyllaHide)或修改标志位绕过[^1]。 - **SMC处理**:自修改代码(Self-Modifying Code)会动态解密关键函数。可通过动态调试在解密后DUMP内存,或静态分析解密算法还原代码。 #### 5. **编写解密脚本** ```python from Crypto.Cipher import AES from Crypto.Util.Padding import unpad key = b'ctf_race_key123' # 提取的密钥 iv = b'initial_vector_iv' # 提取的IV ciphertext = open('encrypted.bin', 'rb').read() cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size) print(plaintext.decode()) ``` - **注意事项**:需确保模式、填充方式与目标程序一致,否则解密可能失败。 #### 6. **实战案例** - **案例1**:某CTF题通过修改S盒实现自定义AES,需对比标准S盒差异后逆向置换逻辑[^4]。 - **案例2**:程序使用CBC模式但IV由时间戳生成,需在内存中捕获IV或通过漏洞预测。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值