Form Maker 1.13.3 SQL注入分析(CVE-2019-10866)
对WordPress插件Form Maker 1.13.3SQL注入漏洞(CVE-2019-10866)的分析。
本文首发先知社区
前言
最近在复习SQL注入的一些知识,对于order by后面的注入遇到的不是很多,正好五月底WordPress的一个表单生成器插件出了一个SQL注入漏洞,恰好是order by的问题,于是拿来分析一波。如有错误,还望师傅们批评指正。
1. 环境搭建
运行环境很简单,只是在vulapps的基础环境的上加了xdebug调试插件,把docker容器作为远程服务器来进行调试。Dockerfile文件:
1 | |
docker-compose文件:
1 | |
php.ini中xdebug的配置
1 | |
因为我是在Mac上,所以要给本机加一个IP地址,让xdebug能够连接。
1 | |
PHPStorm也要配置好相对路径:

插件下载地址:
1 | |
WordPress使用最新版就可以,在这里我使用的版本是5.2.2,语言选的简体中文。
PS: WordPress搭建完毕后,记得关闭自动更新。
2. POC
1 | |
Python脚本,修改自exploit-db
1 | |

3. 漏洞分析
3.1 漏洞利用流程分析
根据POC,我们很容易知道,注入点在参数asc_or_desc上,根据它的命名,极有可能是order by之后的注入。
首先大致浏览下插件目录下的文件结构:

很经典的MVC架构,但是有点无从下手,还是从POC出发吧,
首先全局搜索字符串asc_or_desc,根据传入的参数page=submissions_fm&task=display,以及我们搜索到的结果,可以猜测,submissions_fm就是指代的调用的插件文件,display就是要调用的方法。

在这里下一个断点验证一下。
根据函数调用栈,我们很容易就能知道,在form-maker.php:502, WDFM->form_maker()处,代码将FMControllerSubmissions_fm进行了实例化,然后调用了它的execute()方法。

接下来就进入了Submissions_fm.php:93, FMControllerSubmissions_fm->execute()

获取传入的task和current_id,动态调用FMControllerSubmissions_fm类的方法display,并将current_id的值作为参数传入。
后面依次进入了model类FMModelSubmissions_fm中的get_forms(),get_statistics();和blocked_ips()方法,分别跟进之后并没有发现调用asc_or_desc参数。
继续往下,进入类FMModelSubmissions_fm中get_labels_parameters方法。
路径:wp-content/plugins/form-maker/admin/models/Submissions_fm.php:93

到了第133行:

代码从这里获取了传入的asc_or_desc的值,并将其存入了$asc_or_desc变量中。
跟进一下,看一看代码对其进行了怎样的处理。
路径:wp-content/plugins/form-maker/framework/WDW_FM_Library.php:367

根据传入的键值asc_or_desc,动态调用$_GET[$key],把值存入$value中,然后传入了静态私有方法validate_data()中
继续跟进,在第395行

使用stripslashes()函数去除了value中的反斜杠,又因为$esc_html为true,进入了esc_html
在WordPress手册中,可以查到它的作用是将传入的值转义为HTML块。
跟进一下,我们可以看到代码调用了两个WordPress的内置方法对传入的value值进行了处理
路径wp-includes/formatting.php:4348

从WordPress手册中,能查到_wp_specialchars是对&、<、>、"和'进行了HTML实体编码。

可以知道,在获取asc_or_desc参数的过程中,只过滤了\、&、<、>、"和'。
然后回到get_labels_parameters接着往下看。
在第161行,因为传入的$order_by == group_id满足条件,成功将$asc_or_desc,拼接到了变量$orderby中。

后面虽然有一些查询操作,但是都没有拼接$orderby,也没有对其做进一步的过滤处理。
导致在第311行,Payload拼接进入了SQL语句,然后在312行进行了数据库查询操作。

看一下数据库的日志也能看到,执行了SQL语句:
1 | |
在mysql中执行一下,由于when后面的条件成立,语句中的sleep(5)生效了。

到这里,整个POC的执行流程我们就看完了。
3.2 漏洞原理分析
简单总结一下,我们传入参数?page=submissions_fm&task=display,让代码走到了存在漏洞的方法get_labels_parameters中。

而方法get_labels_parameters中,在获取参数asc_or_desc的值的过程中,基本没有进行过滤,就将其拼接进入了SQL语句中,并执行,导致了SQL注入。

4. 补丁分析
我们将1.13.3版本的插件卸载掉,安装一下1.13.4版本,查看一下是如何修复的。
路径:wp-content/plugins/form-maker/admin/models/Submissions_fm.php:133

简单粗暴,限制了asc_or_desc的值只能为desc和asc其中的一个。
5. 参考链接
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!