原文鏈接:http://netsecurity.51cto.com/art/201211/364775.htm
頁游,最最核心的就是客戶端(swf)與服務端的游戲通信了。游戲通信產生的封包,內容是否可識別,可篡改,可重放,處理邏輯是否有漏洞,都決定了這款游戲是否有重大的漏洞。
網頁游戲的安全問題,在剛入職接觸的時候,寫過兩篇比較淺顯的文章。雖然頁游安全總體上并沒有顯著變化,沒有新的攻擊方法,也沒有新的防御方法,我個人的工作重心也由頁游安全轉向了手游安全,但出于完美主義的偏執,還是希望寫一篇覆蓋完整的頁游安全文章,希望能給頁游產業一點幫助。
一、協議安全(swf安全):自動封包 (重點)
頁游,最最核心的就是客戶端(swf)與服務端的游戲通信了。游戲通信產生的封包,內容是否可識別,可篡改,可重放,處理邏輯是否有漏洞,都決定了這款游戲是否有重大的漏洞。
我們知道頁游前端和后臺的通信一般有兩者方式,一種是http連接,一種是socket連接,前者適用于小型頁游,例如內嵌在QQ平臺的QQ農場,后者適用于大型頁游。
不同的通信方式,產生的數據包格式也不一樣,像HTTP AMF的可以使用charles來抓包查看,像sockets的可以使用WPE抓包查看。
以socket 通信為例,協議采用自定義格式,一般由兩部分組成,包頭與包體,包頭一般是固定長度,包體為可變長度。包頭一般是一些基本信息,例如包長度,版本號,命令號,用戶ID,序列號等;包體就是操作命令對應的接收參數,參數個數不同,參數類型不同會導致包體長度不同。
只要摸清楚協議算法,即包是如何生成的,就可以構造數據包與服務器自由通話,這一后果是非常嚴重的。自由通話意味著你不需要老老實實的在客戶端操作,一條數據包就能代替你一連串的操作,例如發送一條數據包完成一個任務,常用于快速升級,淘寶上的頁游代練絕大多數都是采用的這種方式;自由通話更意味著你可以繞過客戶端的邏輯判斷,傳任意參數給服務端。說到這里,你可能覺得只要服務端能正常處理來自客戶端的參數,不出邏輯錯誤,不出配置錯誤,就萬事大吉。這種想法很常見,例如上海寶開公司的某個開發就說過,我們的游戲邏輯判斷都在服務端,我們沒有外掛。我推測這個人應該不怎么上外網。
理想是豐滿的,現實是骨感的,怎么能保證后臺不將邏輯寫錯,策劃運營不將配置弄錯呢,特別是在高強度的通宵加班后。你可能說靠測試呀,中國頁游行業,配給給游戲的測試人員是非常少的,相應的測試時間也是遠遠不足的,并且測試技術也非常需要提高,總的來說,在頁游行業,能做完整協議測試的公司不多。但玩家,特別是從事外掛制作代練服務的打金工作室會“幫你”好好地徹底地做協議測試。他們會先反編譯客戶端上的SWF文件(緩存中的,內存中的)得到協議生成算法,制作成封包工具,遍歷每個協議號,每個參數輸入,讓你的錯誤無從遁形。
我見過一個非常聰明的外掛制作者,在外掛中添加了腳本分享平臺,號召大家共同摸索,將有問題的封包以腳本的方式上傳以供大家下載,這種集思廣益真的很妙,腳本的分享會給“找bug”精神獎勵,將其帳號公布出來以供大家瞻仰,因此樂意分享的人很多。而且作者還很負責的有腳本審核機制,并支持快捷的查詢。這是什么樣的用戶體驗呀,這就是頁游外掛界的app store
看到這里,你或許想,我保護好SWF文件,不讓其逆向不就行了嗎?有需求,就有滿足需求的地方,市面上有不少給SWF提供加密服務的收費產品,例如Amayeta SWF Encrypt 和 DComSoft SWF Protector ,因為收費,沒用過這些產品,不知道具體原理,但據了解,最常用SWF加密方式,就是破壞SWF標準文件頭,通過向SWF的二進制文件的文件頭寫入無意義的數據,從而導致反編譯軟件無法正常解析SWF文件。下圖是使用反編譯器打開加密的SWF文件,會提示無法解析
我們可以對比一下采用這種加密方式的swf文件頭內容:
(1)未加密swf文件
?
正常的SWF文件,文件頭部是由一個三字節的標識符開始,為0×46、0×57、0×53(“FWS”)或者0×43、0×57、0×53(“CWS”)其中之一。“FWS”標識符說明該文件是未壓縮的SWF文件,“CWS”標識符則說明該文件前8個字節之后(即文件長度字段之后)的全部數據為開源的標準ZLIB方式壓縮。
(2)加密后的SWF文件
很明顯,文件頭部變成了無意義的符號。
實現函數示例(參考http://blog.sina.com.cn/s/blog_731fdd2b01010u9k.html)
有加密就有解密,加密的SWF文件需要還原,雖然反編譯不了加密后的SWF文件,但可以反編譯解密文件找到解密代碼來還原加密SWF文件的文件頭。(參考 http://www.2cto.com/Article/201211/167406.html )
很明顯,這種SWF加密方法沒什么作用。于是大家想著如何用一種無法反編譯的實現方法來隱藏加密算法,例如利用Alchemy能夠編譯C/C++代碼為AS字節碼但無法被反編譯的特性來隱藏加密算法。其實我懷疑目前有工具將Alchemy還原成C了,例如ASV(actionscript view 2012)就號稱是目前最強悍的SWF解密工具,網上都有該工具的團購消息了。
我不懂SWF的加密解密,但我知道有一條萬能守則,任何加密在內存中都是解密狀態的。當無法解密的時候,就從內存中查找導出吧,我們可以先使用SWF Memory Dumper從瀏覽器內存中導出解密并解壓縮的SWF文件,再用傳播程度都爛大街的碩思閃客反編譯得到源碼。這一方法對游戲協議安全來說,是非常非常非常悲劇的。如下圖所示,包的組成結構,包中各個字段的生成算法都可以通過逆向解密SWF文件獲得!
例如下圖為游戲協議結構
例如下圖就是游戲協議對應的命令號
例如下圖為游戲配置表
一切的一切,都注定了要想完全解決協議安全問題,只有靠AS混淆了。目前有一些收費軟件提供AS混淆,例如secureSWF 。但奇怪的是,沒有多少頁游公司實施AS混淆。
寫到這里,或許你會幻想游戲協議算法不會被逆向得知,那不就完事大吉了嗎?再次申明,現實是殘忍的,即使不知道協議算法,照樣可以修改游戲封包。我們可以通過耐心的反復操作來對比封包的不同,定位到修改點。一般使用WPE工具,修改包體。WPE工具的關鍵就是過濾器,查找到符合指定特征的封包,將特定的位置替換為修改的值。如下圖所示,
除了封包篡改,最簡單的連封包結構都不要猜測的就是封包重放作弊了,例如打怪是一條封包,只要反復重放該封包,就能輕易刷取經驗值了。
好的協議設計,一定要考慮到防御封包篡改和封包重放,最簡單的方法是在封包的某個字段加入一個序列號,該序列號包含包體完整性檢驗值,時間因素值,來區分封包是否是重放的,是否有被篡改。
有了好的協議設計,協議是否安全了呢?協議的實現方法在客戶端SWF中,這一事實又講安全問題引回到SWF被逆向的問題上,只要被成功逆向,一切努力都打水漂了。雖然防御艱難,但也不能放棄,一種方法不行,可以用多種方法。總的來說,為了協議安全,可以做如下措施(不僅僅從技術上):
1.好的協議設計,防重放與篡改
2.SWF加密 ,注意加密算法的安全,最好AS混淆
3.耐心的做協議檢測,開發在提交測試前,做協議測試;測試在完成了功能測試,性能測試后也要搞好協議測試;策劃運營對配置表做認真的檢查;
4.設計一套監控系統,監控游戲中的收益與消費,大量的刷取物品肯定會在數值變化中體現出來;
5.留意游戲論壇,游戲QQ群里是否有新漏洞的披露,外掛是否有更新;
6.頻繁更換加密算法,與外掛制作者PK更新速度。
二、自動游戲+加速
自動游戲,簡單的說就是模擬鼠標或鍵盤對游戲UI的操作,代替你做重復的工作。最簡單的自動游戲腳本可以使用按鍵精靈來制作,先對正常操作進行錄制,然后編輯,設置熱鍵,最后回放即可。程序實現中一般會有以下幾個關鍵函數
(1)模擬鍵盤
VOID keybd_event(
BYTE bVk, // 虛擬鍵碼
BYTE bScan, // 掃描碼
DWORD dwFlags,
ULONG_PTR dwExtraInfo // 附加鍵狀態
)
(2)模擬鼠標
VOID mouse_event(
DWORD dwFlags, // motion and click options
DWORD dx, // horizontal position or change
DWORD dy, // vertical position or change
DWORD dwData, // wheel movement
ULONG_PTR dwExtraInfo // application-defined information
)
自動游戲的作弊方式常見于對戰刷怪類游戲,自動識別地圖中怪物出現的位置,自動出招打怪,自動拾取掉落寶物。往往還會配合加速外掛,總的來說,就是靠達成那種不知疲倦(腳本操作)、準確度高(自動識別地圖中UI特征)、快速(對頁游就是加速flash的動畫播放速度)的操作方式來快速升級。
自動游戲類型外掛的防御比較簡單,增加人機識別的因素,類似于論壇避免批量注冊,采用只有人類才能識別的驗證碼(題外話,不少網站的驗證碼其實可以機器識別),例如對于對戰類游戲,記錄每次對戰的頻率和操作時間特性,對異常的操作彈出圖片驗證,中斷自動游戲。
在實施圖片驗證的時候,要考慮到兩個要素:
一是圖片是否真正的機器難以識別,要預防簡單的像素采集技術;
二是圖片庫是否及時更新,要預防圖片庫的遍歷。
而加速外掛,也常見于對戰類游戲。改變操作速度有兩種情況。一種是使用變速齒輪之類的加速外掛加快flash動畫播放速度,一種是速度值為游戲中的某個變量值,修改了對應的數值。
對于加快flash動畫播放速度的加速外掛,我們可以通過對比客戶端服務端時間是否同步來檢測,當檢測到異常的時候,可以彈出圖片驗證,中斷加速。
對于速度由游戲中數值控制的,做好協議安全,使其無法改封包中對應的數值;做好SWF反逆向保護,使其無法修改源碼中控制速度的邏輯。
三、內存安全:內存修改
修改游戲在內存中的數值是經典的單機游戲作弊方法,同樣也適用于網頁游戲,原因很簡單,不可能每個來自客戶端的數據,服務端都做驗證。(看看頁游公司開發前端和后臺的比例吧!)以社交類網頁游戲為例,其中會內嵌不少小游戲,這些小游戲可能是用來賺取游戲經驗或貨幣等數值的,很顯然,這種類型的小游戲基本就是主邏輯在客戶端的單機游戲,只是最后將游戲分數上傳給服務器,服務器再根據游戲分數的不同來下發相應數額的游戲貨幣。我們完全可以在積分上傳前,在內存中查找并修改該數值。 如下圖所示,用cheat engine去查找IE進程中游戲分數。
(cheat engine是我最喜歡的內存修改工具,手游上的內存修改工具和這個比起來簡直是胎兒版的。該工具支持自定義格式的內存搜索,具備強大的反匯編功能,更妙的是可以直接生成外掛,特別贊的是竟然采用了游戲通關的方式來教授工具使用,我的博客中有第八關于第九關通關方法)
程序實現一般會有以下幾個關鍵函數
(1)讀取進程數據ReadProcessMemory
(2) 查找,查找算法可以按數值類型、掃描類型及內存掃描方式來實現
例如數值類型有二進制,1字節,2字節,4字節(游戲最常用),8字節,浮點數,雙浮點數,文本,字節數組,自定義(這個最牛);
例如掃描類型可以支持精確查找,模糊查找(比...大,比...小,兩者之間),數值變化趨勢(數值處于增加中,數值出于減少中,數值沒有變動,與首次掃描數值相同,數值增加了某個指定值,數值減少了某個指定值);
例如內存掃描方式有自定義掃描起始與終止地址,同時掃描只讀內存,深度掃描,快速掃描,掃描時暫停游戲
(3)寫數據WriteProcessMemory
內存修改的防御,有以下幾種建議:
(1)重要數值在內存中拆分存放,使其無法簡單定位到(會使得游戲邏輯變復雜)
(2)默認可以修改,在服務端控制收益上線。(考慮到成本,為目前主流控制方法)
四、存檔安全:存檔修改
在flas在flash單機游戲時代,修改本地存檔文件,是游戲作弊的重要方式,相信有不少人就用過Flash存檔修改器。
隨著頁游興起到現在的頁游繁盛,依賴于存檔進行邏輯判斷的設計減少了,但這塊也不能完全忽略掉。總會有一些功能是需要調用本地存檔的。例如登錄模塊中,記住密碼功能,會將密碼信息存儲在本地,以IE瀏覽器為例,在C:\Documents and Settings\(你的Windows用戶名)\Application Data\Macromedia \Flash Player\#SharedObjects\(一些隨機數字和字母)\ 文件夾下就可以看到存儲密碼的SOL文件,可以使用minerva工具查看,如下圖所示,密碼明文明文存儲的,SOL文件是永久性保存的,除非手動清除,如果玩家在公共環境下登錄,就會有盜號威脅。
也有些開發意識到了這個問題,而采用加密存儲方式,一般采用md5(其實md5不是真正的加密算法)。md5解密的在線網站非常多,如下圖所示,密碼通過兩次md5后存儲,我們可以在http://www.cmd5.com/ 查到。
所以建議存檔加密,采用自定義的加密算法,例如md5后轉置再md5,等等。
五、帳號安全/充值安全:盜號/低價充值
帳號安全和充值安全不僅頁游如此,所有游戲,甚至所有線上應用都如此。如果說開是個大的話題,我僅僅介紹頁游中常見的威脅與防御。
(一)、帳號安全
威脅:
1.外掛盜號
例如下面號稱可以無限刷取游戲貨幣的外掛,實際上在用戶輸入帳號和密碼后,將信息發送給盜號者的郵箱。
2. 社工盜號
在游戲中獲取信任,以為對方代練等好處為引誘盜取帳號。或通過獲取個人信息,從密保問題下手進行盜號。
3.從游戲的帳號管理中心等web入口下手,進行盜號。
例如登錄模塊沒有驗證碼或驗證碼實現機制漏洞,使用字典掃描批量盜號
4.傳輸嗅探盜號
5.利用帳號申訴流程漏洞進行盜號
例如有些申訴打分機制存在提供多次充值證明就可以取回密碼的方式,先充值,再盜號。
防御:
1.安全意識宣傳
2.弱口令檢測
3.異地登錄提醒
4.登錄行為監控
5.設計好帳號相關功能,例如申訴流程
(二)、充值安全
威脅:
1.社工
在網上發帖慌稱發現充值漏洞,騙取貪心網友給自己指定的帳號進行充值
2.利用手機充值漏洞
使用快過期的手機廢卡進行充值,大多數的充值不會再次檢測手機卡是否存活狀態
3.利用寬帶充值漏洞
盜取寬帶帳號進行充值,由于不會實際影響游戲收益,頂多會出現受害者損失嚴重的情況下投訴帶來的不好影響。
4. 真正的充值漏洞
比如說廣泛采用的點卡充值,可能存在點卡被重放使用的漏洞
防御:
1.安全意識宣傳
2.充值相關功能的安全檢測
結論
總的來說,頁游的各種外掛問題很普遍,端游有的它都有,但安全防御不如端游,這很大程度上是因為頁游的開發周期短,生存周期也短,例如較長的神仙道游頁才兩年了,甚至大多數頁游,只是為了短時間洗用戶搶錢,因此不會投入人力物力在外掛防御方面,或許第三方的安全服務會有點市場吧,比如說他們樂意購買支持多項目的AS混淆工具。總之,頁游是個浮躁的市場,只有生命周期強大的游戲,才會注意到外掛問題。
?
==========================================================================================================================
SWF加密之隱藏密鑰篇
本片博文介紹的加密方式為最基礎的隱藏密鑰的加密方式,當然目前來說這樣的加密方式也是可以被破解的,也只是防君子不能放小人,加密最終極的辦法還是混淆。(在swf文件個公開的情況下,如果adobe不提供支持,大部分情況下對swf的加密都是徒勞的),本篇只是對swf加密方式的一個整理,分享一種思路。如果您是swf加密高手很期待和您交流,
密鑰隱藏
破環swf標準文件頭是最簡單也是最常用的方法。 向swf的二進制文件的文件頭寫入無意義的數據,這樣就可以導致破解軟件無法正常解析swf。
如圖所示,向core.swf的ByteArray開始位置寫入無意義的數據,
這樣做的原理是Swf文件的前幾位表示這個swf的版本信息,以及解析swf需要的參數數據,把它修改為無意義的數據,反編譯程序自然也就無法解析了, 當然如果你這樣做了之后,也會造成在運行時flashPlayer無法解析core.swf,
????正所謂加密和解密是必定會是同時存在的一對好基友。所以我們就需要在core.swf加載好之后把破環的文件頭還原回來,你就需要如一個正常的loader.swf來加載被加密的swf,并且把加載的swf文件頭還原回來。如下代碼
由于總所周知的原因,這樣做只能防君子不能防小人,只是增加了破解者一點點工作量而已,破解者不能直接反編譯core.swf、但是他可以破解loader.swf來找到解密代碼(如上圖紅框的數字7是明文存在在loader.swf里的),來還原core.swf的文件頭。然后繼續用反編譯軟件進行反編譯,
?
參考資料?(摘自不知出處的地方)
SWF文件頭
???????所有的SWF文件均以以下頭部開始:
SWF文件頭
字段 | 類型?* | 說明 |
簽字標識 | UI8 | 標識字符: “F”表示未壓縮 “C”表示已壓縮(版本6或后續版本) |
簽字標識 | UI8 | 此標識通常為“W” |
簽字標識 | UI8 | 此標識通常為“S” |
版本 | UI8 | 單字節文件版本數(例如,0x06表示版本6) |
文件長度 | UI32 | 整個文件的字節長度 |
幀尺寸 | RECT | 單位幀的尺寸 |
幀率 | UI16 | 每秒的幀數,其16個位是按照8.8的格式表示的 |
幀數 | UI16 | 影片的總幀數 |
*?此類型在基本數據類型一節中定義 |
文件頭部是由一個三字節的標識符開始,為0x46、0x57、0x53(“FWS”)或者0x43、0x57、0x53(“CWS”)其中之一。“FWS”標識符說明該文件是未壓縮的SWF文件,“CWS”標識符則說明該文件前8個字節之后(即文件長度字段之后)的全部數據為開源的標準ZLIB方式壓縮。
?
上述方法僅僅只能防止一些對swf不了解的外行人,
?
?
如上圖紅框的數字7是明文存在在loader.swf里的。 那現在的思路就很清晰了,要做的就是把好個明文的數字7給隱藏起來,達到讓破解者無法還原core.swf文件頭。由于swf文件格式是公開的,毫無保密性,所以任何用AS實現的加密算法都是耍流氓(沒用的),那我們有沒有辦法用其他方法來隱藏數字7呢。答案是有的:
有2種方法
1.alchemy
???Alchemy?能夠編譯C/C++代碼為AS3字節碼(運行在AVM2上)能夠運行在Flash或者Flex平臺,并且Adobe宣傳Alchemy能夠為計算密集型任務提升性能(但是比原生C/C++慢),
介紹完畢,我可以看到adobe把alchemy吹的神呼其神,事實上好像確實不錯^_^。但是我們今天要用到的不是alchemy執行C/C++代碼飄逸的效率,而是利用alchemy暫時(我只能說暫時,鬼知道以后asv會不會也能把alchemy給還原成C)無法被反編譯的特性,有點旁門左道了,我想adobe搗鼓alchemy的初衷肯定不是讓開發者用來加密自己的swf。但誰讓adobe把swf格式公開了呢(這里扯個淡,任何東西都可能是雙刃劍,破解使開發的勞動成果被瞬間復制的同時也間接間或一部分成就了flash的遍地開花,山寨起來容易啊,在天朝山寨才是王道,個人觀點僅供參考,不要糾結flash真正火的原因),
?
如上圖為alchemy的一個HelloWorld的示例程序,你可以在C(alcnemy)返回我們解密用到的數字7,或者你覺得用數字其不放心。可以用個公式算一個數字出來返回。Alchemy的性能,我想再復雜的運算都是輕松搞定的。
?
?
如上圖所示。 我僅僅寫了個helloworld的程序。Alchemy就給我編譯出幾百個AS類來(截圖只是一部分),你能找出還原算法在哪個文件里面嗎。反正我是找不出,
?
還原時你要做的就是。 把alchemy編譯的swc放到工程庫里,執行如下代碼,用返回的數字來歡迎core.swf的文件頭。
???
?
?
二:Pixel Bender
????Pixel Bender是Adobe開發的一種編程語言,用戶可以使用該語言創建自定義濾鏡、效果和混合模式,以用于Flash、AE(After Effects)和Photoshop。
Pixel Bender與硬件無關,可高效地運行于各種GPU和CPU體系結構之上。Pixel Bender開發人員通過編寫Pixel Bender代碼來創建濾鏡。?欲知道詳情請點擊度娘
和alchemy一樣。Adone?搗鼓Pixel Bender的初衷肯定也不是讓開發者用來加密自己的程序。但是沒辦法,被adobe逼的呀、?
?
如圖所示,你可以在pixelBender的返回值里,返回我們還原core.swf需要的用到的數字7。
用pixelBneder解密的過程過程可能有點復雜,不能直接調用方法并返回值。需要監聽渲染成功事件。
如圖fuckNum(罪過粗口了)就是我們的還原core.swf文件頭需要用到的數字了
=======================================
????好了。回到開始,以上介紹的加密方式目前來說都是可以被破解的,只增加了點破解的難度,加密最終極的辦法還是混淆。這里只是對swf加密方式的一個整理,分享一種思路。如果您是swf加密高手很期待和您交流
?
?
?