2024年羊城杯粤港澳大湾区网络安全大赛WP-数据安全 AK篇

WriteUp 2周前 admin
17 0 0

data-analy1

import csv
import re

field_patterns = {
    '手机号码'r'^d{11}$',
    '身份证号'r'^d{17}[dX]$',
    '出生日期'r'^d{8}$',
    '性别'r'^(男|女)$',
    '密码'r'^[a-fA-Fd]{32}$',
    '姓名'r'^[u4e00-u9fff]+$',
}

desired_fields = ['编号''用户名''密码''姓名''性别''出生日期''身份证号''手机号码']

def match_field(value):
    for field_name, pattern in field_patterns.items():
        if re.match(pattern, value):
            return field_name
    return '编号' if value.isdigit() and 1 <= int(value) <= 10000 else '用户名'


def reorganize_fields(row):
    result_row = {field: '' for field in desired_fields}
    for value in row:
        field_type = match_field(value)
        result_row[field_type] = value
    return [result_row[field] for field in desired_fields]

def reorganize_csv(input_csv, output_csv):
    with open(input_csv, mode='r', encoding='utf-8'as infile, open(output_csv, mode='w', encoding='utf-8', newline=''as outfile:
        reader = csv.reader(infile)
        writer = csv.writer(outfile)
        original_header = next(reader)
        print(f'Original Header: {original_header}')
        print(f'Reorganized Header: {desired_fields}')
        writer.writerow(desired_fields)
        for row in reader:
            reorganized_row = reorganize_fields(row)
            writer.writerow(reorganized_row)
            # print(reorganized_row)
input_file = 'person_data.csv'  # Replace with your CSV file path
output_file = 'result.csv'
reorganize_csv(input_file, output_file)

2024年羊城杯粤港澳大湾区网络安全大赛WP-数据安全 AK篇

将result.csv文件上传,得到flag。

data-analy2

利用如下命令提取相关数据:

tshark -r data.pcapng -Y http.request.method==POST -T fields -e json.value.string >1.csv

再编写如下脚本提取不符合格式数据:

import csv
import re

# 定义正则表达式模式
username_pattern = r'^[a-zA-Z0-9]+$'
name_pattern = r'^[u4e00-u9fa5]+$'
sex_pattern = r'^男|女$'
birth_pattern = r'^d{8}$'
idcard_pattern = r'^d{6}d{8}d{3}[dX]$'
phone_pattern = r'^d{11}$'
phone_prefix = ['734''735''736''737''738''739''747''748''750''751''752''757''758''759''772',
                '778''782''783''784''787''788''795''798''730''731''732''740''745''746''755',
                '756''766''767''771''775''776''785''786''796''733''749''753''773''774''777',
                '780''781''789''790''791''793''799']

# 定义验证函数
def validate_username(username):
    return bool(re.match(username_pattern, username))


def validate_name(name):
    return bool(re.match(name_pattern, name))


def validate_sex_idcard(sex, idcard):
    """
    验证性别是否与身份证号一致。

    参数:
    sex (str): 性别, 可以是 "男" 或 "女"。
    idcard (str): 18 位身份证号码。

    返回值:
    bool: 如果性别与身份证号一致, 返回 True; 否则返回 False。
    """

    # 检查输入是否符合要求
    if sex not in ("男""女"):
        return False
    if len(idcard) != 18:
        return False

    # 根据身份证号码的倒数第二位判断性别
    if int(idcard[-2]) % 2 == 0:
        idcard_sex = "女"
    else:
        idcard_sex = "男"

    # 比较输入的性别与身份证号码的性别
    return sex == idcard_sex


def validate_birth(birth,id_number):
    if birth != id_number[6:14]:
        return False
    return bool(re.match(birth_pattern, birth))

real_address_codes = set(['110101''110102''110105''110106''110107''110108''110109''110111''110112''110113''110114''110115''110116''110117''110118''110119'])

def validate_id_number(id_number):
    """验证身份证号是否合法"""
    if len(id_number) != 18:
        return False
    # 验证地址码是否随机生成
    address_code = id_number[:6]
    if address_code in real_address_codes:
        return False
    # 验证校验码是否正确
    weights = [7910584216379105842]
    total = sum(int(id_number[i]) * weights[i] for i in range(17))
    remainder = total % 11
    check_codes = '10X98765432'
    if check_codes[remainder] != id_number[-1]:
        return False
return True

def validate_phone(phone):
    if not bool(re.match(phone_pattern, phone)):
        return False
    # 检查手机号前缀是否在指定集合中
    if phone[:3not in phone_prefix:
        return False
    return True

# 读取数据并进行验证
data = [
    ['admin8liuhui''鲁芸若''女''19821120''757804199811282189''73760289367'],
    ['liuleiling#ahuopu''I如馨''I''20130805''945955201308057119''77267902532'],
    ['processor''丘陵晴丽''女''20130628''07415020130628957X''78596827832'],
    ['Magic>erooracle''傅余0明''B''19961007''731225199610078288''35375804180']
]
with open('1.csv''r'as file:
    reader = csv.reader(file)
    data = list(reader)
with open('garbage_data.csv''w', newline='', encoding='utf-8'as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(['username''name''sex''birth''idcard''phone'])
    for row in data:
        if len(row)!=6:
            writer.writerow(row)
            continue
        username, name, sex, birth, idcard, phone = row
        print(idcard)
        if not validate_username(username) or 
                not validate_name(name) or 
                not validate_sex_idcard(sex,idcard) or 
                not validate_birth(birth,idcard) or 
                not validate_id_number(idcard) or 
                not validate_phone(phone):
            writer.writerow(row)

2024年羊城杯粤港澳大湾区网络安全大赛WP-数据安全 AK篇

data-analy3

直接在log里面提取,要注意是出现一次用户名信息就会出现一次密码信息,分为用户不存在,信息更新,密码正确三类。

# -*- coding: utf-8 -*-;
import re
import hashlib

f = open('error.log''r', encoding='utf8')
param = open('param.txt''w', encoding='utf8')

line = f.readline()

while line:
    # print(line)
    #data = re.findall(r"user(.*?)n",line.strip())
    match = re.search(r'username=.*', line)
    if match:
        print(match.group(0))
        param.write(match.group(0))
        line = f.readline()
        while line:
            if '\x81\xe4\xb8\xba' in line:
                password = line.strip().split(': ')[-1][:-2]
                print(password)
                param.write('&password=' + password + 'n')
                break
            if '\xe5\x9c\xa8\xef\xbc\x81' in line:
                param.write('&password=' + 'n')
                break
            line = f.readline()
    line = f.readline()

phone_head = ['734''735''736''737''738''739''747''748''750''751''752''757''758''759''772',
              '778''782''783''784''787''788''795''798''730''731''732''740''745''746''755',
              '756''766''767''771''775''776''785''786''796''733''749''753''773''774''777',
              '780''781''789''790''791''793''799']
ck = {'0''1''1''0''2''X''3''9''4''8''5''7''6''6''7''5''8''4''9''3''10''2'}


def parser2list(p):
    # a = [p['username'][0], '', p['name'][0], p['idcard'][0], p['phone'][0]]
    a = []
    if len(p['username'][0]) == 2:
        a.append(p['username'][0][0] + '*')
    else:
        a.append(p['username'][0][0] + '*' * (len(p['username'][0]) - 2) + p['username'][0][-1])
    a.append(hashlib.md5(p['password'][0].encode()).hexdigest())
    if len(p['name'][0]) == 2:
        a.append(p['name'][0][0] + '*')
    else:
        a.append(p['name'][0][0] + '*' * (len(p['name'][0]) - 2) + p['name'][0][-1])
    a.append('*' * 6 + p['idcard'][0][6:10] + '*' * 8)
    a.append(p['phone'][0][:3] + '*' * 4 + p['phone'][0][7:])
    return a


def IsChinese(character):
    for cha in character:
        if not 'u0e00' <= cha <= 'u9fa5':
            return False
    else:
        return True

def check_string(re_exp, str1):
    res = re.search(re_exp, str1)
    if res:
        return True
    else:
        return False

def validId(s):
    n = int(s[0]) * 7 + int(s[1]) * 9 + int(s[2]) * 10 + int(s[3]) * 5 + int(s[4]) * 8 + int(s[5]) * 4 + int(
        s[6]) * 2 + int(s[7]) * 1 + int(s[8]) * 6 + int(s[9]) * 3 + int(s[10]) * 7 + int(s[11]) * 9 + int(
        s[12]) * 10 + int(s[13]) * 5 + int(s[14]) * 8 + int(s[15]) * 4 + int(s[16]) * 2
    n = n % 11
    if s[-1] == ck[str(n)]:
        return True
    else:
        return False
f = open('param.txt''r', encoding='utf8')
out = open('final.txt''w', encoding='utf8')
fail_out = open('no_final.txt''w', encoding='utf8')
out.write('username,password,name,idcard,phonen')
index = 0
for i in f.readlines():
    index += 1
    print(i)
    p = urllib.parse.parse_qs(i.strip())
    print(p)
    if check_string('^[a-zA-Z0-9]+$', p['username'][0]):  # username
        if IsChinese(p['name'][0]):
            if validId(p['idcard'][0]) and len(p['idcard'][0]) == 18:
                if p['phone'][0][:3in phone_head and len(p['phone'][0]) == 11:
                    if 'password' in p.keys():
                        print(p)
                        out.write(','.join(parser2list(p)) + 'n')

原文始发于微信公众号(山石网科安全技术研究院):2024年羊城杯粤港澳大湾区网络安全大赛WP-数据安全 AK篇

版权声明:admin 发表于 2024年8月31日 下午12:51。
转载请注明:2024年羊城杯粤港澳大湾区网络安全大赛WP-数据安全 AK篇 | CTF导航

相关文章