reverse
密码脚本小子当太多了,脚本写不利索,打打reverse练习一下写脚本的能力
然后reverse里面流密码和块密码挺多的,借此为crypto打下基础
SSH复现
一、Let's go to learn crypto
用idapro打开文件,f5反编译得到

发现里面给了key,但目前还不知道什么加密方法
而后面又有一个base64,就是把明文用base64编码,然后比较base64编码和encflag
那encflag就需要找到Cry_Encrypt函数

打开发现了是AES加密,所以,和逆向没什么关系,直接解密就行了

随便翻一下就找到encflag了,如果翻不到,直接用search搜索也行
1 | from base64 import * |
二、babyxor
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
读取一个v4字符串,将其和Str异或,如果i是偶数,再多异或一个,然后比较byte40B040
逻辑很简单,因为异或是可逆的
Str = "'sshctf&X0R_key'"
1 | byte40B040 = 32h, 20h, 32h, 20h, 32h, 20h, 4Fh, 1, 4Dh, 27h, 12h |
直接用byte40b040异或str,就得到flag了
1 | byte = [ |
三、babycrack
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
根据代码,sub_401910应该相当于cout,然后sub_401550相当于cin,需要比较Str和byte_40F040的前37位
1 | byte_40F040 db 0C9h, 22h, 4Ah, 3Ch, 6Ch, 62h, 2 dup(0F9h), 6Fh, 0B1h |
因为1Bh=16+11=27,一共64位,所以前面的就是37位
但是我们发现前面有一个sub_401550(Str,
aSshctfkey),这说明Str是经过处理的,我们假设这个函数是Enc(x)
1 | srand(0xDEADBEEF); |
已经把种子给出来了,我们用C++生成37个种子,就能得到v3
1 | srand(0xDEADBEEF); |
然后我们把这个函数逆向就行
我们先解析一下正向,不妨记每一位为
shift = key[vi%l]
因为char就8位二进制,所以我们假设shift%8是3位,那么,左边是右移5位,只剩下3位高位跑到最后3位,前面都是0,然后右边是左移3位,会把前面三位补到最后面,所以两个或运算之后,因为前面都是0,所以或完就是本来的后五位,然后两个后3位是一样的,因为或本身是不变的,所以这个操作相当于循环右移,就是把前三位移到末尾去
如果我们要用python来逆向的话,移位的时候应该与上一个0xFF,这样就和C++效果一样了
然后
注意str的最后一位应该是125,而不是byte40f040的0
主要是利用异或的可逆性还有移位的可逆性
从第37位开始遍历,因为这个加密没有涉及第38位,所以38位就是125,
先异或回去,判断条件是否成立,如果成立就赋值,否则就不动
然后和125异或,再循环左移,这样就回复第37位了,以此类推
1 | def decrypt(data, a2): |
b@se64 wp
打开压缩包,获得一个可执行文件,用IDA pro打开

shift+F12打开函数列表,发现start函数

发现调用了140001154()函数

进而找到14000184E函数

是一个比较简单的字符串比较函数,下面那个疑似base64编码
但是解码之后好像没什么含义

发现还有一个1400016D0函数

让GPT审阅一下,其实就是base64进行了偏移的变体
他顺便把解密代码也写了...,于是拿到flag
1 | def custom_base64_decode(encoded_str): |