淺析history hack、心血漏洞、CSS欺騙、SQL注入與CSRF攻擊
漏洞產生的原因主要有系統機制和編碼規範兩方面,由於網路協議的開放性,目前以 Web 漏洞居多
關於系統機制漏洞的典型有JavaScript/CSS history hack,而編碼規範方面的漏洞典型有心血漏洞(Heart Bleed)。
在對漏洞概念有一定了解後,將搭建一個測試網站,對CSS欺騙、SQL注入與CSRF攻擊進行實驗測試。
JavaScript/CSS history hack 漏洞
漏洞影響:攻擊者能夠獲取使用者瀏覽器的某些歷史記錄。
攻擊原理:利用瀏覽器自動查詢歷史記錄,以及CSS對訪問過的和未訪問過超連結樣式的不同渲染。比如 百度 這個連結是紫色,因為你最近訪問過百度。而 自建CA證書搭建https伺服器 這個連結是黑色,因為你當前沒有訪問過我上一篇部落格。如果是紫色,刪除訪問歷史後重新整理會變成黑色。
攻擊方法:由於JavaScript可以讀取任何元素的CSS資訊,所以能分辨瀏覽器應用了哪種樣式從而判斷使用者是否訪問過該連結。攻擊者可以搭建自己的網站,在上面定義一些網站的超連結。當其他使用者訪問該網站時,瀏覽器會自動根據使用者的歷史記錄判斷哪些網址曾經訪問過,從而以不同顏色呈現給使用者。
攻擊者的網站後臺可以將使用者訪問過的網站發回給伺服器,達到的效果是能夠檢測使用者是否訪問過某個網站,但並不是直接獲取使用者訪問的歷史記錄。
該漏洞已被修復,如今雖然能夠看到對超連結狀態的不同顯示,但是js已無法獲取到其中的顏色差異。
Heart Bleed漏洞
又稱為心臟出血漏洞,編號(CVE-2014-0160)
漏洞由來:該漏洞由谷歌白帽子尼爾·梅塔(Neel Mehta)提出,他可從特定伺服器上隨機獲取64k的工作日誌,整個過程如同釣魚,攻擊可以一次次持續進行,大量敏感資料會洩露。
產生原因:編碼時未能在memcpy()呼叫使用者輸入的內容前,對長度進行邊界檢查。攻擊者可以輸入超出範圍的位元組,再返回等長的快取內容。
攻擊方法:
OpenSSL有一個叫 Heartbeat(心跳檢測)的拓展,所謂心跳檢測,就是建立一個 Client Hello 問詢來檢測對方伺服器是不是正常線上,伺服器發回 Server hello,表明SSL通訊正常。就像我們打電話時會問對方 “喂聽得到嗎?”一樣。
剛才測試超連結的部落格有關於SSL與https的介紹
每次問詢都會附加一個問詢的字元長度,如果這個字元長度大於實際的長度,伺服器仍是會返回相同規模的字元資訊,於是形成了記憶體裡資訊的越界訪問。
漏洞影響:每發起一個心跳,伺服器就能洩露一點點資料(理論上最多洩露 64K),這些資料裡可能包括使用者的登入賬號密碼、電子郵件甚至是加密金鑰等資訊,也可能並沒有包含這些資訊,但攻擊者可以不斷利用 “心跳”來獲取更多的資訊。就這樣,伺服器一點一點洩露越來越多的資訊,就像是心臟慢慢在出血,心臟出血的名字由此而來,漏洞目前已修復,但該漏洞被提出之前是否已被利用就不得而知。
以上是兩種型別漏洞的簡單介紹,以下將對CSS欺騙、SQL注入與CSRF攻擊進行實驗
CSS欺騙
正如名字一樣,CSS欺騙主要是作為一種欺騙手段,給瀏覽器使用者呈現出虛假資訊。
雖然是很簡單的手段,但是應用卻十分廣泛
欺騙原理:通過CSS定位方式和偽類,實現網頁內容覆蓋
html如人的骨骼,css是外表裝飾,js控制頁面的效果類似神經,CSS欺騙主要是利用CSS對頁面的渲染。
定位方式和偽類簡介
CSS對網頁元素的定位方式有以下四種:
- 靜態定位(static):所有元素的預設定位方式,可以將元素定位於靜態位置,所謂靜態位置就是各個元素在HTML文件流中預設的位置。
- 相對定位(relative):不脫離文件流,參考自身靜態位置通過 top,bottom,left,right定位,並且可以通過z-index進行層次分級。
- 絕對定位(absolute):脫離文件流,通過 top,bottom,left,right 選取其最近的父級元素定位,當父級 position 為 static 時,absolute元素將以body座標原點進行定位,可以通過z-index進行層次分級。
- 固定定位(fixed):所固定的物件是當前可視視窗(瀏覽器視窗)而並非是body或是父級元素,頁面滾動也不會移動,可通過z-index進行層次分級。
常用定位方式:子絕父相
- 當子元素是絕對定位時,父元素採用相對定位,這樣父容器既可以在原文件流中保留位置,子元素也能參照父容器絕對定位。
CSS偽類可以與 CSS 類配合使用,有anchor偽類、first-child偽類等。
如anchor偽類:
- a:link {color:#FF0000;} /* 未訪問的連結 */
- a:visited {color:#00FF00;} /* 已訪問的連結 */
- a:hover {color:#FF00FF;} /* 滑鼠劃過連結 */
- a:active {color:#0000FF;} /* 已選中的連結 */
欺騙案例:早年的淘寶店鋪裝修直接使用css控制頁面顯示效果,有商戶就此製作虛假店鋪資訊。
以下是2012年前後的一家店鋪資訊
圖中所呈現的資訊並非真實的店鋪資訊。
30天銷售量實際值為0,通過店鋪裝修時設定背景圖,呈現出了580件的字樣。
“購物須知”被背景圖偽裝成了 “優質商家 7天無理由退換”。
評價詳情與成交記錄同樣是使用背景圖進行虛假宣傳。
實際並沒有買家評價,只是添加了背景圖片。
為什麼說CSS欺騙雖然簡單但是應用廣泛?
就個人網頁瀏覽經歷而言,在4G之前或者4G剛開始那個時候,這種利用圖片做虛假頁面是很常見的。
最近一次是2018年雙十一時候,在某電商平臺申請退款,商家一直不理會,在平臺進行投訴時發現提交投訴的按鈕怎麼點都沒反應。一開始以為是手機顯示不相容,後來發現那個頁面下半部分是張圖片,提交按鈕只是圖片的一部分。
不過雙十一也可以理解,但是就大多數沒什麼計算機基礎的網民而言,CSS欺騙還是很有效的。
下面將會先介紹SQL注入,然後再將CSS欺騙與SQL注入結合,在搭建的測試網站上實現利用SQL注入前端程式碼進行CSS欺騙。
SQL注入
SQL注入即是指web應用程式對使用者輸入資料的合法性沒有判斷或過濾不嚴,攻擊者可以在web應用程式中事先定義好的查詢語句的結尾上新增額外的SQL語句,在管理員不知情的情況下實現非法操作,是目前最常見危險的漏洞之一。
SQL注入不是一個過期的安全問題,恰恰相反,它是一種非常容易被使用的攻擊方式,SQL注入並不需要高深的攻擊手段便可以輕易使敏感的資料庫資訊被非法瀏覽或刪除。
一般注入過程:
- SQL注入點探測。
通過適當的分析應用程式,判斷什麼地方存在SQL注入點。通常只要帶有輸入提交的動態網頁,並且動態網頁訪問資料庫,就可能存在SQL注入漏洞。 - 收集後臺資料庫資訊。
不同資料庫的注入方法、函式都不盡相同,在注入之前先要判斷一下資料庫的型別。可以輸入特殊字元如單引號,讓程式返回錯誤資訊,根據錯誤資訊提示進行判斷;還可以使用特定函式來判斷,比如輸入“1 and version()>0”,程式返回正常說明version()函式被資料庫識別並執行,而version()函式是MySQL特有的函式,因此可以推斷後臺數據庫為MySQL。 - 猜解使用者名稱和密碼。
資料庫中的表和欄位命名一般都是有規律的,通過構造特殊SQL語句在資料庫中依次猜解出表名、欄位名、欄位數、使用者名稱和密碼。
網站搭建與SQL注入測試
如果有簡單網站的搭建經驗,只需要理解了SQL注入的原理,就可以構建自己的測試。
下圖是搭建的測試網站的登陸介面:
先註冊一個userA的賬號並登入:
網站有三個簡單的頁面,分別是Home、Users、Transfer:
- Home: 顯示使用者的zoobars(當前網站使用者的虛擬貨幣)數量,設定使用者的個人簡介。
- Users:可以搜尋其他使用者並顯示使用者財富和簡介。
- Transfer:可以將自己的zoobars轉給其他使用者。
以下有兩種SQL注入可以使得自己的zoobars變多:
- 通過填寫個人簡介修改自己的zoobars,會改動資料庫zoobars數量
- 通過填寫個人簡介注入CSS程式碼,使得別人搜尋自己時zoobars看上去變多,不會改動資料庫zoobars數量
方法一
注入程式碼:
userA的個人簡介', Zoobars='20
儲存個人簡介後重新整理頁面,userA的zoobars變成了20,簡介顯示“userA的個人簡介”:
這種方法直接改動了資料庫資料,後臺更新個人簡介的php程式碼如下:
<?php
if($_POST['profile_submit']) { // Check for profile submission
$profile = $_POST['profile_update'];
$sql = "UPDATE Person SET Profile='$profile' ".
"WHERE PersonID=$user->id";
$db->executeQuery($sql); // Overwrite profile in database
}
$sql = "SELECT Profile FROM Person WHERE PersonID=$user->id";
$rs = $db->executeQuery($sql);
$rs = mysqli_fetch_array($rs);
echo $rs["Profile"];
?>
第4、5行的$sql值是資料庫要執行的語句,方法1使得實際執行的sql語句變成了:
UPDATE Person SET Profile='userA的個人簡介', Zoobars='20' WHERE PersonID=userA
方法二
由於場景不同,有時候會使用方法二注入,僅修改網頁的顯示進行CSS欺騙:
userA的zoobars數量是20,通過SQL注入前端程式碼,可以使得這個網站的使用者在搜尋userA時看到的數量為200,這裡為了方便觀察,欺騙的字型設定了紅色。
注入程式碼:
<span style="color:#000000;position:relative;left:60px;top:-54px;">0</span>
與之前介紹淘寶商家用CSS直接設定背景圖片不同,這裡是通過SQL注入在個人簡介裡寫了個相對定位的標籤,當網站使用者搜尋userA的個人簡介時,個人簡介裡的html程式碼會被瀏覽器解釋渲染成數字0,並顯示在zoobars數量的後面。
下面將介紹與瀏覽器機制相關的另一種攻擊方式。
CSRF攻擊
CSRF(Cross-site request forgery),即跨站請求偽造。
引誘瀏覽器使用者訪問自己的攻擊網站進行跨站訪問,通過瀏覽器儲存使用者原網站cookie的機制,在攻擊網站獲取使用者的身份許可權並偽造請求進行攻擊。
瀏覽器機制:
當用戶登入某一網站後,本地會儲存一份cookie用於身份認證,如果cookie沒有過期,就不需要反覆進行登入操作。
與JavaScript/CSS history hack不同的是,CSRF暫時無法像修改CSS或JS引擎那樣進行漏洞修補,因為目前的瀏覽器需要這種機制。
場景模擬:程式設計師登入部落格園瀏覽部落格,發現一篇不錯的部落格後打算分享到朋友圈,但第一次分享時網頁會要求先登入朋友圈。當登入分享成功後,沒過多久程式設計師又發現一篇不錯的部落格,打算再次分享,以此往復迴圈,瀏覽器會怎麼做?
目前瀏覽器的機制是會在第一次登陸後儲存使用者的cookie,使得使用者在有效期內不必反覆認證身份,所以後續的跨站不需要再登入。(沒有實際操作過,也可能部落格園分享每次都需要登入,只是舉個例子模擬網頁跨站情景)
瀏覽器儲存cookie的機制是需要的,但同時給了攻擊者可乘之機。
web中使用者身份驗證的漏洞:
簡單的身份驗證只能保證請求發自某個使用者的瀏覽器,卻不能保證請求本身是使用者自願發出的。
也就是說,使用者的瀏覽器傳送了一條請求,同時瀏覽器的cookie也能證明使用者身份,但是並不能保證這條請求是使用者主動在原網站上進行的操作。
以搭建的網站為例進行攻擊演示
攻擊步驟:
- 搭建一個網頁,用於偽造請求,請求內容是從被攻擊者的賬戶轉1個zoobar到自己賬戶
- 在攻擊者申請的網站賬戶裡,填寫個人簡介,SQL注入一個自己的網站連線
- 誘導其他使用者點選攻擊者賬號個人簡介上的網頁連結進行攻擊
搭建網頁
原網頁與程式碼:
Transfer介面點選Send按鈕會發送一條請求,執行轉賬操作。
攻擊者需要製作一個自己的網站,在網站上編寫攻擊操作。
這裡直接將原網站的介面程式碼複製了一份,然後Send的金額寫入預設值1,轉賬物件預設設定成攻擊者的userA賬戶,再通過JS程式碼讓網站在載入時自動執行Send按鈕的提交操作。
攻擊網頁與程式碼:
雖然看上去一樣,但是通過瀏覽器地址可以看出這個另一個網頁,用來模擬進行攻擊的網站。
然後在個人簡介裡注入一個超連結:
<a href="https://localhost/myzoo/send.php">點選獲取</a>
網址是攻擊者自己的網站
這時其他使用者搜尋userA時,會看到如下簡介:
目前userB的zoobars數量為9,如果點選一下這個連結,會跳轉到攻擊者網站並自動給userA轉一個zoobar,之後userA的數量變成21個,userB只剩下8個。
攻擊實際上就是通過使用者瀏覽器儲存的cookie認證,偽造出使用者請求。
應對CSRF攻擊的方法有很多,有一種是可以通過檢查請求的Referer欄位判斷請求的來源網站,不過這是一個攻防的過程,攻擊者也有可能進一步攻擊篡改Referer欄位。
小結
- JavaScript/CSS history hack
利用了瀏覽器為了方便使用者瀏覽而查詢歷史記錄的機制漏洞,已通過完善CSS/JS修補。 - 心血漏洞
程式碼不規範引起的資料洩露漏洞,已被修補。 - CSS欺騙
常用的欺騙技術,需要根據特定場景結合其他攻擊方式。 - SQL注入
最常見安全漏洞之一,資料洩露的主要原因之一,安全風險較高,一定程度上超過緩衝區溢位漏洞,只能儘量避免。 - 跨站請求偽造
利用瀏覽器的機制漏洞,無法直接根治,與SQL注入一樣是個攻防的過程。