实战 JS逆向思路

2024-03-11 984 0

前言

话说在一次的授权测试中,发现了一个有意思的站点,通篇密文,然后我便开始研究其中的解码方法,并附上一些知识点,正文如下。

十六进制解码条件

如果要解密一大串的十六进制编码的数据,第一步肯定要知道需要哪些必要条件才能进行解码啊,那么我们就需要知道以下信息:1. 加密算法:首先,你需要知道所使用的加密算法。常见的加密算法包括AES、DES、RSA等。在你的情况下,你提到是AES加密,这是非常常见且安全的一种对称加密算法。

2. 密钥:对于对称加密算法(如AES),你需要知道用于加密和解密的密钥。密钥的长度可以是128位、192位或256位,这取决于你选择的AES变体(AES-128、AES-192、AES-256)。

3. 初始化向量 (IV):对于某些模式(如CBC模式),你需要一个初始化向量(IV)。IV不需要是保密的,但必须与密文匹配。也就是说,如果你用相同的密钥和不同的IV加密两次,那么两次加密的结果将是不同的,但都可以被相同的密钥和IV解密。

4. 模式:AES可以与多种模式一起使用,如ECB、CBC、CFB、OFB等。不同的模式有不同的用途和安全性考虑。在ECB模式中,对于相同的明文内容,每次加密都会生成相同的密文。这意味着,如果使用相同的密钥对多个块进行加密,每个块都将生成相同的密文。而在CBC模式中,每个块的加密都取决于前一个块的密文。这意味着,对于相同的明文内容,每次加密都会生成不同的密文

5. 填充方案:某些模式需要特定的填充方案。例如,在CBC模式中,通常使用PKCS#7填充。

综上,我们需要知道它使用的加密算法、密钥、模式以及初始化向量IV值(只针对于某些模式),接下来我们进入实战分析。

JS算法逆向【AES算法】

1. 访问页面:

第一反应,直接扔到https://gchq.github.io/CyberChef/里解码,失败。

2. 回到原本的站点找寻解码方式,回到初始门户网站点击F12,开始全局搜索decrypt函数,尝试寻找其加密解密方式:

发现加解密算法为AES,模式有cbc模式,还有ecb模式。(这里下文会进行分点分析)

3. 继续基于AES的加密算法,检索AES,发现new AES的函数,这里传入的参数就是密钥,并把断点就打在key被赋值后,也就是下图中的this.prepare(),然后就发现密钥被打印在控制台了:

在控制台中输入this.key         【访问当前对象(this)有一个名为 key 的属性】

再输入this.key.toString();         【获取 key 属性的值,并调用它的 toString() 方法。toString() 是一个内置方法,用于将一个对象转换为字符串表示形式。如果 key 是一个数字或其他非字符串类型,这将很有用,因为你可以得到一个字符串形式的表示。】4. 显示的密钥为:116, 104, 101, 45, 116, 101, 114, 114, 111, 114, 105, 115, 116, 115, 46, 46
看起来是一串字符的ASCII码值,用逗号分隔,故尝试将这些值转换回对应的字符。可以写个脚本进行解码,脚本如下:

# 定义密钥的ASCII码值列表  
key_list = [116, 104, 101, 45, 116, 101, 114, 114, 111, 114, 105, 115, 116, 115, 46, 46]  
  
# 使用chr()函数将ASCII码值转换为字符,并使用join()函数连接成字符串  
key_string = ''.join(chr(value) for value in key_list)  
  
print(key_string)  # 输出: "th!te!tr!to!ti!ts!tu.u"

运行脚本输出结果为:the-terrorists..

也可以放到https://gchq.github.io/CyberChef/解一下,成功,结果为:the-terrorists..
5. 现在已知条件都差不多了,开始编写一个解密脚本,输出解密成功后的内容,但是从步骤2得知有ecb和cbc两个模式,怎么办呢,那就都尝试一下。

EBC模式

已知:密文(访问页面中的就是)、加密方式aes、密钥the-terrorists..

但是ECB模式不需要初始化向量。(所以ECB模式进行加密和解密可能会导致安全问题,因为它不提供真正的块加密的安全性,但是由此以来提高了加密速度)

解密脚本编写如下:

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes  
from cryptography.hazmat.backends import default_backend  
from cryptography.hazmat.primitives import padding  
import binascii  
  
# 密钥和初始向量  
key = b"the-terrorists.."  
iv = b""  # ECB模式不需要初始向量  
  
# 十六进制密文  
hex_ciphertext = "your-hex-ciphertext"  
  
# 将十六进制密文转换为二进制数据  
ciphertext = binascii.unhexlify(hex_ciphertext)  
  
# 创建一个AES解密器对象  
cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())  
  
# 创建一个PKCS#7填充器对象  
padder = padding.PKCS7(128).padder()  
  
# 解密数据(需要一个与加密时匹配的填充方案)  
decryptor = cipher.decryptor()  
decrypted_data = decryptor.update(ciphertext) + decryptor.finalize()  
  
# 去除填充字节(如果存在)  
unpadder = padding.PKCS7(128).unpadder()  
decrypted_data = unpadder.update(decrypted_data) + unpadder.finalize()  
  
# 将二进制数据转换为字符串  
decrypted_text = decrypted_data.decode("utf-8")  
  
print("Decrypted Text:", decrypted_text)

cmd运行一下,发现报错:错误可能的原因包括:

问题出在解密过程中的去填充(unpadding)步骤。具体来说,cryptography库在尝试去除PKCS#7填充时遇到了无效的填充字节,导致了ValueError异常。

这个问题通常发生在解密的数据被篡改或损坏的情况下。如果加密和解密使用的是相同的密钥和算法,并且输入的数据是有效的密文,那么解密过程应该能够成功完成,不会出现这样的错误。

解决这个问题的方法是:

(1)检查密文:确保你使用的密文是有效的,并且没有被篡改。

(2)检查密钥和算法:确保你使用的密钥和加密算法与用于加密的密钥和算法匹配。

(3)检查填充方案:确保你在解密时使用的填充方案与加密时使用的填充方案一致。

(4)使用正确的库版本:确保你使用的cryptography库版本与加密时使用的版本兼容。

对于第一点,还有待商榷,那就先不管第一点,去尝试第二种模式CBC模式进行解密

CBC模式

已知:密文(访问页面中的就是)、加密方式aes、密钥the-terrorists..

CBC模式使用一个随机生成的初始化向量,使得相同的明文块加密为不同的密文块。(所以CBC模式相比ECB模式提高了安全性,但同时由于串行处理数据,使得加密速度很慢)

在前文“十六进制解码条件”中提到CBC模式需要一个初始化向量IV,在这里IV代码里没写,故CBC模式的IV被硬编码为全0的字节串。

初始化向量(IV)是一个用于加密算法的随机或伪随机的数值,通常与密钥一起使用来初始化密码算法的状态。在加密过程中,IV起着随机化的作用,以确保相同的明文在经过相同密钥的加密下产生不同的密文,增加密码强度。

综上,解密脚本编写如下:

#!/usr/bin/python  
from cryptography.hazmat.backends import default_backend  
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes  
from cryptography.hazmat.primitives import padding  
  
def decrypt_aes(key_str, ciphertext_hex):  
    backend = default_backend()  
      
    # 将密钥字符串转换为字节串  
    key = bytes(key_str, 'utf-8')  
      
    # 将十六进制字符串转换为字节串  
    ciphertext = bytes.fromhex(ciphertext_hex)  
      
    # 使用AES算法和CBC模式  
    cipher = Cipher(algorithms.AES(key), modes.CBC(bytes([0]*16)), backend=backend)  
      
    decryptor = cipher.decryptor()  
      
    # 解密密文  
    decrypted_data = decryptor.update(ciphertext) + decryptor.finalize()  
      
    # 使用PKCS7填充,可以根据具体情况选择其他填充方式  
    unpadder = padding.PKCS7(128).unpadder()  
      
    # 移除填充并返回解密后的数据  
    return unpadder.update(decrypted_data) + unpadder.finalize()  
  
def main():  
    # 提示用户输入密钥和密文  
    key_str = input("请输入密钥(字符串格式):")  
    ciphertext_hex = input("请输入十六进制密文: ")  
      
    try:  
        decrypted_data = decrypt_aes(key_str, ciphertext_hex)  
        print("Decrypted Data:", decrypted_data[16:].decode('utf-8'))  
        #print(bytes.fromhex(decrypted_data.hex()))  
    except Exception as e:  
        print("Decryption error:", e)  
  
if __name__ == "__main__":  
    main()

运行一下,成功解码:还可以使用在线解密工具https://www.toolhelper.cn/:    都可以成功解密,完结撒花!

最后

如果我即时去复现的话那么这个手机号中间4位是不会有****的,但是由于工作繁忙+期间站点停过,所以现在才有时间把这篇文章给梳理完,导致管理员已经把泄露的手机号打码了。


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

靶场战神为何会陨落?
漏洞分析与实战分享 | 深入探讨pkexec提权漏洞
postMessage常见安全问题
[Meachines] [Medium] Lightweight LDAP密码嗅探+TRP00F 自…
ofcms V1.2 代码审计(一)
网安内家拳——东西向网络安全是门高级功夫

发布评论