彼は、PHP-監査-Labsのコード監査Day15の練習の[赤]チームに始まった
リンク:https://github.com/hongriSec/PHP-Audit-Labs
練習に行くことができます興味のある学生
予備知識:
コンテンツのタイトルが来るPHPセキュリティ2017 CALENDAR
15日-次のようにそりコードは次のとおりです。
class Redirect {
private $websiteHost = 'www.example.com';
private function setHeaders($url) {
$url = urldecode($url);
header("Location: $url");
}
public function startRedirect($params) {
$parts = explode('/', $_SERVER['PHP_SELF']);
$baseFile = end($parts);
$url = sprintf(
"%s?%s",
$baseFile,
http_build_query($params)
);
$this->setHeaders($url);
}
}
if ($_GET['redirect']) {
(new Redirect())->startRedirect($_GET['params']);
}
脆弱性分析:
これは、メインの捜査から外れている$_SERVER['PHP_SELF']
任意のURLの脆弱性へのジャンプによってトリガ
まず、プログラムを実行します
- ある場合
$_GET['redirect']
のパラメータは、その後、New 一个 Redirect
オブジェクト、および呼び出すRedirect
クラスのstartRedirect
メソッドを startRedirect
機能受け付けるGET
型params
次いで、パラメータをexplode()
関数$_SERVER['PHP_SELF']
とした値/
に分割$parts
アレイ。$baseFile
値は$parts
、配列の最後の値$url
値が$baseFile?http_build_query($params)
前記http_build_query()
関数はにパラメータでURL
符号化動作、など$params='test=123'
- 次に呼び出す
setHeaders
機能を、第1の復号$url
パラメータは、header()
機能に直接ジャンプ$url
$_SERVER['PHP']
問題:
一見すると、このプログラムは問題なく、それPHPのが付属して
$_SERVER['PHP_SELF']
パラメータを制御することができます。
これはPHP_SELF
、現在のページの絶対アドレスを指します。
例えば、当社のウェブサイト:http://www.test.com/redict/index.php
、
それはPHP_SELF
あります/redict/index.php
。しかし、多くの人が気付かなかった小さな問題があります。
ときにURL
されPATH_INFO
、例えば時間:http://www.test.com/redict/index.php/admin
そして、PHP_SELF
それは/redict/index.php/admin
言って、実際には、PHP_SELF
我々がコントロールできるという部分があります。
デュアルコーディング問題:
URL
元々 、ブラウザによって编码
サーバは、ブラウザのURLからの要求を受信したとき、う、一度URL解码
一度我々はプログラムで見るのでurldecode()
機能が存在し、それが再びだろう解码一次URL
、この時間は、二重コーディングURL
缶を使用し、バイパスするための特定のキーワードを検出します。例えば、/
(2回符号化された)など。%252f
エクスプロイト:
例えば、我々はにジャンプしたい:baidu.com
、それを構成することができるPayload :http://10.211.55.5/phpcode/day15/url.php/http:%252f%252fbaidu.com?redirect=test¶ms=test123
リダイレクトするようにジャンプして、アクセスをhttps://www.baidu.com/
URLを。以下に示すように、ジャンプが302を発生しました:
ケーススタディ:
ケーススタディでは、我々がした選択しました
360webscan 的防护脚本一个历史漏洞
。
セキュリティツールを提供するために、脆弱性のPOCサイト、手続き(メソッド)のみご自身の責任で安全研究と教育の目的のために、攻撃運ぶことができます!
脆弱性分析:
これは、使用して$_SERVER['PHP_SELF']
バイパスにつながる、この変数を360webscan
、スクリプトの保護シールドの保護効果をスクリプトが失敗し、この保護は今スクリプトを更新します。
その構造は次のとおりです。
因为这只是一个防护的辅助脚本,任何的程序都可以安装使用,这里就以 Emlog5.3.1
(百度网盘 密码: hkb4)博客程序为例子,程序不重要,这个脚本可以安装接入到任何的程序中。
因为这只是一个防护的辅助脚本,任何的程序都可以安装使用,这里就以 Emlog5.3.1
博客程序为例子,程序不重要,这个脚本可以安装接入到任何的程序中。安装的方法:解压得到 360safe 文件夹,之后上传到我们的网站根目录中,同时在任意的全局文件中加入如下代码即可安装成功:
if(is_file($_SERVER['DOCUMENT_ROOT'].'/360safe/360webscan.php')){
require_once($_SERVER['DOCUMENT_ROOT'].'/360safe/360webscan.php');
}
在按照上述安装方法安装后,测试访问:http://www.test.com/index.php?test=<script>alert(1)</script>
,XSS拦截显示:
比如GET
传递的数据存在SQL
注入恶意字符都会被拦截,虽然本脚本的正则过滤规则很好了,但是通过这一个$_SERVER['PHP_SELF']
,可以通过白名单规则绕过攻击防护。
在存在绕过漏洞的360webscan历史版本中,如下 第198-218行
的的代码(拦截目录白名单检测):
function webscan_white($webscan_white_name,$webscan_white_url=array()) {
$url_path=$_SERVER['PHP_SELF'];
$url_var=$_SERVER['QUERY_STRING'];
if (preg_match("/".$webscan_white_name."/is",$url_path)==1&&!empty($webscan_white_name)) {
return false;
}
foreach ($webscan_white_url as $key => $value) {
if(!empty($url_var)&&!empty($value)){
if (stristr($url_path,$key)&&stristr($url_var,$value)) {
return false;
}
}
elseif (empty($url_var)&&empty($value)) {
if (stristr($url_path,$key)) {
return false;
}
}
}
return true;
}
在上图的 第2行
,我们看到 $url_path
的值是直接取的$_server['PHP_SELF']
的值,同时没有做任何的验证或过滤。那么我们只要在请求的URL(提交的参数中)
存在白名单目录,那么就可以绕过安全检测。
因为在 webscan_cache.php
中的默认的白名单目录存在 admin
。
漏洞利用:
然后我们访问:http://www.test.com/index.php/admin?test=<script>alert(1)</script>
此处虽然返回的状态码是 404
,但是,我们发现已经不再拦截了,如果再配合某些CMS
或者PHP系统的伪静态特殊性,那么就可以成功的绕过防护。
修复建议:
監査は、実際には抜け穴ない主要で$_SERVER['PHP_SELF']
問題、次いでこのように形成された抜け穴の各種につながる擬似静的ルールのカテゴリーの場合に遭遇します。だから、ここで推奨され$_SERVER['SCRIPT_NAME']
、同時に、我々は最新見ることができることができる場所に360webscan
更新されている問題では、使用しています$_SERVER['SCRIPT_NAME']
。
エピローグ
おかげで再び[赤チーム]