复现一下2020CISCN
reverse
z3
ida64打开之后,查看主函数
跟进byte_404020,以为就是前43个数据呢,后来构建z3的时候发现不对
动调了一下,发现最后对比的v47数组元素是2byte,word类型
上脚本
1 | from z3 import * |
1 | arr = [102,108,97,103,123,55,101,49,55,49,100,52,51,45,54,51,98,57,45,52,101,49,56,45,57,57,48,101,45,54,101,49,52,99,50,97,102,101,54,52,56,125] |
hyperthreading
用ida打开查看,可以可以看到最后的加密函数,
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
一共创建了三个线程,第一个线程的函数就是加密函数了,本人目前水平只能做到这样的修复了。
1 | void __userpurge __noreturn StartAddress(_BYTE *a2@<edi>, LPVOID lpThreadParameter) |
查看第二个线程中的函数
1 | DWORD __thiscall sub_401200(char *this, LPVOID lpThreadParameter) |
第三个线程中的函数
1 | void __stdcall __noreturn sub_401240(LPVOID lpThreadParameter) |
后面跟着一个函数WaitForMultipleObjects函数,中间存放的函数是一二线程:
贴上大佬的讲解
网上关于这题的wp挺少,据我统计共有两种做法。
方法一
一种是直接读汇编,或者修补程序,把加密函数逆出来。加密函数逻辑大概就是这个样子。
1 | (((((input[i]>>2)^(input[i]<<6))&0xff)^0x23)+0x23)&0xff |
最后把对比数组提取出来:
1 | import string |
不得不说,这段爆破代码实在太强了,又学到了……
方法二
读懂程序的逻辑,巧妙绕过第三个线程的isdebugged函数
用od动调,输入字符串之后,动调到WaitForMultipleObjects的时候,程序会自动卡在这个位置上,因为前面判断了程序处于调试模式,所以线程会一直占用,出不来。我们只需要手动暂停调试的程序,等待上面线程没有占用资源之后,再继续执行,之后就会绕过WaitForMultipleObjects函数了。从而到达关键判断处了
因为加密方式未知,这种做法有赌的成分……
这题是简单的异或之类的字符加密,每个字符加密结果固定,所以可以统计每个常见字符对应的加密结果,然后通过对比数组,来推断出flag.
Crypto
rsa
1 | # 小明经过研究,发现RSA加密算法可以推广,也就是它的模不仅仅是只能为两个素数的乘积,只要是2个以上不同的素数相乘都可以。 |
分解出了三个大素数??
1 | import gmpy2 |
bd (rsa-wiener-attack)
1 | from secret import flag |
这题给出的e很大,d是随机生成的,位数为200bit,且满足与phi互质的条件,我目前只能知道的条件为ed = 1 MOD phi
这题使用的方式是rsa-wiener-attack,有关连分数攻击方法
使用的脚本https://github.com/pablocelayes/rsa-wiener-attack
1 | from Crypto.Util.number import * |
这边仅限于了解rsa-wiener-attack攻击的使用