[WUSTCTF2020]level3

本题主要涉及到了base64换表与Linux联调,为了让各位师傅看的更加清楚明白小新从base64的原理与换表原理,再到怎么Linux联调,凡是涉及到的知识点小新将从最基础的开始。

# base64原理

base64:

大部分编码都是由字符串转化成二进制的过程,而Base64的编码则是从二进制转化为字符串。
Base64 编码主要用在传输、存储、表示二进制领域,不能算得上是加密。
是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64是基于64个可打印字符来表示二进制数据的方法。

Base64的索引表,字符选用了"A-Z、a-z、0-9、+、/" 64个可打印字符,这是标准的Base64协议规定。在日常使用中我们还会看到“=”或“==”号出现在Base64的编码结果中,“=”在此是作为填充字符出现。

编码过程:
第一步:
1.1,将待转换字符串每三个字节为一组(有时不是3的倍数这时就要补“=”)
1.2,每个字节占8个二进制位
1.3,共有24个二进制位
第二步:
2.1,将第一步得到的24个二进制位分为每6个为一组,则每3个字节可分为4组
第三步:
3,在每组高位前补充两个0,每组由6个二进制位变成8个二进制位,一共32个二进制位,即四个字节(转换后的字节用来对照base64的码表)
第四步:
4,根据Base64编码对照表获得对应值

注:看到这里有些师傅可能会有些疑问不是3的倍数是怎么补0的,‘=’是什么时候补,不懂的师傅可以这样想要把字符串先转换成二进制每一个8位如果字符串不是3的倍数那二进制数就一定不是6的倍数那就要补0在后面补成6的倍数,再分为每组6个然后在每组高位前补充两个0(这里补不补无所谓主要是一个字节8位要把它当成一个字节,在解码的时候每个base64的字符就是补充后的),转换后的字节用来对照base64的码表,每一个转换完成后看字符数是不是4的倍数,不是就补‘=‘补成4的倍数)

python实现

加密:

def b64encode(str):
    b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    b = ''
    Mi = ''
    for i in  str:
        b += format(ord(i),'08b') #在python中把一个数转换成二进制的形式的时候输出来的不是完整的8位python会把前面的零给抹除,所以要自己补,format这个函数比较实用'08b'的意思就是说把一个数转换成二进制不加'0b'前缀,不足8位在前面补零。
    if len(b) % 6 != 0:
        b = b + '0' * (6 - len(b) % 6) #注意这里在后面补0
    for i in range(0, len(b), 6):
        Mi += b64[int(b[i:i+6], 2)]  # 这里就是转换了这里我没有在每6个前面补0因为也不会影响大小
    if len(Mi) % 4 != 0:
        Mi = Mi + '=' * (4 - len(Mi) % 4)   # 补'='
    return Mi

解密:就是把加密的步骤反过来就行

def b64decode(str):
    b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    b = ''
    key = ''
    for i in range(1,3):
        str = list(str)     # 字符串是不能进行删除操作的所以要转换成列表
        if str[len(str)-i] == '=':
            str.remove('=')    # 删除'=','='最多两个
        str = ''.join(str)   # 转换成字符串 
    for i in str:
        b += format(b64.index(i), '06b') # 这里只要为6个就行,因为有两个是补的也不会影响大小
    if len(b) % 8 != 0:    
        k = len(b) % 8
        b = b[::-1][k:][::-1] # 这一步是为了去除补在后面的0
    for i in range(0, len(b), 8):
        key += chr(int(b[i:i + 8], 2)) # 解码
    return key

换表原理:一句话概括就是比如原本正常加密后的字符是A但变成B了,A与B存在对应关系

python实现

import base64

m = "换表加密后的密文"

string1 = "换表后的表一定也要是64位"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

print (base64.b64decode(m.translate(str.maketrans(string1,string2))).decode())



# str.maketrans(string1, string2):
这个函数用于创建一个映射表,映射表将string1中的每个字符映射到string2中相同位置的字符。如果string1和string2的长度不同,那么较长的字符串中超出较短字符串长度的部分将被忽略。
返回值只是一个转换表。
m.translate():
这个函数中m是一个字符串,translate()方法接受一个转换表作为参数,并返回一个新字符串,其中m中的所有字符都根据转换表进行了替换,原本加密的本来是A被映射成了B

# 题目

1,先对所给文件进行查壳

无壳,用IDA打开,然后F5直接查看主函数

发现两个关键信息,本以为只是简单的base64解码但解码后发现不是,猜测是被换表了,Shift+F12查看这个程序的字符串

没有发现新的表,但看base64_encode函数它就是base64的加密方式

这时候就需要动调看看程序是怎么运行的,因为这是一个Linux的程序,所以需要利用IDA所给的一个扩展文件,要注意程序位数,把它放到要调试的同目录下(要注意的是要放在Linux环境中我这使用的集成环境也有linux环境所以可以放到这里)

开始调试

先断点。在base64_encode函数前面都行

Linux联调

这里要填文件在Linux所在的路径与linux的ip,最好也设置个密码

填好了不要点ok,先在Linux中开启连接

开始动调

这里随便输入就行,主要是要进入base64_encode函数一直,F8单步步过到达base64_encode函数时F7单步步入

这时候点击base64_table会发现它的表给换了,其实一开始动调的时候它就换了

知道了是换表直接上脚本

总结:这道题比较简单但小新也写的比较细为了那些刚接触逆向的师傅们,如有不足之处还请各位师傅们能指点一二,谢谢。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值