-
-
[原创]BS272.exe
-
发表于: 2020-3-15 17:46 3472
-
打开之后先运行,输入code以为是简单的F(A) = F(B) 模式的CreakMe,结果想简单了:
程序没有其他的保护方式,查看关键字符串:
一开始啥头绪没有,但是看到一个大数,同时程序运行起来的提示,原来考核RSA算法。
6D6F632E6D736131352E777777 A324F100182D501F6F6F78F397A3AA59641023D6A3DED8A4BF344F1E0FC71C188F4D
RSA的原理借鉴其他人的流程
https://www.cnblogs.com/stwzhong/p/3402735.html
下面看主程序:
int wmain() { unsigned __int8 v0; // al const char *N; // edi unsigned int v2; // ebx void (*v3)(const char *, ...); // esi int v4; // edx unsigned int v5; // edi char v6; // cl unsigned __int8 v7; // al char *v8; // ebx unsigned int v9; // edi int result; // eax dword_448680 = 0; v0 = 65; N = "A324F100182D501F6F6F78F397A3AA59641023D6A3DED8A4BF344F1E0FC71C188F4D";// 乘积N do { // 循环读入大数 v2 = byte_4281B0[v0]; sub_4019F0(&dword_448680, &dword_448680); sub_401940(&dword_448680, v2); v0 = (N++)[1]; } while ( v0 ); v3 = printf; printf("Please input username:"); memset(byte_448EA0, 0, 10240u); sscanf("www.51asm.com", "%s", byte_448EA0); printf("%s\n", "www.51asm.com"); sub_406230(byte_448EA0, strlen(byte_448EA0)); // 没有卵用 printf("Please input vericode:"); memset(byte_448EA0, 0, 0x2800u); scanf("%s", byte_448EA0); v4 = 0; v5 = strlen(byte_448EA0); if ( v5 ) // 控制输入字符 { while ( 1 ) { v6 = byte_448EA0[v4]; if ( (v6 - '0') > 9u && (v6 - 'a') > 0x19u && (v6 - 'A') > 0x19u ) break; if ( ++v4 >= v5 ) goto LABEL_8; } printf("Invalid char found in input string"); getch(); result = 0; } else { LABEL_8: v7 = byte_448EA0[0]; // 此时是用户输入 dword_448A90 = 0; if ( byte_448EA0[0] ) // 循环读入数据 { v8 = byte_448EA0; do { v9 = byte_4281B0[v7]; sub_4019F0(&dword_448A90, &dword_448A90); sub_401940(&dword_448A90, v9); v7 = (v8++)[1]; } while ( v7 ); v3 = printf; } v3("\ninput accepted as:\n"); Size = 10240; sub_406330(&dword_448C98, byte_448EA0); // 字符串转ascii 6D6F632E6D736131352E777777 v3("Username : %s\n", byte_448EA0); Size = 10240; sub_406330(&dword_448A90, byte_448EA0); v3("Vericode : %s\n", byte_448EA0); v3("\nverifying...\n"); sub_403E30(&dword_448C98); // 求 mod 先传入 username N sub_403E30(&dword_448A90); // 输入的code mod N if ( sub_401510() ) v3("%s\n", &unk_448EB5); else v3("failed\n"); getch(); result = 0; } return result; }
程序自定义了一个大数 N,然后sub_406330是ascii转int函数,动态调试就可以出结果,sub_403E30 传入转换之后的username 对其 MOD N操作,结果不变。
这块看直接看伪代码看不出来,用od动态调试就能看到传入的参数和后面的操作:
关键判断函数是sub_401510
signed int sub_401510() { signed int v0; // eax int v1; // esi int v2; // eax char v4_N; // [esp+10h] [ebp-830h] int v5_p; // [esp+428h] [ebp-418h] char v6; // [esp+42Ch] [ebp-414h] int v7; // [esp+630h] [ebp-210h] int v8; // [esp+634h] [ebp-20Ch] int v9; // [esp+638h] [ebp-208h] v0 = 1; v9 = 0; v8 = 17; v7 = 1; do { if ( *(&v8 + v0) ) break; v7 = --v0; } while ( v0 >= 0 ); v7 = v0 + 1; sub_4064D0(&v5_p, &v7); // username ^ 17 p v1 = 0; while ( 1 ) { v2 = 0; dword_44888C[0] = 1; dword_448888[0] = 0; do { if ( dword_44888C[v2] ) break; dword_448888[0] = --v2; } while ( v2 >= 0 ); dword_448888[0] = v2 + 1; if ( !sub_405310(&dword_448680, &v4_N, 0) ) // 对输入用户名 初始化 sub_401000(&v6, &dword_448A90, dword_448888, v5_p, &v4_N);// RSA解码 Size = 10240; if ( dword_448888[0] ) { sub_4062A0(dword_448888[0]); } else { memset(byte_448EA0, 0, 0x2800u); Size = 0; } if ( !strcmp("Happy Birthday Buddy", byte_448EA0) )// 解码之后和关键字符串比较 break; sub_401940(&v5_p, 1u); if ( ++v1 >= 100 ) return 0; } return 1; }
硬着头皮大概可以理清楚,用户输入的code mod 17 作为RSA里面的 e 参与后面的解码 d 使用,e被保存在一个数组里面,动调可以看到:
解码到和字符串Happy Birthday Buddy 相等,就返回正确(卵提示信息都没有)。
所以整个流程应该是这样:
已知大数 N = A324F100182D501F6F6F78F397A3AA59641023D6A3DED8A4BF344F1E0FC71C188F4D 已知用户名 "www.51asm.com" 用户名 转成整数 U = 6D6F632E6D736131352E777777 U ^ 7 mod N 作为后续解码的 e=9CA87DE3775787F7695F3F316E503600348AB6F58BEF375D0ED8F8BE84425FA7A6C3 目标解码数据 Happy Birthday Buddy\x0ok 明名为 DE = 6B6F007964647542207961646874726942207970706148 e一直到e+ 99之间, 一定存在一对 e, d 使得 code = DE ^ d MOD N (code是用户输入的)
p 和 q 可以用因式分解工具得到:
p= B89EB7E0C9A568202F38B169D9D7E27B93
q =E2389B3C140BE6423EE5EB9DB5DAC2559F
但是这个 e 是动的 ,一个个试, e +2 就能得到正确结果:
e = 9CA87DE3775787F7695F3F316E503600348AB6F58BEF375D0ED8F8BE84425FA7A6C5 d = 3AD75813052BC545DAC589519734FF0972200E8E31DFA08DE50D15CFA2667132E4E1
这里附上RSATool使用方法:
https://www.40huo.cn/blog/rsa-tools.html
然后计算code =
274964845CCC8AAA8A0CD62B0971A23954F741240EEDD43A02F79DA2B7372D68C80C
注意:这里有个雷,就是比较字符串的地方有换行符\0, 然后设置成功提示符是ok(之前的wp有用),所以是多解,但是如果是其他的提示,可能匹配d有难度。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
谁下载
看原图
赞赏
雪币:
留言: