攻防世界逆向高手题之SignIn

99 篇文章 33 订阅

攻防世界逆向高手题之SignIn

继续开启全栈梦想之逆向之旅~
这题是攻防世界逆向高手题的SignIn
在这里插入图片描述

下载附件,照例扔入exeinfope中查看信息:
在这里插入图片描述
64位ELF文件无壳,照例扔入IDA64中查看伪代码信息,有Main函数看main函数:
在这里插入图片描述

代码一目了然,就是中间这几个系统函数有点意思,以前说系统函数通常不是考点,但这么多系统函数就有点问题了。上网查一下这些系统函数用法:

__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*/
.
重述一下就是:
mpz_powm(op1,op2,op3,op4); //求幂模函数 即 op1=op2^op3 mod op4;
mpz_init_set_str(b, “200000”, 10); //即 b=200000,十进制
mpz_cmp(b, c); //b 大于 c,返回 1;b 等于 c,返回 0;b 小于 c,返回-1*/

真的,整个运算过程和RSA计算一样,但是在此之前先看一下最前面的sub_96A(v8, v9)函数的内容:
在这里插入图片描述
双击跟踪看一下:
在这里插入图片描述
这里积累第一个经验:
这里发现取两个数组的下标,第一个a1+i 取的是以输入字符除以16后的整数部分为byte_202010下标。
第二个a1+i+1 取的是以输入字符除以16后的余数部分为byte_202010下标。

不明白的可以看一下我以前的博客https://blog.csdn.net/xiao__1bai/article/details/119986918

再看一下byte_202010数组内容,是0到f的字符,这是十六进制的基数:(一开始我并没有看出是十六进制的基数~哭)
在这里插入图片描述

一个整数一个余数你会发现这是把输入字符变成两个分开的十六进制存储起来,比如输入字符 ‘1’ ,它的整数是49,49除16的整数是3,余数是1,在byte_202010下标中分别对应3和1,构成的31就是字符 '1’的ASCII的十六进制形式,只不过是分开的十六进制,3 1 共两个字节。
.
.
然后后面又回顾了RSA的算法,这次分析细致一点,积累起来日后用。
以前的积累:
在这里插入图片描述

再看我们的原伪代码,有哪些信息:
在这里插入图片描述

由 __gmpz_powm(v6, v6, v5, v4)函数可以看出v6是密文,也是我们用于加密的明文,而且这个明文是我们输入flag取前面说的分开的十六进制后的数。
v5是指数=65537
v4是模N=103461035900816914121390101299049044413950405173712170434161686539878160984549

C可以由判断语句 if ( (unsigned int)__gmpz_cmp(v6, v7) )得来,密文C就是v7=0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35(后面取十六进制)

这里这里考的是我们输入明文后加密出来的密文与v7一样,是常规的RSA解密:
第一种方法,跑以前积累的RSA脚本:
在这里插入图片描述

在这里插入图片描述

第二种方法,自己写RSA解密脚本:(用我之前注释的脚本算了,因为有一些密码学的库不了解)

这里积累第二个经验:
首先根据解密算法我们现在手上有C密文和N模数,但是没有D。而D的算法是e*d=1modψ(n)的逆运算,e我们有,ψ(n)=(p-1)(q-1)也可以通过大数分解由N分出p、q。最后逆运算函数就是libnum.invmod(e, (p - 1) * (q - 1))即可算出D。
D算出来后明文M就可以算出来了,用函数m = pow(c, d, n) 算出M,但是我们的M是前面经过转换拆分的两个单字符十六进制数,所以最后还要十六进制转字符才行。
.
.

大数分解网址:

http://www.factordb.com/index.php

在这里插入图片描述
最终脚本:(这里积累第四个经验)

import libnum
from Crypto.Util.number import long_to_bytes

q = 282164587459512124844245113950593348271
p = 366669102002966856876605669837014229419
e = 65537
c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
n = 103461035900816914121390101299049044413950405173712170434161686539878160984549
 
d = libnum.invmod(e, (p - 1) * (q - 1))		#invmod(a, n) - 求a对于n的模逆,这里逆向加密过程中计算ψ(n)=(p-1)(q-1),对ψ(n)保密,也就是对应根据e*d=1modψ(n),求出d
m = pow(c, d, n)   # 这里的m是十进制形式,pow(x, y[, z])--函数是计算 x 的 y 次方,如果 z 在存在,则再对结果进行取模,其结果等效于 pow(x,y) %z,对应前面解密算法中M=D(C)=(C^d)mod n
string = long_to_bytes(m)  # 获取m明文
print(string)

结果:
在这里插入图片描述

总结:

0积累函数:
__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*/
.
重述一下就是:
mpz_powm(op1,op2,op3,op4); //求幂模函数 即 op1=op2^op3 mod op4;
mpz_init_set_str(b, “200000”, 10); //即 b=200000,十进制
mpz_cmp(b, c); //b 大于 c,返回 1;b 等于 c,返回 0;b 小于 c,返回-1*/

1:
这里积累第一个经验:
这里发现取两个数组的下标,第一个a1+i 取的是以输入字符除以16后的整数部分为byte_202010下标。
第二个a1+i+1 取的是以输入字符除以16后的余数部分为byte_202010下标。

2:
这里积累第二个经验:
首先根据解密算法我们现在手上有C密文和N模数,但是没有D。而D的算法是e*d=1modψ(n)的逆运算,e我们有,ψ(n)=(p-1)(q-1)也可以通过大数分解由N分出p、q。最后逆运算函数就是libnum.invmod(e,
(p - 1) * (q - 1))即可算出D。 D算出来后明文M就可以算出来了,用函数m = pow(c, d, n)
算出M,但是我们的M是前面经过转换拆分的两个单字符十六进制数,所以最后还要十六进制转字符才行。

3:回顾一下以前积累的RSA:
在这里插入图片描述

4:
d = libnum.invmod(e, (p - 1) * (q - 1))
#invmod(a, n) - 求a对于n的模逆,这里逆向加密过程中计算ψ(n)=(p-1)(q-1),对ψ(n)保密,也就是对应根据e*d=1modψ(n),求出d
.
m = pow(c, d, n)
#这里的m是十进制形式,pow(x, y[, z])–函数是计算 x 的 y 次方,如果 z 在存在,则再对结果进行取模,其结果等效于 pow(x,y) %z,对应前面解密算法中M=D©=(C^d)mod n
.
string = long_to_bytes(m) # 获取m明文

解毕!敬礼!

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐一 · 林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值