运维笔记:黑帽SEO后续,编码,不慎掉进WP转义坑

2023年下半年,博客一直被华为PetalBot带来的站内搜索垃圾流量困扰。经过一段时间的整治,从2024年1月开始,这类垃圾流量几乎绝迹了,零星出现的几个僵尸bot也不再顶着petalbot的主机名,溃不成军(我与僵尸bot斗智斗勇的经过还请参见前置文章)。但计划赶不上变化,3月4日开始,101.44.248.*、101.44.249.*、101.44.251.*这几个号段的僵尸bot频繁来袭,而且请求URL也出现变化,导致我的自动监控插件检测不到异常。魔高一尺,那就道高一丈,我也开始迭代插件,处理新常态。

一、变化

3月出现的新僵尸bot请求URL展示

对比一下PetalBot的请求参数,可以明显看到一个是UTF-8编码,一个是URL编码:

GET /?s=%E6%81%92%E8%BE%BE%E4%BB%A3%E7%90%86%E4%B8%80%E6%AD%A5%E5%88%B0%E4%BD%8D%E6%81%92%E8%BE%BE%E5%B9%B3%E5%8F%B0%E3%80%90%E2%94%83%E7%BB%99%E5%8A%9B2%E2%92%8F7%E2%92%8F01705%5B%EF%BC%B1%E3%80%91%E3%80%91 HTTP/1.1

请求参数是中文字符集,比如XX平台、某某娱乐一类的,这一点没什么变化。但和原先PetalBot的请求参数清一色标准的百分号编码不同,这次的僵尸bot的请求参数竟然全是UTF-8编码。

话不多少,先一探究竟。我随机找了一个僵尸请求,放到Python中解码看一下(还试了javascript版本的,结果一样就暂且不表了):

encode_str = b'\xe3\x80\x90\xe2\x94\x83\xe4\xbf\xa1\xe8\xaa\x89\xef\xbc\x9217431(\xe6\x89\xa3)\xe3\x80\x91\xe3\x80\x91\xe5\x81\x9a\xe6\x9d\x8f\xe5\xbd\xa9\xe4\xbb\xa3\xe7\x90\x86\xe4\xbc\x9a\xe4\xb8\x8d\xe4\xbc\x9a\xe7\x8a\xaf\xe6\xb3\x95'

# 解码UTF-8得到中文结果
print(encode_str.decode())
# 输出结果为:【┃信誉217431(扣)】】做杏彩代理会不会犯法

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}

# 拼接URL
full_url = f'https://sophiatazar.com/?s={encode_str.decode()}'
# full_url 打印输出为 https://sophiatazar.com/?s=【┃信誉217431(扣)】】做杏彩代理会不会犯法
# 发送请求看一下
res = requests.get(url=full_url, headers=headers)

# 打印请求URL
print(res.request.url)
# 输出结果为  https://sophiatazar.com/?s=%E3%80%90%E2%94%83%E4%BF%A1%E8%AA%89%EF%BC%9217431(%E6%89%A3)%E3%80%91%E3%80%91%E5%81%9A%E6%9D%8F%E5%BD%A9%E4%BB%A3%E7%90%86%E4%BC%9A%E4%B8%8D%E4%BC%9A%E7%8A%AF%E6%B3%95

因为URL不可包含非ASCII 字符,所以可以看到,解码后的中文字符串所拼接成的URL,已经被Python的requests库进行了URL编码。再对比一下原始的UTF-8编码,可以发现所谓的URL编码,无非就是先将中文字符串转为UTF-8编码,再将\x替换为%,并改大写。

二、疑惑

在本站网页测试搜索“神兵玄奇”,观察参数转码情况

目前我尚不能得知这些僵尸bot用了什么方式、什么工具发送请求,因为参照上图,如果直接在浏览器内打开网站,并在站内搜索框内输入中文,这些参数是能被正常转为URL编码的。又如前文所言,我用Python和JS尝试发送带中文参数的请求,URL都能顺利转码为URL编码。

目前初步猜测是用了某种不会对请求进行URL转码的工具。为了求证我的想法,我问了ChatGPT,是不是存在某些工具,不会对带中文参数的URL进行转码的?ChatGPT给出的答复如下:

一般情况下,在发送请求时,URL 中的中文字符会自动转码为 URL 编码形式。这是因为 URL 中只能包含特定的字符集,而中文字符不属于这些字符集,因此需要进行转码以确保 URL 的正确性。

然而,如果您想发送不经过 URL 编码的 URL,可以使用一些工具或库来实现。以下是一些常见的工具或库,它们在发送请求时不会自动转码 URL:

Curl:Curl 是一个功能强大的命令行工具,可以用来发送 HTTP 请求。在 Curl 中,您可以直接使用原始的 URL,而不需要进行 URL 编码。例如:curl "https://www.example.com/path?param=中文"

Postman:Postman 是一个流行的 API 开发工具,提供了一个用户友好的界面来发送 HTTP 请求。在 Postman 中,您可以直接输入原始的 URL,而不需要进行 URL 编码。

axios(JavaScript):axios 是一个流行的 JavaScript HTTP 客户端库,用于在浏览器和 Node.js 中发送 HTTP 请求。默认情况下,axios 会自动对 URL 进行编码。但是,您可以通过设置 paramsSerializer 选项为一个自定义函数,来禁用 URL 编码。

我当下就用Curl发了个请求试试,服务器日志录得的路径是:

GET /?s=\xa1i?\xabH?\xa2\xb117431(\xa6\xa9)\xa1j\xa1j\xb0\xb5\xa7\xf6\xb1m\xa5N\xb2z?\xa4\xa3?\xa5\xc7\xaak HTTP/1.1

三、折腾

我的插件针对PetalBot设的匹配字段是【,因为所有这类垃圾请求的共性就是必带中文方括号【】。【所对应的的UTF-8编码是 E3 80 90,URL编码表示就是%E3%80%90,因为正常的请求URL都经过URL转码,因此%E3%80%90可以匹配到此前的PetalBot发出的垃圾请求。

我没怎么多想,就直接设置了新的匹配字段\xe3\x80\x90。本以为可以高枕无忧,没想到垃圾请求接二连三,但插件一个都收不到。出于测试目的,我取消了IP白名单,用服务器日志上的路径试了一下,结果把自己给报上去了。很奇怪,为什么我用自己做实验成功了,但垃圾请求却没有成功被插件捕获呢?

我单独把用来匹配字段的函数摘出来,放到编译器内试了一下,在字符串状态下,\xe3\x80\x90\xe2\x94\x83\xe4\xbf\xa1\xe8\xaa\x89\xef\xbc\x9217431(\xe6\x89\xa3)\xe3\x80\x91\xe3\x80\x91\xe5\x81\x9a\xe6\x9d\x8f\xe5\xbd\xa9\xe4\xbb\xa3\xe7\x90\x86\xe4\xbc\x9a\xe4\xb8\x8d\xe4\xbc\x9a\xe7\x8a\xaf\xe6\xb3\x95可以匹配到\xe3\x80\x90。我自己用服务器日志上的url也试成功了,这足以证明代码没问题。

那会不会是请求的URL发生了某种变化?我的请求URL是通过全局变量$_SERVER[“REQUEST_URI”]获取的,我一方面将$_SERVER[“REQUEST_URI”]写入debug.log,一方面写了个函数将其输出到控制台上。结果我发现Wordpress会给\x再加上一道反斜杠\转义,多次请求同一个URL,就会出现多道反斜杠。

于是我又在想,$_SERVER[“REQUEST_URI”]获得的是原始请求URL吗?这时我发现了一篇文章,开发者必藏:WordPress 数据转义是怎么处理的?,里面提到:

WordPress 的 $_GET$_POST$_COOKIE$_SERVER  $_REQUEST 数据中的字符串是被转义的

这个是 WordPress 和其他 PHP 框架最大的不同,所以在 WordPress 进行开发的时候,一定要记住这个,不然会引起一些莫名其妙的问题,然后根本不知道怎么去解决。

以及:

为了方便操作,WordPress 提供了两个常用的函数除了对字符串进行转义和反转义操作之外,也可以对数组中的字符串进行转义和反转义操作,

  • wp_slash($value):以递归方式将反斜杠添加到字符串或字符串数​​组中
  • wp_unslash($value):删除字符串或字符串数​​组中的反斜杠。

于是我用wp_unslash处理了一下$_SERVER[“REQUEST_URI”],结果真正的URL是:

URL inspector: /?s=杏彩彩票app【┋给力2Ⅰ7431[扣〓】

真相大白了,原来我在日志里看到的URL已经被服务器用UTF-8编码过了,原始的请求,就是一串中文字符串,你拿UTF-8编码的字符去匹配,当然匹配不到啦。接下来就很简单了,直接用中文字符【】作为匹配字符串即可。

发布者

《运维笔记:黑帽SEO后续,编码,不慎掉进WP转义坑》上有2条评论

  1. 是专门有站内搜索的发包软件的用于SEO,博主可以了解一下。。。这种软件可以模拟出各种参数来达到欺骗行为,伪装成一个正常访客一样搜索访问。

    1. 做站的老哥内行人啊,这次的情况奇怪就是它的请求参数没有进行URL编码,不知道是什么原因造成的,感觉是某种设计不良

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注