某券商的網路下單系統,在登入後或變更密碼時,會將此密碼編碼並紀錄在Cookie裡,本文將說明如何破解從此Cookie內容而得到明文密碼。基於職業道德,不便提供此下單系統的網址及細部資訊。
每次變更密碼後,檢視回應(response)的標頭(header)發現LoginPWD欄位值的長度是4的倍數(圖1),且字元符合BASE64編碼形式,猜測密碼是利用BASE64編碼後再記錄到Cookie,但是解碼LoginPWD的值卻得到亂碼(圖2),而非原來的密碼明文,推測「執行BASE64編碼前,密碼應該還進行其他編碼處理」。既然使用BASE64 to Text得到亂碼,只好改用BASE64 to Hex來觀查解碼後的內容(圖3)。
圖1:檢視回應內容的標頭資訊 |
圖2:直接解碼只得到亂碼 |
圖3:使用BASE64 to Hex查看解碼後的結果 |
要破解密碼,當然不會只使用一組資訊,下表是筆者以不同的密碼得出下單系統回傳的LoginPWD值,並和該密碼的BASE64編碼進行比較。
NO | 密碼 | 直接BASE64編碼 | 密碼的Hex | LoginPWD | 解碼成Hex |
1 | AaBbCcDdE012 | QWFCYkNjRGRFMDEy | 416142624363446445303132 | AZiE4EEKG79Npb05nw== | 019884E0410A1BBF4DA5BD399F |
2 | AaBbCcdDe012 | QWFCYkNjZERlMDEy | 416142624363644465303132 | AZiE4EEKO59tpb05nw== | 019884E0410A3B9F6DA5BD399F |
3 | ABC123456789 | QUJDMTIzNDU2Nzg5 | 414243313233343536373839 | AbuFszBaa+4+orQynw== | 01BB85B3305A6BEE3EA2B4329F |
4 | abc123456789 | YWJjMTIzNDU2Nzg5 | 616263313233343536373839 | IZulszBaa+4+orQynw== | 219BA5B3305A6BEE3EA2B4329F |
5 | ABC123 | QUJDMTIz | 414243313233 | AbuFszBaXw== | 01BB85B3305A5F |
6 | abc123 | YWJjMTIz | 616263313233 | IZulszBaXw== | 219BA5B3305A5F |
從上表可以找出幾個現象
- 當密碼長度不一樣時,LoginPWD的長度也不一樣,但仍維持4的倍數。
- LoginPWD的長度都比直接BASE64編碼多出4個字元,如上表LowinPWD欄的粗藍字。
- 由於筆者測試的密碼都是3的倍數,而LoginPWD出多的4字元之後兩碼皆為==,依照BASE64的規則,代表有2個填充字元,推測下單系統會先在原密碼之後附加1字元再執行編碼。
- 比對各組密碼,相同位置相同字元,對應的LoginPWD內容也相同,如項次3及5紅字部分。
開始思考開發者可能使用的編碼方式
- 是不是使用對照表轉換BASE64的編碼字元?
但從上表項次1或2的黃底字看到k及N都對應到E,顯然不合理。 - 是不是使用特定KEY進行轉碼?
試著將「密碼的Hex」與「解碼成Hex」的值進行XOR運算(「解碼成Hex」的最後一碼是附加的,故先捨棄),結果如下表的「XOR結果」欄
NO | 密碼 | 密碼的Hex | 解碼成Hex | XOR結果 |
1 | AaBbCcDdE012 | 416142624363446445303132 | 019884E0410A1BBF4DA5BD399F | 40F9C68202695FDB08958C0B |
2 | AaBbCcdDe012 | 416142624363644465303132 | 019884E0410A3B9F6DA5BD399F | 40F9C68202695FDB08958C0B |
3 | ABC123456789 | 414243313233343536373839 | 01BB85B3305A6BEE3EA2B4329F | 40F9C68202695FDB08958C0B |
4 | abc123456789 | 616263313233343536373839 | 219BA5B3305A6BEE3EA2B4329F | 40F9C68202695FDB08958C0B |
5 | ABC123 | 414243313233 | 01BB85B3305A5F | 40F9C6820269 |
6 | abc123 | 616263313233 | 219BA5B3305A5F | 40F9C6820269 |
從上表的「XOR結果」得到如下結論
- 從項次1到6的XOR結果,可知下單系統會逐字元進行XOR處理。
- 由項次5多出來的「5F」,與項次4同一位置的KEY相同,得知下單系統附加的字元是ASCII的NUL字元(十六進制碼 00)。
目前解得35碼的XOR Key值是「40F9C68202695FDB08958C0B9F74F518BC6361D42F22998F31B2895B67BF64AA505D528E」,亦即「0x40,0xF9,0xC6,0x82,0x02,0x69,0x5F,0xDB,0x08,0x95,0x8C,0x0B,0x9F,0x74,0xF5,0x18,0xBC,0x63,0x61,0xD4,0x2F,0x22,0x99,0x8F,0x31,0xB2,0x89,0x5B,0x67,0xBF,0x64,0xAA,0x50,0x5D,0x52,0x8E」
知道XOR的Key值後,就能對任意LoginPWD進行解碼,步驟如下:
- 先將LoginPWD進行BASE64 to Hex解碼,得到十六進制結果,以HEX表示。
- 將HEX的最右邊的Byte捨棄,因它是附加的字元NUL,無關緊要。以HEX2表示。
- 從XOR Key的左邊取出和HEX2等長的資料,以KEY2表示。
- 將HEX2與KEY2進行XOR,
- 將得到的十六進制值轉成ASCII即得到密碼明文。
就以「LoginPWD: E62TszBaa+4+orQynw==」為例:
- 先將「E62TszBaa+4+orQynw==」進行BASE64 to Hex解碼,得到「13AD93B3305A6BEE3EA2B4329F」。
- 將「13AD93B3305A6BEE3EA2B4329F」最右邊的Byte(即9F)捨棄,剩12Byte。
- 從XOR Key的左邊取出12Byte,即「40F9C68202695FDB08958C0B」。
- 將「13AD93B3305A6BEE3EA2B432」與「40F9C68202695FDB08958C0B」進行XOR即得「535455313233343536373839」。
- 將「535455313233343536373839」轉成ASCII,得到密碼明文「STU123456789」。
沒有留言:
張貼留言