小菜一碟 - WHCTF - 2016 - Reverse

来源:互联网 发布:js字符串加逗号 编辑:程序博客网 时间:2024/04/27 15:05

下载地址

32位win控制台程序,调试信息还有,用32位IDA加载,F5查看main如下:

int main(){  int *v0; // eax@1  int v2; // [sp+1Ch] [bp-B0h]@1  signed int v3; // [sp+78h] [bp-54h]@1  signed int v4; // [sp+7Ch] [bp-50h]@1  signed int v5; // [sp+80h] [bp-4Ch]@1  signed int v6; // [sp+84h] [bp-48h]@1  signed int v7; // [sp+88h] [bp-44h]@1  signed int v8; // [sp+8Ch] [bp-40h]@1  signed int v9; // [sp+90h] [bp-3Ch]@1  signed int v10; // [sp+94h] [bp-38h]@1  signed int v11; // [sp+98h] [bp-34h]@1  signed __int16 v12; // [sp+9Ch] [bp-30h]@1  char v13; // [sp+9Eh] [bp-2Eh]@1  char v14; // [sp+9Fh] [bp-2Dh]@1  int v15; // [sp+B8h] [bp-14h]@1  int v16; // [sp+BCh] [bp-10h]@1  __main();  v3 = 1953723722;  v4 = 2037543968;  v5 = 1970239776;  v6 = 1700929650;  v7 = 1629516915;  v8 = 1696621678;  v9 = 2037344878;  v10 = 1970239776;  v11 = 1818588018;  v12 = 8550;  v13 = 0;  qmemcpy(&v2, &_data_start__, 0x5Cu);  gets(&v14);  v16 = 23;  v15 = strlen(&v14);  v0 = encrypt((char *)&v3, 1LL, &v14);  if ( checkEqure(v0, &v2, v15, v16) )  //判断俩字符串内容是否完全相同    puts("You Win!");  else    puts("Try again!");  getchar();  return 0;}

其中encrypt函数如下:

int *__cdecl encrypt(char *key, __int64 seed, char *string){  __int64 seeda; // [sp+18h] [bp-40h]@1  __int64 k; // [sp+20h] [bp-38h]@2  __int64 v; // [sp+28h] [bp-30h]@2  int lenKey; // [sp+30h] [bp-28h]@1  int lenString; // [sp+34h] [bp-24h]@1  int *result; // [sp+38h] [bp-20h]@1  int count; // [sp+3Ch] [bp-1Ch]@1  seeda = seed;         //seed=1  result = (int *)malloc(0x64u);  lenString = strlen(string);  lenKey = strlen(key);  for ( count = 0; count < lenString; ++count )  {    v = string[count];    k = key[seeda];    if ( checkIn(string[count], key) )  //判断string[count]是否在key字符串中      result[count] = (16 * v + k) % 2500;    else      result[count] = (v ^ (k << seeda)) % 2500;    seeda = (seeda + 5) % lenKey;  }  return result;}

可见程序对输入的字符串逐位进行变换后存入result并返回。

因为这个算法不容易逆,所以采用逐位爆破即可。

seed=1s='9D00000060090000A7080000B3070000C4060000F70500000508000056070000C4070000130300003006000040070000B50600008B080000B307000022000000C4060000EB04000085060000BE0600009A070000AF07000059050000'key='Just try your best and enjoy yourself!'#s和key都可以动态调试时从内存中copy得到a=list()i=0while i<len(s):    n=int(s[i:i+2],16)+256*int(s[i+2:i+4])    a.append(n)    i+=8def encrypt(n):    k=ord(key[seed])    if chr(n) in key:        result=(16*n+k)%2500    else:        result=(n^(k<<seed))%2500    return resultout=""for i in range(len(a)):    for x in range(0x20,0x7f):        if encrypt(x)==a[i]:            out+=chr(x)            break    seed=(seed+5)%len(key)print(out)#whctf{you_are_the_best}
0 0