Wiz分析
数据库分析
wizksent.wiz_document 所有文章数据存储
wizksent.wiz_deleted 所有删除的文章、附件,文章即便从回收站删除了还是会显示在这个库中,附件尚不清楚
wizksent.wiz_attachment 上传的所有附件,以及手机端录音文件
wizksent.wiz_comment 所有评论

wizasent.wiz_user 当前所有用户
wizasent.wiz_template 当前模板记录
wizasent.wiz_log_user 用户登录数据(平台,IP,账号)
源码配置文件分析
mysql root密码获取
# 修改mysql数据库密码,只需要执行一次
if [ ! -f "$runOnceFile" ]; then
echo "----------change mysql password-------------"
mysql -uroot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'aI9DCyNpEKWe9pn5';flush privileges"
fi
mysql -uroot -paI9DCyNpEKWe9pn5 -e "show databases;"
mysqlSock=$?通过对docker文件系统的导出,查看到/wiz/app/ 下有一个entrypoint.sh文件,这里面找到了设置的mysql root用户密码--paI9DCyNpEKWe9pn5
加密过后确实符合数据库中的密码记录

新建数据库用户思路
docker exec -it --user root wiz1 /bin/bash #进入容器
pkill mysqld #关闭mysql服务
mysqld_safe --skip-grant-tables & #安全模式进入,无视root密码
mysql #进入mysql
FLUSH PRIVILEGES; #刷新权限
CREATE USER 'yin'@'%' IDENTIFIED BY '123456'; #创建用户
GRANT ALL PRIVILEGES ON *.* TO 'yin'@'%' WITH GRANT OPTION; #授予所有权限
FLUSH PRIVILEGES;
SELECT user,host FROM mysql.user;
EXIT
pkill mysqld
sed -i 's/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf
service mysql start
代码不能一次执行,需要确保上一个命令运行成功后在执行
新建数据库SQL语句分析
INSERT INTO `wiz_server` (`SERVER_GUID`, `SERVER_NAME`, `INTERNAL_SERVER_URL`, `SERVER_TYPE`, `SERVER_NOTE`, `SERVER_IP`, `SERVER_STATE`, `SERVER_GROUP`, `SERVER_URL`, `ACCESS_ID`, `ACCESS_KEY`)
VALUES
('00000000-0000-0000-0000-000000000000', 'wiz', 'http://web/wizks', 1, 'wiz', 'http://web/wizks', 1, 'ztj', 'http://web/wizks', 'ks01', '12345678');在日志文件中,发现了这样一条sql语句,目前还不知道这里面的账号密码是拿来干什么的?
拓展分析
通过对运行文件的分析,发现其实还可以手动配置云端数据库,经过实践,这个数据库版本只能是mysql5.7
#!/bin/bash
# 如果不存在 /wiz/index/.runonce
runOnceFile=/wiz/storage/index/.runonce
mysqlUpgradeFile=/wiz/storage/index/.mysqlUpgrade
architecture=$(uname -m)
echo architecture = $architecture
isUbuntu=false
if [ "$architecture" = "armv7l" ]; then
isUbuntu=true
echo "current is arm, in ubuntu"
elif [ "$architecture" = "aarch64" ]; then
isUbuntu=true
echo "current is arm64, in ubuntu"
fi
mkdir -p /wiz/storage/logs/nginx
mkdir -p /wiz/storage/index
mkdir -p /wiz/storage/db
# mysql
echo "-----------------copy mysql config-----------------"
if [ "$isUbuntu" = true ]; then
cp -fr /wiz/config/mysqld.cnf /etc/mysql/mysql.conf.d/mysqld.cnf
cp /wiz/app/wizserver/libwizsqlcjk.so /usr/lib/mysql/plugin/
else
cp -fr /wiz/config/my.cnf /etc
cp /wiz/app/wizserver/libwizsqlcjk.so /usr/lib64/mysql/plugin/
fi
# nginx
echo "-----------------copy nginx config-----------------"
cp -fr /wiz/config/nginx.conf /etc/nginx
cp -fr /wiz/config/mime.types /etc/nginx
echo "-----------------copy crontab config-----------------"
cp -fr /wiz/config/crond /etc/pam.d
if [ "$isUbuntu" = true ]; then
cp -fr /wiz/config/root /var/spool/cron/crontabs
else
cp -fr /wiz/config/root /var/spool/cron
fi
# executable
chmod u+x /wiz/app/clear_tmp.sh
chmod u+x /wiz/app/wait-for-it.sh
chmod u+x /wiz/app/template_upload.sh
chmod u+x /wiz/app/entrypoint.sh
if [ "$isUbuntu" = true ]; then
echo "do nothing"
else
chmod 644 /etc/my.cnf
fi
# 创建数据存储目录,这个在宿主机,只需要执行一次。
if [ ! -f "$runOnceFile" ]; then
echo "----------init mysql database-------------"
# mysql初始化数据库,在my.cnf里面指定了数据库位置
if [ "$isUbuntu" = true ]; then
mysqld --initialize-insecure --user=root --datadir=/wiz/storage/db
else
/usr/sbin/mysqld --initialize-insecure --user=root --datadir=/wiz/storage/db
fi
fi
# 启动redis, nginx, mysql服务
echo "----------start redis-------------"
if [ "$isUbuntu" = true ]; then
/usr/bin/redis-server &
else
/usr/bin/redis-server /etc/redis.conf &
fi
echo "----------wait redis-------------"
/wiz/app/wait-for-it.sh -h 127.0.0.1 -p 6379 -t 60
echo "----------start nginx-------------"
/usr/sbin/nginx -c /etc/nginx/nginx.conf &
echo "----------start mysql-------------"
if [ "$isUbuntu" = true ]; then
/etc/init.d/mysql start
else
/usr/sbin/mysqld --user=root &
fi
echo "----------wait mysql-------------"
/wiz/app/wait-for-it.sh -h 127.0.0.1 -p 3306 -t 60
mysqlService=$?
# 修改mysql数据库密码,只需要执行一次
if [ ! -f "$runOnceFile" ]; then
echo "----------change mysql password-------------"
mysql -uroot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'aI9DCyNpEKWe9pn5';flush privileges"
fi
mysql -uroot -paI9DCyNpEKWe9pn5 -e "show databases;"
mysqlSock=$?
if [[ $mysqlService != 0 || $mysqlSock != 0 ]];then
rm -f /var/lib/mysql/mysql.sock /var/lib/mysql/mysql.sock.lock /var/run/mysqld/mysqld.sock /var/run/mysqld/mysqld.sock.lock /var/run/mysqld/mysqld.pid
if [[ $mysqlService != 0 ]];then
rm -f /wiz/storage/db/ib_logfile0 /wiz/storage/db/ib_logfile1
fi
chmod a+rwx -R /wiz/storage
echo "------- The first start mysql faild ---------"
echo "------- start mysql again ---------"
# 杀死之前的mysql进程
ps aux |grep mysql|grep -v 'grep'|awk '{print $2}'|xargs kill
if [ "$isUbuntu" = true ]; then
/etc/init.d/mysql start
else
/usr/sbin/mysqld --user=root &
fi
/wiz/app/wait-for-it.sh -h 127.0.0.1 -p 3306 -t 60
mysqlService=$?
for i in {1..10}
do
mysql -uroot -paI9DCyNpEKWe9pn5 -e "show databases;"
mysqlSock=$?
if [[ $mysqlSock == 0 ]];then
break;
else
sleep 10
fi
done
fi
if [[ $mysqlService != 0 || $mysqlSock != 0 ]];then
echo "===== start mysql failed ======"
exit
fi
# 升级mysql
if [[ -f $runOnceFile && ! -f $mysqlUpgradeFile ]]; then
mysql -uroot -paI9DCyNpEKWe9pn5 -e "show databases;"
## 针对wizbox老的docker服务修改mysql密码;
## 老的wizbox密码是123456上条命令执行结果会失败,成功会返回0;
if [[ $? != 0 ]]; then
mysql_upgrade -uroot -p123456
mysql -uroot -p123456 -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'aI9DCyNpEKWe9pn5';flush privileges";
else
mysql_upgrade -uroot -paI9DCyNpEKWe9pn5
fi
mysql -uroot -paI9DCyNpEKWe9pn5 -e "set @@global.show_compatibility_56=ON;"
date > $mysqlUpgradeFile
fi
echo "----------init and upgrade database-------------"
cd /wiz/app/wizserver
# 使用传入的外部数据库地址
if [[ -n $MYSQL_EXTERNAL_HOST && -n $MYSQL_EXTERNAL_USER && -n $MYSQL_EXTERNAL_PASSORD && -n $MYSQL_EXTERNAL_PORT ]];then
NODE_ENV=production node upgrade_db.js -h $MYSQL_EXTERNAL_HOST -u $MYSQL_EXTERNAL_USER -p $MYSQL_EXTERNAL_PASSORD -P $MYSQL_EXTERNAL_PORT
else
NODE_ENV=production node upgrade_db.js
fi
if [[ ! -f "$runOnceFile" && -n $ADMIN_PASSWORD ]]; then
echo '----------init admin user password -------------'
adminPassword=$(node init_user_password.js -p $ADMIN_PASSWORD)
if [[ -n $MYSQL_EXTERNAL_HOST && -n $MYSQL_EXTERNAL_USER && -n $MYSQL_EXTERNAL_PASSORD && -n $MYSQL_EXTERNAL_PORT ]];then
mysql -h$MYSQL_EXTERNAL_HOST -u$MYSQL_EXTERNAL_USER -p$MYSQL_EXTERNAL_PASSORD -P$MYSQL_EXTERNAL_PORT -e "use wizasent; update wiz_user set password = '${adminPassword}' where email='admin@wiz.cn'"
else
mysql -uroot -paI9DCyNpEKWe9pn5 -e "use wizasent; update wiz_user set password = '${adminPassword}' where email='admin@wiz.cn'"
fi
fi
echo "----------start node service-------------"
# 启动node服务
cd /wiz/app/wizserver/
pm2 start app.js --name="as" --log-date-format="YYYY-MM-DD HH:mm:ss.SSS" --max-memory-restart 1024M -f -- -s as
pm2 start app.js --name="note" --log-date-format="YYYY-MM-DD HH:mm:ss.SSS" --max-memory-restart 3000M -f -- -s note
pm2 start app.js --name="ws" --log-date-format="YYYY-MM-DD HH:mm:ss.SSS" --max-memory-restart 1024M -f -- -s ws
pm2 start app.js --name="index" --log-date-format="YYYY-MM-DD HH:mm:ss.SSS" --node-args="--expose-gc" --max-memory-restart 3000M -f -- -c 1 -i 1 -t 1 -s index
pm2 start app.js --name="search" --log-date-format="YYYY-MM-DD HH:mm:ss.SSS" -f -- -s search
pm2 start app.js --name="editor" --log-date-format="YYYY-MM-DD HH:mm:ss.SSS" -f -- -s editor
# 初始化模版数据
if [ ! -f "$runOnceFile" ]; then
echo "----------init template-------------"
/wiz/app/wait-for-it.sh -h 127.0.0.1 -p 5001 -t 60
asService=$?
if [[ $asService != 0 ]]; then
echo "as service start failed";
exit;
fi
bash /wiz/app/template_upload.sh
date > $runOnceFile
fi
echo "----------start cron -------------"
if [ "$isUbuntu" = true ]; then
cron -n
else
crond -n
fi
tail -f /dev/null
这是源文件,具体在docker中配置如下
###需要在运行docker的时候配置如下的环境变量
MYSQL_EXTERNAL_HOST=mysqlurl#cq-cdb-m8k5r9tr.sql.tencentcdb.com
MYSQL_EXTERNAL_USER=username#root 不一定是root但必须可以用这个账户创建数据库
MYSQL_EXTERNAL_PASSORD=password#a202502231553312
MYSQL_EXTERNAL_PORT=3306#20719自己的服务器端口如果在日志中出现这个错误可以增加如下配置:Index column size too large
[mysqld]
# 启用大索引前缀
innodb_large_prefix=1
# 使用Barracuda文件格式
innodb_file_format=Barracuda
# 每表单独文件
innodb_file_per_table=1
# 默认行格式设为DYNAMIC
default_storage_engine=InnoDB
innodb_default_row_format=DYNAMIC实际储存文件分析
在镜像中的/wiz/storage/data_root/document2目录下有按照用户UID分的文件夹,每一个文件夹下面就是该用户的所有文件
但是这些文件里面是没有这一条文章的元信息的,也就是说在这个文件夹里面是看不到文章的路径,名称,创作时间等信息的,这就需要和mysql配合一起才能够获取到完整的文件信息
对于信息的提取,我们想要的数据是:文章名称,创作时间,修改时间,创作者,附件数,图片数,音频数,文章字数,附件信息,音频长度
目前仅通过mysql数据的获取我们能够拿到的信息以已经加粗,剩下唯一拿不到的数据就是文章当中的图片数,音频长度,想要获取图片数量的唯一办法就是解析实际存储的文章文件,这就不得不对挂载的用户数据目录进行开发了
按道理来说是可以通过对存储文件的文件夹进行分析获取附件信息的,但是由于存储的时候所有的附件都被打入了zip压缩包导致后续想要或许原始文件名称较为繁琐,这里就采用从mysql中的文章附件信息表来获取这一数据
这里有一项bug:对于在笔记中保存的是录音文件的附件的size参数会有问题,无法查看正常的大小

可以看到这里面的mp3格式的文件都是没有正常的size参数的,现在又要重MySQL返回到原始文件来查看了

我们发现在每一个文件的保存地址下有一个note.info的文件,里面的resources参数下有附件的大小数据,既然这里有数据,那我们不妨把这个数据在对原始路径的解析步骤处拿出来,但是这样解决的话就无法避免一对多的情况出现,因为info文件里面是没有mp3文件的名称的,当一个笔记里面存在多条音频数据的时候这样的简单获取就会造成数据错误,为了避免这样的情况我我的建议是后期通过对网页端数据获取的API进行处理来获取这里的真实的音频长度信息,毕竟我要的是音频长度,而不是音频大小,这里获取的大小其实还是需要进行模糊计算才能得到长度信息,所以长度信息目前交由网页端解析地方进行处理
可视化展示统计数据
这里我们借鉴GitHub的贡献热力图的设计参考,我们将如下信息进行量化评分并转为颜色信息