[HUBUCTF 2022 新生赛]simple_RE | NSSCTF ——Base64编码
前言
作为一个小萌新,我决定写一篇自己的博客来记录自己在逆向方面的学习历程,从发布我的每一道题的wp开始,向成为一名很牛的ctfer努力吧!
一、题目分析
首先下载题目拖入IDA
可以很清晰的看到主要函数
追踪进入发现这是一个base64编码
但是他的字符表被替换了
二、解题思路
我有以下两种解题思路:
1.先处理编码后的密文:
对照魔改后的base64字符表,把编码后的密文替换为正常状态下的密文。随后正常的对base64编码后的文本解码即可。
2.模拟base64解码更换字符表
自己编写一个base64解密exp!学会了解码之后,只需要将自己设置的字符表改成题中的字符表就行了。
先来讲解base64编码步骤:
- 把3个字节归为一组,每组共3*8=24 bit;
- 把每组均分为四份,每份6 bit并前补2个bit 0变成四字节,每个字节转化为一个数字;
- 依照字符表把每字节对应数字转化为字符;
- 第1步中不足3字节的分组转换后填充“=”,缺1个填充1个“=”,缺2个填充2个“=”。
def base64_one(flag):
value_end = ''
flag_byte = flag.encode()
flag_byte = ['{:0>8}'.format(str(bin(i))[2:]) for i in flag_byte]
flag_byte_list = [''.join(flag_byte[3*x:3*x+3]) for x in range(len(flag_byte)//3)]
# 处理最后三位不满足的情况
if len(flag_byte)%3:
flag_byte_end = ''.join(flag_byte[len(flag_byte) - len(flag_byte) % 3:len(flag_byte)])
if len(flag_byte) % 3 == 2:
flag_byte_end += '0' * 8
else:
flag_byte_end += '0' * 16
flag_byte_list.append(flag_byte_end)
for i in flag_byte_list:
value = ''.join(i)
for i in range(4):
str1 = '{:0>8}'.format(value[6*i:6*(i+1)])
if int (str1,2):
value_end += base64_chars[int(str1,2)]
else:
value_end += '='
return value_end
知道了base64编码步骤之后,想解码也就很简单了,倒着来就行:
- 首先照着字符表把字符转化为数字;
- 把数字转化为2进制后拼接在一起,每4个为一组,每组共4*6=24个‘0’或‘1’;
- 每个等号对应补6个‘0’,后续运算时遇到值为0的字节,自动忽略。
- 每组按个数均分为3份,每份8个‘0’或‘1’,对应编码前每个字节的8个bit;
- 将各组中的每份转化为1个字节的8bit,完成解码。
def base64_done(value_start):
flag = ''
value_list = [base64_chars.find(value) for value in value_start if value != '=']
value_byte = ['{:0>6}'.format(str(bin(i))[2:]) for i in value_list]
value_byte_list = [''.join(value_byte[4*x:4*x + 4]) for x in range((len(value_byte)//4))]
for str1 in value_byte_list:
flag_list = [int(str1[8*i:8*i+8],2) for i in range(3)]
for i in range(3):
flag += chr(flag_list[i])
#下面处理超出部分
if value_start[-1]=='=':
flag_byte = ''
i = 0
for value in range(4*(len(value_byte)//4),len(value_byte)):
flag_byte += ''.join(['{:0>6}'.format(value_byte[value])])
i += 1
if i == 3:
flag_byte += '0'*6
else:
flag_byte += '0'*12
flag_list = [int(flag_byte[i:i+8],2) for i in [0,8,16] if int(flag_byte[i:i+8],2) != 0]
flag += ''.join([chr(i) for i in flag_list])
return flag
后记
以后我也会坚持更新的。诸君,共赴之。