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
| __int64 __fastcall main(int a1, char **a2, char **a3) { char v4[16]; char v5[16]; char v6[16]; char v7[16]; char v8[112]; char v9[1000]; unsigned __int64 v10;
v10 = __readfsqword(0x28u); puts("[sign in]"); printf("[input your flag]: "); __isoc99_scanf("%99s", v8); sub_96A(v8, v9); __gmpz_init_set_str(v7, "ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35", 16LL); __gmpz_init_set_str(v6, v9, 16LL); __gmpz_init_set_str(v4, "103461035900816914121390101299049044413950405173712170434161686539878160984549", 10LL); __gmpz_init_set_str(v5, "65537", 10LL); __gmpz_powm(v6, v6, v5, v4); if ( __gmpz_cmp(v6, v7) ) puts("GG!"); else puts("TTTTTTTTTTql!"); return 0LL; }
|
这一题涉及到的知识点非常多 所以写进博客记录一下
出现了不认识的系统函数 上网查阅一下其对应的作用
1 2 3 4 5 6 7 8 9 10
| __gmpz_init_set_str 其实就是 mpz_init_set_str int mpz_init_set_str (mpz_t rop, const char *str, int base) 函数:
这三个参数分别是多精度整数变量,字符串,进制。 这个函数的作用就是将 str 字符数组以 base 指定的进制解读成数值并写入 rop 所指向的内存。 . void mpz_powm (mpz_t rop, const mpz_t base, const mpz_t exp, const mpz_t mod) 函数: 其实就是计算 base 的 exp 次方,并对 mod 取模,最后将结果写入 rop 中, 这个运算的过程和RSA的加密过程一样。 . 接下来就是__gmpz_cmp函数,看这个函数名就知道这是比较函数。 mpz_cmp(b, c); //b 大于 c,返回 1;b 等于 c,返回 0;b 小于 c,返回-1*/
|
随后跟进一下sub_96A函数 看一下他对v8这个字符串进行了什么样的处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| size_t __fastcall sub_96A(const char *a1, __int64 a2) { size_t result; int v3; int i;
v3 = 0; for ( i = 0; ; i += 2 ) { result = strlen(a1); if ( v3 >= result ) break; *(a2 + i) = word_202010[a1[v3] >> 4]; *(a2 + i + 1LL) = word_202010[a1[v3++] & 0xF]; } return result; }
|
word_202010这个数组跟进一下 查看内容
a2是v9 即一个空的数组 用来存放运算完的v8
看一下if的第一个语句 涉及到了>>右移运算符
(5条消息) 关于C/C++左移右移运算符的总结_pineapple-coder的博客-CSDN博客
这其实就是一个转16进制的算法 将这两个十六进制数分开存储
比如输入字符 ‘1’ ,它的整数是49,49除16的整数是3,余数是1,在word_202010下标中分别对应3和1,构成的31就是字符 ‘1’的ASCII的十六进制形式,只不过是分开的十六进制,3 1 共两个字节
程序主体部分到这里已经了解清楚了 接下来就是逆向RSA加密
e=65537
密文c=0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
n=103461035900816914121390101299049044413950405173712170434161686539878160984549
浅析RSA算法 - 知乎 (zhihu.com)
首先我们需要分解出两个指数p q
利用工具得到
1 2
| p=282164587459512124844245113950593348271 q=366669102002966856876605669837014229419
|
随后计算私匙
最后成功得到明文
1
| suctf{Pwn_@_hundred_years}
|