目录
第十九题rome
第二十题rsa
第十九题rome
解压、查壳。
无壳,用32位IDA打开,检索字符串,找到一个字符串“You are correct!”,与flag相关,对其交叉引用找到函数,查看伪代码。
int func()
{
int result; // eax
int v1[4]; // [esp+14h] [ebp-44h]
unsigned __int8 v2; // [esp+24h] [ebp-34h] BYREF
unsigned __int8 v3; // [esp+25h] [ebp-33h]
unsigned __int8 v4; // [esp+26h] [ebp-32h]
unsigned __int8 v5; // [esp+27h] [ebp-31h]
unsigned __int8 v6; // [esp+28h] [ebp-30h]
int v7; // [esp+29h] [ebp-2Fh]
int v8; // [esp+2Dh] [ebp-2Bh]
int v9; // [esp+31h] [ebp-27h]
int v10; // [esp+35h] [ebp-23h]
unsigned __int8 v11; // [esp+39h] [ebp-1Fh]
char v12[29]; // [esp+3Bh] [ebp-1Dh] BYREF
strcpy(v12, "Qsw3sj_lz4_Ujw@l");
printf("Please input:");
scanf("%s", &v2);
result = v2;
if ( v2 == 65 )
{
result = v3;
if ( v3 == 67 )
{
result = v4;
if ( v4 == 84 )
{
result = v5;
if ( v5 == 70 )
{
result = v6;
if ( v6 == 123 )
{
result = v11;
if ( v11 == 125 )
{
v1[0] = v7;
v1[1] = v8;
v1[2] = v9;
v1[3] = v10;
*(_DWORD *)&v12[17] = 0;
while ( *(int *)&v12[17] <= 15 )
{
if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 64 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 90 )
*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 51) % 26 + 65;
if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 96 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 122 )
*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 79) % 26 + 97;
++*(_DWORD *)&v12[17];
}
*(_DWORD *)&v12[17] = 0;
while ( *(int *)&v12[17] <= 15 )
{
result = (unsigned __int8)v12[*(_DWORD *)&v12[17]];
if ( *((_BYTE *)v1 + *(_DWORD *)&v12[17]) != (_BYTE)result )
return result;
++*(_DWORD *)&v12[17];
}
return printf("You are correct!");
}
}
}
}
}
}
return result;
}
分析代码:将字符串“Qsw3sj_lz4_Ujw@l”赋值给v12,用v2接收输入,进行判断(这里把ascll码转换成字符串可以看出整个if嵌套语句的条件能拼出ACTF{},与flag没有关系)。接着对v1的四位分别赋值,但是不难发现v7到v10都是查不到值的,大概能确定v1就是flag。
最后是while循环15次,遍历v12,根据v12中字符的大小写分别运算得到flag,可以写脚本求解。
import base64
v12 = [81, 115, 119, 51, 115, 106, 95, 108, 122, 52, 95, 85, 106, 119, 64, 108]
flag = ''
for i in range(0, 16):
for k in range(0, 127):
z = k
if 64 < k <= 90:
k = (k - 51) % 26 + 65
if k <= 96 or k > 122:
pass
else:
k = (k - 79) % 26 + 97
if k == v12[i]:
flag += chr(z)
print(flag)
得到flag为Cae3ar_th4_Gre@t
第二十题rsa
首先需要了解rsa加密:rsa加密是对明文的E次方后除以N后求余数的过程,N = p * q,其中p和q是两个大素数,而公钥是E和N的组合。
rsa解密则是密文进行D次方后除以N的余数,私钥是D和N的组合,知道私钥就可以解密了
这道题有两个文件,flag.enc和pub.key。可以根据后缀和文件名判断出前者为密文,而后者为公钥
可以用Typora打开key文件,发现公钥N为“MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMAzLFxkrkcYL2wch21CM2kQVFpY9+7+ /AvKr1rzQczdAgMBAAE= ”
可以用工具网站(http://tool.chacuo.net/)解出E和N。
E=65537 (0x10001)
N=0xC0332C5C64AE47182F6C1C876D42336910545A58F7EEFEFC0BCAAF5AF341CCDD
先将N转化为10进制,再使用工具网站(factordb.com)解出p和q。
p为285960468890451637935629440372639283459
q为304008741604601924494328155975272418463
根据L=lcm(p-1,q-1),算出L,再根据1 < D < L,E*D mod L = 1算出D,有了D和N,就可以对密文进行解密了。
写一个脚本(需要安装rsa)
import rsa
e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
d = 81176168860169991027846870170527607562179635470395365333547868786951080991441
key = rsa.PrivateKey(n, e, d, q, p)
with open(r'C:\\Users\\40271\\Downloads\\41c4e672-98c5-43e5-adf4-49d75db307e4\\output\\flag.enc', 'rb') as flag:
flag = flag.read()
print(rsa.decrypt(flag, key))
解得flag为flag{decrypt_256}