'); }

虎符_CrackMe


拖入ida,开始会进行长度判断

if ( len != 17 )                              // len==17
   exit(-3);

然后会让你再次输入,第二次输入后,紧接着就对第二次输入的值进行判定

image-20211019201547825

其中math_函数

// local variable allocation has failed, the output may be wrong!
__m128 __fastcall sub_7FF7F3C31360(double a1, double a2)
{
  double v2; // xmm7_8
  __int128 v3; // xmm6

  v2 = a1;
  a1 = pow(a1, a2 - 1.0);
  *((double *)&v3 + 1) = *(&a1 + 1);
  *(double *)&v3 = a1 / exp(v2);
  return (__m128)v3;                            // return pow(a1,a2-1.0)/exp(a1)
}

可以直接爆破解第二次输入的值,需要注意的是,比较的值不是静态下的值,需要动调看值。

最好不要直接cttl c+ctrl v代码,爆破时间太久

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double math_(double a1,double a2){
    return pow(a1,a2-1)/exp(a1);
}

int main()
{
    int i=0,j;
    while(1){

        double v17=0.0;
        double v18=0.0;
        double v19=(double)i+1.0;   //将(double)((int)input2 / 12379)看成一个整体i,缩短时间
        do{
            v17=v17+math_(v18,v19)*0.001;
            v18=v18+0.001;
        }while(v18<=100.0);
        double v20=(int)(v17+v17+3.0);
        if(v20==0x13B03)
            break;
        i++;
    }
    for(j=0;j<12379;j++){
        double v16=0.0;
        double v21=0;
        double v22=(double)j+1.0;
        do{
            v16=v16+math_(v21,v22)*0.001;
            v21=v21+0.001;
        }while(v21<=100.0);
        if((int)(v16+v16+3.0)==0x5a2)
            break;
    }

    printf("%d",i*12379+j);
    return 0;
}

得到第二次输入的值:99038

接着往下面看,

image-20211019202442692

Block内的值:99038198076198076

接着往后面看就能发现是将第一次输入的值进行了分别加密,分别为前7位与后10位

image-20211019202626716

紧接着就对异或后的值进行了比较

image-20211019203405475

这样就可以获得第一次输入前7位的值:

a="99038198076198076"
b=[ 0x08, 0x4D, 0x59, 0x06, 0x73, 0x02, 0x40]
for i in range(len(b)):
    print(chr(ord(a[i])^b[i]),end="")
#answer:1ti5K3y

然后处理第一次输入的后10位,

image-20211019203720048

就是一个原汁原味的RC4加密,带脚本

strflag=""
S=[0x7f,0x36,0x11,0x8,0x56,0xfc,0x16,0x87,0xea,0x75,0xc,0x99,0xf8,0x7e,0xd8,0x79,0xb,0xff,0x9e,0x32,0x2e,0x6f,0x2,0xc1,0x34,0x72,0x25,0x53,0x7b,0x1,0x14,0x30,0x57,0xcb,0x40,0x48,0x93,0xa2,0x3b,0xf0,0x49,0xaa,0x95,0xa4,0x94,0x6e,0x44,0x27,0x13,0x6d,0xe4,0x24,0xb5,0x74,0xa6,0x3c,0xbf,0x23,0x9a,0x84,0x4c,0x33,0x22,0x59,0x45,0x4f,0x7d,0xb4,0x82,0x55,0x15,0x19,0xe5,0x64,0xf9,0xbd,0x3f,0xdd,0xdb,0xeb,0x70,0x1f,0x63,0xf7,0x4e,0xac,0x89,0x90,0xaf,0x6,0x92,0x47,0xee,0x3e,0x42,0x81,0x5a,0x5d,0x46,0x65,0xda,0x58,0xbc,0x98,0xb1,0xd1,0x3d,0x5c,0x5e,0x8c,0x9b,0xe1,0x8a,0xc7,0x5f,0x2f,0xd4,0xa1,0xfd,0x2d,0xec,0x86,0x1c,0xa0,0x9c,0xbe,0xca,0xc4,0xe9,0x9f,0x2b,0xcc,0x69,0x31,0xa7,0xd2,0xdf,0xb3,0x4b,0x4,0xc2,0x3a,0x4d,0xcf,0x77,0x97,0x12,0xa,0x39,0xd0,0x6a,0x29,0x4a,0x54,0xd6,0x37,0xa3,0x7c,0xab,0xce,0xf5,0xc6,0x21,0x43,0x35,0x80,0xbb,0xe6,0xb6,0x2a,0xc3,0xde,0xd5,0x76,0x7a,0xfa,0xfb,0xd9,0x71,0xae,0x6c,0x17,0xe8,0xcd,0x8e,0x88,0xe2,0x0,0x73,0x50,0x52,0xf2,0xe,0xc0,0xc9,0x96,0xb9,0x83,0x5b,0x9,0x1d,0x1e,0x8f,0x5,0xd7,0x67,0xef,0x9d,0xdc,0xc8,0xe3,0x68,0x8b,0x7,0x60,0x20,0xb0,0x8d,0x10,0xa8,0xe0,0xfe,0xed,0x1b,0x38,0xb7,0xf1,0x66,0x3,0xf3,0x91,0xd3,0xd,0xa5,0x28,0x1a,0xc5,0x61,0x78,0xf6,0xad,0xb2,0xe7,0xba,0x62,0xf4,0xb8,0x85,0x51,0x26,0x6b,0x18,0xa9,0xf,0x2c,0x41]
flag=[0xB2, 0xD6, 0x8E, 0x3F, 0xAA, 0x14, 0x53, 0x54, 0xC6, 0x06]
i=0
j=0
for m in range(len(flag)):
    i=(i+1)%256
    j=(j+S[i])%256
    tmp=S[i]
    S[i]=S[j]
    S[j]=tmp
    strflag+=chr(flag[m]^S[(S[i]+S[j])%256])
print(strflag)
#answer:RC4_crypt0

最后将两段拼接起来,获取第一次输入的值:1ti5K3yRC4_crypt0

输入程序获得最终flag

image-20211019204025557

flag{1ti5K3yRC4_crypt099038}

  目录