1

---私は Cookie/セッション ID を実験してきましたが、概念を理解するのに少し苦労しています。私は Debian ディストリビューションに取り組んでいます。Burp を使用して要求/応答をキャプチャ/変更します。私が知っていることは以下です。

を。Cookie は /root/.mozilla/firefox/pya18ecc.default/cookies.sqlite のクライアント マシン データベースに保存されます。moz_cookies テーブル内。データベースへのアクセスに sqlite3 を使用しています。

b. セッション変数はサーバーの /var/lib/PHP5 に保存されます。

サーバー上の PHP コードは以下のとおりです。

<?php
require_once 'login.php';

$connection = new mysqli($db_hostname,$db_username,$db_password,$db_database);
if($connection->connect_error) die ($connect->connect_error);

if (isset($_SERVER['PHP_AUTH_USER']) &&
   isset($_SERVER['PHP_AUTH_PW']))
    {
        $username = mysql_entities_fix($connection,$_SERVER['PHP_AUTH_USER']);
        $password = mysql_entities_fix($connection,$_SERVER['PHP_AUTH_PW']);

        $query = "SELECT * FROM user WHERE username = '$username'";

        $result = $connection->query($query);

        if(!$result) die ($connection->error);
        elseif ($result->num_rows) 
        {
            $row = $result->fetch_array(MYSQLI_NUM);    
            $result->close();
            $salt1="!@#$";
            $salt2="$#@!";
            $token = hash('ripemd128',"$salt1$password$salt2"); 

            if($token == $row[3])
                {
                    session_start();
                    $_SESSION['username'] = $username;
                    $_SESSION['password'] = $password;
                    $_SESSION['forename'] = $row[0];
                    $_SESSION['surname'] = $row[1];
                        echo "$row[0] $row[1] : Hi '$row[0]' you are logged
                            in as '$row[2]'";
                    die("<p><a href = continue.php> CLICK HERE TO CONTINUE</a></p>");
                }
            else    {die("Invalid Username/ Password Combination");}            
        }
        else
            {
                die("Invalid Username/ Password Combination");
            }
    }
else
    {
            header('WWW-Authenticate: Basic realm="Restricted Section"');
                header('HTTP/1.0 401 Unauthorized');
                die("Please enter your username and password to Login");
    }
    $connection->close();
function mysql_entities_fix($connection,$var)
    {
        return htmlentities(mysql_entities_string($connection,$var));
    }
function mysql_entities_string($connection,$var)
    {
        if (get_magic_quotes_gpc()) $var = stripslahes($var);
        return $connection->real_escape_string($var);

    }
?>
  1. request(1)を送るとこんな感じ。

リクエスト(1)

 GET /ses3.php HTTP/1.1
 Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Linux i686;      rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
  1. 応答 (1) はログイン ページ (基本 HTTP 認証) です。

レスポンス(1)

HTTP/1.0 401 Unauthorized
Date: Sat, 28 Mar 2015 07:27:44 GMT
Server: Apache/2.2.22 (Debian)
X-Powered-By: PHP/5.4.36-0+deb7u3
WWW-Authenticate: Basic realm="Restricted Section"
Vary: Accept-Encoding
Content-Length: 48
Connection: close
Content-Type: text/html

Please enter your username and password to Login

----ここまで、セッション ID や Cookie の交換はありません。(私が間違っている場合は、プロンプトを表示しますか?)

  1. 私はユーザー名とパスワードで応答し、request(2) は

リクエスト(2)

GET /ses3.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0     Iceweasel/31.5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Authorization: Basic YnNtaXRoOm15c2VjcmV0

---- 上記のリクエストを転送すると、応答を転送する前に /var/lib/PHP5 でセッション ID: cl5mi7tbhdnobpv8kkau7thjo6 を受け取ったことがわかります(2)。これは、サーバーが同じものを作成し、応答で転送する準備ができているためです (2)

  1. 応答(2)は

レスポンス(2)

HTTP/1.1 200 OK
Date: Sat, 28 Mar 2015 07:36:13 GMT
Server: Apache/2.2.22 (Debian)
X-Powered-By: PHP/5.4.36-0+deb7u3
Set-Cookie: PHPSESSID=cl5mi7tbhdnobpv8kkau7thjo6; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-    revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 117
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

Bill Smith : Hi 'Bill' you are logged
                             in as 'bsmith'<p><a href = continue.php> CLICK HERE TO CONTINUE</a></p>

----SELECT * FROM moz_cookies を確認すると、クライアント m/c に保存されている Cookie が表示されません。では、彼らはどこで救われているのでしょうか? (これは私の最初の質問です)

  1. 次に、セッション変数「cl5mi7tbhdnobpv8kkau7thjo6」をサーバーから削除し、クライアントのブラウザーで再度更新ボタンを押しました。リクエスト(3)/レスポンス(3)は以下のとおりです

リクエスト(3)

GET /ses3.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: PHPSESSID=cl5mi7tbhdnobpv8kkau7thjo6
Authorization: Basic YnNtaXRoOm15c2VjcmV0
Connection: keep-alive
Cache-Control: max-age=0

レスポンス(3)

HTTP/1.1 200 OK
Date: Sat, 28 Mar 2015 07:50:01 GMT
Server: Apache/2.2.22 (Debian)
X-Powered-By: PHP/5.4.36-0+deb7u3
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 117
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

Bill Smith : Hi 'Bill' you are logged
                            in as 'bsmith'<p><a href = continue.php> CLICK   HERE TO CONTINUE</a></p>

-----これで、サーバーは /var/lib/PHP5 の下に設定された同じセッション変数を再び取得しました。サーバーはセッション変数を認識すべきではありませんか? また、保存された Cookie が原因でこれが発生している場合、なぜ moz_cookies テーブルの下でそれらを見ることができないのですか ..... 説明してください ?(これは私の 2 番目の質問です)

4

2 に答える 2

2

考慮すべきいくつかの項目:

  1. Cookie は、ディスクまたはメモリに保存できます。それらがどのように保存されるかは、ブラウザーの設定 (Firefox のプライベート ブラウジング モードなど) とサーバーの設定 (セッション処理に関する PHP ドキュメントを参照) によって異なります。

  2. HTTP 接続は、Keep-Alive ヘッダーを使用してキャッシュできます。

サーバー上のセッション ID をファイルに保存するように設定されているようですが、ブラウザの Cookie はファイルではなくメモリに保存されているため、PHP ファイルは表示されますが、Firefox の Cookie ファイルは表示されません。

ファイルを削除したにもかかわらず、サーバーがセッションIDを認識している理由については、PHPがセッションが認証されていることを認識しているため、サーバーのRAMにキャッシュする必要があるようです。(PHP の第一人者は、セッションの仕組みの詳細を記入できる場合があります)。

リクエスト 3 を受け取った後、PHP はセッション ID ファイルを探します。見つからない場合は、セッションが有効であることを認識しているため、ファイルを再度書き込みます。セッションを削除したい場合、PHP プログラマーは舞台裏でセッション ID ファイルを削除するのではなく、PHP でそれを行う必要があるため、これは予想される動作です。

クライアントがリクエスト 3 でセッション ID を送信したことに気付くでしょう。クライアントは各リクエストでセッション ID Cookie を送信しますが、サーバーはこのセッション中に Set-Cookie 命令で再度応答するべきではありません。ブラウザはセッション ID Cookie を保持し、リクエストごとにそれを送信できるようになったため、それ以上の認証は必要ありません。

この戦略の弱点は、セッション ハイジャックの可能性が残されている可能性があることです。攻撃者がブラウザーからセッション ID Cookie を取得できる場合、資格情報を使用してサーバーに対してコマンドを実行する可能性があります。

セッション ID の取得は、多くの要因によって、攻撃者にとって簡単な作業である場合とそうでない場合があります。たとえば、被害者のコンピューターが、攻撃者によって制御されるウイルスまたはその他のマルウェアに感染している場合、攻撃者はおそらくその時点で被害者のコンピューターを pwn し、セッション ID の取得など、何でも実行できます。他の攻撃では、クロスサイト スクリプティング ( XSS ) 攻撃を使用して、被害者のブラウザーをだましてセッション ID を漏らさせます。

XSS とセッション ハイジャックに対する特定の防御策がありますが、この問題もかなり複雑であり、詳細に調査する価値があります。たとえば、より安全なセッションでは、応答ごとに変更されるワンタイム トークンを使用できますが、その戦略は非同期 HTTP 呼び出しの使用によって複雑になる可能性があります。

于 2015-03-28T09:35:05.083 に答える
1

ここまで、セッション ID や Cookie の交換はありません。(私が間違っている場合は、プロンプトを表示しますか?)

いいえ、その通りです。ここまでsession_startは呼び出されていないため、交換するセッション Cookie はありません。

これで、サーバーは /var/lib/PHP5 の下に設定された同じセッション変数を再び取得しました。サーバーはセッション変数を認識すべきではありませんか?

おそらくそうすべきですが、そうではありません。何が起こっていると思いますか: クライアントがセッション ID を送信すると、サーバーはそれをまだ認識していなくても喜んで使用します。これは (理論的には) session fixationに使用できます。そのため、セッション内の何かが変更されるたびに ID を再生成することが推奨されます (実際には、デフォルトで にsession.use_trans_sid設定されているため、セッションの固定は問題になりません)。0

私が奇妙だと思うのは、データもまだそこにあるということです (私はこの動作を再現できませんでした)。私の推測では、実際にフォームを再送信していますか?

また、保存された Cookie が原因でこれが発生している場合、moz_cookies テーブルの下でそれらを確認できないのはなぜですか?

私の推測では、Cookie はまだブラウザのメモリに残っています。同じことを試しましたが、ブラウザ インターフェイスから Cookie を削除しましたか?

その他

これは単なるテスト スクリプトであることはわかっていますが、それでも次のようになります。

  • 単純なエスケープよりも、準備済みステートメントを使用することをお勧めします。
  • プレーンテキストのパスワードをセッションに保存しないでください)。
  • サニタイズされていないユーザー入力をエコーし​​ません。
  • ハッシュは、サイト固有ではなく、ユーザー固有にする必要があります。
  • htmlentities は、SQL インジェクションではなく XSS から保護するため、データをデータベースに挿入するときではなく、データをエコーするときに適用する必要があります。
于 2015-03-28T09:48:49.293 に答える