- 從0到1:CTFer成長之路
- Nu1L戰(zhàn)隊
- 7964字
- 2021-01-07 17:32:07
3.3 密碼學和逆向知識
加密算法與偽隨機數算法是開發(fā)中經常用到的東西,在CTF比賽中也是。除了CRYPTO分類下對密碼算法純粹的考慮,Web題目也會涉及密碼學的使用,最常見的有對敏感信息如密碼或用戶憑據進行加密保存、對重要信息的校驗等。這些過程中可能隱藏著一些對密碼學的錯誤使用,比賽過程中在成功偽造出我們需要的信息后,配合其他漏洞,最終可獲取flag。
除了密碼學,對源碼進行混淆加密也是正常操作。利用Python、PHP、JavaScript等語言的特性,比賽題目將代碼變成不那么直觀的樣子,加大了分析難度,但是只要掌握了方法,參賽者也能很快分析出藏在混淆背后的秘密。
本節(jié)就CTF中常見的Web+CRYPTO或Web逆向題目進行探討。
3.3.1 密碼學知識
在密碼學與Web結合的題目中往往包含明顯的提示,如題目的關鍵詞中有ENCRYPT、DECRYPT等,甚至直接給出相關代碼,讓參賽者進行分析。
3.3.1.1 分組加密
分組加密就是將一個很長的字符串分成若干固定長度(分組長度)的字符串,每塊明文再通過一個與分組長度等長的密鑰進行加密,將加密的結果進行拼接,最終得到加密后的結果。當然,在分組過程中,塊的長度不一定是分組長度的整數倍,所以需要進行填充,讓明文變?yōu)榉纸M長度的整數倍。這個填充的過程剛好可以幫助我們識別分組加密。
3.3.1.2 加密方式的識別
在分組加密方式中,加密過程中明文會被分為若干等長的塊。隨著明文長度的增加,密文的長度可能不變,或一次增加固定的長度,而這個增加的長度就是在分組加密中使用到的密鑰的長度。這類題目中常見的加密算法有AES和DES兩種。其中,DES的分組長度固定為64比特,而AES有AES-128、AES-192、AES-256三種。由此可以初步判定加密時使用的算法是哪一種,再根據題目提供的信息對密鑰進行爆破,或者配合其他攻擊方式偽造密文。
在分組加密中有ECB、CBC、CFB、PCBC、OFB、CTR六種模式,對每種模式的加密的區(qū)別可以參考密碼學部分,下面將通過對其中三種加密方式和相應例題來介紹這類題目中常包含的套路。
3.3.1.3 ECB模式
ECB(Electronic CodeBook,電子密碼本)模式的工作流程圖見圖3-3-1和圖3-3-2。
在加密過程中,需要加密的消息,按照分組大小被分為數個塊,再使用密鑰對若干塊明文分別加密,將加密結果拼接后得到密文。解密過程類似。這種加密方式最大的問題就是對所有分塊使用同樣的密鑰進行加密,若明文相同,則產生的密文也相同。所以,針對ECB這種加密方式,我們只需關注某一組已知可控的明文及對應的加密結果,即可對其余加密塊進行攻擊。
這里以HITCON 2018 Oh My Reddit為例進行講解。題目代碼請參考:https://github.com/orangetw/My-CTF-Web-Challenges/tree/master/hitcon-ctf-2018/oh-my-raddit/src。

圖3-3-1

圖3-3-2
根據提示,flag is hitcon{ENCRYPTION_KEY},我們可以得知這是一道密碼與Web相結合的題目;再查看hint界面,提示

密鑰都是小寫字符。
查看題目中涉及的鏈接和對應的明文不難發(fā)現,隨著title長度的變化,每次密文在產生長度變化時都變化了16個字符,由此可以推斷出密鑰的長度為64bit,加密方式可能為DES。
我們發(fā)現了網頁中兩條很有趣的鏈接,這兩條鏈接中title開頭的字符串都是“Bypassing W”,而密文中也存在相同的“1d8feb029243ed633882b1034e878984”:

可以猜想加密使用的模式為ECB模式(因為開頭及結尾均不同的情況下,對相同字符串的加密結果相同)。那么,根據我們現在的已知信息:
? 密鑰的長度為64bit,8字符,可能為DES加密方式。
? 密鑰中的字符均為小寫字符。
? 對“Bypassing W”中某8個字符的加密結果可能為“3882b1034e878984”。
我們可以嘗試爆破密鑰。因為388...984串出現在后面,也應該以8位為窗口,倒著將“Bypassing W”作為明文進行爆破,即按照"assing+W"、"passing+"(“+”是因為將title進行了URL編碼)的順序進行嘗試。
我們使用hashcat工具:

命令中的“617373696e672b57”是將"assing+W"轉化為HEX編碼后的結果。運行結束后,我們得到了一個可能的密鑰“l(fā)dgonaro”。使用這個密鑰對密文進行解密:

解密成功且內容有意義,可以認為密鑰正確。但是我們按照格式提交flag后,提示錯誤。再觀察題目,其中有文件下載相關鏈接,通過分析該鏈接,我們可以實現任意文件下載。下載app.py進行分析,最終得到密鑰。

3.3.1.4 CBC模式
CBC(Cipher Block Chaining,密碼分組鏈接)中,每塊明文都需要與前一塊密文進行異或,再進行加密,最后將得到的加密后的密文塊進行拼接,得到最終的密文串。這就使得在CBC加密過程中,對每塊明文進行加密時要依賴前面的所有明文塊,同時通過IV(Initialization Vector,初始向量)保證每條消息的唯一性,其工作流程見圖3-3-3和圖3-3-4。

圖3-3-3(來自維基百科)

圖3-3-4(來自維基百科)
異或運算有如下性質:

由于IV和密文塊直接參與了異或解密的過程,就導致了在出題過程中常見的兩種攻擊方式:通過IV,影響第一個明文分組;通過第n個密文分組影響第n+1個明文分組。
根據解密流程,假如修改第n個分組解密后的結果,設p_n代表第n組明文,c_n代表第n組密文,dec(key,c)為解密算法,key為密鑰。代碼如下:

如果想修改某一組的解密結果,只需知道原來的明文是什么、想修改的明文內容、上一組向后傳遞的密文即可(若為第一組,則需要IV)。
這里以PicoCTF 2018的Secure Logon題目為例,題目中提供了服務器端的代碼:https://github.com/shiltemann/CTF-writeups-public/blob/master/PicoCTF_2018/writeupfiles/server_noflag.py。在/flag路由下,只有獲取Cookie中保存的由AES加密后的JSON串,且admin字段為1的情況下,才會將flag顯示到頁面中。


/login路由中則給出了Cookie的生成算法:

其中使用的加密算法為:


通過對login函數及AESCipher的分析,我們可以知道:使用的AES-128-CBC加密算法;Cookie中的內容為base64(iv,data);data為json.dumps(cookie)的結果;Cookie中包含{"admin":0,"username":"something","password":"something"},并按key字母序進行了排序。
為了達成admin為1,我們需要進行CBC比特翻轉攻擊。
根據json.dumps的結果,可知需要修改的字符位于整個加密字符串的第11位,將其從0變?yōu)?。

根據分組長度為16,我們可以得知要翻轉的字符位于第一組第11位。
根據公式,我們開始進行翻轉攻擊。所需要的IV已經保存在Cookie中base64解密結果的前16位中。那么,我們需要的所有信息都已經滿足,開始寫程序翻轉:

將翻轉后的Cookie進行替換,即可成功拿到flag。
3.3.1.5 Padding Oracle Attack
Padding Oracle是Padding根據服務器對信息解密時的表征來對應用進行攻擊,針對的同樣是CBC加密模式,其中的關鍵是Padding的使用。在分組加密中,需要先將所有的明文串分成若干固定長度的分組,為了滿足這樣的需求,要求我們對明文進行填充,將其補充為完整的數據塊。
在填充時有多種規(guī)則,其中最常見的是PKCS#5標準中定義的規(guī)則,即當明文中最后一個數據塊包含N個內容為N的填充數據(N取決于明文塊最后一部分的數據長度)。每個字符串都應該包含至少一個填充塊,也就是說:需要補充1個數據塊時,補充01;需要補充2個數據塊時,補充02……當字符串長度正好為分組長度的整數倍數時,額外添加一個塊,內容為Padding,見圖3-3-5。

圖3-3-5
在解密時,服務器將數據解密后,在判斷最后一個數據塊末尾的Padding是否合法時,可能因為Padding出現的錯誤而拋出填充異常,就是給攻擊者對加密進行攻擊時的Oracle(提示)。一般的Web應用會將IV和加密后的字符串一同交還給客戶端作為憑據,用于以后對客戶身份的驗證時使用。這里以P.W.N.CTF 2018:Converter為例(見圖3-3-6),題目地址:http://converter.uni.hctf.fun/,主要功能是為用戶輸入一個字符串,通過服務器的轉換器將該格式的文檔轉換為其他格式。注意,轉換Markdown時使用的為pandoc,可能存在命令注入的漏洞。在完成輸入后,服務器返回一串Cookie:

對這段cookie進行修改,發(fā)現:在修改字符串的最后一位時,提示“ValueError:Invalid padding bytes.”;在修改字符串的最開始一位時,提示“JSONDecodeError:Expecting value:line 1 column 1(char 0)”;不進行修改時,頁面返回正常,見圖3-3-7。
由于輸入相同的內容時,返回的vals的值不同,我們可以推測用于加密的算法采用的加密模式為CBC模式。在逐步增加傳入的內容的長度時,我們發(fā)現,返回的vals的長度在發(fā)生變化時,變化的長度為32,所以可以確定加密方式是128-CBC方式。根據這些內容,我們可以嘗試Padding Oracle攻擊,恢復明文。因為在CBC模式進行解密時需要一個IV,且服務器只返回了我們一個vals,所以我們可以先假設第一個分組為IV,后續(xù)信息為加密結果。
在題目的場景中,根據應用程序的提示,我們可以判斷出一個加密字符串的填充是否正確,同時可以對該應用進行Padding Oracle攻擊。
那么,在本題中,我們可以認為服務器返回的信息與明文間有對應關系,見圖3-3-8。
由于我們不知道明文的內容,圖中明文都用'?'進行代替。但是不難推測,最后一個block中一定包含一個合法的Padding。

圖3-3-6

圖3-3-7

圖3-3-8
在CBC模式的解密過程中,對最后一個分組加密、解密的流程見圖3-3-9和圖3-3-10,符號⊕代表異或。
在了解了CBC方式對字符串如何進行解密及Padding的規(guī)則后,我們可以利用Padding Oracle對這道題被加密的明文進行恢復。至于原理,我們以其中某個加密塊為例進行講解。選取第一塊,注意第一塊在進行異或時操作數為IV,之后的塊在進行異或時,操作數為前一個密文塊。為了操作方便,只對一個加密塊進行破解。在破解時,先將IV設為全0。

圖3-3-9

圖3-3-10
通過將Cookie設置為

進行訪問,服務器返回ValueError:Invalid padding bytes。因為在使用0作為IV進行解密后,解密的結果包含的Padding出現了錯誤,而導致解密過程中出現填充異常,見圖3-3-11。

圖3-3-11
通過變化IV,使最終得到的解密結果的字節(jié)進行變化,當IV+1即Cookie為

時,雖然依舊返回500錯誤,但服務器解密出的明文的結果已經發(fā)生了變化,見圖3-3-12。

圖3-3-12
由于IV的變化,服務器完成解密時最終字符串的內容變化為0x3C。如此重復,直到解密出的明文的最后1字節(jié)為0x01,Cookie的內容如下

則服務器返回“JSONDecodeError:Expecting value:line 1 column 1(char 0)”,而不是由發(fā)生填充錯誤導致的“ValueError:Invalid padding bytes.”。此時可以推測最后一個字符為0x01,滿足了Padding的要求,見圖3-3-13。根據異或的計算過程和CBC解密的流程,我們可以知道

也就是把對第一個密文塊進行解密后的中間值的內容為0x73。
在正常解密流程中,該字符與原IV中同樣位置的字符進行異或運算,運算后的值為最終的解密結果。所以0x73 xor 0x51=0x22(hex解碼后為'"'),即原來的明文字符串中的值。

圖3-3-13
現在我們已經知道了最后1字節(jié)在解密后的中間結果。通過修改IV,我們可以使最后1字節(jié)在異或后的最終結果為0x02,那么此時由于倒數第二個字符解密結果不滿足Padding規(guī)則(見圖3-3-14),服務器會再次返回500錯誤。

圖3-3-14
那么,依舊逐步修改IV,使最終解密的結果為0x02,正確填充時(見圖3-3-15),Cookie如下所示


圖3-3-15此時,根據類似的計算過程,可以還原倒數第二位的內容:

如此重復,直到填充字符串的長度為整個塊的長度,此時我們可以還原第一個塊的全部內容,見圖3-3-16。

圖3-3-16
再根據CBC模式的解密規(guī)則,在解密過程中,解密時產生的中間結果不受到IV的影響。此時將第二個密文塊直接拼接至置0的IV序列后,按照類似的步驟,但在異或得到明文時,需要與前一個密文塊對應位置的值進行異或,這樣可以完成對第二個密文塊進行破解。如此反復,最終恢復整個明文。
根據第二部分CBC模式加密解密的原理,在已知明文、密文、目標明文、IV時,我們可以構造任意字符串,此時可以將需要的命令注入cookie,即將

修改為

在修改的過程中,需要從最后一個密文塊開始偽造。在偽造時,它的前一個密文塊解密后的內容也會改變。由于Padding Oracle的存在,我們可以獲得修改后的密文塊解密時的中間結果,從而依次向前推進,完成對任意字符串的偽造。
原理介紹完畢,但是為了方便解題,可以使用https://github.com/pspaul/padding-oracle中提供的工具,僅需修改小部分代碼,即可實現全部功能。
針對本題目所編寫的代碼如下:

3.3.1.6 Hash Length Extension
在Web中,密碼學的應用除了加密還有簽名。當服務器端生成一個需要保存在客戶端的憑據時,正確使用哈希函數可以保證用戶偽造的敏感信息不會通過服務器的校驗而對系統的正常運行造成影響。哈希函數很多采用的是Merkle-Damg?rd結構,如MD5、SHA1、SHA256等,在錯誤使用的情況下,這些哈希算法會受到哈希長度擴展攻擊(Hash Length Extension,HLE)的影響。
首先,HLE適用的加密情況為Hash(secret+message),這時雖然我們不知道secret的內容,但是依舊可以在message后拼接構造好的payload,發(fā)給服務器,并通過服務器的校驗。要理解這種攻擊手法,我們需要對Hash算法有了解。這里以SHA1為例,在加密時,我們需要關注的有三個步驟(具體算法請見密碼學部分):
(1)對信息進行處理
在SHA1算法中,算法將輸入的信息以512bit為一組進行處理,這時可能出現不足512bit的情況,就需要我們對原信息進行填充。填充時,在該數組的最后填上一個1,再持續(xù)填入0,直到整個消息的長度滿足length(message+padding)%512=448。這里之所以是448,因為我們需要在消息的最后補充上該信息的長度信息,而這部分的長度64bit加上之前的448bit剛好能作為一個512bit的分組。
(2)補長度
MD算法中,最后一個分組用來填寫長度,這也正是SHA1算法能夠處理的信息的長度不能超過2^64bit長度的原因。
(3)計算hash
在計算信息摘要時,在補位完成后的信息中取出512bit進行哈希運算。在運算時,有5個初始的鏈接變量A=0x67452301,B=0xEFCDAB89,C=0x98BADCFE,D=0x10325476,E=0xC3D2E1F0,用來參與第一輪的運算。在第一輪的運算后,A、B、C、D、E會按照一定規(guī)則,更新為經過當前輪的計算后,哈希函數得出的結果。也就是說,在每輪運算后,得出的結果都會作為下一輪的初始值而繼續(xù)運算。重復該過程,直到對全部信息分組完成運算,輸出Hash計算的結果,也就是SHA1值。
對于題目中可能出現的Hash(secret+message)方式,服務器一般會將Hash運算的結果即Hash(secret+message+原填充+原長度)的結果發(fā)給客戶端。那么,現在只需要猜對secret的長度,完成填充及補長度的過程,就可以在不知道secret的情況下得到Hash函數某一輪計算的中間結果,即對Hash(secret+message+原填充+原長度+payload)運算時,剛好處理完payload之前一個分組的中間結果。由于中間結果在之后的運算中不會受到之前分組中信息的影響,這就導致了可以在保證Hash運算結果正確的情況下,將任意payload添加至原信息的尾部。
我們以Backdoor CTF 2017中的Extends Me為例,題目中提供了相應的源碼(https://github.com/jbzteam/CTF/tree/master/BackdoorCTF2017):

在login函數中,通過post方式傳入username,在Cookie中傳入data和user的值。其中,data是SLHA1(key|username|user)的結果。在這個簽名過程中,key為未知參數,username可控,user可控。只有在data中的內容與SLHA1簽名后的結果相同時,才會返回flag。
再觀察SLHA1函數,可以發(fā)現,它是一種類似SHA1算法的Hash算法,但修改了其中的填充和鏈接變量,所以SLHA1算法也會受到HLE的威脅。

那么,此時的解題的思路是將admin這一字符串填充至user的末尾。我們可以按照修改后的思路對程序進行修改,完成哈希長度擴展。


這里爆破的長度是一個范圍,是因為我們不知道key的長度是多少,所以需要填充的內容的長度無法確定。在算法正確的情況下,通過遍歷方式,在key的長度正確時,服務器會將flag返回。
3.3.1.7 偽隨機數
在密碼學中,偽隨機數也是一個重要的概念。但是軟件并不能生成真隨機數。用不安全的庫生成的偽隨機數不夠隨機,也是CTF比賽中的一個考點。
偽隨機數的生成實現一般是“算法+種子”。PHP中有mt_rand和rand兩種生成偽隨機數的函數,它們對應的播種函數為mt_srand和srand。在seed相同時,不論生成多少次,它們產生的隨機數總是相同的,以下程序輸出的隨機數見圖3-3-17。

假如以某種方式我們得到了服務器所使用的種子,不管是固定值還是時間戳,我們都可以對之后生成的偽隨機數進行預測。
在rand函數中,如果沒有調用srand,那么產生的隨機數則有規(guī)律可循,即:

圖3-3-17
state[i]=state[i-3]+state[i-31]
此外,在每次調用mt_rand時,PHP都會檢查是否已經播種。如果已經播種,就直接產生隨機數,否則自動播種。自動播種時,使用的種子范圍為0~232,而且在每個PHP處理的進程中,只要進行了自動播種,就會一直使用這個種子,直到該進程被回收。所以,我們可以在保持連接keep-alive時,根據前幾次隨機數生成的結果,使用php_mt_seed工具對種子進行爆破,從而達到預測隨機數的目的。
雖然我們只對PHP的偽隨機數進行了說明,但是實際上,其他語言中也存在偽隨機數的強弱的問題,如Python中,見圖3-3-18。
在應對此類題目的時候可以查閱相關的官方文檔中相關函數的介紹,如果生成的偽隨機數可以被預測,則會有相關該偽隨機函數不適合加密之類的提示,見圖3-3-19和圖3-3-20。

圖3-3-18

圖3-3-19

圖3-3-20
3.3.1.8 密碼學小結
上文介紹的幾種密碼學的攻擊方式和例子只是少部分Web與Crypto結合的產物,但是密碼學重點不止這些,如分組加密模式中依然有可以被重放攻擊的CFB模式,可以被位反轉攻擊影響的CTR模式,甚至其他流加密算法。雖然沒有與Web相結合的例子,但是依然可以成為以后出題人的關注點,出現在題目中。所以,Web參賽者也要懂得一些密碼學的知識,識別一個加密算法是否易受到攻擊,并將題目中獲取的數據和需要構造的字符串即時交給隊內的密碼學大佬,最終達到題目中的要求。
3.3.2 Web中的逆向工程
3.3.2.1 Python
在CTF比賽時,一些目標可能存在任意文件下載漏洞但對可以下載的文件類型進行了限制,如Python中禁止下載.py文件。Python在運行時為了加速程序運行,因此會將.py文件編譯為.pyc或.pyo文件,通過恢復這些文件中的字節(jié)碼信息,同樣可以獲得原程序的代碼。
比如,在LCTF 2018的L playground2中,關鍵代碼見圖3-3-21,文件下載的接口限制了不能直接下載.py文件,但可以下載相應的.pyc文件進行反編譯,獲得源代碼,見圖3-3-22。

圖3-3-21

圖3-3-22
3.3.2.2 PHP
CTF Web比賽中很可能碰到對代碼進行加密的情況。為了理解PHP加密,我們需知道PHP在運行時不會被直接執(zhí)行,而是經過一次編譯,執(zhí)行編譯后的Opcode,其中有三個重要的函數,分別是zend_compile_file、zend_compile_string、zend_execute。常見的加密方法有對問文件進行加密、對代碼進行加密、實現虛擬機等方式,由于加密方式的不同解密時也會根據不同算法,調用解密插件修改后的編譯或執(zhí)行函數。
傳統的PHP加密方案只是在PHP代碼的基礎上,通過代碼混淆的方式破壞其可讀性,通過殼對最終執(zhí)行代碼進行解密,再通過eval將解密的結果執(zhí)行。對于這類題目,既然我們知道它最終通過eval將代碼進行解密,那么直接通過hook eval執(zhí)行過程。在PHP的擴展中,在初始化時將zend_compile_file替換為我們自行編寫的函數,在每次執(zhí)行的時候輸出其參數,就能將解密的結果輸出。
例如,phpjiami就采取了這種方法。在PWNHUB中,“傻fufu的工作日”一題就采用了這種加密方式。題目源代碼網址為https://github.com/CTFTraining/pwnhub_2017_open_weekday。題目提供了由phpjiami處理后的備份文件,可以直接下載加密后的代碼,見圖3-3-23。

圖3-3-23
網絡上有很多編寫好的hook eval插件源代碼,如https://github.com/bizonix/evalhook,只需編譯并加載到PHP中,再運行我們的源碼,就可以得到真正的源代碼,見圖3-3-24。
除了使用這種方式進行代碼混淆,使用插件對代碼進行加密也是一種方式。這種加密方式通過對PHP底層的zend_compile_*進行hook,在hook后的函數中進行解密操作,再將解密后的源代碼傳給PHP的相關執(zhí)行函數。對于這種類型的加密,我們仍然可以使用hook eval類似的方式進行解密。
比如,在SCTF 2018的Simple PHP Web中,源代碼地址如下:https://github.com/CTFTraining/sctf_2018_babysyc.git。通過文件包含漏洞直接讀取index.php源代碼發(fā)現是亂碼,懷疑代碼進行過加密。通過對phpinfo.php的觀察,我們發(fā)現服務器啟動了encrypt_php插件,那么在指定插件目錄下下載該插件。分析該加密插件,該加密對zend_compile_file進行了hook,見圖3-3-25。
再觀察encrypt_compile_file中的邏輯。在函數執(zhí)行的最后,加密程序直接將解密后的結果傳回了最開始的zend_compile_file,見圖3-3-26,此時只需調整hook插件與解密插件的位置,讓hook函數在解密函數后被調用,就可以輸出解密后的代碼,見圖3-3-27。

圖3-3-24

圖3-3-25

圖3-3-26

圖3-3-27
另一種加密方式是對已經編譯后的Opcode進行處理,此時監(jiān)控zend_compile_*并不會有任何效果,因為加密根本沒有使用PHP進行編譯,而是直接解密得到Opcode并執(zhí)行。由于編譯的過程沒有起作用,因此只能hook函數zend_execute,甚至其中真正執(zhí)行代碼的zend_execute_ex,從中得到Opcode后再進行分析。PHP的vld擴展提供了對Opcode進行分析的工具,需要修改vld的源代碼,將dump OpCode的代碼加到vld_execute_ex中,然后人工分析opcode,就能逐步分析出加密的結果。

例如,RCTF 2019中的sourceguardian一題,我們看到sg_load函數和題目名字的提示可知,代碼使用sourceguardian加密,見圖3-3-28,使用修改后的vld,可以將Opcode導出。

圖3-3-28

圖3-3-28(續(xù))
對Opcode進行分析后,即可逐步恢復源代碼,見圖3-3-29。

圖3-3-29
還有一種最復雜的加密方式,即重新實現一個VM,將PHP的源代碼編譯生成的opcode加密,混淆為僅能被自定義的VM理解的樣式,交給自定義的VM進行解析。其中典型的例子如VMP,由于需要完成對虛擬機、代碼的共同分析,工作量巨大,故很難實現解密。
3.3.2.3 JavaScript
不管怎樣,JavaScript加密最終會將解密后的結果交給JavaScript引擎來執(zhí)行,由此我們只需像解密PHP一樣,為其中的關鍵函數加入hook,就可以完成解密了。
如在大多數情況下,加密的代碼在進行解密后,如果想再次被執(zhí)行,只能通過調用eval等函數,那么我們可以將eval函數修改為打印的函數,不讓其執(zhí)行,而是輸出,就可以得到其中的關鍵代碼。

一些代碼可能對開發(fā)者工具進行檢測,對于這種反調試方式,我們可以通過BurpSuite的代理功能,刪除其中反調試部分的代碼。JavaScript代碼加密實現的難度太大,所以很多時候只是采用混淆的方式進行處理。而混淆僅僅對變量名和代碼結構進行了調整,可以通過代碼美化工具,將其結構進行優(yōu)化,甚至通過Partial Evaluation技術解決。現在網絡上有很多開源的工具能對代碼進行優(yōu)化,如Google的Closure Compiler、FaceBook的Prepack、JStillery。雖然大多數應用是對代碼進行優(yōu)化,但是在優(yōu)化的過程中會在編譯期重構AST、計算函數、初始化對象等,最終呈現可讀的代碼。
- RESTful Java Web Services Security
- Securing Blockchain Networks like Ethereum and Hyperledger Fabric
- Kali Linux CTF Blueprints
- 網絡安全意識導論
- 深入淺出隱私計算:技術解析與應用實踐
- 同態(tài)密碼學原理及算法
- 網絡運維親歷記 (網絡運維紀實文學)
- 黑客攻防與網絡安全從新手到高手(絕招篇)
- 網絡安全應急響應實戰(zhàn)
- 編譯與反編譯技術實戰(zhàn)
- End to End GUI Development with Qt5
- 博弈論與數據安全
- 信息技術基礎:提高篇·實驗與習題
- 網絡空間安全導論
- 功能型密碼算法設計與分析