侧边栏壁纸
  • 累计撰写 38 篇文章
  • 累计创建 23 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

【Reverse】TEA系列加密算法

Fup1p1
2022-10-08 / 0 评论 / 0 点赞 / 774 阅读 / 5,728 字 / 正在检测是否收录...

TEA

加密使用的数据为2个32位无符号整数,密钥为4个32位无符号整数即密钥长度为128位

void encrypt(unsigned int* v, unsigned int* key) {
  unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
  for (size_t i = 0; i < 32; i++) {
    sum += delta;
    l += ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
    r += ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
  }
  v[0] = l;
  v[1] = r;
}
 
void decrypt(unsigned int* v, unsigned int* key) {
  unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
  sum = delta *32;
  for (size_t i = 0; i < 32; i++) {
    r -= ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
    l -= ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
    sum -= delta;
  }
  v[0] = l;
  v[1] = r;
}

XTEA

TEA的迭代版本增加了更多的密钥表,移位和异或操作等等

void encrypt(unsigned int* v, unsigned int* key) {
  unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
  for (size_t i = 0; i < 32; i++) {
    l += (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
    sum += delta;
    r += (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]);
  }
  v[0] = l;
  v[1] = r;
}
 
void decrypt(unsigned int* v, unsigned int* key) {
  unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
  sum = delta * 32;
  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;
}

代码借鉴于Link

XXTEA

XXTEA是一个非平衡Feistel网络分组密码,在可变长度块上运行,这些块是32位大小的任意倍数(最小64位),使用128位密钥

我个菜鸡,只能搜的别人的模板 Link
我解题就以这个改了( * ^ ▽ ^ * )

#include <stdio.h>
#include <stdlib.h>
#define delta 0x9e3779b9
 
int main()
{
    unsigned int v[8] = {0x10BD3B47, 0x6155E0F9, 0x6AF7EBC5, 0x8D23435F, 0x1A091605, 0xD43D40EF, 0xB4B16A67, 0x6B3578A9};
    unsigned int key[4] = {0x00001234, 0x00002345, 0x00004567, 0x00006789};
    unsigned int sum = 0;
    unsigned int y,z,p,rounds,e;
    int n = 8;
    int i = 0;
    rounds = 6 + 52/n;
    y = v[0];
    sum = rounds*delta;
     do
     {
        e = sum >> 2 & 3;
        for(p=n-1;p>0;p--)
        {
            z = v[p-1];
            v[p] -= ((((z>>5)^(y<<2))+((y>>3)^(z<<4))) ^ ((key[(p&3)^e]^z)+(y ^ sum)));
            y = v[p];
        }
        z = v[n-1];
        v[0] -= (((key[(p^e)&3]^z)+(y ^ sum)) ^ (((y<<2)^(z>>5))+((z<<4)^(y>>3))));
        y = v[0];
        sum = sum-delta;
     }while(--rounds);
 
    for(i=0;i<n;i++)
    {
        printf("%c%c%c%c",*((char*)&v[i]+0),*((char*)&v[i]+1),*((char*)&v[i]+2),*((char*)&v[i]+3));
        //printf("%c%c%c%c",*((char*)&v[i]+3),*((char*)&v[i]+2),*((char*)&v[i]+1),*((char*)&v[i]+0));
    }
    return 0;
}

例题

1.New Star Week 3 EZTEA

题目Link
QQ截图20221008195147
QQ截图20221008195020

key已知,虽然数字很臭,我们还知道密文。还有一个一个一个delta=289739776
(转成十六进制更臭了)
QQ截图20221008200044
加密部分小小的魔改了一下。
小改一下脚本,直接run

#include <stdio.h>
#include <stdlib.h>
#define delta 289739776
 
int main()
{
    unsigned int v[9] = {0x38FA8A82, 0xD7501380, 0xE40969D, 0x4E169120, 0x713A29AB, 0x6CE5393D, 0xB69D752E, 0x841A88E6, 0x6F31B459};
    unsigned int key[4] = {0x19,0x19,8,0x10};
    unsigned int sum = 0;
    unsigned int y,z,p,rounds,e;
    int n = 9;
    int i = 0;
    rounds = 6 + 52/n;
    y = v[0];
    sum = (rounds*delta)& 0xffffffff;
     do
     {
        e = sum >> 2 & 3;
        for(p=n-1;p>0;p--)
        {
            z = v[p-1];
            v[p] -= ((((z<<5)^(y>>3))+((y<<2)^(z>>4))) ^ ((key[(p&3)^e]^z)+(y ^ sum)))& 0xffffffff;
            y = v[p];
        }
        z = v[n-1];
        v[0] -= (((key[(p^e)&3]^z)+(y ^ sum)) ^ (((y>>3)^(z<<5))+((z>>4)^(y<<2))))& 0xffffffff;
        y = v[0];
        sum = (sum-delta)& 0xffffffff;
     }while(--rounds);
 
    for(i=0;i<n;i++)
    {
        printf("%c%c%c%c",*((char*)&v[i]+0),*((char*)&v[i]+1),*((char*)&v[i]+2),*((char*)&v[i]+3));
        //printf("%c%c%c%c",*((char*)&v[i]+3),*((char*)&v[i]+2),*((char*)&v[i]+1),*((char*)&v[i]+0));
    }
    return 0;
}

QQ截图20221008200217

2022年浙江省信息安全竞赛技能赛初赛re2

赛后复盘做出来的,so不知flag是不是对的。

此题是python逆向。
使用pyinstxtractor解析exe文件,然后使用pycdc将解析包里的re.pyc转成可读的py代码。uncompyle6是解析不出来滴。省赛还是断网比赛,找不到对的工具,直接G了。
QQ截图20221009082536

from ctypes import *
import binascii

def encrypt(n, v, key):
    de = 1311062073
    ro = 6 + 52 // n
    total = c_uint32(0)
    z = c_uint32(v[n - 1])
    e = c_uint32(0)
    if ro > 0:
        total.value += de
        e.value = total.value >> 2 & 3
        for p in range(n - 1):
            y = c_uint32(v[p + 1])
            v[p] = c_uint32(v[p] + XX(z, y, total, key, p, e).value).value
            z.value = v[p]
        y = c_uint32(v[0])
        v[n - 1] = c_uint32(v[n - 1] + XX(z, y, total, key, n - 1, e).value).value
        z.value = v[n - 1]
        ro -= 1
        continue
    return v


def XX(z, y, total, key, p, e):
    xx = c_uint32((z.value >> 6 ^ y.value << 3) + (y.value >> 3 ^ z.value << 4) ^ (total.value ^ y.value) + key[p & 3 ^ e.value])
    return xx

if __name__ == '__main__':
    k = [
        4,
        3,
        2,
        1]
    n = 2
    xx = input('plz input your flag(DASCTF{*}):')
    vvalue = [
        722695011,
        893015348,
        0xFB586025L,
        752171035,
        1118151735,
        0x916AAD6EL,
        0xC3F6A656L,
        0xA3E014EFL]
    for i in range(1):
        if len(xx) != 40:
            print('error')
        else:
            xx = xx[7:39]
            comppare = []
            for i in range(0, 32, 8):
                value = []
                xxx = xx[i:i + 8]
                xxx1 = xxx[0:4].encode()
                xxx2 = xxx[4:].encode()
                hexvalue1 = binascii.b2a_hex(xxx1).decode()
                hexvalue2 = binascii.b2a_hex(xxx2).decode()
                value.append(int(hexvalue1, 16))
                value.append(int(hexvalue2, 16))
                res = encrypt(n, value, k)
                comppare.append(res[0])
                comppare.append(res[1])
            if comppare == vvalue:
                print('correct')
                continue
            print('error')
        return None

对着模板小改一波

#include <stdio.h>
#include <stdlib.h>
#define delta 1311062073
 
int main()
{   //每次解密2个32位无符号数字
    unsigned int v[8] = {722695011,893015348};//0xFB586025L,752171035,1118151735,0x916AAD6EL,0xC3F6A656L,0xA3E014EFL
    unsigned int key[4] = {4,3,2,1};
    unsigned int sum = 0;
    unsigned int y,z,p,rounds,e;
    int n = 2;
    int i = 0;
    rounds = 6 + 52/n;
    y = v[0];
    sum = rounds*delta;
     do
     {
        e = sum >> 2 & 3;
        for(p=n-1;p>0;p--)
        {
            z = v[p-1];
            v[p] -= (((z>>6)^(y<<3))+((y>>3)^(z<<4))^(y ^ sum) + ((key[(p&3)^e])));
            y = v[p];
        }
        z = v[n-1];
        v[0] -= (((z>>6)^(y<<3))+((y>>3)^(z<<4))^(y ^ sum) + (key[(p&3)^e]));
        y = v[0];
        sum = sum-delta;
     }while(--rounds);
 
    for(i=0;i<n;i++)
    {
        //printf("%c%c%c%c",*((char*)&v[i]+0),*((char*)&v[i]+1),*((char*)&v[i]+2),*((char*)&v[i]+3));
        /*此题要逆着输出,不然会得到
        3txx_444
        p_n13hty
        s1_ns3e_
        1r_y?thg
        拼起来是
        3txx_444p_n13htys1_ns3e_1r_y?thg
        怎么看都不像flag,看着像逆序,试了一下逆序就对了,虽然我不知道为什么。(若有懂哥,评论区教教我Thanks♪(・ω・)ノ)
        */
        printf("%c%c%c%c",*((char*)&v[i]+3),*((char*)&v[i]+2),*((char*)&v[i]+1),*((char*)&v[i]+0));
    }
    return 0;
}

8个数字,每次解密两个,得

xxt3444_
1n_pyth3
n_1s_e3s
y_r1ght?

DASCTF{xxt3444_1n_pyth3n_1s_e3sy_r1ght?}
感觉应该是对的。
QQ图片20221009092156

0

评论区