小菜一碟 - WHCTF - 2016 - Reverse

下载地址

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=1
s='9D00000060090000A7080000B3070000C4060000F70500000508000056070000C4070000130300003006000040070000B50600008B080000B307000022000000C4060000EB04000085060000BE0600009A070000AF07000059050000'
key='Just try your best and enjoy yourself!'
#s和key都可以动态调试时从内存中copy得到
a=list()
i=0
while i<len(s):
    n=int(s[i:i+2],16)+256*int(s[i+2:i+4])
    a.append(n)
    i+=8

def encrypt(n):
    k=ord(key[seed])
    if chr(n) in key:
        result=(16*n+k)%2500
    else:
        result=(n^(k<<seed))%2500
    return result

out=""
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}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值