难度系数:3.0
题目来源: NJUPT CTF 2017
题目描述:菜鸡和菜猫进行了一场Py交易
考察内容:写解密脚本
附件是.pyc格式,py和pyc文件的差别 :pyc是py编译后生成的文件,pyc运行的速度有所提高,并且pyc可以防止源码泄露
所以第一步是反编码,把pyc文件变成py文件
用的是软件:Easy Python Decompiler
下载链接:https://pan.baidu.com/s/1WQ52TfZfDycHnNGzCYTZOg 提取码:hzt6
但是看到有在线转换的:https://tool.lu/pyc/
把文件拖到该软件后,会在源目录下生成一个pyc_dis文件,打开这个文件可以看到:
# Embedded file name: 1.py import base64 def encode(message): s = '' for i in message: x = ord(i) ^ 32 x = x + 16 s += chr(x) return base64.b64encode(s) correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt' flag = '' print 'Input flag:' flag = raw_input() if encode(flag) == correct: print 'correct' else: print 'wrong'
这是一个Python2.x的文件,与Python3.x有几个不同的点:
- print 在Python2.x中可以不加括号 print 'Input flag:' ,在Python3.x中需要加括号 print ('Input flag:')
- Python2.x中 raw_input 将所有输入作为字符串看待,返回字符串类型 ,input( ) 只能接收“数字”的输入,在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型( int, float )
在Python3.x中raw_input( )和input( )进行了整合,去除了raw_input( ),仅保留了input( )函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型
看文件内容:
主要是定义了一个函数,flag是传入的参数,经过函数中的一系列加密后 flag变成了 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
那么我们要做的就是把flag解密出来 ,要解密就要“反其道而行之” ,先来研究一下这个函数加密的步骤
import base64 def encode(message): s = '' #定义s为字符串变量 for i in message: #循环,其中i是字符串中的每一个字符 x = ord(i) ^ 32 #ord函数是将字符转为数字,是chr函数的配对函数 ^是异或 x = x + 16 s += chr(x) return base64.b64encode(s) #base64加密,需要引入base64模块
然后开始编写我们的解密脚本:
import base64 a = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt' str=base64.b64decode(a) #加密时在最后加密成base64了,所以这里我们一开始就base64解密 s = '' #加密时后+16就先-16,一个数异或两次得到的是他本身 #这里不能用ord,因为返回的数值会超出定义范围 for i in str: i = i-16 i = i ^ 32 s += chr(i) print(s)
得到的结果为:
nctf{d3c0mpil1n9_PyC}