打破SSS的技術封鎖

作者:彭碩 文章來源:黑客防線
最近實在是忙得不亦樂乎,一邊埋頭整理開學要上交的網絡安全研究課題,一邊在網上清理惡意網站。我的愛機也跟着我連軸轉,沒有多少休息的時間(還好我的機器是雙Xeon的服務器,哈哈)。一天突然要用到SSS,立刻到黑白網絡上Down了一個下來。結果一註冊傻眼了,這個SSS 7.30竟然用上了網絡認證,註冊機生成的註冊文件根本沒法通過認證。忽然想起了05年《黑客在線》上有一個文章介紹SSS,翻來看看。這不看還好,看完了我差點沒從6樓跳下去。雜誌上面寫着:“面對SSS無法破解的問題,小編採用虛擬機恢復大法……”我真的絕望了,看來N多的高人已經對這個SSS束手無策,我還能做什麼呢?難道就只能這樣了嗎?
不過,我就是不信邪,非得要把這個SSS破掉不可。爆破?不太可能。其它的方法呢?我又不會(檢討一下,當年破解沒學好)。乾脆順水推舟,由着SSS來算了。

靈巧的破解

首先,咱們還是老方法,用註冊機生成一個註冊文件。這個註冊文件不是萬能的,但是沒有它是萬萬不能的。填寫註冊信息,按Generate就OK了。
好了,我們先不管它,讓它一邊涼快去(蝴蝶:不管它你生成它做什麼?欠扁……),不是這個意思,等一會才能用到它啦。
在下一步之前,必須說一個東西:host文件。這個文件大家不會不知道吧?它的功能就是替代DNS進行域名解析,以便達到快速訪問的目的,而且它在查詢中的優先權要比網絡上的任何DNS服務器都高。所以,只要改host文件,就可以“綁架”域名了。有很多朋友的機器,就算輸入了正確的網址,也會上一些惡意網站,多半是這個文件被修改了的原因。需要注意,這個文件沒有後綴名,位於%windir%/system32/drivers/etc下(Windows 2000/XP/2003系統),我們用記事本把這個文件打開,在裏面加入這麼一行:
127.0.0.1 www.safety-lab.com
這個www.safety-lab.com是SSS的官方站點,我們這麼做就是爲了欺騙SSS,讓它連接到自己的機器上。因爲經過我的Sniffer抓包發現,SSS在認證註冊的時候,向http://www.safety-lab.com/update/db/keys.php提交了用戶數據,並且在驗證失敗的時候,服務器端返回了一個1。有經驗的朋友一眼就能看出來,SSS應該就是靠這個返回值來判斷用戶是否合法。也就是說,只要讓這個值變成0,我們就可以成功註冊了。
有人會問了,你怎麼知道返回0,就是註冊成功呢?不可能是別的數字嗎?其實這個我也是猜一半,用社會工程學推導一半。其實,有時玩黑客並不一定只需要技術,還需要那麼一點點的運氣。
我們先來架設一個Web服務器,既然大家都是Windows用戶,就用IIS好了(以下配置IIS的過程是在2003系統下實現的,2000/XP可能有所不同,請參考相關資料)。進入站點的屬性—〉主目錄—〉配置—〉映射,爲.dat,.pl和.php三種後綴的文件添加映射。可執行文件框裏,你的.asp文件是怎麼設置的,不動就行。
這樣做的目的是讓這三種後綴名的文件,在IIS中都可以被當作ASP文件執行。其實,用別的語言實現也可以的,不過筆者只會ASP,沒辦法。設置好映射,我們來做幾個文件,“忽悠忽悠”SSS。
最要緊的就是先註冊了,否則什麼功能也不能用。我們來分析一下這個keys.php的代碼(其實是asp語言,這個keys.php在IIS中是被當成asp執行的):
[以下代碼在keys.php中]
<%
Dim crc,name,founder ‘定義幾個變量
founderr=true '爲了防止程序出錯,把控制錯誤的變量設爲true
if request("crc")<>"" and request("name")<>"" then
founderr=false
end if

if founderr=false then
response.write "<html><body>0" '如果有輸入,就返回一個值
response.end
end if

if founderr=true then
response.write "<html><body>1" '處理意外情況,防止SSS收不到返回值而掛掉。
response.end
end if
%>
這段代碼很簡單,只接受SSS發送上來的CRC和NAME兩個變量,並返回一個值。大家可能看出來了,這個返回值<html>和<body>標籤並沒有結束,其實這不需要結束。因爲我分過析Sniffer抓到的完整的數據包,發現就是這樣的。也許是Safety-Lab故意做的一個陷阱吧,管他呢,能註冊就OK。
我們的host文件不是已經改好了嗎?那就把以上的代碼保存成keys.php,放到你的IIS根目錄下的/update/db/下(如果你的IIS根目錄在E:/inetpub/wwwroot/,就放在E:/inetpub/wwwroot/update/db/)。然後我們打開SSS,導入註冊文件,點擊Done,看看,這不就完事了?

不過,單單破解,並不能滿足我們的要求。如果現在你用在線升級,仍然會失敗。而且還會把你剛註冊上去的授權撤銷。那怎麼辦呢?嘿嘿,接着往後看不就知道了?

破了軟件不能升級,那就跟用D版XP一個感覺——很不爽。所以,又花了點功夫,把升級的限制也解除了,雖然不是很完善,但確實可以檢測升級了。
還是老方法,用Sinffer把升級過程的包抓下來,分析一下。我們看到SSS的升級程序訪問了以下頁面:(前面都是http://www.safety-lab.com/,省略)
/update/db/keys.php 還是驗證身份,陰險……
/update/sss/update.dat 這是一個數據文件(功能未知);
/update/db/getdbaudits.pl 一個數據引導文件,用於生成更新列表。
先拿出來分析,然後各個擊破。這個keys.php剛纔講過了,我就不說了。update.dat文件好像是一個引索文件,據我的觀察,它還是在變動的,但是它卻是沒有經過服務器的解析,可以直接下載下來,但爲了保持數據最新,我們還是用動態的方法來處理吧。先看一段代碼吧:
[以下代碼在update.dat中]
<%
On error resume next '沒別的意思,防止出錯而以
Dim sURL

Dim Retrieval

Function GetURL(url)
Set Retrieval = Server.CreateObject("Microsoft.XMLHTTP")
With Retrieval
.Open "GET", url, False, "", ""
.Send
GetURL = .ResponseText
End With

Response.BinaryWrite retrieval.responseBody '輸出二進制到瀏覽器
Set Retrieval = Nothing
End Function

sURL = "http://safety-lab.com/update/sss/update.dat" '這個是要獲取地址
Response.Write GetURL(sURl)
%>
這是ASP編程中很經典的一個函數的應用。這個頁面的作用就是讓IIS到另一個站點,取得一個頁面,然後傳回客戶端。假設這個存在於主機A上的頁面指向的是主機B上的內容,但是主機A的客戶通過訪問這個頁面,就可以在主機A上看見主機B上的東西。但是,這個和普通網頁中用JavaScript實現的頁面重定向是不同的:JavaScript是讓客戶端重新定向,這個是以IIS爲中介的服務器的重定向。
尤其是針對程序請求的頁面的時候。因爲程序不會識別那些由JavaScript語言組成的重定向語句,而這樣的方法則不需要客戶端的支持。哦,差點忘了一個事情,如果你的機器上有類似VisNetic Firewall一類的帶有IDS功能的防火牆,把它關閉,否則會出錯的。我當時調試的時候,這個update.dat怎麼訪問都有問題,後來發現是VisNetic的過濾功能把請求給過濾了。
再來看另外一個文件代碼:
[以下代碼在getdbaudits.pl中]
<%
On error resume next
Dim outformat,sURL
outformat=request("outformat")

Dim Retrieval

Function GetURL(url)
Set Retrieval = Server.CreateObject("Microsoft.XMLHTTP")
With Retrieval
.Open "GET", url, False, "", ""
.Send
GetURL = .ResponseText
End With
Response.BinaryWrite retrieval.responseBody '輸出二進制到瀏覽器
Set Retrieval = Nothing
End Function

sURL = "http://safety-lab.com/update/db/getdbaudits.pl?outformat=" & outformat
Response.Write GetURL(sURl)
%>

這個文件和上一個文件是大同小異,只不過多了一個對變量的處理而已。明白ASP的朋友一眼就能看出來,不太清楚的,向高人討教一下吧。這個頁面請求的應該是更新列表,不過不算太大,全部返回的數據也就有8-10KB。我們很快就能看到結果。
看見了吧?這就得到了更新列表了。我猜有很多人可能馬上就要去點擊那個Next按鈕了吧?彆着急,這裏有問題需要處理。先兜個圈子,給大家說說我原來的思路,以下的過程僅僅是概念講解,大家無需跟着操作。
我仍然是採用了Sniffer抓包的方法,看到升級程序訪問了/update/db/getaudits.pl文件,而且後面足足跟了有825個字符的變量!我不在文章裏列出來了,免得佔用空間(詳見光盤:數據.txt)。這些變量雖然多,但是交給程序處理還是遊刃有餘的。於是乎,我寫了一個對應的頁面:
[以下代碼在getaudits.pl中]
<%
On error resume next
Dim outformat,sURL
outformat=Request.ServerVariables("Query_String")
'註釋: Request.ServerVariables("Query_String")用於獲得url中?後面的東西
Dim Retrieval
Response.Buffer = True
Function GetURL(url)

Set Retrieval = Server.CreateObject("Microsoft.XMLHTTP")
With Retrieval
.Open "GET", url, False, "", ""
.Send
GetURL = .ResponseText
End With

Response.BinaryWrite retrieval.responseBody '輸出二進制到瀏覽器
Set Retrieval = Nothing
End Function

sURL = "http://safety-lab.com/update/db/getaudits.pl?" & outformat
Response.Write GetURL(sURl)
%>
這個頁面是用來下載更新數據的。由於這個請求的頁面沒有變量名稱,網頁後邊直接加數據,我也很爲難。後來上網查找資料,原來用Request.ServerVariables("Query_String")就可以直接獲取“?”後面的東西了。從理論上講,這個頁面能完全返回升級程序需要的數據,但是理論總是有和實際脫離的地方。
SSS的升級程序爲了防止網絡故障而讓程序長時間失去響應,設置了一個連接超時時間,大概在10秒鐘左右。Safety-Lab.com是俄羅斯的網站,而且要下載的數據,動不動就要幾百KB,以目前的連接速度,根本無法在10秒內完成下載(我用的可是2M的網通ADSL),這個頁面還不支持所謂的即時傳遞數據(就是下一點,傳一點),等IIS把所有的數據從Safety-Lab.com下載回來的時候,SSS的升級程序早就Timed Out了。當然,有連接俄羅斯網站速度超快的朋友,也可以用這個方法。
那我們怎麼辦?辦法是有的。後來我發現,訪問Safety-Lab上的getaudits.pl是不需要授權的。怎麼樣?想到了沒有?在升級程序出現更新列表的時候(如圖4),在host文件“127.0.0.1 www.safety-lab.com”的前面加上一個“#”(沒有引號),這樣Windows就會忽略這行內容了。接着,點擊Next,就可以下載升級數據了。
可能有的朋友看過文章會注意到我所有頁面裏的轉向地址都寫的是:http://safety-lab.com/。大家感覺這個地址與前面有www的地址是一樣的,可那時在通過DNS解析的時候,在host文件裏即使差一個字符也不行的。我們在host文件裏,設置的是http://www.safety-lab.com/解析到本地,並不等於http://safety-lab.com/也解析到本地。另外強調一點,SSS一般把升級數據下載到C:/Program Files/Common Files/Safety-lab/Download,你到SSS的安裝目錄是找不到的。

最後,我做對一些常見的問題做出解答,也方便大家參考。
問:我的.dat(或.pl,.php)爲什麼無法執行,或者只看到源文件?
答:沒有給以上的文件在IIS中設置映射。把以上三種後綴名的映射,都設置成與.asp文件的映射一樣,就可以了。如果你的IIS是6.0,請在Web服務擴展中開啓asp支持。

問:我其它的設置完全正確,但是升級程序提示“Download Error, HTTP Error Disconnect server”是怎麼回事?
答:由於safety-Lab.com是境外網站,訪問並不一定暢通。連接失敗是時有發生的事情,請再試一次或者斷線重連。另外,請檢查防火牆是否限制了IIS進程(w3wp.exe)訪問網絡。

問:爲什麼我無法註冊SSS?爲什麼我一更新就提示我的註冊無效?
答:這是因爲你沒有修改host文件造成的。按照上文修改host文件,並在升級程序顯示更新列表後(如圖4所示)再改回來。


到此爲止,一個在業界內擁有相當高的評價的掃描器,就已經被完全破解了。真是很難理解,一款在反破解上下了大功夫的安全審計軟件,卻栽在這樣的小技巧下(我記得MS的程序員管這個叫Hack)。我想,這也就是WTF說的“靈活的入侵思維”吧。其實,按照這個思路走下去,很多帶有網絡註冊認證功能,一度被認爲是“無法破解”的軟件,也可以輕易地解除使用限制。

實用的防護
上面我已經講述瞭如何利用Web註冊認證的缺陷破解軟件,我們也見識到了針對Web註冊認證這種新興註冊手段的攻擊方法。在下面的文章中,我來和大家談談怎樣才能堵住Web註冊上的缺口(以下文章中的代碼實例,完全用ASP語言實現)。
從上文的事例看,判斷註冊信息合法性並返回一個值的Keys.php文件的頁面,在設計存在一個很嚴重的邏輯錯誤。該設計者最可能的想法是這樣的:
[以下代碼在keys.asp中]
<!--#include file="conn.asp"-->
<%
Dim CRC,Name,err
err=true

if request("crc")<>"" and request("name")<>"" then
crc=request("crc")
name=request("name")
err=false
end if

if Not IsNumeric(crc) or Not IsNumeric(name)then
err=true
response.write "<html><body>1"
response.end
end if

if err=false then
Set rs=Server.CreateObject("ADODB.Recordset")
sql="select * from users where ucrc="&crc &" and uname = " & name '我們假設name和crc的數據都存儲在數據庫中
rs.open sql,conn,1,1
if rs("id")="" then
response.write "<html><body>1"
response.end
else
response.write "<html><body>0"
response.end
end if
end if
%>
一切看起來似乎很完美了吧?我所實現的其實可能還不如人家,不過你還是可以看到過濾SQL Injection攻擊的語句。但是,作爲判斷標示符返回的兩個結果,0和1就是非常不恰當的選擇了。一般有經驗的攻擊者,在得到錯誤時返回的“1”後,很自然地就會聯想到正確的時候會返回“1”,這樣,這道網絡認證的保護就是形同虛設了。
最好的辦法就是:首先,必須修改你的程序,不要讓它僅僅靠判斷返回的是“0”還是“1”來判斷用戶是否合法。你可以給程序添加一個模塊,把Web驗證服務器的返回信息處理一下,如果能和用戶提交的信息形成某種特定的關係,就判斷爲合法用戶,反之則爲非法。
其次,你的Web驗證服務器端的頁面,也必須做更改。你的Web驗證服務器,可以按照以下步驟處理用戶提交的信息:
1. 把用戶提交的信息放到數據庫中查詢;
2. 如果查詢不到相關的數據,則直接返回一個失敗代碼(如“1”);
3. 如果查詢成功,則把用戶提交的數據做一個處理,並返回給客戶端;
4. 爲了防止用戶濫用正版註冊號,每個註冊號應設定一個註冊次數限制(如10次)。
最後,你需要給你的軟件加以強大的反破解保護,讓一般的Cracker根本對你的軟件無從下手。否則,就算你的Web註冊認證如何嚴密,都毫無意義了。因爲,Cracker會直接通過修改程序,跳過你的Web註冊認證。
另外,升級也是一個需要保護的地方。你可以把上邊驗證用戶的代碼,添加到顯示更新列表的程序裏,這樣既不會佔用你太多的資源,又可以阻止非授權的用戶獲取更新列表。客戶的升級程序,在獲得升級列表之前,也向驗證服務器遞交一下用戶的身份信息。
其實,按照我上面所述的方法來看,實現並不十分複雜。這裏面也沒有太深奧的技術可言。不過,就是這一點點的小技巧,也可以爲難住一大批想要吃白飯的人呢(我可不是指研究破解的同行)。

 

 

 

 

----------------------------------------------

注:

 

此文其實是一個很好的思路,而不只是對SSS的一個突破。當年看完這篇文章後,就想到利用它的這種腳本的工作方式,實現代理訪問學校內部網站來實現查考試成績的功能(PS:學校查成績的網站是內部可訪問的,不對外。)。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章