https://buuoj.cn/challenges#[GWCTF%202019]xxor

64 elf

Tea加密

加上解个方程组

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  int i; // [rsp+8h] [rbp-68h]
  int j; // [rsp+Ch] [rbp-64h]
  __int64 input[6]; // [rsp+10h] [rbp-60h] BYREF
  __int64 buffer[6]; // [rsp+40h] [rbp-30h] BYREF
 
  buffer[5] = __readfsqword(0x28u);
  puts("Let us play a game?");
  puts("you have six chances to input");
  puts("Come on!");
  memset(input, 0, 40);
  for ( i = 0; i <= 5; ++i )
  {
    printf("%s", "input: ");
    __isoc99_scanf("%d", (char *)input + 4 * i);
  }
  memset(buffer, 0, 40);
  for ( j = 0; j <= 2; ++j )
  {
    a = input[j];
    b = HIDWORD(input[j]);
    tea((unsigned int *)&a, dword_601060);      // 2,2,3,4
    LODWORD(buffer[j]) = a;
    HIDWORD(buffer[j]) = b;
  }
  if ( (unsigned int)sub_400770(buffer) != 1 )
  {
    puts("NO NO NO~ ");
    exit(0);
  }
  puts("Congratulation!\n");
  puts("You seccess half\n");
  puts("Do not forget to change input to hex and combine~\n");
  puts("ByeBye");
  return 0LL;
}

基本类型数据大小

input 是 int64 的 每个 8 块,上下两块填数据(4 块)

后面 ab 紧挨着,一起传进去 tea 加密

后面再 check

先解出来 check:

__int64 __fastcall sub_400770(_DWORD *a1)
{
  if ( a1[2] - a1[3] == 2225223423LL
    && a1[3] + a1[4] == 4201428739LL
    && a1[2] - a1[4] == 1121399208LL
    && *a1 == -548868226
    && a1[5] == -2064448480
    && a1[1] == 550153460 )
  {
    puts("good!");
    return 1LL;
  }
  else
  {
    puts("Wrong!");
    return 0LL;
  }
}

z3约束求解

这里注意是无符号数,转化成 16 进制先再做求解

from z3 import *  
  
a0, a1, a2, a3, a4, a5 = Ints('a0 a1 a2 a3 a4 a5')  
s = Solver()  
# a1[2] - a1[3] == 0x84A236FFLL  
#     && a1[3] + a1[4] == 0xFA6CB703LL  
#     && a1[2] - a1[4] == 0x42D731A8LL  
#     && *a1 == 0xDF48EF7E  
#     && a1[5] == 0x84F30420  
#     && a1[1] == 0x20CAACF4  
s.add(a2-a3 == 0x84A236FF)  
s.add(a3+a4 == 0xFA6CB703)  
s.add(a2-a4 == 0x42D731A8)  
s.add(a0 == 0xDF48EF7E)  
s.add(a5 == 0x84F30420)  
s.add(a1 == 0x20CAACF4)  
  
if s.check() == sat:  
    print(s.model())
[a4 = 2652626477,
a0 = 3746099070,
a2 = 3774025685,
a5 = 2230518816,
a3 = 1548802262,
a1 = 550153460]

再反向 tea 解密回去

__int64 __fastcall tea(unsigned int *input, _DWORD *box)
{
  __int64 result; // rax
  unsigned int v3; // [rsp+1Ch] [rbp-24h]
  unsigned int v4; // [rsp+20h] [rbp-20h]
  int v5; // [rsp+24h] [rbp-1Ch]
  unsigned int i; // [rsp+28h] [rbp-18h]
 
  v3 = *input;
  v4 = input[1];
  v5 = 0;
  for ( i = 0; i <= 0x3F; ++i ) // 注意这里的<=不是< 被坑了两次
  {
    v5 += 0x458BCD42;
    v3 += (v4 + v5 + 0xB) ^ ((v4 << 6) + *box) ^ ((v4 >> 9) + box[1]) ^ 0x20;
    v4 += (v3 + v5 + 0x14) ^ ((v3 << 6) + box[2]) ^ ((v3 >> 9) + box[3]) ^ 0x10;
  }
  *input = v3;
  result = v4;
  input[1] = v4;
  return result;
}

change input to hex and combine~

#include<bits/stdc++.h>  
  
using namespace std;  
  
  
int main() {  
    unsigned int input[6] = {3746099070, 550153460, 3774025685, 1548802262, 2652626477, 2230518816};  
    __int64 result; // rax  
    unsigned int v3; // [rsp+1Ch] [rbp-24h]  
    unsigned int v4; // [rsp+20h] [rbp-20h]  
    int v5; // [rsp+24h] [rbp-1Ch]  
  
    int box[4] = {2, 2, 3, 4};  
    for (int i = 0; i < 3; i++) {  
        v3 = input[i * 2];  
        v4 = input[i * 2 + 1];  
        v5 = 1166789954 * 64;  
        for (unsigned int j = 0; j <= 0x3f; j++) {  
            v4 -= (v3 + v5 + 0x14) ^ ((v3 << 6) + box[2]) ^ ((v3 >> 9) + box[3]) ^ 0x10;  
            v3 -= (v4 + v5 + 0xB) ^ ((v4 << 6) + *box) ^ ((v4 >> 9) + box[1]) ^ 0x20;  
            v5 -= 0x458BCD42;  
        }  
        input[i * 2] = v3;  
        input[i * 2 + 1] = v4;  
    }  
    for (unsigned int i: input) {  
        cout << hex << i;  
    }  
}
666c61677b72655f69735f6772656174217d
flag{re_is_great!}