https://buuoj.cn/challenges#[SUCTF2019]SignIn
exeinfo: NOT Win EXE - .o - ELF [ 64bit obj. Shared obj file - CPU : AMD x86-64 - OS/ABI: unspecified ]
定位到 main 函数
__int64 __fastcall main ( int a1 , char ** a2 , char ** a3 )
{
char v4 [ 16 ]; // [rsp+0h] [rbp-4A0h] BYREF
char v5 [ 16 ]; // [rsp+10h] [rbp-490h] BYREF
char v6 [ 16 ]; // [rsp+20h] [rbp-480h] BYREF
char v7 [ 16 ]; // [rsp+30h] [rbp-470h] BYREF
char v8 [ 112 ]; // [rsp+40h] [rbp-460h] BYREF
char v9 [ 1000 ]; // [rsp+B0h] [rbp-3F0h] BYREF
unsigned __int64 v10; // [rsp+498h] [rbp-8h]
v10 = __readfsqword ( 0x 28 u );
puts ( "[sign in]" );
printf ( "[input your flag]: " );
__isoc99_scanf ( " %99s " , v8);
sub_96A (v8, v9);
__gmpz_init_set_str (v7, "ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35" , 16 LL );
__gmpz_init_set_str (v6, v9, 16 LL );
__gmpz_init_set_str (v4, "103461035900816914121390101299049044413950405173712170434161686539878160984549" , 10 LL );
__gmpz_init_set_str (v5, "65537" , 10 LL );
__gmpz_powm (v6, v6, v5, v4);
if ( ( unsigned int ) __gmpz_cmp (v6, v7) )
puts ( "GG!" );
else
puts ( "TTTTTTTTTTql!" );
return 0 LL ;
}
__gmpz_init_set_str
函数非常奇怪,网上一查知道这是一个字符串进制数转成数字的函数
官方文档: https://gmplib.org/ → https://gmplib.org/manual/Assigning-Integers#index-mpz_005fset_005fstr
Function: int
mpz_set_str (mpz_t rop, const char *str, int base)
Set the value of rop from str, a null-terminated C string in base base. White space is allowed in the string, and is simply ignored.
The base may vary from 2 to 62, or if base is 0, then the leading characters are used: 0x
and 0X
for hexadecimal, 0b
and 0B
for binary, 0
for octal, or decimal otherwise.
For bases up to 36, case is ignored; upper-case and lower-case letters have the same value. For bases 37 to 62, upper-case letters represent the usual 10.. 35 while lower-case letters represent 36.. 61.
This function returns 0 if the entire string is a valid number in base base. Otherwise it returns −1.
https://gmplib.org/manual/Integer-Exponentiation#index-mpz_005fpowm_005fui
Function: void
mpz_powm (mpz_t rop, const mpz_t base, const mpz_t exp, const mpz_t mod)
Set rop to (base raised to exp) modulo mod .
Negative exp is supported if the inverse base-1 mod mod exists (see mpz_invert
in Number Theoretic Functions ). If an inverse doesn’t exist then a divide by zero is raised.
ro p = ba s e e x p % m o d
其实就是 公钥密码学算法类型综述 里面的 rsa 加密
下载yafu 运行
factor(10346103590081691412139010129904904441395040517371217043416168653)
或者在线分解:
http://www.factordb.com/index.php?query=103461035900816914121390101299049044413950405173712170434161686539878160984549
得到
> . \y afu-x64.exe "factor(103461035900816914121390101299049044413950405173712170434161686539878160984549)"
fac: factoring 103461035900816914121390101299049044413950405173712170434161686539878160984549
fac: using pretesting plan: normal
fac: no tune info: using qs/gnfs crossover of 95 digits
div: primes less than 10000
fmt: 1000000 iterations
rho: x^2 + 3, starting 1000 iterations on C78
rho: x^2 + 2, starting 1000 iterations on C78
rho: x^2 + 1, starting 1000 iterations on C78
pm1: starting B1 = 150K, B2 = gmp-ecm default on C78
ecm: 30/30 curves on C78, B1=2K, B2=gmp-ecm default
ecm: 74/74 curves on C78, B1=11K, B2=gmp-ecm default
ecm: 161/161 curves on C78, B1=50K, B2=gmp-ecm default, ETA: 0 sec
starting SIQS on c78: 103461035900816914121390101299049044413950405173712170434161686539878160984549
==== sieving in progress (1 thread ): 36224 relations needed ====
==== Press ctrl-c to abort and save state ====
32701 rels found: 17655 full + 15046 from 172381 partial, (3391.97 rels/sec )
SIQS elapsed time = 61.3158 seconds.
Total factoring time = 71.3922 seconds
*** factors found ***
P39 = 282164587459512124844245113950593348271
P39 = 366669102002966856876605669837014229419
ans = 1
按照 rsa 加密方法走一遍计算私钥就可以了
RSA加密
脚本
import gmpy2
import binascii
E = 65537
N = 103461035900816914121390101299049044413950405173712170434161686539878160984549
C = 0x ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
p = 282164587459512124844245113950593348271
q = 366669102002966856876605669837014229419
phi = (p - 1 ) * (q - 1 )
D = gmpy2.invert(E, phi)
M = pow (C, D, N)
print (binascii.unhexlify( hex (M)[ 2 :]).decode())
这行代码是在做什么的呢?它首先将整数 M 转换为十六进制字符串,然后去掉前两个字符(这两个字符是 ‘0x’,表示这是一个十六进制数)。然后,它使用 binascii.unhexlify 函数将这个十六进制字符串转换为二进制数据。最后,它使用 decode 方法将这个二进制数据解码为一个字符串。
suctf{Pwn_@_hundred_years}