WordPress 插件
组件名称 SEO Plugin by Squirrly SEO
受影响版本 <= 12.4.01
组件 Slug squirrly-seo
组件链接 https://wordpress.org/plugins/squirrly-seo/
漏洞类别 A3: 注入
漏洞类型 SQL 注入
Contributor + 权限
SEO Plugin by Squirrly SEO 允许你通过内链功能改善网站的 SEO,该功能可以让你根据特定关键词选择源页面和目标页面。你可以通过内链管理页面(/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks)管理每个链接的关键词、源页面、目标页面和状态。
在 12.4.01 及以下版本的 Squirrly SEO 插件中,你可以在内链管理页面搜索已创建的内链。当用户(Contributor+)输入的搜索词未经验证直接传入数据库查询时,就会发生 SQL 注入漏洞。
虽然搜索结果不会直接显示在内链管理页面上,但可以使用基于时间的 SQL 注入技术(如 SLEEP 函数)提取数据库信息。
使用具有 Contributor 或更高权限的账户登录目标站点,该站点安装了版本 12.4.01 或更低版本的 Squirrly SEO 插件。
然后,当你访问以下 URL 时,由于 SQL 注入载荷中的 IF 语句条件 '1=1' 始终为真,SLEEP(5) 函数将执行,页面将在 5 秒后加载。
http://localhost:8080/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks&stype&squery='+AND+1%3D2)+UNION+SELECT+(IF(1=1,SLEEP(5),1)),2,3,4,5,6,7%23
另一方面,如果你将 IF 语句条件改为 '1=2',由于结果值为假,页面将立即加载。
http://localhost:8080/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks&stype&squery='+AND+1%3D2)+UNION+SELECT+(IF(1=2,SLEEP(5),1)),2,3,4,5,6,7%23
在 Squirrly SEO 插件的内链管理页面(/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks)上,当搜索内链时,会调用 /wp-content/plugins/squirrly-seo/models/Qss.php 文件中的 getSqInnerlinks 函数查询数据库。

此时,我们可以看到变量 $query_where 被直接插入到 SQL 查询中。让我们看看变量 $query_where 的值是如何构造的:
$search 包含在内链搜索期间输入的搜索词,并使用 sanitize_text_field 函数处理用户输入数据。$search 被用作条件子句的一部分,并存储在变量 $query_where 中。$query_where 中会添加更多条件,并通过 apply_filters 函数应用过滤器。因此,虽然用户在内链搜索期间输入的搜索词会经过 sanitize_text_field 函数处理,但该函数无法阻止 SQL 注入攻击。SQL 查询中使用的特殊字符(单引号(')、注释符(#)等)不会被过滤,当包含 SQL 注入载荷的变量 $search 未经适当转义直接传入数据库查询时,就会产生 SQL 注入漏洞。
⚠️ 实现的 PoC 代码使用管理员账户登录,创建一个具有漏洞复现所需最低权限(Contributor+)的账户,然后使用该账户触发漏洞。

接下来,输入以下命令运行 PoC 代码。
所需模块requests
python poc.py
