攻防世界 SignIn
工具:IDA64、Python、yafu
附件拖进IDA中,分析main函数
输入字符串放在v8中,,然后将v8和v9交给sub_96A函数处理
size_t __fastcall sub_96A(const char *a1, __int64 a2)
{
size_t result; // rax
int v3; // [rsp+18h] [rbp-18h]
int i; // [rsp+1Ch] [rbp-14h]
v3 = 0;
for ( i = 0; ; i += 2 )
{
result = strlen(a1);
if ( v3 >= result )
break;
//取高四位
*(_BYTE *)(a2 + i) = byte_202010[a1[v3] >> 4];
//取低四位
*(_BYTE *)(a2 + i + 1LL) = byte_202010[a1[v3++] & 0xF];
}
return result;
}
sub_96A函数的作用是将v8转为16进制字符串放在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);
mpz函数是c++大数计算的函数,mpz_init_set_str是将字符串转为大整数放在变量中
__gmpz_powm(v6, v6, v5, v4);
mpz_powm是计算v6的v5次方模v4
的值,结果放在v6中
可以看出,这是RSA加密,v4是n,v7是c,v6是m,v5是e
要计算d,首先要找到n的两个素因数p和q,使用素数分解工具yafu分解n
得到p和q
p = 366669102002966856876605669837014229419
q = 282164587459512124844245113950593348271
直接写解密脚本
import gmpy2
from Crypto.Util.number import *
def hex2bytes(hex_str: str) -> bytes:
return bytes.fromhex(hex_str)
n = gmpy2.mpz(103461035900816914121390101299049044413950405173712170434161686539878160984549)
p = gmpy2.mpz(366669102002966856876605669837014229419)
q = gmpy2.mpz(282164587459512124844245113950593348271)
e = 65537
d = gmpy2.invert(e,(p-1)*(q-1))
c = bytes_to_long(hex2bytes('ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35'))
m = long_to_bytes(pow(c,d,n)).decode()
print(m)
得到flag:suctf{Pwn_@_hundred_years}