ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021强网杯 LongTimeAgo

2021-06-20 14:05:38  阅读:277  来源: 互联网

标签:tmp __ sub LongTimeAgo rbp 强网杯 int64 2021 rsp


我们这题被锤了,理由是与摘星实验室wp重合度高

重合度有多高我不知道,但是我们所有人都压根没听说过这个实验室

所以在这里放一个更加细致的wp,不想让几十个小时的努力付之东流。

文件打开了,函数很多,有3800个

先查字符串,对照着程序的运行结果

找到main函数

在这里,IDA 7.0无法很好的解释该程序,导致F5得到结果看起来正确但实际并不完整。

而IDA 7.6则会显著的标出错误部分,方便汇编代码上的审查

这是IDA7.6最初分析出来的main函数

看一下汇编代码,发现其中有很多字节码的混淆

这些才是导致IDA误判函数内容的原因

手动修复一下

得到main函数

void __usercall sub_4A2980(__int64 a1@<rbx>, __int64 a2@<rbp>, __int64 a3@<rdi>, __int64 a4@<rsi>, __int64 a5@<r12>, __int64 a6@<r13>, __int64 a7@<r14>, __int64 a8@<r15>)
{
  char *v8; // r15
  char *v9; // rdi
  int *v10; // r12
  char *v11; // r14
  char *v12; // rbx
  char *v13; // r13
  int v14; // eax
  signed __int64 v15; // rax
  int v16; // edx
  int v17; // eax
  signed __int64 v18; // rax
  int v19; // edx
  int v20; // ecx
  int v21; // eax
  __int64 v22; // rax
  char v23; // dl
  char v24; // [rsp+30h] [rbp-3F8h]
  __int64 v25; // [rsp+70h] [rbp-3B8h]
  char v26; // [rsp+80h] [rbp-3A8h]
  __int64 v27; // [rsp+C8h] [rbp-360h]
  __int64 v28; // [rsp+110h] [rbp-318h]
  __int64 v29; // [rsp+158h] [rbp-2D0h]
  char v30; // [rsp+1A0h] [rbp-288h]
  int v31; // [rsp+1C4h] [rbp-264h]
  __int64 v32; // [rsp+1E8h] [rbp-240h]
  int v33; // [rsp+20Ch] [rbp-21Ch]
  char v34; // [rsp+2C0h] [rbp-168h]
  char v35[8]; // [rsp+3E0h] [rbp-48h]

  sub_40CC40();
  memset(&v24, 0, 0x50ui64);
  sub_49F840(&unk_4A68E0, "Input Your Key:");
  sub_4A04A0(&unk_4A6580, &v24);
  if ( strlen(&v24) == 64 )
  {
    if ( __OFADD__(1, 2004318072) )
    {
      if ( !__OFADD__(1, 2004318072) )
        JUMPOUT(*(_QWORD *)&byte_4A2A4F);
    }
    v8 = &v24;
    v9 = &v34;
    v10 = (int *)&unk_4A4020;
    v11 = &v34;
    sub_49F840(&unk_4A68E0, "Are You Sure You Want To Keep Waiting...\n");
    v12 = &v26;
    v13 = &v26;
    do
    {
      v14 = sub_401DB0(v8, 8i64);
      v12[8] = 0;
      *((_DWORD *)v12 + 1) = v14;
      v15 = 4i64;
      while ( 1 )
      {
        v16 = v15;
        if ( v12[v15 + 3] )
          break;
        if ( !--v15 )
        {
          v16 = 0;
          break;
        }
      }
      *(_DWORD *)v12 = v16;
      v17 = *v10;
      v11[8] = 0;
      *((_DWORD *)v11 + 1) = v17;
      v18 = 4i64;
      while ( 1 )
      {
        v19 = v18;
        if ( v11[v18 + 3] )
          break;
        if ( !--v18 )
        {
          v19 = 0;
          break;
        }
      }
      v8 += 8;
      *(_DWORD *)v11 = v19;
      v12 += 36;
      v11 += 36;
      ++v10;
    }
    while ( v8 != (char *)&v25 );
    sub_403460(&v30, 13i64);
    sub_403460(&v31, 14i64);
    sub_403460(&v32, 15i64);
    sub_403460(&v33, 16i64);
    sub_4029E0(&v26, &v30);
    sub_4029E0(&v27, &v30);
    sub_402030(&v28, &v30);
    sub_402030(&v29, &v30);
    v20 = 0;
    while ( 1 )
    {
      v21 = *(_DWORD *)v13;
      if ( *(_DWORD *)v13 != *(_DWORD *)v9 )
        break;
      if ( v21 - 1 >= 0 )
      {
        if ( v35[36 * v20 - 861 + v21] != v35[36 * v20 - 285 + v21] )
          break;
        v22 = v21 - 2;
        while ( (signed int)v22 >= 0 )
        {
          v23 = v13[v22-- + 4];
          if ( v23 != v9[v22 + 5] )
            goto LABEL_2;
        }
      }
      ++v20;
      v13 += 36;
      v9 += 36;
      if ( v20 == 8 )
      {
        sub_401550("QWB{%s}\n");
        return;
      }
    }
  }
LABEL_2:
  sub_401550("sorry\n");
}

第一关做了一个小判断,在修复函数前是很难看出来什么意思的

但也可以用x64dbg进行动态调试,勉强能够猜出是判断字符串的长度是不是等于0x40

之后遇到一个很费时的一个函数401EF0

进去之后基本看不懂,但是输入是写死的,只需要把每一个返回值找到就行了

记录下这些返回值,就是产生的key

key = [0xfffd,0x1fffd,0x3fffd,0x7fffd]

在下面的函数中被用到

随后来到函数sub_403460

看到这里(v16>>11) & 3

基本上就能猜出来是XTEA加密了

同时delta是0xE6EF3D20 sum是0x70C88617

其中的运算符全部用函数来代替了

接着再看sub_402030

里面又出现了401EF0函数,用来产生一个值

再往下看又遇见了xor函数

即把密文与401EF0产生的值进行异或操作

这四个函数都是相同的操作

依次找出所有的异或值

0xfd,0x1fd,0x3fd,0x7fd

然后就是进行字符串的比对了

由此写出脚本

def TEAdecode(c, key):
    tmp_0 = c[0]
    tmp_1 = c[1]
    sum = 0xa6a53780
    delta = 0x3d3529bc
    for i in range(32):
        tmp_1 -= ((tmp_0<<4) + key[2]) ^ (tmp_0 + sum) ^ ((tmp_0>>5) + key[3])
        tmp_1 &= 0xffffffff
        tmp_0 -= ((tmp_1<<4) + key[0]) ^ (tmp_1 + sum) ^ ((tmp_1>>5) + key[1])
        tmp_0 &= 0xffffffff
        sum -= delta
    return (tmp_0, tmp_1)
 
def XTEAdecode(circle, c, key):
    tmp_0 = c[0]
    tmp_1 = c[1]
    delta = 0x70C88617
    sum = 0xE6EF3D20
    for i in range(circle):    
        tmp_1 -= (((tmp_0 << 4) ^ (tmp_0 >> 5)) + tmp_0) ^ (sum + key[(sum>>11) & 3])
        tmp_1 &= 0xffffffff        
        sum += delta;  
        tmp_0 -= (((tmp_1 << 4) ^ (tmp_1 >> 5)) + tmp_1) ^ (sum + key[sum & 3])
        tmp_0 &= 0xffffffff
    return (tmp_0, tmp_1)


 
c = [0x1F306772, 0xB75B0C29, 0x4A7CDBE3, 0x2877BDDF, 0x1354C485, 0x357C3C3A, 0x738AF06C, 0x89B7F537]
key = [0xfffd,0x1fffd,0x3fffd,0x7fffd]



for i in range(0, 4, 2):
    c[i] ^= 0xfd
    c[i+1] ^= 0x1fd
for i in range(4, 8, 2):
    c[i] ^= 0x3fd
    c[i+1] ^= 0x7fd
 

flag = ''  
for i in range(0, 4, 2):
    ans = XTEAdecode(32, c[i:], key)
    flag += hex(ans[0])[2:] + hex(ans[1])[2:]
for i in range(4, 8, 2):
    ans = TEAdecode(c[i:], key)
    flag += hex(ans[0])[2:] + hex(ans[1])[2:]
print("QWB{"+flag.upper()+"}")

不知道是不是因为xtea和tea解密脚本相似度高的原因

但是如果是因为这个而ban掉参赛队伍,未免不太负责.毕竟解密脚本全网统一,我也是从网上找的代码....

标签:tmp,__,sub,LongTimeAgo,rbp,强网杯,int64,2021,rsp
来源: https://blog.csdn.net/qq_30097049/article/details/117998667

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有