针对绕过Waline在数据库刷评的攻击的排查

现象:

  • 后台多出30余条数据,但无法在后台查看;
  • 在LeanCloud中,必填数据均为undefiend;
  • 废话IP归属地均为国外。

排查:

1. 怀疑部署的VPS遭到入侵

VPS查看最新登陆记录;

1
last

没有可疑的登陆记录,排除;

2. 怀疑对方直接访问数据库

但LeanCloud无法查看API访问日志;

3. 怀疑Waline服务端

在docker日志中发现以下字段:

1.

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就被限额了。

  1. 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,但官方的态度有些犹豫,所以,我需要更多人意识到这个问题。