YOU NEED PYTHON writeup

    xiaoxiao2021-04-13  35

    第一次独立做出来的ctf题目,记录一下。以后也会把ctf记录和总结写出来

    题目地址:https://dn.jarvisoj.com/challengefiles/题目:you_need_python.zip.74d515955b9aa607b488a48437591a14

    下载附件解压缩后发现有两个文件 先看第一个

    import marshal, zlib, base64 exec(marshal.loads(zlib.decompress(base64.b64decode('eJxtVP9r21YQvyd/ieWm66Cd03QM1B8C3pggUuzYCSWstHSFQijyoJBhhGq9OXJl2ZFeqAMOK6Q/94f9Ofvn1s+d7Lgtk/3O997du/vc584a0eqpYP2GVfwDEeOrKCU6g2LRRyiK4oooFsVVUSqkqxTX6J1F+SfSNYrrdKPorC76luhbpOEGCZNFZw2KG3Rmk26QtuXi3xTb7ND6/aVu0g2RuvhEcZNut5lAGbTvAFbyH57TkYLKy8J6xpDvQxiiiaIlcdqJxVcHbXY6bXNlZgviPCrO0+StqfKd88gzNh/qRZyMdWHE29TZZvIkG7eZFRGGRcBmsXJaUoKCQ9fWKHwSqNeKFnsM5PnwJ7q2aKk4AFhcWtQCh+ChB5+Lu/RmyYUxmtOEYxas7i/2iuR7Ti14OEOSmU0RADd4+dQzbM1FJhukAUeQ+kZROuLyioagrau76kc1slY1NNaY/y3LAxDQBrAICJisV2hMdF2lxQcyFuMoqcX3+TCl6xotqzSpkqmxYVmjXVjAXiwBsEfBrd1VvTvLCj2EXRnhoryAKdpxcIgJcowUB68yAx/tlCAuPHqDuZo0CN3CUGHwkPhGMA7aXMfphjbmQLhLhJcHa0a+mpgB191c1U1lnHJQbgkHx+WGxeJbejnpkzSavo2jkxZ7i725npGAaTc8FXmUjbUETHUmkxXN5zqL5WiWxwE7Bc11yyYzNJpN02jerq+DzNNodfxOX8kE4FcmYKscDdYD1oPGGucXYNmgs1F+NTf3GOt3Mg7b+NTVruqoQyX1hOEUacKw+AGbP38ZOq9THRXaSbL5pXGQ8bho/Z/lrzQaHxdoCrlev+t6nZ7re57r+57rHXag93Deh37k+vuw9zorO/Qj/B50cAf2oyOsvut3D+ADWxdxfN/1Drqu39mHzvcRswv/Hvz7sHeg9w8Qzy99DzuFwxhPhs6zWTbOI3OZRiaZZcVj5wVwOklx7OwVxR47PR46r/SVM8ulBJic9zku/eqY/MqJxiDj+Gd55wS3f35pbLCzHoEwzKKpDkN5i+TR+1AYCWTo5IV0Z0P9H3phDDd6lMzPdS5bbo9eJGbTsW9nbDqLL1N9Iq+rRxDbll2x67a9Lf27hw5uK1s1rZr6DOPF+FI='))))

    不妨先运行一下 输入key和flag,暂且不知道key和flag的值是多少。

    返回到代码: exec()函数可用来执行执行储存在字符串或文件中的Python语句(应该可以是.pyo文件)。 marshal.loads()将二进制流反序列化为对象 zlib.decompress()对字符串进行解压缩 base64.b64decode()为base64解码

    分析可知,代码中marshal.loads()处理后的字符串是pyo格式的编译程序。利用uncompyle2.uncompyle()将其反编译为py文件,得到程序的源码

    import hashlib def sha1(string): return hashlib.sha1(string).hexdigest() def calc(strSHA1): r = 0 for i in strSHA1: r += int('0x%s' % i, 16) return r def encrypt(plain, key): keySHA1 = sha1(key) intSHA1 = calc(keySHA1) r = [] for i in range(len(plain)): r.append(ord(plain[i]) + int('0x%s' % keySHA1[i % 40], 16) - intSHA1) intSHA1 = calc(sha1(plain[:i + 1])[:20] + sha1(str(intSHA1))[:20]) return ''.join(map(lambda x: str(x), r)) if __name__ == '__main__': key = raw_input('[*] Please input key:') plain = raw_input('[*] Please input flag:') encryptText = encrypt(plain, key) cipherText = '-185-147-211-221-164-217-188-169-205-174-211-225-191-234-148-199-198-253-175-157-222-135-240-229-201-154-178-187-244-183-212-222-164' if encryptText == cipherText: print '[>] Congratulations! Flag is: %s' % plain exit() else: print '[!] Key or flag is wrong, try again:)' exit()

    分析代码可知,程序接受两个参数key和plain,encrypt(key,plain)的返回值与代码给出的字符串相等的话则说明找到了正确的flag。

    key参数可从题目给的第二个文件中找到。文件名为key_is_here_but_do_you_know_rfc4042,rfc4042中定义了utf-9编码。github上找到了utf-9的编解码库,通过解码,获取了文件中的内容

    a = open('C:\\Users\\lenovo\\Desktop\\txt_a', 'r') b = a.read() print utf9.utf9decode(b) 输出结果为:#输出为: _____*((__//__+___+______-____%____)**((___%(___-_))+________+(___%___+_____+_______%__+______-(______//(_____%___)))))+__*(((________/__)+___%__+_______-(________//____))**(_*(_____+_____)+_______+_________%___))+________*(((_________//__+________%__)+(_______-_))**((___+_______)+_________-(______//__)))+_______*((___+_________-(______//___-_______%__%_))**(_____+_____+_____))+__*(__+_________-(___//___-_________%_____%__))**(_________-____+_______)+(___+_______)**(________%___%__+_____+______)+(_____-__)*((____//____-_____%____%_)+_________)**(_____-(_______//_______+_________%___)+______)+(_____+(_________%_______)*__+_)**_________+_______*(((_________%_______)*__+_______-(________//________))**_______)+(________/__)*(((____-_+_______)*(______+____))**___)+___*((__+_________-_)**_____)+___*(((___+_______-______/___+__-_________%_____%__)*(___-_+________/__+_________%_____))**__)+(_//_)*(((________%___%__+_____+_____)%______)+_______-_)**___+_____*((______/(_____%___))+_______)*((_________%_______)*__+_____+_)+___//___+_________+_________/___

    看样子是一个很长的表达式,很轻松的想到“_”的个数表示数字,于是通过以下代码对其进行解析

    a = open('C:\\Users\\lenovo\\Desktop\\txt_a', 'r') b = a.read() c = utf9.utf9decode(b) num = 0 data = '' for i in c: if i == '_': num += 1 else: if num != 0: data += repr(num) num = 0 data += i data += repr(num) print eval(data) 结果为5287002131074331513

    第一次做的时候我直接把这个当作key进行暴力破解,发现得出的结果是一堆乱码。于是又返回这里,想到这个可能是一个字符串的ascii编码的10进制表示,尝试解码

    str_data = hex(d)[2:-1] key = '' for i in range(len(str_data)/2): key += chr(eval('0x'+str_data[2*i:2*i+2])) print key

    得到key为I_4m-k3y

    最后,直接利用反编译的代码,爆破出flag值

    import hashlib def sha1(string): return hashlib.sha1(string).hexdigest() def calc(strSHA1): r = 0 for i in strSHA1: r += int('0x%s' % i, 16) return r def encrypt(plain, key): keySHA1 = sha1(key) intSHA1 = calc(keySHA1) r = [] for i in range(len(plain)): r.append(ord(plain[i]) + int('0x%s' % keySHA1[i % 40], 16) - intSHA1) intSHA1 = calc(sha1(plain[:i + 1])[:20] + sha1(str(intSHA1))[:20]) return ''.join(map(lambda x: str(x), r)) string = '-185-147-211-221-164-217-188-169-205-174-211-225-191-234-148-199-198-253-175-157-222-135-240-229-201-154-178-187-244-183-212-222-164' flag = '' flag_list = [] for i in range(len(string)/4): for j in range(200): if encrypt(flag + chr(j), 'I_4m-k3y') == string[0:4*(i+1)]: flag += chr(j) flag_list.append(j) break print flag

    结果为flag{Lif3_i5_5h0r7_U_n33d_Py7h0n}

    转载请注明原文地址: https://ju.6miu.com/read-669260.html

    最新回复(0)