IDF实验室:倒行逆施--python ByteCode

前言:
            跟着小甲鱼Python 教学视频学了1天半, 因为不是会员, 又想找题作, 刚好看到这个Python 的逆向题, 便拿来练手(不小心又自虐了...);
    虽然花的时间久了一点,走了弯路,但是最终我还是解出来了 ,感动啊 啊 啊 啊 啊 啊 啊 啊 啊.....


地址:
ctf.idf.cn/index.php?g=game&m=article&a=index&id=45
题目:

pan.baidu.com/s/1jGpB8DS



STEP 1:
下载下来,发现是一个.pyc文件,这并不是一个标准的.py文件,搜索文件格式后发现,这是一个python生成的字节码文件,利用现成工具:
uncompyle2 进行解码。
uncompyle2 安装方式:
在git上下载uncompyle2包,cd 到目录:
python setup.py install
对文件进行解码:
uncompyle2 crackme.pyc > crackme.py

STEP 2:
查看源码:

def encrypt(key, seed, string):
            rst = []
            for v in string:
                        rst.append((ord(v) + seed ^ ord(key[seed])) % 255)
                        seed = (seed + 1) % len(key)
            return rst

if __name__ == '__main__':
            print "Welcome to idf's python crackme"
            flag = input('Enter the Flag: ')
            KEY1 = 'Maybe you are good at decryptint Byte Code, have a try!'
            KEY2 = [124, 48, 52, 59, 164, 50, 37, 62, 67, 52, 48, 6, 1, 122, 3, 22, 72, 1, 1, 14, 46, 27, 232]
            en_out = encrypt(KEY1, 5, flag)
            if KEY2 == en_out:
                        print 'You Win'
            else:
                        print 'Try Again !'
可见,其主要加密方法为
(ord(v) + seed ^ ord(key[seed])) % 255

思路 1:
    对算法进行逆向,编写python程序解密:
    1.利用KEY1 和参数seed值5 求出GETSEED的列表
     def getseed(key, seed):
                rst = []
                itmp=1
                while itmp <= 23:
                            real1 = seed ^ ord(key[seed])
                            rst.append(real1)
                            seed = (seed + 1) % len(key)
                            itmp += 1
                return rst
    2.利用KEY2 和GETSEED列表求出原文的整型值
            def decrypt(key, seed):
                        rst = []
                        itmp = 0
                        for v in seed:
                                    if key[itmp] > seed[itmp]:
                                                real2 = key[itmp] - seed[itmp]
                                    else:
                                                real2 = key[itmp] + 255 - seed[itmp]
                                    rst.append(real2)
                                    itmp += 1           
                        return rst
    3.进行转换,输出原文 (这部分用C 写的...)
            #include<stdio.h>
            int main()
            {
                    int n[]={原文的整型值组成的数组};
                    char str1[24]="";   
                    int  i=0;   
                    for (;i<=23;i++)
                    {
                            str1[i]=(char)n[i];
                    }
                    printf("%s",str1);
            }
思路1的结果:W�˽{ƫ��φ�H���·}
只能正确解出5个位置的字符,其他的是乱码,这个情况卡了好久...还是不知道自己的想法错在了哪里,最终放弃这个思路...


思路2:爆破!!!
        1.取出关键加密函数:
        def encrypt(key, seed, v):
                    return (ord(v) + seed ^ ord(key[seed]))%255
        2.编写爆破解密函数:
        def decrypt():
                    i = 0
                    rst = []
                    while i <= 22:
                              for j in range(254):
                                        if(encrypt(KEY1, 5+i,chr(j))==KEY2[i]):
                                        rst.append(j)
                                        break
                              i += 1
                    return rst
        3.用刚才写的C码进行转换(原因:今天由于自身问题没看到到python的整型转换char类型的函数...,现在才发现这个函数是chr()...)
思路2的结果: WCTF{ILOVEPYTHONSOMUCH}

虽然爆破结果对了,但是还要请教Python的前辈们,我这个思路一错在了哪里。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值