关于结局解密 初次接触网络安全领域
涉及知识点:
文件内容分析(文件头,二进制/文本,网页源代码)
密码学与加解密技术(暴力破解,base64,RSA,md5)
程序逆向(或关键信息RSA私钥 明文写在程序内)
算是个CTF入门题,根据评论区线索自行操作了一番
1. 找到彩蛋 重启游戏 邮件下拉到底找到彩蛋
中间空白有线索
clue.jpg
2. 寻找文件 在Steam打开本地文件
双击发现无法打开图片
且大小只有几KB不像是图片,很有可能被修改后缀
用记事本打开
1 7z集' 缡? " 訦Ot耥u_河槡俶藽鳭R鱣?f暱朢vPs梾o^埞??!
发现文件头为7z,猜测是压缩包7z格式
修改文件后缀尝试解压
发现解压需要密码
3. 破解压缩包密码 由于是7z格式,可用工具较少
使用Passware Kit Forensic字典攻击(即常用密码进行暴力尝试)
密码较为简单 1分钟就完成解密
压缩包密码: password
4. 解Base64编码 压缩包里clue/7/3/Hello.html
Base64 编码后的字符串长度通常是4的倍数。如果长度不是4的倍数,可能会在末尾有一个或两个等号(=)作为填充
Zm9sZGVy77yaMjk5ZDEyZDg4ZTBlOTljMQ==
对这段Base64编码进行转换
1 2 3 4 5 6 7 import base64encoded_string = "Zm9sZGVy77yaMjk5ZDEyZDg4ZTBlOTljMQ==" decoded_bytes = base64.b64decode(encoded_string) decoded_string = decoded_bytes.decode('utf-8' , errors='ignore' ) print (decoded_string)
输出folder:299d12d88e0e99c1
暗示文件夹/299d12d88e0e99c1/?
5. 寻找文件夹 较快的方法:使用Everything进行搜索
文件夹中有
readme.exe
打开发现需要输入密码
runtime.txt
打开发现文本
1 gAp9xge69vuNF4Kyr/UcjO3iFlFt+e5OFZ5/zYcv703qor2K0eorwcbddlgX/6JiAq1+qnbKPnOZ+MHk7Vy55wKeLYShEvc44jZYT0HIoHLEczXOFgq8qdNsF7RhjNYNNKzDy1cc0i2pDXGTczxqct0CUkHUNI0jkpn9Vm8O19J/caIWb1NdOzfhr86gEzehkXh560sv5X8LBgo0kmJc9pEprJ+SV9vQ4pA4W+C7AtipyC7FU/51tUI/Dl9q2hpUnE1Qt4PyBDsRiaWWQ0ORQCANEapVc/b70ffxYDim5aBfvwYhc7DEo5oFcQUOiAorOnWayzz3CE0I+4qu5nRqgg==
发现这段Base64编码被加密 RSA AES?
已知一段加密数据
6. 寻找私钥 6.1 法1 查看源文件 关键信息明文写在程序里,可以减少反编译步骤
6.2 法2 反编译exe 使用IDA64进行反编译exe
阅读理解C语言代码
意思是若输入的是iamnottom
会打印KEY
…
重新双击运行readme.exe
输入密码
6.3 得到私钥 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC04AAI4K7DdGTx KL86f54wT0ouQrDlL4krCz7DfeuFtaRPbHR/X+2wV7iX+e+doquuAgJ56DyLaRgm ZxV6ksn/vfg0qVJlKfgfqnUsH+5quun14oc7gsdNWHkJqUh9O8pTce/ElK2YbABi 9J06p4Z1PyxpjTkViFz+YVpY5zHo2ysa4tlH1VCpYjjzUQXAMD3NbroBXTYa2Lex UI/Xb2mnZepcGc5/ovQAzf227ORwNS6TcQiz0Wa+V7Ggz3fNBqtqipVg6QHT71a7 TOfZCOPTOW6K49p70DX+3Z3ezpIiX/ZpgBGGAckMGsNsI8lGIAR3vjXsNBeQ0sn2 FFnp+T+9AgMBAAECggEAFo0TFAhHYdEiQLsO1JFSvL02B3yDJ5/8nyRAyAjsE3ip Ksnf4H2qWeEl/7TGvkWo2AIiIubknZEV1LvnfqfMjZk22AIAZuKLsA8FmuHETQRO 5TxAFhhhFvCf7qdvhUWuHSdIeJ784dMdXTkYXVbDudyNgf98jYW56nFi3VC99UUg TaZWXAwr0yjDVqRWe2TpqjDAqNauvVFOhJgsNQ2yJf+XjqTLngM05vQg97CY1BUa pQ4YlvonfX2t4URxz5wsf88DJCRvjTuedezNFyMfyJyPWFylDsvoio9UTk000Tae Zr7Ab0e+gMbdcgo7lgOw7jue0mM+SH/uILU8SaRHVQKBgQDpcibMd56CQ0MT7Kw/ Zue1hpjrcaWlCK5nZ/21Eyu5giAA8CcKvTAL08r4E/ZV7gs28wsk8TZ/wvP63Xqj +Z+t98IRgJyFhed/2cUHRjEtGBkPbrzG0f2QgzDXx2Xkg27h6xXH7SSCZ6SV5Wr2 Ngnt9LuKmjnQx90sAhBxRpblIwKBgQDGWZr/DBncbK6/SKKr+h7sf8fWmEJvlC9E 2pyszEm6foKMxUKOCLpvzLuXZBDDj4tJrPg2oGaA2zU9TAvzX6spT7VnvJhwmP+r +QUysTnv0rUZDs5mHGYbjWly+9J6GcYzb896kL6EMK9BNGVfSiH2vsV6ugYJIo61 Zkv/+6/FnwKBgQC7qp3QL7WIiKQLB29tRL+vKXYTiHgeVP1Hecz2XWQALMCnoGfy dSaDy45Wok2cxNHVKctitlsWmFXk7VmjKpCYnR0xTtAFcyEooZuH/oCX/NBgnKg7 uSJ7o0uHm++opZRlH8SRxW1dPA6OxjCXn9eZqO1/Pf6Ofa2qrDolpha2OwKBgG23 y0Eh1HxVsiQlbbZr2QdBd62A8978vVj9BIWhS3dZ26U6yKIAugB1457Ov2ct1AKh J3wwJgNJPp31nva1CN0FNnd3n2tJdsQOL43m8wFyMLL3ubxKIUFEa/wqyDa6YyS4 yLAnuPsuYwNSlHCtdTQkOuC0XfpXn1FAkPG8q3JJAoGBAMy4385KPM27iQE38UBm 9gh17VBqaUxd+9s6Zkb4noS00vR3S0oDrQaNIdPCJphm1xlewqx2jbYMQX7aDrgF r7mV6V2V78Ex8P7YoL9CfndnoYcq5mZTwKhuKZaenHNYk33qAuEVOkwGI+JcedSn OHYMpp6ckBxSzsNcekc+mH0i -----END PRIVATE KEY-----
7. 解RSA加密 常见的填充方式包括:
python无敌
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 from cryptography.hazmat.backends import default_backendfrom cryptography.hazmat.primitives import serializationfrom cryptography.hazmat.primitives.asymmetric import paddingfrom cryptography.hazmat.primitives import hashesimport base64encrypted_data_b64 = "gAp9xge69vuNF4Kyr/UcjO3iFlFt+e5OFZ5/zYcv703qor2K0eorwcbddlgX/6JiAq1+qnbKPnOZ+MHk7Vy55wKeLYShEvc44jZYT0HIoHLEczXOFgq8qdNsF7RhjNYNNKzDy1cc0i2pDXGTczxqct0CUkHUNI0jkpn9Vm8O19J/caIWb1NdOzfhr86gEzehkXh560sv5X8LBgo0kmJc9pEprJ+SV9vQ4pA4W+C7AtipyC7FU/51tUI/Dl9q2hpUnE1Qt4PyBDsRiaWWQ0ORQCANEapVc/b70ffxYDim5aBfvwYhc7DEo5oFcQUOiAorOnWayzz3CE0I+4qu5nRqgg==" private_key_str = """-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC04AAI4K7DdGTx KL86f54wT0ouQrDlL4krCz7DfeuFtaRPbHR/X+2wV7iX+e+doquuAgJ56DyLaRgm ZxV6ksn/vfg0qVJlKfgfqnUsH+5quun14oc7gsdNWHkJqUh9O8pTce/ElK2YbABi 9J06p4Z1PyxpjTkViFz+YVpY5zHo2ysa4tlH1VCpYjjzUQXAMD3NbroBXTYa2Lex UI/Xb2mnZepcGc5/ovQAzf227ORwNS6TcQiz0Wa+V7Ggz3fNBqtqipVg6QHT71a7 TOfZCOPTOW6K49p70DX+3Z3ezpIiX/ZpgBGGAckMGsNsI8lGIAR3vjXsNBeQ0sn2 FFnp+T+9AgMBAAECggEAFo0TFAhHYdEiQLsO1JFSvL02B3yDJ5/8nyRAyAjsE3ip Ksnf4H2qWeEl/7TGvkWo2AIiIubknZEV1LvnfqfMjZk22AIAZuKLsA8FmuHETQRO 5TxAFhhhFvCf7qdvhUWuHSdIeJ784dMdXTkYXVbDudyNgf98jYW56nFi3VC99UUg TaZWXAwr0yjDVqRWe2TpqjDAqNauvVFOhJgsNQ2yJf+XjqTLngM05vQg97CY1BUa pQ4YlvonfX2t4URxz5wsf88DJCRvjTuedezNFyMfyJyPWFylDsvoio9UTk000Tae Zr7Ab0e+gMbdcgo7lgOw7jue0mM+SH/uILU8SaRHVQKBgQDpcibMd56CQ0MT7Kw/ Zue1hpjrcaWlCK5nZ/21Eyu5giAA8CcKvTAL08r4E/ZV7gs28wsk8TZ/wvP63Xqj +Z+t98IRgJyFhed/2cUHRjEtGBkPbrzG0f2QgzDXx2Xkg27h6xXH7SSCZ6SV5Wr2 Ngnt9LuKmjnQx90sAhBxRpblIwKBgQDGWZr/DBncbK6/SKKr+h7sf8fWmEJvlC9E 2pyszEm6foKMxUKOCLpvzLuXZBDDj4tJrPg2oGaA2zU9TAvzX6spT7VnvJhwmP+r +QUysTnv0rUZDs5mHGYbjWly+9J6GcYzb896kL6EMK9BNGVfSiH2vsV6ugYJIo61 Zkv/+6/FnwKBgQC7qp3QL7WIiKQLB29tRL+vKXYTiHgeVP1Hecz2XWQALMCnoGfy dSaDy45Wok2cxNHVKctitlsWmFXk7VmjKpCYnR0xTtAFcyEooZuH/oCX/NBgnKg7 uSJ7o0uHm++opZRlH8SRxW1dPA6OxjCXn9eZqO1/Pf6Ofa2qrDolpha2OwKBgG23 y0Eh1HxVsiQlbbZr2QdBd62A8978vVj9BIWhS3dZ26U6yKIAugB1457Ov2ct1AKh J3wwJgNJPp31nva1CN0FNnd3n2tJdsQOL43m8wFyMLL3ubxKIUFEa/wqyDa6YyS4 yLAnuPsuYwNSlHCtdTQkOuC0XfpXn1FAkPG8q3JJAoGBAMy4385KPM27iQE38UBm 9gh17VBqaUxd+9s6Zkb4noS00vR3S0oDrQaNIdPCJphm1xlewqx2jbYMQX7aDrgF r7mV6V2V78Ex8P7YoL9CfndnoYcq5mZTwKhuKZaenHNYk33qAuEVOkwGI+JcedSn OHYMpp6ckBxSzsNcekc+mH0i -----END PRIVATE KEY-----""" encrypted_data = base64.b64decode(encrypted_data_b64) private_key = serialization.load_pem_private_key( private_key_str.encode(), password=None , backend=default_backend() ) def decrypt_data (encrypted_data ): try : print (f"Try padding_type OAEP to Decryption..." ) return private_key.decrypt( encrypted_data, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) except Exception as e: print (f"OAEP Decryption failed" ) try : print (f"Try padding_type PKCS1v15 to Decryption..." ) return private_key.decrypt( encrypted_data, padding.PKCS1v15() ) except Exception as e: print (f"PKCS1v15 Decryption failed" ) decrypted_data = decrypt_data(encrypted_data) print (decrypted_data.decode())
b4e9ab2f61cbfda4
8. 解MD5加密 首先他有十六位
可能是某种数据的哈希值 例如
MD5(16/32位十六进制)
SHA-1(40位十六进制)
SHA-256(64位十六进制)
MD5加密后的位数有两种类型: 16位与32位 默认使用32位。 16位实际上是从32位字符串中取中间的第9位到第24位的部分
例如 “admin” : 16位加密 7a57a5a743894a0e 32位加密 21232f297a57a5a743894a0e4a801fc3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import hashlibp1 = 1 target_hash = "b4e9ab2f61cbfda4" for i in range (100000 ): original_data = f"{i:05d} " hash_value = hashlib.md5(original_data.encode()).hexdigest() if p1: hash_value = hash_value[8 :24 ] if hash_value == target_hash: print (f"Found original data: {original_data} " ) break else : print ("Original data not found." )
Found original data: 95173
9.小结 解密成功
这个密码正好对应了本作游戏公司Odd Games
Odd有奇数的含义
给予创作者大大的肯定👍
测评 一款单人解密策略模拟游戏。玩家将穿越回到1999年躲避流氓软件的恶意安装。
前面的关卡还是比较常见。到了中间有不少关卡还是没见过,有些难找需要攻略。
优点: - 主题玩法新颖 - 探索性强 - 构思巧妙
缺点: - 内置小游戏戏份过重 - 体量小