2.15----pyinstaller打包----RC4加密

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一. pyinstaller 打包

  • 打开控制台,Pyinstaller -F -w 猜数游戏.py(该命令会去除控制台,运行即运行仅程序窗口)按下回车

  • 打包成功后控制台显示successful

  • 随后py文件夹下会生成一个dist的文件

  • 双击打开dist文件,有一个exe的程序,这个就是py打包成的,双击打开文件即可。

  • 常用参数 含义

  -i 或 -icon 生成icon 			-F 创建一个绑定的可执行文件
  -w 使用窗口,无控制台 			-C 使用控制台,无窗口
  -D 创建一个包含可执行文件的单文件夹包(默认情况下)
  -n 文件名

二. 反编译由pyinstaller打包的exe文件

  • 首先看程序图标,就知道是不是由pyinstaller编译的
    在这里插入图片描述

  • 之后再命令行中输入此命令,即会出现一个文件夹

在这里插入图片描述

  • 这时,我们打开PYZ-00.pyz_extracted 文件夹,发现里面全是.pyc文件,且没有加密,就可以进行下一步了
  • 或者我们可以找到主程序的文件,修改后缀名为.pyc即可
  • 下面我们需要将.pyc放入16进制编辑器中,将正常的 pyc 文件中的 magic 和 时间戳 复制过来,因为第一行缺少magic与时间
  • 接着就可以将他反编译成.py文件
  • 看看代码

三. RC4加密

3.1RC4算法原理

  • RC4生成一种称为密钥流的伪随机流,与明文异或结合,从而加密,解密时与密文进行异或操作,那么,他就是一种对称加密算法
  • 密钥流由KSA与PRGA组成
  • 实现方法:根据秘钥生成S盒,利用PRGA生成秘钥流,秘钥与明文异或产生密文

3.1.1 KSA(密钥调度算法)及根据秘钥生成S表

  • RC4首先用KSA完成对大小为256字节的数组S的初始化(按照升序,给每个字节赋值0,1,2,3,4,5,6…,254,255)及替换,替换时使用密钥
  • 直接构造一个S[256],遍历0-255,然后创建临时K[256],用于存储种子秘钥,长度不够循环填充直到K被填满,根据T[i]将S[i]与S中的另外一个字节对换,对S的操作仅仅是交换,唯一改变的是位置,但里面的元素是没变的还是0-255
    s_box = list(range(256)) #这里没管秘钥小于256的情况,小于256不断重复填充即可
    j = 0
    for i in range(256):
        j = (j + s_box[i] + ord(key[i % len(key)])) % 256
        s_box[i], s_box[j] = s_box[j], s_box[i]
    #print(type(s_box)) #for_test
    return s_box

3.1.2 PRGA生成密钥流

    res = []
    i = j =0
    for s in plain:
        i = (i + 1) %256
        j = (j + box[i]) %256
        box[i], box[j] = box[j], box[i]
        t = (box[i] + box[j])% 256
        k = box[t]
        res.append(chr(ord(s)^k))  #直接与每一个字节明文相异或

3.2 脚本实现

import codecs

MOD = 256
def KSA(key):
    key_length = len(key)
    # create the array "S"
    S = list(range(MOD))  # [0,1,2, ... , 255]
    j = 0
    for i in range(MOD):
        j = (j + S[i] + key[i % key_length]) % MOD
        S[i], S[j] = S[j], S[i]  # swap values

    return S


def PRGA(S):
    i = 0
    j = 0
    while True:
        i = (i + 1) % MOD
        j = (j + S[i]) % MOD

        S[i], S[j] = S[j], S[i]  # swap values
        K = S[(S[i] + S[j]) % MOD]
        yield K


def get_keystream(key):
    S = KSA(key)
    return PRGA(S)


def encrypt_logic(key, text):
    # For plaintext key, use this
    key = [ord(c) for c in key]
    keystream = get_keystream(key)

    res = []
    for c in text:
        val = ("%02X" % (c ^ next(keystream)))  # XOR and taking hex
        res.append(val)
    return ''.join(res)


def encrypt(key, plaintext):
    plaintext = [ord(c) for c in plaintext]
    return encrypt_logic(key, plaintext)


def decrypt(key, ciphertext):
    ciphertext = codecs.decode(ciphertext, 'hex_codec')
    res = encrypt_logic(key, ciphertext)
    return codecs.decode(res, 'hex_codec').decode('utf-8')


if __name__ == '__main__':
    print(decrypt("1592539037299", "08985BCFBF8C87583190"))  # 解密
    print(encrypt("1592539037299", "test123NEW"))  # 加密



四. stream.exe

  • 结合上文学习,进行解包与一次反编译,得代码
  • 发现是RC4加密
import base64

def gen(key):
    s = list(range(256))
    j = 0
    for i in range(256):
        j = (j + s[i] + ord(key[i % len(key)])) % 256
        tmp = s[i]
        s[i] = s[j]
        s[j] = tmp
    i = j = 0
    data = []
    for _ in range(50):
        i = (i + 1) % 256
        j = (j + s[i]) % 256
        tmp = s[i]
        s[i] = s[j]
        s[j] = tmp
        data.append(s[(s[i] + s[j]) % 256])
    return data


def encrypt(text, key):
    result = ''
    for c, k in zip(text, gen(key)):
        result += chr(ord(c) ^ k)
    result = base64.b64encode(result.encode()).decode()
    return result

text = input('Flag: ')
key = 'As_we_do_as_you_know'
enc = encrypt(text, key)
if enc == 'wr3ClVcSw7nCmMOcHcKgacOtMkvDjxZ6asKWw4nChMK8IsK7KMOOasOrdgbDlx3DqcKqwr0hw701Ly57w63CtcOl':
    print('yes!')
    return None
None('try again...')


  • 题目函数设置的很友好,就是原封不动的RC4加密
  • 对称加密法,则解密时gen函数不用变
  • 密钥同样不变
  • 编程如下:
import base64

def gen(key):
    s = list(range(256))
    j = 0
    for i in range(256):
        j = (j + s[i] + ord(key[i % len(key)])) % 256
        tmp = s[i]
        s[i] = s[j]
        s[j] = tmp
    i = j = 0
    data = []
    for _ in range(50):
        i = (i + 1) % 256
        j = (j + s[i]) % 256
        tmp = s[i]
        s[i] = s[j]
        s[j] = tmp
        data.append(s[(s[i] + s[j]) % 256])
    return data
def decrypt(text, key):
    result = ''
    text = base64.b64decode(text).decode()
    for c, k in zip(text, gen(key)):
        result += chr(ord(c) ^ k)
    return result

text='wr3ClVcSw7nCmMOcHcKgacOtMkvDjxZ6asKWw4nChMK8IsK7KMOOasOrdgbDlx3DqcKqwr0hw701Ly57w63CtcOl'
key = 'As_we_do_as_you_know'
print(decrypt(text, key))

  • flag{python_reverse_is_easy_with_internet}
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值