哈希和加密的區別
哈希(Hash)與加密(Encrypt)兩者是完全同的概念,正確區別兩者是正確選擇和使用哈希與加密的基礎
哈希與加密最大的不同在於:
哈希將目標轉化成具有相同長度的、不可逆的雜湊字符串
而加密將目標轉化為不同長度的、可逆的密文,長度一般隨明文增長而增加
如果被保護數據僅僅用作比較驗證,在以后不需要還原成明文形式,則使用哈希;如果被保護數據在以后需要被還原成明文,則需要使用加密。
hash長度擴展攻擊是hash函數本身的一個算法缺陷攻擊,我門已經在前面研究了md5算法的加密過程。
我們從具體的題來對這個攻擊進行理解:
http://web.jarvisoj.com:32778/
首先對其進行目錄掃描,發現了index.php~ 這個是php的備份文件,但是無法直接打開,我們可以將其放在linux下,將其重新命名,並用vim -r index.php打開便成功恢復為php代碼。
代碼不長,我們來簡單進行審計下
?php
$auth = false;
$role = "guest";
$salt =
if (isset($_COOKIE["role"])) {
$role = unserialize($_COOKIE["role"]);
$hsh = $_COOKIE["hsh"];
if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) {
$auth = true;
} else {
$auth = false;
}
} else {
$s = serialize($role);
setcookie('role',$s);
$hsh = md5($salt.strrev($s));
setcookie('hsh',$hsh);
}
if ($auth) {
echo "<h3>Welcome Admin. Your flag is
} else {
echo "<h3>Only Admin can see the flag!!</h3>";
}
?>
可以看到$s為role,hsh為salt拼接$s的翻轉字符串,然后再進行md5加密,然后進行驗證
$auth = false;
$role = "guest";
$salt =
if (isset($_COOKIE["role"])) {
$role = unserialize($_COOKIE["role"]);
$hsh = $_COOKIE["hsh"];
if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) {
$auth = true;
} else {
$auth = false;
我們仔細看這段代碼通過cookie傳入的值,滿足role=admin很容易,我們直接在包里修改就可以了,但是因為不知道salt的值,我們無法滿足hsh=md5(salt+role),修改了role和hsh的值,無法滿足等式成立。
而服務器則將認證信息都存在用戶的瀏覽器的cookie里,而服務器只需保留salt的值便可以驗證用戶的身份了,但是這樣會存在哈希長度擴展攻擊,可以在不知道salt的情況下讓等式成立,成功成為管理員。
簡述一下這個哈希長度擴展攻擊的過程,我們先補充第一次的salt+身份信息的長度,使之符合MD5算法的要求,這一步服務器也是這么做的,只不過服務器將補足后的信息拿去運算,然后得到hash(記為hash1),返回給我們。但我們在補足長度之后再拼接上其他信息,比如admin,看看會發生什么。服務器會先進行之前一樣的運算得到hash1,用這個hash1再作為register,拿去加密后一個塊admin(這句話如果不明白再看看hash的原理),最終完成MD5(salt+role)得到一個值hash2與hsh比較。重點來了,現在MD5(salt+role)我們也可以完成,得到那個hash2了。可是我們不是不知道那個salt嗎?是的,這次服務器的MD5過程是從頭開始運算,到倒數第二步是用hash1去運算admin塊,最后得到hash2.
可我們知道hash1(第一次服務器正常的身份信息),和admin(我們自己加上的嘛),那么我們做一次hash1和admin的MD5運算不就得到hash2了嘛(不需要使用salt)。把hash2賦值給hsh,傳入就滿足了hsh=MD5(salt+role),相當於直接使用了第一次salt運算后的hash1來對hash2進行加密,這樣無需知道salt的值便可完成運算,完成身份驗證。
這道題的主體就是這樣,對於哈希長度擴展攻擊的防護也很簡單,只需要將用戶信息加在salt前面級就行了。因為hash是從前向后分塊進行運算的。
可以使用hashpump來進行這種攻擊
HashPump是一個借助於OpenSSL實現了針對多種散列函數的攻擊的工具,支持針對MD5、CRC32、SHA1、SHA256和SHA512等長度擴展攻擊。而MD2、SHA224和SHA384算法不受此攻擊的影響,因其部分避免了對狀態變量的輸出,並不輸出全部的狀態變量。
kali下安裝HashPump
git clone https://github.com/bwall/HashPump
apt-get install g++ libssl-dev
cd HashPump
make
make install
至於想在python里實現hashpump,可以使用hashpumpy這個插件:
(注意還是得先安裝了libssl-dev)
pip install hashpumpy
推薦在linux里使用,使用方法可以這樣獲取:
python
>>> import hashpumpy
>>> help(hashpumpy.hashpump)
直接用hashpump生成
將生成的新的md5通過cookie傳入,便成功成為管理員。