[Upload-labs] pass-09〜pass-12の詳細な説明
[Pass-09]フィルタリングロジックバイパス
1.ソースコード分析
#index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
$file_name = trim($_FILES['upload_file']['name']); //去除首尾空格
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.'); //取后缀名
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空
if (!in_array($file_ext, $deny_ext)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . '/' . $file_name;
$is_upload = true;
}
} else {
$msg = '此文件不允许上传';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
上記のコードからわかるように、以前のほとんどすべてのフィルタリングポスチャが使用されており、それをバイパスする方法はないようです。
ただし、コードを注意深く監査すると、元の秘密がdeldot()関数にあることがわかりました。
#common.php
<?php
function deldot($s){
for($i = strlen($s)-1;$i>0;$i--){
$c = substr($s,$i,1); //substr(string,start,length)第一个字符从0开始
if($i == strlen($s)-1 and $c != '.'){
return $s;
}
if($c != '.'){
return substr($s,0,$i+1);
}
}
}
?>
関数に問題はなく、ループチェックです。末尾がドットの場合は1ビット進み、ドットでない場合はその位置より前の文字列が取得されます。
ここでの抜け穴は、パラメーターがdeldot()関数を再度使用して、フィルターレイヤーの最後の最後のポイントを削除しないことです。
したがって、ファイル名を作成できますmuma.php. .
。つまり、phpの後にスペースとスペースを追加して、上記のコードをフィルタリングした.php.
後、ブラックリストを正常にバイパスし、Windows機能を使用しての末尾を自動的に削除します。ファイルを保存するときのサフィックス名ドットはapacheを正常に解析します。
2.テストプロセス
古いルールでは、最初にトロイの木馬ファイルをアップロードしてみてください。
げっぷを使用してパッケージをキャプチャし、サフィックス名を次のように変更します.php. .
再生、アップロードが成功しました!
アップロードされたファイルを表示する:
案の定、Windowsはphpの背後にあるドットを削除するのに非常に親密です。
包丁でつなぐだけ。
概要:
このレベルは、フィルタリングロジックの不適切な処理によって引き起こされる抜け穴であり、サフィックスポイントのループフィルタリングはありません。
[パス-10]二重書き込みバイパス
1.ソースコード分析
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");
$file_name = trim($_FILES['upload_file']['name']); //去除首尾空格
$file_name = str_ireplace($deny_ext,"", $file_name); //将黑名单中的字符串替换为空
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $file_name)) {
$img_path = $UPLOAD_ADDR . '/' .$file_name;
$is_upload = true;
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
上記のコードからわかるように、バックエンドによってアップロードされるファイル名のサフィックスは、ブラックリストに従って照合され、空のサフィックスに置き換えられます。これは置き換えであるため、サフィックス名を二重に書き込んでバイパスします。
2.テストプロセス
最初にアップロードしてみてください:
burpを使用してパッケージをキャプチャし、接尾辞phpを二重に書き込みます。
再生、アップロードが成功しました!しかし、接尾辞はhppに変更されましたか???どうしたの?
よく考えてください。置換ロジックは、前から後ろに置き換え、.phphpp
最初に前のphpを空に置き換え、次に残りを置き換えることです。hpp
したがって、二重書き込みの位置を変更し.pphphp
ます。これは問題ないはずです。
案の定!次に包丁でつなぎます。
概要:
このレベルのフィルタリングロジックは前のものとは異なり、機密性の高いサフィックス名を空に置き換えて、合法かどうかに関係なく正常にアップロードします。実際の開発と使用では、多数のジャンクファイルが生成されます。 、ストレージスペースを占有し、潜在的な可能性もあります。たとえば、脆弱性を含むファイルがある場合でも、トロイの木馬ファイルは悪用されます。
このレベルでは、機密性の高いサフィックスを一度に空のサフィックスに置き換えるだけなので、二重書き込みをバイパスできますが、二重書き込みの位置と置換の論理的な順序に注意してください。
[Pass-11] GET%00が切り捨てられました
1.ソースコード分析
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif'); //设置白名单
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1); //取后缀名
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext; //截断就在这里发生
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
}
else{
$msg = '上传失败!';
}
}
else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}
ここではホワイトリストメカニズムが使用されています。サフィックスがjpg、png、gifのいずれかである場合、ファイルの名前が変更されて保存されます。
2.テストプロセス
最初にphpファイルをアップロードすると、サフィックスがpng、jpg、gifのファイルのみがアップロードできることがわかりました。これに基づいて、ホワイトリストフィルターである必要があると判断されます。
げっぷを使用してパケットをキャプチャし、確認します。
図に示すように、アップロードされたファイルの保存パスがPOSTリクエストで送信されていることがわかります。これは、パスが制御可能であることを意味し、%00を使用してカットオフおよびバイパスを試みることができます。
%00とは何ですか?
%00はNULLの16進表現です。オペレーティングシステムがファイルを読み取るときにNULLが検出されると、ファイルが終了したと見なされ、次のコンテンツは読み取られなくなります。
%00切り捨てバイパス条件:
1.phpバージョンは5.3.4未満です
2、magic_quotes_gpc =オフ
magic_quotes_gpc(魔法の引用符スイッチ)関数、magic_quotes_gpc = Onの場合、phpの関数は、ユーザーによって要求されたデータを判断および解析することです。たとえば、post、get、Cookieからのデータの特殊文字( '、 "、\、NULL)エスケープするバックスラッシュを追加します。
%00切り捨てバイパスの原則:
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
このphpコードは、アップロードされたファイルが保存されるパスを設定するために使用されます。通常の状況では、パスは次のように設定されます。
../upload//随机数+时间qianxun.jpg
ただし、ファイルが保存されるパスが制御可能な場合は、パスを次のように変更できます。
../upload/1.php%00
次に、バックグラウンドスプライシングに渡すロジックは次のとおりです。
../upload/1.phpNULL/随机数+时间qianxun.jpg
ただし、切り捨てNULLのためにオペレーティングシステムが読み取る場合、
../upload/1.php
最大で読み取ることができます。この操作は、アップロードされたファイルqianxun.jpgを次のように保存するのと同じです。
../upload/1.php
qianxun.jpgは、サフィックスが変更されたトロイの木馬ファイルにすぎないため、現時点では、切り捨てバイパスのためにファイルの名前が1.phpに変更されているため、apacheで正常に解析できます。
行きましょう!!
../upload/1.php%00
再送信するパスを変更します。
結果はエラーでした。エラーメッセージを見ると、0がエスケープされていることがわかります。。。
magic_quotes_gpcがオンになっていることが原因である可能性があります。脆弱性を再現するには、php構成ファイルでmagic_quotes構成をoffに変更して保存し、apacheを再起動します。
再試行:
図に示すように、アップロードは成功しました!
アップロードされたファイルを表示する:
ブラウザを使用してファイルにアクセスします。
概要:
%00の切り捨てに使用されるシナリオ:
ほとんどの場合、テストはパッケージをキャプチャしてファイル名を変更することによって実行されます。ファイル名のサフィックスの最後に16進形式%00を追加します。例:filename = '1.php [null] .jpg'、ただしphp、
$FILES['file']['name']
ファイル名を取得すると切り取られてい1.php
たため、バックエンドif(in_array($file_ext,$ext_arr))
フィルタリングから逃れることができなくなりました。別の状況があります:
ファイル名がURLから取得され、ファイルがバックグラウンドで保存されている場合は、ファイル名が使用される
$_REQUEST['file_name']
か、$_GET['file_name']
ファイル名がパスの後ろでスプライスされます(例:$file_path="upload/".$_REQUEST['file_name'].rand(10,99).date("YmdHis").".".$file_ext;
現時点では、変更する必要があるのはurlパラメーターの値をfile_name =1.php%00.jpg
に設定し、トロイの木馬ファイルのサフィックスを直接アップロードします。jpgを変更します。バックエンドのロジックは、サフィックスが.jpgであるため、トロイの木馬の画像をホワイトリストでフィルタリングできることです。来ている。$_REQUEST['file_name']
得られた値がされた1.php%00.jpg
パスの後にスプライシングされたupload/1.php[null].jpg+随机数+时间+后缀名
。原因は、ヌルの切り捨てについては、最後に保存したファイルパスにupload/1.php
。これは、ピクチャーホースの名前を直接1.phpに変更するのと同じで、apacheが正常に解析できるようにします。別の状況:
これはこのレベルの場合であり、保存パスはURLから渡されるため、ユーザーは制御し、パスに%00を直接追加し、保存時に切り取ることができます。効果は同じです。
[パス-12] POST%00切り捨て
1.ソースコード分析
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
//将post传递的文件保存路径直接拼接到了最终的路径中
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
}
else{
$msg = "上传失败";
}
}
else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}
2.テストプロセス
トロイの木馬ファイルをアップロードします。
げっぷを使用してパケットをキャプチャします。
ファイルの保存パスがポストによって渡されていることがわかります。
%00の切り捨て方法を試してください。
+の16進数の2bをnullの16進数の00に変更し、Enterキーを押します。
このレベルのファイルのパスはPOSTリクエストを介して渡されるため、バックグラウンドが自動的にデコードされないため、%00を直接使用することはできません。したがって、16進形式で00を追加してください。
変更前 | 変更後 |
---|---|
パッケージが配置された後、図に示すようにアップロードは成功します!
チョッパーで接続します。
成功!
概要:
このレベルは前のレベルと同じですが、パスの受け渡し方法が異なります。つまり、00の形式が異なります。最後のレベルはGET送信であるため、%00が使用されます。このレベルはPOST送信であるため、16進形式の00が使用されます。
00切り捨てバイパスの可能性があるかどうかは判断できると思います。重要なのは、アップロードしたファイルがバックグラウンドで保存されるパスが、ファイル名か、渡された保存パスかを問わず、ユーザーが制御できるかどうかです。ユーザーによって、それが最終パスに直接接続されているかどうかにかかわらず、そうであれば、それは危険です。