[NSSCTF 2nd]MyBase

文章讲述了在动态调试过程中对Base64编码的字符进行解码的详细过程,涉及到了字符处理、位操作和异常处理,最终通过脚本实现了一个Base64解密并随机化字符的示例,揭示了NSSCTF比赛中的旗标解密方法。
摘要由CSDN通过智能技术生成

发现关键函数

 

 直接base64没解出来,题目说动态调试,就试一下

调试后再次进入,base表变了,试一下,还是不对,只好再仔细分析一下。

  *a3 = 4 * ((len + 2) / 3);                    // 计算编码后的字符长度
  v13 = malloc(*a3);
  if ( !v13 )
    return 0i64;
  v15 = 0i64;
  v14 = 0i64;
  while ( v15 < len )
  {
    v4 = v15++;
    v12 = *(unsigned __int8 *)(str + v4);       // str[1]
    if ( v15 >= len )
    {
      v6 = 0;
    }
    else
    {
      v5 = v15++;
      v6 = *(unsigned __int8 *)(str + v5);      // str[2]
    }
    v11 = v6;
    if ( v15 >= len )
    {
      v8 = 0;
    }
    else
    {
      v7 = v15++;
      v8 = *(unsigned __int8 *)(str + v7);      // str[3]
    }
    v10 = (v11 << 8) + (v12 << 16) + v8;        // v10=(str[2]<<8)+(str[1]<<16)+str[3]
                                                // 数组中第 4 个字节左移 8 位,第 3 个字节左移 16 位,第 2 个字节左移 24 位,然后将它们相加,得到一个 24 位整数的值
    v13[v14] = base64_table[v8 & 0x3F];         // &0x3f保留v8的低 6 位
    v13[v14 + 1] = base64_table[(v10 >> 6) & 0x3F];
    v13[v14 + 2] = base64_table[(v10 >> 12) & 0x3F];// 向右移动12位,从而将v10的第12位移动到第0位
                                                // 得到了v10中第12到第23位(共 12 位)所代表的整数值
    v9 = v14 + 3;
    v14 += 4i64;
    v13[v9] = base64_table[(v10 >> 18) & 0x3F]; // 变成4字节
    if ( !setjmp(env) )
      exception_handler();
  }
  if ( len % 3 == 1 )
  {
    v13[*a3 - 1] = '=';
  }
  else if ( len % 3 != 2 )
  {
    goto LABEL_18;                              // 不足3位补'='
  }
  v13[*a3 - 2] = '=';
LABEL_18:
  v13[*a3] = 0;
  return v13;
}

这3个字符取的位置跟正常的相反,没发现什么特别的,只好看wp了

还是看漏了 ,唉

每处理完3个字符后会进行exception_handler()

所以enc36个字符,有9个base表,调九次。

找到一个脚本的

from pwn import u32 
from ctypes import *
 
clibc = cdll.LoadLibrary("msvcrt.dll")
 
enc = b'YkLYv1Xj23X7N0E5eoFgUveKeos1XS8K9r4g'
tab = b'+86420ywusqomkigecaYWUSQOMKIGECABDFHJLNPRTVXZbdfhjlnprtvxz13579/'
 
flag = b''
for i in range(0,len(enc),4):
    v = [tab.index(enc[i+j]) for j in range(4)]
    k3 = ((v[1]&3)<<6) + v[0]
    k2 = ((v[2]&0xf)<<4) + (v[1]>>2)
    k1 = (v[3]<<2)|(v[2]>>4)
    flag += bytes([k1,k2,k3])
    
    #change tab
    seed = tab[0] #取第1个字符为种子
    clibc.srand(seed)
    ttab = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
    v = [_ for _ in ttab]
    for j in range(63,0,-1):
        v3 = clibc.rand()
        v[v3%(j+1)],v[j] = v[j],v[v3%(j+1)]
    tab = bytes(v)
    print(flag, tab)
 
 
print(flag)
#NSSCTF{Welc0me_T0_Re_World}

感谢[NSSCTF 2nd] NSS两周年纪念赛。_hint1 = (2019-2023*m) % mod-CSDN博客

不太会写,所以只能生撕,搞9次base64

得到flag

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值