所有日志都是从
Nginx
的access.log
中提取的。其中的IP
信息为攻击者的代理 IP
,且取出了Cloudflare
的IP
。
收到新评论通知邮件
当我打开邮箱后提示有 5 封邮件未读,邮件的时间是间歇性的。一开始以为只是良性测试,但没过多久就冒出了大量重复的评论。
邮件的内容大致如下:
您的博客有新的评论!
johnniang, 您好!
有访客在《ARTS-w002》留言:
YYY:YYY
你可以点击查看完整内容
发送频率如下:
序号 | 时间 |
---|---|
1 | Dec 6, 2019 7:08 PM |
2 | Dec 6, 2019 7:09 PM |
3 | Dec 6, 2019 7:16 PM |
4 | Dec 6, 2019 7:17 PM |
5 | Dec 6, 2019 7:18 PM |
对方产生邪恶的念头
该访客试探性地评论我的博客,发现并不需要审核就能够评论,接着就产生了邪恶的念头......
由于评论接口
是限制了连续快速请求的,该攻击者一开始并不知道评论的具体间隔时间,然后不断地试探 rate limit
(如果仔细阅读过源码
就会发现,默认的 rate limit
时间其实是 5s
)。
对方实施攻击计划
该攻击者迅速编写了 Python
脚本,准备攻击评论接口。
[06/Dec/2019:11:39:29 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "python-requests/2.22.0" "161.117.xxx.xxx"
[06/Dec/2019:11:39:29 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "python-requests/2.22.0" "161.117.xxx.xxx"
[06/Dec/2019:11:39:30 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "python-requests/2.22.0" "161.117.xxx.xxx"
[06/Dec/2019:11:39:49 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 337 "-" "python-requests/2.22.0" "161.117.xxx.xxx"
[06/Dec/2019:11:39:50 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "python-requests/2.22.0" "161.117.xxx.xxx"
[06/Dec/2019:11:39:50 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "python-requests/2.22.0" "161.117.xxx.xxx"
[06/Dec/2019:11:39:51 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "python-requests/2.22.0" "161.117.xxx.xxx"
[06/Dec/2019:11:39:51 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "python-requests/2.22.0" "161.117.xxx.xxx"
从日志中看到,出现了 400 的错误(Frequnt Access
),该访客可能还未猜出精确的间隔时间。但攻击者仍不放弃,继续试图从浏览器上寻找评论的 rate limit
:
[06/Dec/2019:11:40:18 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 428 "https://johnniang.me/archives/arts-2" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:40:26 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 428 "https://johnniang.me/archives/arts-2" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:40:31 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 428 "https://johnniang.me/archives/arts-2" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
可能是在浏览器上点起来
不爽,于是又给 Python
穿上马甲(伪装 User-Agent)继续试探:
[06/Dec/2019:11:41:58 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 428 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:41:58 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:41:59 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:42:11 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 428 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:42:12 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:42:59 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 428 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:43:09 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 428 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:43:10 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 279 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
从攻击的规律来看,一直在评论我的一篇文章
,为了不给我其他访客造成影响,我只能被迫开启文章的评论审核功能。
最终,该攻击者终于找到了评论接口的 rate limit
,于是间隔 5s
就发送一个 POST
请求:
[06/Dec/2019:11:47:54 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:48:00 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:48:05 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:48:11 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:48:16 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:48:22 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:48:27 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:48:33 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
尝试禁用该篇文章的评论
此后邮箱的状况如下图:
几乎所有的恶意评论都指向的同一篇文章,我尝试禁用该篇文章的评论功能(减少正常访客的影响)。
对方继续被追击
好景不长,攻击者随即发现了请求中出现了大量的 400
错误,于是就通过电脑的浏览器访问我的博客的被攻击的文章,评论之后才发现该篇文章的评论功能已经被禁用:
[06/Dec/2019:11:55:27 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 95 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:55:30 +0000] "GET /archives/arts-2 HTTP/1.1" 200 19072 "https://johnniang.me/archives" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:55:32 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 95 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
攻击者继续访问我的其他文章,发现其他文章的评论功能是正常的。
[06/Dec/2019:11:55:35 +0000] "GET /archives HTTP/1.1" 200 13396 "https://johnniang.me/archives/arts-2" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:55:36 +0000] "GET /archives/a1074-reversing-linked-list HTTP/1.1" 200 15191 "https://johnniang.me/archives" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:55:37 +0000] "GET /api/content/options/comment HTTP/1.1" 200 106 "https://johnniang.me/archives/a1074-reversing-linked-list" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:55:37 +0000] "GET /api/content/posts/37/comments/top_view?page=0&sort=&size=5&total=0 HTTP/1.1" 200 1034 "https://johnniang.me/archives/a1074-reversing-linked-list" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:55:38 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 95 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:57:16 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:57:22 +0000] "POST /api/content/posts/comments HTTP/1.1" 404 95 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:57:27 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:57:33 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:57:39 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:57:44 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:11:57:50 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
于是攻击者的武器
升级了,开始乱抢扫射
,遍历文章的 ID
(该 ID
是从 1 开始的自增属性)并发送评论请求。我的邮箱就这么被狂轰滥炸
(轻微):
被迫关闭评论的 API
最后只能被迫关闭评论接口这个 API
了。同时也导致正常访客无法正常发送评论(攻击者的目的也达到了)。
对方终于放弃
在得到大量的 403
错误之后,对方终于放弃了。
[06/Dec/2019:12:00:18 +0000] "POST /api/content/posts/comments HTTP/1.1" 404 95 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:12:00:24 +0000] "POST /api/content/posts/comments HTTP/1.1" 400 95 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:12:00:31 +0000] "POST /api/content/posts/comments HTTP/1.1" 200 427 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:12:00:37 +0000] "POST /api/content/posts/comments HTTP/1.1" 403 99 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
[06/Dec/2019:12:00:42 +0000] "POST /api/content/posts/comments HTTP/1.1" 403 99 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36" "161.117.xxx.xxx"
不足
接口的限制不够灵活,仍然能够被有效地攻击。需要一个有效的限制策略,比如限制频率为 5s、1min、30min、1hour、3hour、6hour、12hours、24hours 等等。