第八届西湖论剑·中国杭州网络安全安全技能大赛-Misc-DSASignatureData

用wireshark查看过滤POST之后发现传输的信息
在这里插入图片描述
先用脚本提取其中的信息保存在extracted_data.json文件中

import pyshark
from urllib.parse import urlparse, parse_qs
import json

# 用于存储提取的数据
extracted_data = []

# 读取PCAP文件并过滤 HTTP POST 请求
cap = pyshark.FileCapture("1.pcapng", display_filter="http.request.method == POST")

# 遍历捕获的数据包,提取 HTTP POST 请求
for packet in cap:
    if "HTTP" in packet:
        try:
            # 尝试从 packet.http.uri 获取 URI
            uri = packet.http.uri if hasattr(packet.http, 'uri') else None
            # 如果没有找到 uri,尝试使用 full_uri
            if uri is None and hasattr(packet.http, 'request_full_uri'):
                uri = packet.http.request_full_uri

            if uri:
                # 从 URI 中提取 userid 参数
                parsed_uri = urlparse(uri)
                query_params = parse_qs(parsed_uri.query)
                userid = query_params.get("userid", [None])[0]  # 获取userid参数

                # 如果找到了userid,就继续处理
                if userid:
                    print(f"UserID Found: {userid}")

                    # 提取并打印 POST 请求体数据(如果有的话)
                    if hasattr(packet.http, 'file_data'):
                        # 获取 POST 数据,数据是十六进制字符串
                        raw_data = packet.http.file_data
                        # 去掉冒号,将十六进制字符串转为字节
                        raw_data_no_colon = raw_data.replace(":", "")

                        try:
                            # 将十六进制字符串转换为字节
                            byte_data = bytes.fromhex(raw_data_no_colon)
                            decoded_data = byte_data.decode('utf-8')

                            # 处理 Unicode 转义字符
                            decoded_data = decoded_data.encode('utf-8').decode('unicode_escape')

                            # 提取 name, idcard, phone
                            data = json.loads(decoded_data)
                            if all(k in data for k in ['name', 'idcard', 'phone']):
                                # 将 userid, name, idcard, phone 保存到字典中
                                extracted_data.append({
                                    "userid": userid,
                                    "name": data["name"],
                                    "idcard": data["idcard"],
                                    "phone": data["phone"]
                                })
                        except UnicodeDecodeError:
                            print("Unable to decode POST data as UTF-8.")

        except AttributeError as e:
            print(f"Error parsing packet: {e}")

# 将提取的数据保存到一个 JSON 文件
with open("extracted_data.json", "w", encoding="utf-8") as f:
    json.dump(extracted_data, f, ensure_ascii=False, indent=4)

print(f"Extracted data saved to extracted_data.json")

再对json文件进行转换,其中包含排序和去重操作,并保存在output_sorted_unique.csv中

import csv
import json

# 假设你的数据在 extracted_data.json 中,首先读取数据
with open("extracted_data.json", "r", encoding="utf-8") as f:
    json_data = json.load(f)

# 如果数据是字典格式(仅有一个记录),将其转换为列表
if isinstance(json_data, dict):
    json_data = [json_data]

# 将所有字段转换为文本,确保统一格式
for entry in json_data:
    for key in entry:
        entry[key] = str(entry[key])  # 将每个字段转换为字符串

# 去重:使用集合对去重
unique_data = {tuple(entry.items()) for entry in json_data}

# 将去重后的数据重新转换为字典
unique_data = [dict(item) for item in unique_data]

# 排序:根据 userid 排序,确保按数字顺序排序
unique_data.sort(key=lambda x: int(x["userid"]))  # 按照 userid 排序,先转成整数


# 指定输出的 CSV 文件名称
csv_file = "output_sorted_unique.csv"

# 打开 CSV 文件进行写入
with open(csv_file, mode='w', newline='', encoding='utf-8') as file:
    # 创建 DictWriter 对象,字段名称根据 JSON 字典的键来设置
    fieldnames = ["userid", "name", "idcard", "phone"]
    writer = csv.DictWriter(file, fieldnames=fieldnames)

    # 写入表头
    writer.writeheader()

    # 写入每一行数据
    writer.writerows(unique_data)

print(f"CSV 文件已保存为 {csv_file}")

下面就开始对签名进行验证,并将验证不成功即被篡改的数据放到flag.csv中

import csv
from Crypto.PublicKey import DSA
from Crypto.Signature import DSS
from Crypto.Hash import SHA256
import base64

# 1. 加载公钥
def load_public_key(filename):
    with open(filename, 'rb') as f:
        key = DSA.import_key(f.read())
    return key

# 2. 验证数字签名
def verify_signature(data, signature, public_key):
    h = SHA256.new(data.encode())  # 计算数据的哈希值
    verifier = DSS.new(public_key, 'fips-186-3')  # 使用DSA算法进行签名验证
    try:
        # 解码Base64签名并验证
        verifier.verify(h, base64.b64decode(signature))
        return True  # 验证通过
    except ValueError:
        return False  # 验证失败

# 3. 读取数据文件并进行签名验证
def validate_signatures(data_file, signature_file, flag_file):
    # 打开flag.csv文件,用于保存验证失败的记录
    with open(flag_file, 'w', newline='', encoding='utf-8') as f_flag:
        flag_writer = csv.writer(f_flag)
        flag_writer.writerow(['userid', 'name', 'idcard', 'phone'])  # 写入表头

        # 读取数据文件和签名文件
        with open(data_file, 'r', encoding='utf-8') as f_data, open(signature_file, 'r', encoding='utf-8') as f_sig:
            reader_data = csv.reader(f_data)
            reader_sig = csv.reader(f_sig)

            # 跳过标题行
            next(reader_data)
            next(reader_sig)

            # 对每一行数据进行签名验证
            for data_row, sig_row in zip(reader_data, reader_sig):
                userid, name, idcard, phone = data_row
                username, name_signature, idcard_signature, phone_signature = sig_row

                # 获取对应用户的公钥
                public_key_filename = f"public/public-{userid.zfill(4)}.pem"
                public_key = load_public_key(public_key_filename)

                # 验证每个字段的签名
                is_name_valid = verify_signature(name, name_signature, public_key)
                is_idcard_valid = verify_signature(idcard, idcard_signature, public_key)
                is_phone_valid = verify_signature(phone, phone_signature, public_key)

                # 检查是否有任意一项验证失败
                if not is_name_valid or not is_idcard_valid or not is_phone_valid:
                    # 如果有验证失败,则将这一行写入flag.csv
                    flag_writer.writerow([userid, name, idcard, phone])

                # 输出验证结果
                print(f"用户{userid}验证结果:")
                print(f"  姓名签名验证{'通过' if is_name_valid else '失败'}")
                print(f"  身份证签名验证{'通过' if is_idcard_valid else '失败'}")
                print(f"  电话签名验证{'通过' if is_phone_valid else '失败'}")
                print("-" * 30)

# 文件路径
data_file = 'output_sorted_unique.csv'  # 你的数据文件
signature_file = 'data-sign.csv'  # 你的签名文件
flag_file = 'flag.csv'  # 保存验证失败记录的文件

# 执行签名验证并保存不通过的数据到flag.csv
validate_signatures(data_file, signature_file, flag_file)

最终在平台提交flag.csv得到flag

在这里插入图片描述
提交即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值