reverse-for-the-holy-grail-350 攻防世界

工具

IDA+虚拟机(kali)

思路展开
1.查壳,无壳,64位,放到虚拟机运行

灵魂三连问
灵魂三连问

2.iDA(64-bit)启动

先从下往上找,找关键比较,再从上往下,找用户输入与函数关系
关键函数
找关键函数的原则:用户的输入变量,第一个过程判断输入符合条件,第二个过程实现算法(输入字符串+算法=结果字符串)
stringMod关键函数

__int64 __fastcall stringMod(__int64 *a1)
{
  __int64 len; // r9
  __int64 c_str; // r10
  __int64 i; // rcx
  signed int v4; // er8
  int *temp_2; // rdi
  int *temp_3; // rsi
  signed int t; // ecx
  signed int j; // er9
  int g; // er10
  unsigned int h; // eax
  int sign; // esi
  int v12; // esi
  int temp[24]; // [rsp+0h] [rbp-60h]

  memset(temp, 0, 0x48uLL);
  len = a1[1];
  if ( len )
  {
    c_str = *a1;
    i = 0LL;
    v4 = 0;
    do
    {
      v12 = *(char *)(c_str + i);
      temp[i] = v12;                            // temp=a1
      if ( 3 * ((unsigned int)i / 3) == (_DWORD)i && v12 != firstchar[(unsigned int)i / 3] )// 当i是3的倍数时,str=first[i/3]
        v4 = -1;
      ++i;
    }
    while ( i != len );
  }
  else
  {
    v4 = 0;
  }                                             // 将正确的a1赋值给temp
  temp_2 = temp;
  temp_3 = temp;
  t = 666;
  do
  {                                             // 将temp里的每个字符与v7异或,v7变化
    *temp_3 = t ^ *(unsigned __int8 *)temp_3;
    t += t % 5;
    ++temp_3;
  }
  while ( &temp[18] != temp_3 );
  j = 1;
  g = 0;
  h = 1;
  sign = 0;
  do
  {
    if ( sign == 2 )
    {
      if ( *temp_2 != thirdchar[g] )            // 2 5 8 11 15 17
        v4 = -1;
      if ( h % *temp_2 != masterArray[g] )      // 1 4 7 10 14 16
        v4 = -1;
      ++g;
      h = 1;
      sign = 0;
    }
    else
    {
      h *= *temp_2;
      if ( ++sign == 3 )
        sign = 0;
    }
    ++j;
    ++temp_2;
  }
  while ( j != 19 );
  return (unsigned int)(t * v4);
}

看了一圈,函数分三层,第一层赋值操作,当i是3的倍数时,对字符有规定(确定0 3 6 9 12 15 18六个字符),第二层异或操作,异或的值变化,第三层对异或后的值循环,0 1 2 三个为一组

3.脚本
firstchar=[65, 105, 110, 69, 111, 97]
thirdchar=[751, 708, 732, 711, 734, 764]
masterArray=[471, 12, 580, 606, 147, 108 ]
t=[]
x=666
for i in range(18):
    t.append(x)
    x+=x%5
flag=[0 for i in range(18)]
index=0
for i in range(0,18,3):
    flag[i]=firstchar[index]  #0,3,6,9,12,15
    index+=1
index=0
for i in range(2,18,3):
    flag[i]=thirdchar[index]^t[i]  #2 5,8,11,14,17
    index+=1
index=0
for i in range(1,18,3):
    for f in range(32,126):  #常用可输入字符,符合条件的留下来
        if (flag[i-1]^t[i-1])*(f^t[i])%(flag[i+1]^t[i+1])==masterArray[index]:
            flag[i]=f
            index+=1
            break;

print('tuctf{'+''.join(map(chr,flag))+'}')

tuctf{AfricanOrEuropean?}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值