GDOUCTD NSSCTF2023广东海洋大学比赛WP RE(上) Tea Check_Your_Luck

Check_Your_Luck

下载文件是cpp
在这里插入图片描述
是个解方程的题,用python的z3

from z3 import *
v,w,x,y,z=BitVecs('v w x y z',16)

l=Solver()
l.add(v * 23 + w * -32 + x * 98 + y * 55 + z * 90 == 333322)
l.add(v * 123 + w * -322 + x * 68 + y * 67 + z * 32 == 707724)
l.add(v * 266 + w * -34 + x * 43 + y * 8 + z * 32 == 1272529)
l.add(v * 343 + w * -352 + x * 58 + y * 65 + z * 5 == 1672457)
l.add(v * 231 + w * -321 + x * 938 + y * 555 + z * 970 == 3372367)
if l.check() == sat:
    print(l.model())
else:
    print ('Error')
#[y = 1754, z = 777, x = 677, w = 123, v = 4544]

在这里插入图片描述

Tea

打开可执行文件有输出,直接打开ida
shift+F12点进去
在这里插入图片描述
在这里插入图片描述
他提示你,这是假的flag,看看哪个函数引用了它,往上追,就来到了关键的地方

__int64 sub_140016230()
{
  char *v0; // rdi
  __int64 i; // rcx
  char v3[32]; // [rsp+0h] [rbp-20h] BYREF
  char v4; // [rsp+20h] [rbp+0h] BYREF
  int v5; // [rsp+24h] [rbp+4h]
  int v6; // [rsp+44h] [rbp+24h]
  int v7[12]; // [rsp+68h] [rbp+48h] BYREF
  _DWORD v8[16]; // [rsp+98h] [rbp+78h] BYREF
  int v9[31]; // [rsp+D8h] [rbp+B8h] BYREF
  int j; // [rsp+154h] [rbp+134h]
  int k; // [rsp+174h] [rbp+154h]
  int m; // [rsp+194h] [rbp+174h]

  v0 = &v4;
  for ( i = 102i64; i; --i )
  {
    *(_DWORD *)v0 = -858993460;
    v0 += 4;
  }
  sub_14001137F(&unk_140023009);
  v5 = 32;
  v6 = 0;
  v7[0] = 1234;
  v7[1] = 5678;
  v7[2] = 9012;
  v7[3] = 3456;
  memset(v8, 0, 0x28ui64);
  v9[15] = 0;
  v9[23] = 0;
  sub_1400113E8();
  for ( j = 0; j < 10; ++j )
    sub_1400111FE("%x", &v8[j]);
  sub_140011339(v7);
  sub_140011145(v8, v9);
  sub_1400112B7(v8, v7);
  v6 = sub_140011352(v8);
  if ( v6 )
  {
    printf("you are right\n");
    for ( k = 0; k < 10; ++k )
    {
      for ( m = 3; m >= 0; --m )
        printf("%c", (unsigned __int8)((unsigned int)v9[k] >> (8 * m)));
    }
  }
  else
  {
    printf("fault!\nYou can go online and learn the tea algorithm!");
  }
  sub_140011311(v3, &unk_14001AE90);
  return 0i64;
}

最后一句话提醒了我们这是tea加密
最后v9输出flag。
v6 = sub_140011352(v8);
进去发现是一个返回值为bool类型的函数
在这里插入图片描述
说明了形参a1等于v8
由此我们知道了tea加密后的v8的值
sub_1400112B7(v8, v7);
进入这个函数,就是魔改版的茶加密,在解密前,我们还要知道v7
的值。
sub_140011339(v7);
进入这个函数,直接对v7进行赋值。
在这里插入图片描述
然后我们再解密,我们首先把加密改成c语言形式

for (int i = 0; i <= 8; ++i )
    {
    v5 = 0;
    v6 = 256256256 * i;
    v3 = i + 1;
    do
    {
      ++v5;
      v8[i] += v6 ^ (v8[v3]+ ((v8[v3] >> 5) ^ (16 * v8[v3]))) ^ (v6 + v7[v6&3]);
      v8[v3] += (v6 + v7[(v6>>11)&3]) ^ (v8[i]+ ((v8[i] >> 5) ^ (16 * v8[i])));
      v6 += 256256256;
    }
    while ( v5 <= 0x20 );
    }

之后再逆向写,为了检验正确性,自己可以赋值一组数,然后互相解密,看看结果对不对

#include <bits/stdc++.h>

using namespace std;
int sub_140011339(int *a1)
{
    int v6;
    int v7;
    int v8;
    int v9;
    v6 = 2233;
    v7 = 4455;
    v8 = 6677;
    v9 = 8899;
    *a1 = 2233;
    *(a1+1) = v7;
    *(a1+2) = v8;
    *(a1+3) = v9;
    return 0;
}
int main()
{
    int v7[12];
    unsigned int v8[15];
    int v5,v6,v3;
    v7[0] = 1234;
    v7[1] = 5678;
    v7[2] = 9012;
    v7[3] = 3456;
    sub_140011339(v7);
    //cout<<v7[3]<<endl;
    v8[0] = 444599258;
    v8[1] = 4154859931;
    v8[2] = 1226314200;
    v8[3] = 4060164904;
    v8[4] = 359413339;
    v8[5] = 1013885656;
    v8[6] = -2066432216;
    v8[7] = -249921817;
    v8[8] = 856928850;
    v8[9] = 3718242937;
    for (int  i = 8; i >= 0; --i )
    {
        v5 = 0;
        v6 = 0xF462900 * i;
        v3 = i + 1;
        v6=v6+(33*0xF462900);
        do
        {
            v6-=0xF462900;
            v8[v3]-=(v6+v7[(v6>>11)&3])^(v8[i]+((v8[i]>>5)^(16 * v8[i])));
            v8[i]-=v6^(v8[v3]+((v8[v3]>>5)^(16*v8[v3])))^(v6+v7[v6&3]);
            ++v5;
        }
        while ( v5 <= 0x20 );
    }
    /*for(int j=0;j<10;j++)
    cout<<v8[j]<<endl;*/
    for (int k = 0; k < 10; ++k )
    {
      for (int m = 3; m >= 0; --m )
        printf("%c",(v8[k] >> (8 * m)));
    }
    return 0;
}

要注意不能把v8定义成int类型,要定义成unsigned int类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值