本文最后更新于 2025-01-11T09:53:01+08:00
Reverse UPX mini 既然是UPX那必须先DIE查壳 一看就不对劲,upx最多只见过3.96的,不过这里先用upx自己脱一下可以脱 直接继续查,64位无壳,进入ida 明显的base64直接,解密 秒解 BaseCTF{Hav3_@_g0od_t1m3!!!}
ez_xor 简单xor,直接看ida,查位数64位 看码了解,关键函数keystream和encrpt,输入长度为28,str、v11、v12、v13加起来正好28位,这个题目要注意的就是ida中的c是小端序的会所有的数据都会反转,而且记得使用原数据,不要用转义后的容易出错 写pythonexp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 def key_stream (key ): key_box = [] for i in range (28 ): key_box.append(key[i%3 ] ^ i) return key_boxdef decrypt (enc, key ): flag = "" key = key[::-1 ] for i in range (len (enc)): flag += chr (enc[i] ^ key[i]) return flag enc1 = bytes .fromhex("1D0B2D2625050901" )[::-1 ] enc2 = bytes .fromhex("673D491E20317A24" )[::-1 ] enc3 = bytes .fromhex("34056E2E2508504D" )[::-1 ] enc4 = b"\"@;%" enc = enc1 + enc2 + enc3 + enc4print (enc) key = (7499608 ).to_bytes(4 , 'little' ) key_box = key_stream(key)print (key_box) flag = decrypt(enc,key_box)print (flag)
BasePlus 以上来就搞个base64啊,我感觉像,但是没有确定,于是就看不懂函数里面的几个值为什么没有数了,这么奇怪,果然还是没有学过,不过这次好好分析了一番下次应该就可以瞬间秒杀了,看题 我们能了解重要函数为Encode,进入 了解了这个是base64后我们还要和源代码分析,发现存在不同 了解了这中间有个异或的操作,十分简单
1 2 3 4 5 6 do { *(_BYTE *)(a2 + v8) = v4[v8] ^ 0xE ; ++v8; }while ( v8 != v5 );
直接cyberChef换表加异或双重解密完成, 贴个无广告的cyberchef 得到flag BaseCTF{BA5e_DEcoD1N6_sEcr3t}
Ezpy 首先就是按照惯例,文件属性查询,直接die,也可以用DEID或者peexam去查。不过die很全面,但是确实很卡 看题目我们就知道是一个这是一个python题目,其实还有一个办法,pythonexe图标大多都是这个,看DIE竟然没有显示是什么软件打包的,那么我们便可以试试pyinstxtractor 这就是解包过程,和使用方法,在这个过程中pyinstxtractor会自动创建一个导出包,我们可以查看,同时我们也可以发现解包软件对python版本的需求,你有想法的可以用pyenv 去除掉这个错误,其实我感觉没什么区别,主要在于后面pyc文件中的magic number 进入解包文件夹,会发现资源文件夹和大量的动态链接库,我们只取敌将首级,直接看到一个没有后缀的题目同名软件Ezpy 这个其实是pyc也就是python的字节码。我们需要的就是这个,python大部分就是利用pyc来进行反编译,我们所知的反编译工具有pycdc (pycdc会有些麻烦,不过感觉强大些,因为是反编译难免会出现错误,而这个的错误出现会更加稀少)和uncompyle6 这个的安装非常的简单,有python就行(但是只支持3.8及一下的,作者大大不更3.9了) 好现在我们开始执行一下pycdc(记得改Ezpy后缀名,pycdc就没关系),就会发现惊喜了,失败了 这个就是我说的magicnumber的问题解决办法也非常简单,一般解包后都会自带一个struct文件。用字节查看器打开推荐010 ,不过大部分都是损坏的我在这贴一个magicnumber 。 注意大小端序,照着改就行。建议是十六个字节,留空留下栈区 然后直接反编译(也可以用网络版的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import Keyimport sysdef init_Sbox (seed ): k_b = (lambda .0 = None : [ ord (seed[i % len (seed)]) for i in .0 ])(range (256 )) s = list (range (256 )) j = 0 for i in range (256 ): j = (j + s[i] + k_b[i]) % 256 s[i] = s[j] s[j] = s[i] return sdef KeyStream (text, Sbox ): s = Sbox.copy() (i, j) = (0 , 0 ) k = [ 0 ] * len (text) for r in range (len (text)): i = (i + 1 ) % 256 j = (j + s[i]) % 256 s[i] = s[j] s[j] = s[i] t = (s[i] + s[j]) % 256 k[r] = s[t] ^ Key.keykey[r % len (Key.keykey)] return kdef Encrypt (text, seed ): Sbox = init_Sbox(seed) key = KeyStream(text, Sbox) enc = (lambda .0 = None : [ text[i] ^ key[i] for i in .0 ])(range (len (text))) return bytes (enc) enc = b'\xe6\xaeC~F\xf2\xe3\xbb\xac\x9a-\x02U\x85p\xeb\x19\xd1\xe4\xc93sG\xb0\xeb1\xb5\x05\x05\xc3\xd7\x00\x18+D\xbc\x0cO\x9em\xf1\xbd' flag = input ('Please input Your flag:' ) flag = (lambda .0 : [ ord (i) for i in .0 ])(flag) flag = Encrypt(flag, Key.key)if flag != enc: print ("It's not flag!" ) continue print ('You are right!' ) sys.exit(1 )continue
就是一个非常简单的rc4 直接给出exp