[reverse]河北省职工职业技能大赛决赛re2(rotate-xtea-aes)

main

cpp 复制代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *v3; // rdi
  int v4; // r15d
  unsigned __int64 i; // rbx
  unsigned int *v6; // rbx
  __int64 v7; // rdi
  __int64 v8; // rsi
  char *v9; // rax
  int v10; // r12d
  int v11; // r14d
  char *v12; // r13
  _QWORD *v13; // rsi
  void *v14; // rax
  void *v15; // rbx
  int v16; // edi
  void *Block; // [rsp+20h] [rbp-89h] BYREF
  int v19; // [rsp+28h] [rbp-81h]
  int v20; // [rsp+2Ch] [rbp-7Dh]
  __int128 v21; // [rsp+30h] [rbp-79h] BYREF
  __int128 v22; // [rsp+40h] [rbp-69h]
  char Buffer[16]; // [rsp+50h] [rbp-59h] BYREF
  __int128 v24; // [rsp+60h] [rbp-49h]
  char v25; // [rsp+70h] [rbp-39h]
  __int128 Src[4]; // [rsp+80h] [rbp-29h] BYREF
  char v27; // [rsp+C0h] [rbp+17h]

  memset(Src, 0, sizeof(Src));
  v27 = 0;
  v21 = 0i64;
  v22 = 0i64;
  sub_7FF601481010("flag:\r\n", argv, envp);
  v25 = 0;
  *Buffer = 0i64;
  v24 = 0i64;
  sub_7FF601481BA0("%32s");
  v3 = Buffer;
  v4 = 0;
  for ( i = 0i64; i < 0x10; ++i )
  {
    sub_7FF601481C00(v3, "%02hhX");             // str-hex
    v3 += 2;
  }
  rotate(Src);                                  // 循环左移
  v6 = &v21;
  v21 = Src[0];
  Block = 0x341200001212i64;                    // xtea的密钥
  v7 = 2i64;
  v19 = 0x5612;                                 // xtea的密钥
  v20 = 0x8923;                                 // xtea的密钥
  do
  {
    xtea(v6, &Block);
    v6 += 2;
    --v7;
  }
  while ( v7 );
  v8 = -1i64;
  Src[0] = v21;
  do
    ++v8;
  while ( *(Src + v8) );
  LODWORD(v21) = 4;
  *&v22 = aDfb8007c773561;                      // aes的密钥
  *(&v21 + 4) = 0x100000004i64;
  HIDWORD(v21) = 10;
  v9 = sub_7FF601481070(&v21);                  // aes密钥扩展算法
  v10 = v21;
  Block = v9;
  if ( v8 % (4 * v21) )
    v11 = 4 * v21 * (v8 / (4 * v21) + 1);
  else
    v11 = v8;
  v12 = operator new(v11);
  memcpy(v12, Src, v8);
  memset(&v12[v8], 0, v11 - v8);
  v13 = operator new(v11);
  if ( v11 / (4 * v10) > 0 )
  {
    do
    {
      v14 = sub_7FF6014813E0(&v21, &v12[4 * v10 * v4], Block);// aes加密,ecb
      v10 = v21;
      v15 = v14;
      v16 = 4 * v21;
      memcpy(v13 + 4 * v21 * v4, v14, 4 * v21);
      j_j_free(v15);
      ++v4;
    }
    while ( v4 < v11 / v16 );
  }
  j_j_free(Block);
  j_j_free(v12);
  if ( *v13 == qword_7FF6014860A0 && v13[1] == qword_7FF6014860A8 )// 密文
    puts("Congratulations!");
  else
    sub_7FF601481010("no!\n");
  return 0;
}

流程是输入的字符每两个转为一个字节,单字节循环左移,xtea加密,aes加密。

注意最后密文显示是小端序模式,在脚本解密时,应按8字节逆转。xtea部分同理,按4字节逆转。

脚本内的xtea的key并未用到。可根据算法手动计算xtea内部异或用到的数(4字节无符号数)。

python 复制代码
from ctypes import * 
from Crypto.Cipher import AES
from Crypto.Util.number import *
def l_rotate(n, d):
    return (n << d)|(n >> (8 - d))&1

def r_rotate(n, d):
    return (n >> d)|(n << (8 - d))&0b10000000

def encrypt(v, key):
    v0, v1  = c_uint32(v[0]), c_uint32(v[1])
    # delta = 0x9E3779B9
    #first round
    v0.value+=(0x1212^(((v1.value << 5) ^ (v1.value >> 6))+ v0.value))
    # total = c_uint32(delta * 32)
    offset=[0xcbbdfd0f,0xcbbdfd0f,0x98a8c4ba,0x98a908ba,0x65942576,0x65942576,0x327edc10,0x327e9810,0xff69a3bb,0xff69a3bb,0xcc546b66,0xcc54e277,0x993fcc22,0x993f5511,0x662a82bc,0x662a60bc,0x33154a67,0x33156c67,][::-1]
    for i in range(9):
        # total.value -= delta 
        v1.value += (((v0.value << 4) ^ (v0.value >> 5)) + v0.value) ^ (offset[2*i] )
        v0.value += (((v1.value << 5) ^ (v1.value >> 6)) + v1.value) ^ (offset[2*i+1])
        
    #last round
    v1.value+=(0xfed36875^(((v0.value << 4) ^ (v0.value >> 5)))+v0.value) 
    return [v0.value, v1.value] 


def decrypt(v, key):
    v0, v1  = c_uint32(v[0]), c_uint32(v[1])
    # delta = 0x9E3779B9
    #first round
    v1.value-=0xfed36875^(v0.value+((v0.value << 4) ^ (v0.value >> 5))) 
    # total = c_uint32(delta * 32)
    offset=[0xcbbdfd0f,0xcbbdfd0f,0x98a8c4ba,0x98a908ba,0x65942576,0x65942576,0x327edc10,0x327e9810,0xff69a3bb,0xff69a3bb,0xcc546b66,0xcc54e277,0x993fcc22,0x993f5511,0x662a82bc,0x662a60bc,0x33154a67,0x33156c67,]
    for i in range(9):
        # total.value -= delta 
        v0.value -= (((v1.value << 5) ^ (v1.value >> 6)) + v1.value) ^ (offset[2*i] )
        v1.value -= (((v0.value << 4) ^ (v0.value >> 5)) + v0.value) ^ (offset[2*i+1] )
    #last round
    v0.value-=(0x1212^(((v1.value << 5) ^ (v1.value >> 6))+ v1.value))

    return [v0.value, v1.value] 
  

# test
if __name__ == "__main__":
    cipher=long_to_bytes(0xd5913f4fa43609f541b139503107e67f)

    key_aes=b'dfb8007c773561da'

    aes=AES.new(key_aes,AES.MODE_ECB)

    
    plain_aes=aes.decrypt(cipher)
    print('AES decrypt:',hex(bytes_to_long(plain_aes)),len(plain_aes))
    

    value = [[bytes_to_long(plain_aes[:4][::-1]),bytes_to_long(plain_aes[4:8][::-1])],[bytes_to_long(plain_aes[8:12][::-1]),bytes_to_long(plain_aes[12:][::-1])]]

    print(value)
    
    key_tea = [0x1212, 0x3412, 0x5612, 0x8923]

    plain_tea0 = decrypt(value[0], key_tea)
    print("XTEA Decrypted data is : ", hex(plain_tea0[0]), hex(plain_tea0[1]))
    plain_tea1 = decrypt(value[1], key_tea)
    print("XTEA Decrypted data is : ", hex(plain_tea1[0]), hex(plain_tea1[1]))
    
    plain_bytes=long_to_bytes(plain_tea0[0])[::-1]+long_to_bytes(plain_tea0[1])[::-1]+long_to_bytes(plain_tea1[0])[::-1]+long_to_bytes(plain_tea1[1])[::-1]

    l=[]
    print('info: lens',len(plain_bytes),plain_bytes)
    
    
    for each in plain_bytes:
        
        origin=r_rotate(each,1)
        l.append(long_to_bytes(origin))
    print(l)
    l=b''.join(l)
    print(l,len(l))
    print('%x'%(bytes_to_long(l)))
"""
decaec9d25889199865401fb84cd8a7c   flag
"""

xtea做的不多第一眼看过去确实有点蒙。

aes如果ida有findcrypt插件能直接识别, 或者看到sbox,63,7c打头也能想到了。

还好只有一个分组,且并没用少见的加密模式。

相关推荐
祁许1 天前
【Golang】手搓DES加密
开发语言·golang·密码学
白#泽5 天前
信息安全设计实验3 1-3学时
ai·密码学
看星猩的柴狗5 天前
现代密码学|古典密码学例题讲解|AES数学基础(GF(2^8)有限域上的运算问题)| AES加密算法
密码学
Nonullpoint.6 天前
对称加密与非对称加密:密码学的基石及 RSA 算法详解
java·计算机网络·算法·网络安全·密码学
it技术分享just_free7 天前
软考教材重点内容 信息安全工程师 第 3 章 密码学基本理论
网络安全·信息安全·密码学·软考
abments9 天前
JavaScript逆向爬虫教程-------基础篇之JavaScript密码学以及CryptoJS各种常用算法的实现
javascript·爬虫·密码学