日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

宽字节注入和防御

發布時間:2024/3/13 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 宽字节注入和防御 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

0、前言

最近要為了自動化審計搜集所有PHP漏洞,在整理注入的時候,發現寬字節注入中使用iconv造成的漏洞原理沒有真正搞懂,網上的文章也說得不是很清楚,于是看了榮哥(lxsec)以前發的一篇http://www.91ri.org/8611.html,加上我們兩個人的討論,最終有了這一篇深入的研究成果。

?

1、概述

主要是由于使用了寬字節編碼造成的。,典型情景是網站使用GBK編碼,數據庫使用UTF-8編碼

什么是字符集?

計算機顯示的字符圖形與保存該字符時的二進制編碼的映射關系。

如ASCII中,A(圖形)對應編碼01000001(65)。

對于MYSQL數據庫來說,涉及字符集的地方大致分為存儲和傳輸時,即:

(1)存儲在服務器端的數據是何種編碼

(2)客戶端和服務器交互的時候數據傳輸使用的編碼。

?

2、MYSQL服務器端存儲字符集

在MYSQL服務器端進行數據存儲時,允許在以下的級別設置字符集:

(1)服務器端字符集(character_set_server)

(2)庫字符集

(3)表字符集

(4)字段字符集

優先級為:字段----->表------->庫-------->服務器

對應的語法是:

Create table test( name varchar(20) charset gbk, number varchar(10), age int )engine=innodb charset=utf-8 ;

?

?

3、客戶端與服務器交互數據傳輸的字符集

存儲時的字符集已經確定了,不會影響交互階段的字符集。

在MYSQL中,還有一個中間層的結構,負責客戶端和服務器之間的連接,所以稱為連接層。

交互的過程如下:

(1)客戶端以某種字符集生成的SQL語句發送至服務器端,這個“某種字符集”其實是任意規定的,PHP作為客戶端連接MYSQL時,這個字符集就是PHP文件默認的編碼。

(2)服務器會將這個SQL語句轉為連接層的字符集。問題在于MYSQL是怎么知道我們傳過來的這個SQL語句是什么編碼呢?這時主要依靠兩個MYSQL的內部變量來表示,一個是character_set_client(客戶端的字符集)和character_set_connection(連接層的字符集)。可以使用show?variables?like?‘character_set_%’?;進行查看。

可以看到,這里的客戶端字符集為GBK,連接層字符集也是為GBK。

兩者相同,就不會有問題,如果不一致,就會出現亂碼問題了。

使用MYSQL中的set命令可以對這些內部變量做設置,如修改客戶端編碼為UTF-8;

set?character_set_client?=?UTF-8

(1)服務器將轉換好的SQL語句,轉為服務器內部編碼與存儲在服務器上的數據進行交互

(2)服務器處理完之后,將結果返回給客戶端,還是轉為服務器認為客戶端可以認識的編碼,如上圖的GBK,使用character_set_results來確定返回客戶端的編碼。

平時在PHP中寫的set?names?UTF-8相當于下面三條同時執行:

(1)set?character_set_client?=?UTF-8

(2)set?character_set_connection?=?UTF-8

(3)set?character_set_results?=?UTF-8

?

4、亂碼問題原理

設置三個字符集相同,這也就不會出現亂碼的真正原理。網頁上有時會出現亂碼是因為PHP動態文件將數據打印到瀏覽器的時候,瀏覽器也會按照一定的字符集進行判斷,如果PHP的響應數據編碼和瀏覽器編碼一致,就不會出現亂碼,否則就出現亂碼。可以通過在PHP中使用header()來指定這個響應數據的編碼。

?

5、寬字節注入原理

有三種形式:

(1)情景一:在PHP中使用mysql_query(“set?names?GBK”);指定三個字符集(客戶端、連接層、結果集)都是GBK編碼。

情景代碼:?

?

mysql_query(“set names GBK”); $bar = addslashes($_GET[‘bar’]) ; $sql = “select password from user where bar=’{$bar}’”; $res = mysql_query($sql) ;

?

?

提交:http://127.0.0.1/foo.php?bar=admin%df%27

這時,發生如下轉換:

%df%27=====(addslashes)======>%df%5c%27======(GBK)======>運’

帶入sql為:

Select?password?from?user?where?bar=‘運’

成功將單引號閉合。為了避免漏洞,網站一般會設置UTF-8編碼,然后進行轉義過濾。但是由于一些不經意的字符集轉換,又會導致漏洞。

?

(2)情景二:

使用set?names?UTF-8指定了UTF-8字符集,并且也使用轉義函數進行轉義。有時候,為了避免亂碼,會將一些用戶提交的GBK字符使用iconv函數(或者mb_convert_encoding)先轉為UTF-8,然后再拼接入SQL語句。

情景代碼:

?

mysql_query(“set names UTF-8”) ; $bar =iconv(“GBK”,”UTF-8”, addslashes($_GET[‘’bar])) ; $sql = “select password from user where bar=’{$bar}’” ; $res = mysql_query($sql) ;

?

?

?

我們可以看到,為了使得SQL語句中的字符集保持一致,一般都會使用iconv等字符集轉換函數進行字符集轉換,問題就是出在了GBK向UTF-8轉換的過程中。

提交:http://127.0.0.1/foo.php?bar=%e5%5c%27

變換過程:(e55c轉為UTF-8為e98ca6)

e55c27====(addslashes)====>e55c5c5c27====(iconv)====>e98ca65c5c27

可以看到,多出了一個5c,將轉義符(反斜杠)本身轉義,使得后面的%27發揮了作用。

測試如下:



?

(3)情景三:使用iconv進行字符集轉換,將UTF-8轉為GBK,同時,set?names字符集為GBK。提交%e9%8c%a6即可。

這個情景的大前提是先編碼后轉義:

e98ca6====(iconv)=====>e55c=====(addslashes)====>e55c5c

同樣可以多出一個反斜杠進行利用,在此不再詳述,因為漏洞條件比較苛刻。

?

?

6、安全方案

對于寬字節編碼,有一種最好的修補就是:

(1)使用mysql_set_charset(GBK)指定字符集

(2)使用mysql_real_escape_string進行轉義

原理是,mysql_real_escape_string與addslashes的不同之處在于其會考慮當前設置的字符集,不會出現前面e5和5c拼接為一個寬字節的問題,但是這個“當前字符集”如何確定呢?

就是使用mysql_set_charset進行指定。

上述的兩個條件是“與”運算的關系,少一條都不行。

測試;

輸出:

?

?

轉自http://write.blog.csdn.net/postedit/42874517

?

轉載于:https://www.cnblogs.com/drkang/p/8644435.html

總結

以上是生活随笔為你收集整理的宽字节注入和防御的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。