新版宝塔加密数据解密
PanelForensics已经支持,快去基佬站下载吧
最近啊,fic中出现了宝塔,结果PanelForensics居然没有梭哈,这怎么行??
于是我就一通分析,发现这个版本更新了架构,并且对密码的加解密是通过调用二进制依赖进行实现的
我这里就以mysql的密码为例,在新版本中,mysql的密码主要会出现在3个地方,涉及2个sqlite文件(另外,宝塔的主要数据存储数据库default.db
的文件路径也改到了/www/server/panel/data/db/default.db
,但其中很多部分都被摘除,另建数据库保存)
/www/server/panel/data/db/database.db
/www/server/panel/data/db/panel.db
一般用户的账号密码(database.db
)
远程数据库的账号密码(database.db
)
本地数据库root密码(panel.db
)
可以看到很明显的特征BT-0x:
,后面跟了一段密文
通过不断的跟代码,可以找到python中的解密函数
这里导入了一个模块PluginLoader
,可以找到是一个so,也就是说数据的加解密被放到了二进制程序中
可以在db_decrypt
中找到解密代码
很明显可以看到key和iv的获取方式
可以看到key就是一眼顶针,取偶数位的字符,得到key为3P+_lN3+jPW6Kgt#
iv的情况就比较复杂,需要先判断是否存在/www/server/panel/data/div.pl
文件,如果不存在,还需要从数据库中读取div再写入文件(所以div.pl
和db
目录或许是检测这个版本较好的方式)
实际上,如果没有div.pl
,还会有个默认的iv(但是前面无论如何都会保证div.pl
存在,所以这里保留的iv4HpOz4pT^4Hh-Lfl
应该永远用不上)
很明显可以看到div是加密的,仍需要解密,所以跟进_aes_decrypt_module
函数看后续操作
很明显用_get_sgin_key
函数获得了解密div所需要的key和iv
根据逻辑来看,就是把v4劈开,分成了key和iv
char *__fastcall Ploader::_get_sgin_key(Ploader *this, char *a2, char *a3)
{
char *result; // rax
int v4[35]; // [rsp+18h] [rbp-A0h]
int v5; // [rsp+A4h] [rbp-14h]
int v6; // [rsp+A8h] [rbp-10h]
int v7; // [rsp+ACh] [rbp-Ch]
int v8; // [rsp+B0h] [rbp-8h]
int i; // [rsp+B4h] [rbp-4h]
v4[0] = 90;
v4[1] = 87;
v4[2] = 50;
v4[3] = 119;
v4[4] = 66;
v4[5] = 97;
v4[6] = 56;
v4[7] = 100;
v4[8] = 55;
v4[9] = 72;
v4[10] = 78;
v4[11] = 54;
v4[12] = 69;
v4[13] = 54;
v4[14] = 65;
v4[15] = 69;
v4[16] = 83;
v4[17] = 71;
v4[18] = 50;
v4[19] = 87;
v4[20] = 66;
v4[21] = 112;
v4[22] = 107;
v4[23] = 101;
v4[24] = 120;
v4[25] = 101;
v4[26] = 84;
v4[27] = 84;
v4[28] = 114;
v4[29] = 84;
v4[30] = 104;
v4[31] = 54;
v8 = 0;
v7 = 0;
v6 = 0;
v5 = 32;
for ( i = 0; i < v5; ++i )
{
if ( v8 )
{
a3[v6] = v4[i];
v8 = 0;
++v6;
}
else
{
a2[v7] = v4[i];
v8 = 1;
++v7;
}
}
a2[16] = 0;
result = a3 + 16;
a3[16] = 0;
return result;
}
解一下
v4 = [90,87,50,119,66,97,56,100,55,72,78,54,69,54,65,69,83,71,50,87,66,112,107,101,120,101,84,84,114,84,104,54]
v8 = 0
key = [0]*16
iv = [0]*16
idx_key = 0
idx_iv = 0
for i in range(32):
if v8 == 1:
iv[idx_iv] = v4[i]
v8 = 0
idx_iv += 1
else:
key[idx_key] = v4[i]
v8 = 1
idx_key += 1
print(key)
for v in key:
print(chr(v),end='')
print()
print(iv)
for v in iv:
print(chr(v),end='')
# key:Z2B87NEAS2BkxTrh
# iv :WwadH66EGWpeeTT6
此时可以解密div
随后可以用解密后的iv去解密一开始的密文
成功解密