zoukankan      html  css  js  c++  java
  • BUUOJ | [ACTF新生赛2020]usualCrypt (多重加密)

    题目地址

    静态分析

    无壳 PE 文件,拖入 IDA 反汇编,结构如下:

    主函数

    12 和 26 行的sub_403CF8显然是输出函数,21 - 25 行的while()是字符串比较的过程,

    看来还是一个输入 flag 加密验证正确性的模型

    容易发现19行的sub_401080是加密函数,进入分析:

    sub_401080

    主体的代码比较熟悉,是base64加密算法,但在加密前执行了sub_401000(),这是一个改变密钥对应表的函数

    byte_40E0A0byte_40E0AA看起来是两个数组,其实都是一个字符串上(即密钥表串)的地址,

    所以这个子函数的功能就是把一个字符串上的范围内的字符按偏移索引(result)两两交换

    在操作后,base64 的加密规则未变,但是部分字符的意义发生了变化

    在写逆向脚本代码的时候可以用 python 的字典构造原密钥与改过的密钥的对应关系

    在加密后,该函数又调用了sub_401030

    sub_401030

    不难看出这个子函数把字符串每个英文字符进行了大小写转换,最后形成数据段保存的密码byte_40E0E4

    逆向代码

    该程序进行了多重加密,在取出密码之后首先要进行大小写转换,令其出于 base64(更改密钥表后)加密后的形态

    第二步是还原经 base64(更改密钥表后)加密字符的原含义,还原规则即sub_401000()的交换

    最后得到了真实的nbase64n加密字符串,解密即可得到flag{bAse64_h2s_a_Surprise}

    代码如下:

    import base64
    
    flag = ''; dict = {}; offset = 10
    orgin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    for i in range(len(orgin)):
        dict[orgin[i]] = orgin[i]
    for i in range(6, 15): #sub_401000()
        dict[orgin[i]] , dict[orgin[i+offset]] = dict[orgin[i+offset]] , dict[orgin[i]] # 恢复base64密钥表
    secret = 'zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9'.swapcase() #sub_401030()
    for i in range(len(secret)):
        flag += dict[secret[i]] 
    flag = base64.b64decode(flag)
    print(flag)
    
  • 相关阅读:
    高精度
    欢迎来到我的博客!
    1
    POJ 2774 求两个串的最长公共前缀 | 后缀数组
    ural1297 求最长回文子串 | 后缀数组
    洛谷 [SCOI2010]股票交易 | 单调性DP
    BZOJ 1096: [ZJOI2007]仓库建设 | 斜率优化DP
    洛谷 P2906 [USACO08OPEN]牛的街区Cow Neighborhoods | Set+并查集
    BZOJ 1010: [HNOI2008]玩具装箱toy | 单调队列优化DP
    BZOJ 1342: [Baltic2007]Sound静音问题 | 单调队列维护的好题
  • 原文地址:https://www.cnblogs.com/zhwer/p/12775703.html
Copyright © 2011-2022 走看看