背景
SQL注入漏洞是用来构建SQL查询的用户输入未经适当处理导致的漏洞。比如:
图1: 使用WordPress的SQL查询示例
从上面的代码来看,其中存在SQL注入攻击漏洞,因为从$_GET中提取的$_id在传递给SQL查询时没有经过任何处理。在最新的WordPress版本中,默认会在$_POST/$_GET/$_REQUEST/$_COOKIE中加入了magic quotes。这可以帮助WordPress维护,并提供最佳的安全能力。因此,上面的代码其实是没有漏洞的。
除了给所有输入值加斜杠(slash)外,WordPress会提供许多内置的处理函数来对输入进行处理,以确保输出的安全。开发者可以使用sanitize_email()来处理邮件地址,或用sanitize_text_field()来清除文本域的值,或用sanitize_sql_orderby()来验证SQL ORDER BY clauses。用户输入最常见的类型是由WordPress sanitize_*()的类来涵盖的。
虽然WordPress核心是尽最大可能来帮助开发者来防止恶意伪造的用户输入、不好的编码实践、误用逃逸函数会导致简单或关键的漏洞。
漏洞分析
FG-VD-19-092 – SQL Injection in AdRotate Plugin through 5.2 for WordPress
该漏洞是一个经典SQL注入漏洞,存在于 AdRotate插件5.2版本中。漏洞位于dashboard/publisher/adverts-edit.php文件的第25行。
图2: adverts-edit.php中的SELECT statement用于从数据库中获取广告
变量$ad_edit_id用于构建SQL查询。该变量是从函数adrotate_manage的变量$_GET中提取的。
图3: 用户控制的变量$ad_edit_id
因为esc_attr变量只能逃逸HTML属性,在SQL查询中$ad_edit_id变量无法用双引号逃逸,因此可以注入payload到$ad_edit_id中来执行任意的SQL语句。
图4: AdRotate插件5.2泄漏的数据库版本
因为管理接口只对管理员角色可用,缺乏CSRF token使非认证的攻击者可以远程窃取信息,包括session token,可以通过SQL注入漏洞以最小的用户交互来引发XSS:
图5: SQL注入引发的XSS
开发者的补丁中只是对查询中的$ad_edit_id变量加了引号。
图6: AdRotate 5.3版本中的SQL注入漏洞补丁
FG-VD-19-099 – SQL Injection in NextGEN Gallery Plugin through 3.2.10 for WordPress
NextGEN Gallery 插件提供了很完美的照片管理方法,操作也不复杂,从2007年开始就成为标准的WordPress照片管理插件,每年新下载量超过150万。截止目前,NextGEN Gallery 插件的活跃安装超过90万,是照片管理插件中使用最多的之一。
该插件的AJAX API中存在漏洞,用户可以在发布文章时从图片库中附件照片。
图7: 用户提供的输入在get_displayed_gallery_entities_action中处理
modules/attach_to_post/package.module.attach_to_post.php中的函数get_displayed_gallery_entities_action是负责在特定的图片库中显示图片的。数组参数 displayed_gallery是通过POST方法提取的以创建gallery对象,如第119行代码所示。对象的属性可以通过esc_sql帮助函数逃逸。然后调用第130行的get_entities,指向modules/nextgen_gallery_display/package.module.nextgen_gallery_display.php中的函数get_entities。
图8: get_entities根据返回的请求调用对应的函数
因为返回请求有both值,因此第832行的_get_image_entities会被调用。
图9:_get_image_entities获取gallery中的所有图像
该函数会准备一个查询来返回展示的gallery中的所有图像。如第1041行所示,会使用一个基于来自创建的gallery对象的$sort_by和$sort_direction的排序过程。任意有权限使用NextGEN Gallery 的经过认证的用户都可以操作params来创建gallery对象。虽然该对象的所有属性都可以用esc_sql逃逸,但攻击者并不需要逃逸引号就可以在ORDER BY语句中执行SQL注入攻击。因此,esc_sql无法预防NextGEN Gallery 被攻击者利用的情况。
图10: NextGEN Gallery中的SQL盲注
图11: NextGEN Gallery中的SQL盲注2,false会返回空结果
发布的补丁中只允许ORDER BY语句中出现特定的值,因此查询就是安全的。
图12: Imagely通过白名单修复安全漏洞
FG-VD-19-098 – SQL Injection in Impress Give Plugin through 2.5.0 for WordPress
Give 是评分最高、下载量最多的wordpress插件。该插件的漏洞代码位于includes/donors/class-give-donors-query.php的get_order_query函数中。
图13: Give插件中的漏洞代码
如注释所示,get_order_query尝试移除ORDER BY语句中不存在的列,通过使用esc_sql帮助函数来过滤排序的值。因为467行中销毁不存在的行后,会在第470行中重插入一个逃逸值,因此移除并不会如研究人员所想。许多人都知道esc_sql函数在预防ORDER BY语句中的SQL注入攻击中是没有用处的。因此,构建的查询中是有漏洞的。相同的SQL盲注技术可以用来利用该漏洞。
Impress 团队发布的1行补丁允许过滤器正常工作,因此查询是安全的。
图14: Give插件补丁
建议
为了预防开发WordPress插件过程中的SQL注入攻击。研究人员建议开发者遵循WordPress编码规范和安全编码最佳实践。研究人员建议:
· 不要信任任何用户输入。对用户提供的所有数据执行有效性检查和处理。
· 如果不确定数据是不是安全的,应用内置的处理函数来适配数据。比如,sanitize_sql_orderby()就修复了所有发现的漏洞。
· 除了使用esc_sql,99%的case可以用预先准备好的语句。
· 如果无法使用预先准备好的语句,可以使用esc_sql和引号内的逃逸值。