现象:
- 后台多出30余条数据,但无法在后台查看;
- 在LeanCloud中,必填数据均为undefiend;
废话IP归属地均为国外。
排查:
1. 怀疑部署的VPS遭到入侵
VPS查看最新登陆记录;
没有可疑的登陆记录,排除;
2. 怀疑对方直接访问数据库
但LeanCloud无法查看API访问日志;
3. 怀疑Waline服务端
在docker日志中发现以下字段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 2022-07-31T08:26:06.834872643Z [2022-07-31T16:26:06.834] [14] [DEBUG] - Post Comment Start! 2022-07-31T08:26:06.835180185Z [2022-07-31T16:26:06.834] [14] [DEBUG] - Post Comment initial Data: { 2022-07-31T08:26:06.835188339Z link: 'undefined', 2022-07-31T08:26:06.835191204Z mail: 'undefined', 2022-07-31T08:26:06.835193497Z nick: 'undefined', 2022-07-31T08:26:06.835195760Z pid: 'undefined', 2022-07-31T08:26:06.835198024Z rid: 'undefined', 2022-07-31T08:26:06.835200227Z ua: 'undefined', 2022-07-31T08:26:06.835202409Z url: 'undefined', 2022-07-31T08:26:06.835204615Z comment: 'undefined', 2022-07-31T08:26:06.835206944Z ip: '2408:8214:5500:4e36:9414:20b5:5c7f:d97d', 2022-07-31T08:26:06.835209234Z insertedAt: '2022-07-31T08:26:06.834Z', 2022-07-31T08:26:06.835211537Z user_id: 'undefined' 2022-07-31T08:26:06.835213759Z }
|
对方向客户端发送带有空值的数据,客户端没有验证空值,直接写入了数据库。
之后,LeanCloud的API就被限额了。
2.
1 2
| 2022-08-01T03:05:37.090173132Z NotFoundError: url `/resources/images/emotions/B%E7%AB%99/tv_doge.webp` not found. 2022-08-01T02:24:40.022954737Z NotFoundError: url `/resources/images/emotions/%E5%B4%A9%E5%9D%8F3/%E5%B4%A9%E5%9D%8F3_%E5%BF%AB%E4%B9%90.webp` not found.
|
这个webp文件对应的是存储在我主站下的表情。
我并不理解攻击者访问这两个路径的用意,或许只是在嘲讽。
攻击还原
原理已经知道了,以下是实现攻击的Python3脚本:
1 2
| import requests requests.post('https://siteof.waline.instance/comment', data={"comment":123,"nick":None,"mail":None,"link":None,"ua":None,"url":None})
|
就是这么简单,绕过Web客户端,直接发送 关键字段为null的评论数据,也因此,在评论后台查看的时候会显示一片空白,只能进入数据库删除。
试图解决
在Waline的用户群和一堆群友讨论了一番。
Waline的主要维护者lizheming建议我 启用评论hooks。
尝试·Hooks
使用的是preSave
,加入了判断comment内部分内容是否为空的分支条件。
docker加载了评论hook,但是执行无果,具体日志如下:
1 2 3 4 5 6 7 8 9 10 11
| 2022-08-01T13:56:14.795789535Z [2022-08-01T21:56:14.795] [14] [DEBUG] - Comment IP ~~XXX.XXX.XXX.XXX~~ check OK! 2022-08-01T13:56:15.608620760Z [2022-08-01T21:56:15.607] [14] [DEBUG] - Comment duplicate check OK! 2022-08-01T13:56:16.334946985Z [2022-08-01T21:56:16.328] [14] [DEBUG] - Comment post frequence check OK! 2022-08-01T13:56:16.335395672Z [2022-08-01T21:56:16.331] [14] [DEBUG] - Comment initial status is waiting 2022-08-01T13:56:16.340518312Z [2022-08-01T21:56:16.333] [14] [DEBUG] - Comment akismet check result: waiting 2022-08-01T13:56:16.340578595Z [2022-08-01T21:56:16.336] [14] [DEBUG] - Comment keyword check result: waiting 2022-08-01T13:56:16.343837988Z [2022-08-01T21:56:16.339] [14] [DEBUG] - **Comment post hooks preSave done!** 2022-08-01T13:56:17.076109346Z [2022-08-01T21:56:17.065] [14] [DEBUG] - Comment have been added to storage. 2022-08-01T13:56:17.093522436Z Notification mail send success: undefined 2022-08-01T13:56:17.094307965Z [2022-08-01T21:56:17.093] [14] [DEBUG] - Comment notify done! 2022-08-01T13:56:17.094888673Z [2022-08-01T21:56:17.094] [14] [DEBUG] - Comment post hooks postSave done!
|
没有成功。
自己动手,丰衣足食
大概花费了一些时间,摸清了Waline评论的处理过程,然后简短在comment.js
加入了一些判断语句。
目前已提交PR,但官方的态度有些犹豫,所以,我需要更多人意识到这个问题。