【攻防世界】Reverse——ereere writeup

查看strings window,看到字符串“correct”和“wrong“,猜测字符串所在的位置就是我们要分分析的内容。

反编译代码发现代码有点乱,因为大部分变量名是没有意义的,是很难读懂的。经过分析后,我重新命名了部分函数名,使其变得可读:

int sub_400BC8()
{
  int result; // $v0
  int len; // [sp+18h] [+18h]
  unsigned __int8 *v2; // [sp+1Ch] [+1Ch]
  char v3[100]; // [sp+20h] [+20h] BYREF
  int v4; // [sp+84h] [+84h]

  v4 = dword_49E990;
  printf("please input your flag:");
  ((void (*)(const char *, ...))scanf)("%s", v3);
  len = length(v3);
  encrpyt(v3);
  v2 = (unsigned __int8 *)newbase64(v3, len);
  if ( compare(v2, "ScDZC1cNDZaxnh/2eW1UdqaCiJ0ijRIExlvVEgP43rpxoxbYePBhpwHDPJ==") )
  {
    put("wrong!");
    result = -1;
  }
  else
  {
    put("correct!");
    result = 0;
  }
  if ( v4 != dword_49E990 )
    sub_420350();
  return result;
}

BOOL __fastcall encrpyt(char *a1)
{
  BOOL result; // $v0
  unsigned int i; // [sp+1Ch] [+1Ch]
  int v3; // [sp+20h] [+20h]
  int v4; // [sp+24h] [+24h]
  unsigned __int8 v5; // [sp+2Bh] [+2Bh]

  ((void (__fastcall *)())init_tab)();
  v4 = 0;
  v3 = 0;
  for ( i = 0; ; ++i )
  {
    result = i < length(a1);
    if ( !result )
      break;
    v3 = (v3 + 1) % 256;
    v4 = (tab[v3] + v4) % 256;
    v5 = tab[v3];
    tab[v3] = tab[v4];
    tab[v4] = v5;
    a1[i] ^= tab[(unsigned __int8)(tab[v3] + tab[v4])];
  }
  return result;

这样就很清晰,首先对输入进行加密(encrypt),然后在通过一个修改过的Base64函数(仅仅是修改了表的顺序,这个解密方法我在做mobile easyjni那篇博客上有具体步骤,这里不详细解释)。最后做对比。

了解它的基本逻辑,比较费时间分析。但是分析好了,解密就很简单。要做逆向,所以先解密newBase64(下面的fromBase64函数),然后再decrypt。事实上,init_tab和decrypt的逻辑跟反编译后得到的代码(init_tab和encrypt)是一样的,不用修改,直接改写成python就可以了:
 

import base64

def fromBase64(result):

    new="ZYXWVUTSRQPONMLKJIHGFEDCBAabcdefghijklmnopqrstuvwxyz/+9876543210"  
    ori = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

    change = result.translate(str.maketrans(new,ori))
   # print("after changing:"+change)
    #print(base64.b64decode(change))
    return base64.b64decode(change)
def init_tab():
    flag= 'flag{123321321123badbeef012}'
    aFlag1233213211 = [ord(x) for x in flag]
 
    tab = [i % 256 for i in range(256)]


    current_index_in_key_array = 0
    index_in_flag = 0
    new_index = 0
  
    for current_index_in_key_array in range(256):


        current_value = tab[current_index_in_key_array]
        new_index = (current_value + new_index + aFlag1233213211[index_in_flag]) % 256

    
        tab[current_index_in_key_array], tab[new_index] = tab[new_index], tab[current_index_in_key_array]

      
        index_in_flag  +=1
        if index_in_flag >= len(aFlag1233213211):
            index_in_flag=0
    print(len(tab))
    print(tab)
    return tab
def decrypt(enc):
    dec= []
    tab = init_tab()
    v3 = 0
    v4 = 0
    for i in range(len(enc)):
        v3 = (v3+1)%256
        v4 = (v4+tab[v3])%256
        tab[v3],tab[v4] = tab[v4],tab[v3]
        sum = tab[(tab[v3]+tab[v4])%256]
        dec.append(enc[i]^sum)
    #print(dec)
    return dec
if __name__ == '__main__':
    result = "ScDZC1cNDZaxnh/2eW1UdqaCiJ0ijRIExlvVEgP43rpxoxbYePBhpwHDPJ=="
    input = fromBase64(result)
    #input = b'\x1d\xc5\x80_\xe7\x0cX\x06\xb1\x9e\x1d=x?\x85v\xa6\x97\x89\x0f\xe2\x8c\x84U\xc6[\xc4V\x02\xbb\xf2\xbaq\xa3\x16\xc1x\xa6!\xa7\x04\x96)'
    enc = decrypt(input)
    flag = ''.join([chr(x) for x in enc])
    print(flag)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值