无壳直接进入查看main函数
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 ( (unsigned int)__gmpz_cmp(v6, v7) ) puts("GG!"); else puts("TTTTTTTTTTql!"); return 0LL; }
__gmpz_init_set_str函数:其实就是 mpz_init_set_str int mpz_init_set_str (mpz_t rop, const char *str, int base) 函数,
这三个参数分别是多精度整数变量,字符串,进制。 这个函数的作用就是将 str 字符数组以 base 指定的进制解读成数值并写入 rop 所指向的内存。
然后这个__gmpz_powm(v6, v6, v5, v4)函数(//rop = base^exp取余mod v6=v6^v5 mod v4):
其实就是计算 base 的 exp 次方,并对 mod 取模,最后将结果写入 rop 中, 这个运算的过程和RSA的加密过程一样。
还有这个__gmpz_cmp函数,看这个函数名就知道这是比较函数。要的是v6==v7
有前面的_gmpz_powm可以猜到v4为n
现在手上有的是n=103461035900816914121390101299049044413950405173712170434161686539878160984549
有n可以求得p和q。
加下来就可以求出欧拉函数并且借助gmpy2库得到d
d=91646299298871237857836940212608056141193465208586711901499120163393577626813
之后对密文进行解密了,密文就是上面那串十六进制
进入96A函数分析:里面是十六进制的0-9和a-f 。那就将m转化为十六进制=73756374667b50776e5f405f68756e647265645f79656172737d
根据题目的运算写出脚本。
m = "73756374667b50776e5f405f68756e647265645f79656172737d" flag = "" i = 0 while(1): a = int(m[i],16) b = int(m[i+1],16) i = i + 2 flag = flag + chr((a<<4)+b) if(i == len(m)): break print(flag)
求出的就是flag,因为96A函数把v8转化为了v9,v9就是密文解密得到的结果两者相等的话v6即等于v7,也就会输出Tql,所以我们这里逆运算得到的v8也就应该是正确的flag