Form Maker 1.13.3 SQL注入分析(CVE-2019-10866)
对WordPress
插件Form Maker 1.13.3
SQL注入漏洞(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 协议 ,转载请注明出处!