数安题目附件
https://wwapq.lanzoub.com/b01bjg8v3g 密码:18bg
pclean
题目内容:某保险平台在用户注册过程中收集了大量个人信息,但由于数据录入系统存在漏洞,导致数据库中混入了许多不符合规范的"脏数据"。现需要你对这些数据进行清洗,识别出所有不符合规范的数据记录。附件中的 user_data.db即为数据库文件,请你依据附件中的《个人信息数据规范文档.md》,识别出所有不符合规范的数据记录。将数据清洗后的"脏数据"结果保存到csv文件(文件编码为utf-8)中,并将该文件上传至该题的校验平台(在该校验平台里可以下载该题的示例文件example.csv,可作为该题的格式参考),校验达标即可拿到flag
┼────────────────────────────────────┤ │ username │ 仅大小写字母、数字、下划线 │ ├──────────┼─────────────────────_─────────────┤ │ name │ 仅中文字符 │ ├──────────┼────────────────────────────────────┤ │ gender │ 仅"男"或"女" │ ├──────────┼────────────────────────────────────┤ │ phone │ 11位数字,前3位在指定号段内 │ ├──────────┼────────────────────────────────────┤ │ email │ 恰好一个@,@前后有内容,域名含后缀 import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)SecretBackup
题目内容:安全审计团队在公司离职员工的云盘中发现了一份加密的数据备份文件。该员工曾负责财务系统维护,存在数据窃取嫌疑。请对这份备份文件进行安全审计,还原其中隐藏的敏感信息。
压缩包解压密码为:202501
修复损坏的 PNG 文件原始 PNG 文件头存在两处错误:文件签名错误:前 4 字节不是标准的 89 50 4E 47(‰PNG)IHDR 高度错误:IHDR 中高度字段为 400(0x00000190),但根据解压数据量(1920800 字节)推算,正确高度应为 800;修复后重新计算 IHDR 的 CRC32 校验值修复步骤:data[0:4] = b'x89PNG'# 修正签名data[20:24] = struct.pack('>I', 800) # 修正高度为 800crc = binascii.crc32(data[12:29]) & 0xFFFFFFFF # 重新计算 CRCdata[29:33] = struct.pack('>I', crc) # 写入正确 CRC#!/usr/bin/env python3"""修复 SecretBackup 挑战中损坏的 PNG 文件:1. 修正文件签名(前4字节改为 89 50 4E 47)2. 修正 IHDR 高度(400 → 800)3. 重新计算并写入正确的 IHDR CRC32"""import structimport binasciiimport sysdef fix_png(input_path, output_path=None):# 读取原始文件 with open(input_path, 'rb') as f: data = bytearray(f.read())# 1. 修复 PNG 签名:前 4 字节应为 89 50 4E 47('x89PNG') data[0:4] = b'x89PNG'# 2. 修复 IHDR 高度:从 400 (0x00000190) 改为 800 (0x00000320)# IHDR 块结构(偏移基于文件起始):# 0-7: 签名# 8-11: 块长度(13)# 12-15: 块类型 "IHDR"# 16-19: 宽度# 20-23: 高度 <-- 目标# 24: 位深度# 25: 颜色类型# 26: 压缩方法# 27: 滤波方法# 28: 交错方法# 29-32: CRC32(覆盖偏移 12-28 共 17 字节) old_height = struct.unpack('>I', data[20:24])[0]print(f"[*] 当前高度: {old_height}")# 新高度 800(由 IDAT 解压数据量 1920800 字节推算:# height = decompressed_size / (width * 3 + 1) = 1920800 / 2401 = 800) new_height = 800 data[20:24] = struct.pack('>I', new_height)print(f"[*] 已修改高度为: {new_height}")# 3. 重新计算 IHDR CRC32(覆盖 类型 + 数据 = data[12:29]) crc_data = data[12:29] # 'IHDR' + 13 字节数据 new_crc = binascii.crc32(crc_data) & 0xFFFFFFFFprint(f"[*] 新 CRC32: {new_crc:}")# 写入 CRC(偏移 29-32,大端序) data[29:33] = struct.pack('>I', new_crc)# 保存结果if output_path is None: output_path = input_path.replace('.png', '_fixed.png') with open(output_path, 'wb') as f: f.write(data)print(f"[+] 修复完成,已保存到: {output_path}")return output_pathif __name__ == '__main__':if len(sys.argv) > 1: input_file = sys.argv[1]else: input_file = '202501_secret.png'# 默认文件名 fix_png(input_file)flag{b2607454056ecb4d3dc9375a6fb76fdb}
peach_garden_xor
题目内容:公司在进行历史文档归档时,将一份重要的.docx文件进行了简单加密后存入备份系统。现在备份系统只导出了加密后的文件task.docx.enc,原始密钥已经丢失。请你从这份加密文档中恢复被隐藏的数据内容,找回其中的flag。
## Summary.docx 文件经简单异或加密后丢失密钥。利用 ZIP/DOCX 固定文件头 `PKx03x04` 进行已知明文攻击恢复密钥,解密提取文档内容后 ROT13 解码获得 flag。## Solution### Step 1: 恢复异或密钥.docx 本质是 ZIP 压缩包,文件头固定为 `50 4B 03 04` (PKx03x04)。读取加密文件头部 4 字节与已知明文异或即可得到密钥 `01 35 7C A9`。### Step 2: 解密并提取文档用恢复的 4 字节密钥循环异或解密整个文件,得到有效 ZIP 后解压提取 word/document.xml。文档内容为《三国演义》桃园结义选段,末尾藏有 ROT13 编码的 flag 字符串。### Step 3: ROT13 解码`synt{nq213351-9510-46p0-8622-9pqrn9s634q2}` → ROT13 → 最终 flag。# peach_garden_xor - Solve Script# XOR decrypt .docx -> extract text -> ROT13 decode flagimport zipfileimport ioimport codecsimport xml.etree.ElementTree as ET# Read encrypted filewith open('task.docx.enc', 'rb') as f: enc = f.read()# Known plaintext attack: .docx/ZIP header PKx03x04 -> 50 4B 03 04KEY = [enc[0] ^ 0x50, enc[1] ^ 0x4B, enc[2] ^ 0x03, enc[3] ^ 0x04]print(f"[*] Recovered XOR key: {bytes(KEY).hex()}")# Decrypt with repeating XOR keydec = bytes([enc[i] ^ KEY[i % 4] for i in range(len(enc))])# Extract document.xml from ZIPz = zipfile.ZipFile(io.BytesIO(dec))xml = z.read('word/document.xml')# Parse Word document textns = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'tree = ET.fromstring(xml)texts = [t.text for t in tree.iter(f'{{{ns}}}t') if t.text]content = ''.join(texts)# Find the ROT13-encoded flag pattern in document textimport rematch = re.search(r'[a-z]+{[a-z0-9-]+}', content)encoded = match.group(0)flag = codecs.encode(encoded, 'rot_13')print(f"[+] Flag: {flag}")flag{ad213351-9510-46c0-8622-9cdea9f634d2}
exam_system
题目内容:某教育机构的在线考试系统近期发现存在异常API访问行为。安全团队获取了数据库备份文件(exam_system.db)及《安全审计规范.md》,数据库中包含用户表(users)、角色表(roles)、API权限表(api_permissions)以及访问日志表(access_logs)。经初步排查,部分用户的个人信息存在数据录入错误,这些"幽灵账户"的访问记录不应计入违规统计。请根据附件中的《安全审计规范.md》,校验用户个人信息找出所有幽灵账户,排除幽灵账户后找出access_logs中所有违规的API访问操作,按规范要求的格式计算并提交flag。
某教育机构的在线考试系统近期发现存在异常API访问行为。安全团队获取了数据库备份文件 `exam_system.db` 及《安全审计规范.md》。数据库中包含以下四张表:- **users**: 用户表(id, username, password, name, idcard, phone, role_id, status)- **roles**: 角色表(id, role_name, description)- **api_permissions**: API权限表(id, role_id, api_endpoint, can_access)- **access_logs**: 访问日志表(id, user_id, api_endpoint, access_time)需按《安全审计规范.md》要求:1. 校验用户个人信息找出所有"幽灵账户"2. 排除幽灵账户后找出所有违规API访问操作3. 按规范格式计算并提交 flag## 解题思路### 一、幽灵账户识别(个人信息校验)根据审计规范,身份证号或手机号校验不通过的用户视为"幽灵账户"。#### 身份证号校验身份证号为18位,校验规则:- 前17位为数字,第18位为校验码(数字或X)- 加权系数:`[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]`- 前17位分别乘以对应系数后求和,对11取余- 余数与校验码对应关系:| 余数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 ||------|---|---|---|---|---|---|---|---|---|---|----|| 校验码 | 1 | 0 | X | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |#### 手机号校验手机号为11位数字,前3位必须在52个合法号段集合内。### 二、违规API访问识别排除幽灵账户后,按以下优先级判定违规类型(最小类型编号优先):| 类型 | 描述 | 判定条件 ||------|------|----------|| 1 | 已离职用户访问 | status = `inactive` || 2 | 非工作时间访问 | access_time 不在 9:00-18:00 范围内 || 3 | 未授权API访问 | 用户角色对该 API 的 can_access = 0(或未定义) |注意:`on_leave` 状态(休假)不等于离职,不计入类型1;仍可能因类型2或类型3违规。### 三、Flag 计算格式:将所有违规记录按 `日志ID-类型编号` 升序排列,英文逗号连接,计算该字符串的 MD5 哈希值。flag{md5("id1-type1,id2-type2,...")}## 解题过程### 1. 数据库分析users: 200 rowsroles: 8 rows (super_admin, admin, teacher, invigilator, student, teaching_assistant, auditor, guest)api_permissions: 360 rows (8 roles × ~45 API endpoints)access_logs: 80000 rows### 2. 幽灵账户检测结果共有 **30** 个幽灵账户(身份证号或手机号校验不通过):| User ID | 身份证校验 | 手机号校验 ||---------|-----------|-----------|| 3 | 校验码错误 | 通过 || 12 | 通过 | 号段不合法 || 16 | 通过 | 号段不合法 || 31 | 校验码错误 | 号段不合法 || 34 | 校验码错误 | 通过 || 40 | 通过 | 号段不合法 || ... | ... | ... |### 3. 违规记录排除幽灵账户后,共发现 **9** 条违规记录:| 日志ID | 违规类型 | 违规原因 ||--------|---------|----------|| 14728 | 3 | 未授权API访问 || 24311 | 1 | 已离职用户访问 || 30736 | 1 | 已离职用户访问 || 38039 | 2 | 非工作时间访问 || 40118 | 2 | 非工作时间访问 || 41610 | 1 | 已离职用户访问 || 47445 | 3 | 未授权API访问 || 60354 | 2 | 非工作时间访问 || 76513 | 1 | 已离职用户访问 |### 4. 违规字符串14728-3,24311-1,30736-1,38039-2,40118-2,41610-1,47445-3,60354-2,76513-1import sqlite3import hashlibDB_PATH = r'exam_system.db'IDCARD_COEFFS = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]# Remainder -> check digit mappingCHECK_MAP = {0: '1', 1: '0', 2: 'X', 3: '9', 4: '8', 5: '7', 6: '6', 7: '5', 8: '4', 9: '3', 10: '2'}def validate_idcard(idcard):"""Validate 18-digit Chinese ID card number via checksum."""if not idcard or len(idcard) != 18:return Falseif not idcard[:17].isdigit():return False total = sum(int(idcard[i]) * IDCARD_COEFFS[i] for i in range(17)) expected_check = CHECK_MAP[total % 11]return idcard[17].upper() == expected_checkVALID_PREFIXES = {'134', '135', '136', '137', '138', '139', '147', '148','150', '151', '152', '157', '158', '159', '172', '178','182', '183', '184', '187', '188', '195', '198','130', '131', '132', '140', '145', '146', '155', '156','166', '167', '171', '175', '176', '185', '186', '196','133', '149', '153', '173', '174', '177', '180', '181','189', '190', '191', '193', '199',}def validate_phone(phone):"""Validate 11-digit phone number by prefix check."""if not phone or len(phone) != 11:return Falseif not phone.isdigit():return Falsereturn phone[:3] in VALID_PREFIXESdef find_ghost_accounts(conn): cur = conn.cursor() cur.execute('SELECT id, idcard, phone FROM users') users = cur.fetchall() ghost_ids = set()for uid, idcard, phone in users: idcard_ok = validate_idcard(idcard) phone_ok = validate_phone(phone)if not idcard_ok or not phone_ok: ghost_ids.add(uid)return ghost_idsdef find_violations(conn, ghost_ids): cur = conn.cursor()# Build user lookup: id -> (status, role_id) cur.execute('SELECT id, status, role_id FROM users') user_map = {row[0]: (row[1], row[2]) for row in cur.fetchall()}# Build permission lookup: (role_id, api_endpoint) -> can_access cur.execute('SELECT role_id, api_endpoint, can_access FROM api_permissions') perm_map = {}for role_id, api, can in cur.fetchall(): perm_map[(role_id, api)] = can# Scan all access logs cur.execute('SELECT id, user_id, api_endpoint, access_time FROM access_logs ORDER BY id') logs = cur.fetchall() violations = []for log_id, user_id, api_endpoint, access_time in logs:# Exclude ghost accountsif user_id in ghost_ids:continue user_info = user_map.get(user_id)if not user_info:continue status, role_id = user_info# Type 1: inactive userif status == 'inactive': violations.append((log_id, 1))continue# Type 2: outside working hours hour = int(access_time[11:13])if hour < 9 or hour >= 18: violations.append((log_id, 2))continue# Type 3: unauthorized API access can_access = perm_map.get((role_id, api_endpoint), 0) # default: no accessif can_access == 0: violations.append((log_id, 3))return violationsdef compute_flag(violations): viol_str = ','.join(f'{vid}-{vtype}'for vid, vtype in violations) md5_hash = hashlib.md5(viol_str.encode()).hexdigest()return f'flag{{{md5_hash}}}', viol_strdef main(): conn = sqlite3.connect(DB_PATH) ghost_ids = find_ghost_accounts(conn)print(f'[+] Ghost accounts found: {len(ghost_ids)}')for gid in sorted(ghost_ids):print(f' User ID: {gid}') violations = find_violations(conn, ghost_ids)print(f'n[+] Violations found (excluding ghost accounts): {len(violations)}')for vid, vtype in violations:print(f' Log {vid} -> Type {vtype}') flag, viol_str = compute_flag(violations)print(f'n[+] Violation string: {viol_str}')print(f'[+] Flag: {flag}') conn.close()return flagif __name__ == '__main__': main()flag{15cb6dceb13da3077c6df3f86d219e9d}
MaskTrace
题目内容:业务方从用户库导出了一份user_export.sql,里面既有启用账号也有停用账号,各字段格式参差不齐,还混入了不少看似合理却经不起严格校验的异常数据。请参考附件中的《脱敏规范.md》逐字段实现脱敏与合法性校验,只挑出status=active的用户,按id升序导出表头为id,username,password,name,idcard,phone,email,bankcard,address,ip,birthday的CSV(文件编码为utf-8),并将该文件上传至该题的校验平台(在该校验平台里可以下载该题的示例文件example.csv,可作为该题的格式参考),校验达标即可拿到flag。
import reimport csvimport hashlibfrom datetime import date, datetimeSQL_PATH = r'C:UsersZhuanZ(无密码)Downloads7:MaskTrace的附件tempdirDS附件MaskTrace附件MaskTrace附件user_export.sql'OUTPUT_PATH = r'C:UsersZhuanZ(无密码)Downloads7:MaskTrace的附件tempdirDS附件MaskTrace附件MaskTrace附件output.csv'# ============================================================# Constants# ============================================================IDCARD_COEFFS = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]CHECK_MAP = {0: '1', 1: '0', 2: 'X', 3: '9', 4: '8', 5: '7', 6: '6', 7: '5', 8: '4', 9: '3', 10: '2'}VALID_PHONE_PREFIXES = {'134', '135', '136', '137', '138', '139', '147', '148','150', '151', '152', '157', '158', '159', '172', '178','182', '183', '184', '187', '188', '195', '198','130', '131', '132', '140', '145', '146', '155', '156','166', '167', '171', '175', '176', '185', '186', '196','133', '149', '153', '173', '174', '177', '180', '181','189', '190', '191', '193', '199',}REFERENCE_DATE = date(2026, 5, 1)HEADERS = ['id', 'username', 'password', 'name', 'idcard', 'phone','email', 'bankcard', 'address', 'ip', 'birthday']# ============================================================# Helper: username-style masking# ============================================================def mask_middle_keep_ends(s):"""Keep first and last char, replace middle with *. len=2: keep first, replace last with *. len>=3: keep first & last, middle all *.""" n = len(s)if n == 0:return''if n == 1:return sif n == 2:return s[0] + '*'return s[0] + '*' * (n - 2) + s[-1]# ============================================================# Field processors (each returns desensitized string or "INVALID")# ============================================================def process_username(raw):"""Length 2 → a*, length ≥3 → A*****6, preserve case."""if len(raw) < 2:return'INVALID'return mask_middle_keep_ends(raw)def process_password(raw):"""MD5 → 32-char lowercase hex."""return hashlib.md5(raw.encode('utf-8')).hexdigest()def process_name(raw):"""Must be all Chinese chars, length ≥ 2. Mask: 张* / 欧*娜."""if len(raw) < 2:return'INVALID'for ch in raw: cp = ord(ch)if not (0x4E00 <= cp <= 0x9FFF or 0x3400 <= cp <= 0x4DBF):return'INVALID'return mask_middle_keep_ends(raw)def process_idcard(raw):"""18-digit ID card: valid date + checksum. Output: ******YYYY********"""if not raw or len(raw) != 18:return'INVALID'if not raw[:17].isdigit():return'INVALID'if raw[17] not in'0123456789Xx':return'INVALID'# Validate birth date (positions 7-14, 0-indexed 6-14) dob_str = raw[6:14] try: dob = datetime.strptime(dob_str, '%Y%m%d').date()if dob.year < 1900 or dob > date.today():return'INVALID' except ValueError:return'INVALID'# Validate checksum total = sum(int(raw[i]) * IDCARD_COEFFS[i] for i in range(17)) expected = CHECK_MAP[total % 11]if raw[17].upper() != expected:return'INVALID'# Mask: keep only birth year year = dob_str[:4]return'******' + year + '********'def process_phone(raw):"""Normalize: strip non-digits, remove leading 86. Must be 11 digits with valid prefix. Mask: 152****6242.""" digits = re.sub(r'D', '', raw)# Remove China country code prefix if presentif digits.startswith('86') and len(digits) > 11: digits = digits[2:]if len(digits) != 11 or not digits.isdigit():return'INVALID'if digits[:3] not in VALID_PHONE_PREFIXES:return'INVALID'return digits[:3] + '****' + digits[7:]def process_email(raw):"""Normalize to lowercase. Validate format. Mask username part, keep domain. Otherwise INVALID.""" raw = raw.lower()if'@' not in raw:return'INVALID' parts = raw.split('@')if len(parts) != 2 or not parts[0] or not parts[1]:return'INVALID'local, domain = parts# Domain must have at least one dot, not at start/endif'.' not in domain or domain.startswith('.') or domain.endswith('.'):return'INVALID'# Basic local part check: no spaces, reasonable charsif not re.match(r'^[a-z0-9._+-]+$', local):return'INVALID'if len(local) < 1:return'INVALID' masked_local = mask_middle_keep_ends(local)return masked_local + '@' + domaindef process_bankcard(raw):"""Normalize: strip non-digits. Must be 16-19 digits. Mask: keep first 6 + ****...**** + last 4.""" digits = re.sub(r'D', '', raw) n = len(digits)if n < 16 or n > 19 or not digits.isdigit():return'INVALID' star_count = n - 10return digits[:6] + '*' * star_count + digits[-4:]def process_address(raw):"""Must contain 号. Keep before first 号, append ***.""" idx = raw.find('u53f7') # 号if idx == -1:return'INVALID'return raw[:idx] + '***'def process_ip(raw):"""Must be valid IPv4 (4 octets, 0-255). Mask last octet: 192.168.10.*""" parts = raw.split('.')if len(parts) != 4:return'INVALID' try: octets = [int(p) for p in parts] except ValueError:return'INVALID'for o in octets:if o < 0 or o > 255:return'INVALID'return'.'.join(parts[:3]) + '.*'def process_birthday(raw):"""YYYY-MM-DD or YYYY/MM/DD. Valid date. Output decade range.""" sep = '/'if'/'in raw else'-' parts = raw.split(sep)if len(parts) != 3:return'INVALID' try: y, m, d = int(parts[0]), int(parts[1]), int(parts[2]) bd = date(y, m, d) except (ValueError, TypeError):return'INVALID'# Age as of REFERENCE_DATE age = REFERENCE_DATE.year - bd.yearif (bd.month, bd.day) > (REFERENCE_DATE.month, REFERENCE_DATE.day): age -= 1if age < 0:return'INVALID'# future birth date lo = (age // 10) * 10 hi = lo + 9return f'{lo}-{hi}'PROCESSORS = {'username': process_username,'password': process_password,'name': process_name,'idcard': process_idcard,'phone': process_phone,'email': process_email,'bankcard': process_bankcard,'address': process_address,'ip': process_ip,'birthday': process_birthday,}# ============================================================# Parse SQL# ============================================================def parse_sql(path): with open(path, 'r', encoding='utf-8') as f: content = f.read() pattern = ( r"VALUESs*(s*" r"'(d+)',s*'([^']*)',s*'([^']*)',s*'([^']*)',s*" r"'([^']*)',s*'([^']*)',s*'([^']*)',s*'([^']*)',s*" r"'([^']*)',s*'([^']*)',s*'([^']*)',s*'([^']*)'" r"s*)" ) rows = []for m in re.finditer(pattern, content): row = {'id': int(m.group(1)),'username': m.group(2),'password': m.group(3),'name': m.group(4),'idcard': m.group(5),'phone': m.group(6),'email': m.group(7),'bankcard': m.group(8),'address': m.group(9),'ip': m.group(10),'birthday': m.group(11),'status': m.group(12), } rows.append(row)return rows# ============================================================# Main# ============================================================def main(): all_rows = parse_sql(SQL_PATH)print(f'[+] Total rows parsed: {len(all_rows)}')# Filter active active = [r for r in all_rows if r['status'] == 'active']print(f'[+] Active users: {len(active)}')# Process output_rows = [] stats = {h: {'valid': 0, 'invalid': 0} for h in HEADERS if h != 'id'}for row in active: out = {'id': row['id']}for field in HEADERS:if field == 'id':continue raw = row[field] result = PROCESSORS[field](raw) out[field] = resultif result == 'INVALID': stats[field]['invalid'] += 1else: stats[field]['valid'] += 1 output_rows.append(out)# Sort by id output_rows.sort(key=lambda r: r['id'])# Statsprint('n[+] Field statistics:')for field in HEADERS:if field == 'id':continue s = stats[field]print(f' {field}: valid={s["valid"]}, INVALID={s["invalid"]}')# Write CSV with open(OUTPUT_PATH, 'w', encoding='utf-8', newline='') as f: writer = csv.DictWriter(f, fieldnames=HEADERS) writer.writeheader() writer.writerows(output_rows)print(f'n[+] Output written to: {OUTPUT_PATH}')print(f'[+] Total output rows: {len(output_rows)}')if __name__ == '__main__': main()CovertChannel
题目内容:安全运营中心(SOC)在部署的网络探针中捕获了一段可疑流量。威胁情报分析师发现一台内网终端(10.10.20.33)在短时间内发送了大量异常的ICMP和DNS请求。初步研判为APT组织利用多种隐蔽信道进行数据外泄。请深入分析该流量捕获文件,还原被窃取的敏感数据。
## Summary两条隐蔽信道协同工作完成数据外泄:DNS TXT 记录传递 AES-128 密钥,ICMP TTL 字段(0/1)编码传输 AES-ECB 加密的 Flag。## Solution### Step 1: DNS TXT 提取 AES 密钥tshark 过滤 DNS TXT 记录,`secret.exfil-cdn.com` 的响应中包含 base64 编码的 AES 密钥:tshark -r suspicious_traffic.pcapng -Y "dns.txt" -T fields -e dns.txt# TW9yZVNlY3VyZUFlczEyOA== → "MoreSecureAes128" (16 bytes, AES-128)### Step 2: ICMP TTL 隐蔽信道提取加密密文ICMP echo request 到 `45.76.188.23`,TTL 仅取 0 或 1,每位传输 1 bit。984 个包传输 984 bits = 123 bytes,解码为 ASCII:60226d3cd3cf345df0baa3c8dec0d9d225b3ff91634498db4f5a7d4452dd1a2c208d4efc9da73eb8884fb69c3b1202c5|AES-ECB, key is in DNS TXT前面的 96 位十六进制串即为 AES-128-ECB 加密的密文(48 bytes = 3 个 AES block)。### Step 3: AES-128-ECB 解密以 DNS TXT 中的 `MoreSecureAes128` 为密钥,对 TTL 信道提取的密文进行 AES-128-ECB 解密,去除 PKCS7 padding 后得到 Flag。import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)0TracePurge
题目内容:某公司CRM系统中今日有多次客户数据导出任务。今晨监控团队在外部数据交易渠道发现一份疑似客户数据样本,初步研判可能与今天某次内部导出有关。请你作为数据分析工程师,结合附件中提供的外部样本、内部导出日志、文件外发检测日志和客户索引,定位本次事件对应的内部导出任务,并形成本次事件的处置清单 response_plan.csv。每行代表一个本次事件中需要处置的真实客户主体。详细的提交规则、字段含义、处置动作定义见附件中的“事件响应说明.md”。将处置清单response_plan.csv(文件编码为utf-8)上传至该题的校验平台(在该校验平台里可以下载该题的示例文件example.csv,可作为该题的格式参考),校验达标即可拿到flag。
import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)1import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)2ShadowMeter
题目内容:某业务系统在巡检中发现疑似异常数据高频采集行为,管理员导出了相关时间段的Apache访问日志和调试日志,但尚未确认攻击者采集了哪些数据,也无法确认有效信息是否被外传;请分析附件中的日志,复盘异常访问过程,恢复其中被带出的有效数据,并提交最终得到的完整flag{...}。
import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)3import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)4flag{c1b50d61ac8b81fac5ab3ea499056c0a}
SectorVault
题目内容:某企业在终端巡检后发现一台办公终端上曾运行过本地敏感数据扫描工具,但扫描缓存和部分审计发布文件疑似已被清理,管理员保留了该终端的磁盘镜像作为取证材料。请分析附件镜像,恢复被清理的扫描缓存、发布归档及相关线索,依据镜像内的识别规范统计本次巡检范围内的有效敏感数据记录,并按发布策略定位正确归档、推导解压口令,读取其中flag.txt后提交完整的flag{xxx}。
import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)5import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)6flag{b294816b2e2d1d50ea34f79bd7e42d6c}
close_primes
题目内容:某数据安全系统使用RSA公钥对一张包含敏感信息的图片进行了加密存储,并只保留了公开密钥与加密后的二进制文件。管理员认为只要私钥没有泄露,图片内容就是安全的。但密钥生成过程似乎存在隐患。请你分析给出的pubkey.pem和encrypted.bin,恢复原始图片并找出其中的flag。
import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)7import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)8LevelLedger
题目内容:某互联网金融业务后台发生了一起数据泄露事件,运维人员从应急溯源中提取出一份混合台账mixed_data.csv,里面既有业务系统正常打印的明文字段,也有原本被存储层加密保护的敏感字段;攻击者还把仅在内部KMS里使用的RSA私钥一起带了出来(leaked_private.pem),导致部分敏感字段事实上已经"裸奔"。请你结合泄漏的私钥,对这份台账中的每一行做一次合规分类分级——按附件中《分类分级规范.md》给出的判定规则把每一行准确分到idcard/bankcard/phone/ip/normal之一并标注对应等级,将结果保存到classified_data.csv(UTF-8编码,无BOM)并上传至该题的校验平台(在该校验平台里可以下载该题的示例文件example.csv,可作为该题的格式参考),校验达标即可拿到flag。
import sqlite3import csvimport reVALID_PREFIXES = {'134','135','136','137','138','139','147','148','150','151','152','157','158','159','172','178','182','183','184','187','188','195','198','130','131','132','140','145','146','155','156','166','167','171','175','176','185','186','196','133','149','153','173','174','177','180','181','189','190','191','193','199'}def validate_username(u):if u is None:return Falsereturn bool(re.fullmatch(r'[a-zA-Z0-9_]+', u))def validate_name(n):if n is None:return Falsereturn bool(re.fullmatch(r'[u4e00-u9fff]+', n))def validate_gender(g):if g is None:return Falsereturn g in ('男', '女')def validate_phone(p):if p is None:return Falseif not re.fullmatch(r'd{11}', p):return Falsereturn p[:3] in VALID_PREFIXESdef validate_email(e):if e is None:return Falseif e.count('@') != 1:return Falselocal, at, domain = e.partition('@')if not local or not domain:return Falseif'.' not in domain:return Falsereturn Truedef is_dirty(row):# row: (id, username, name, phone, email, gender) _, username, name, phone, email, gender = rowif not validate_username(username):return Trueif not validate_name(name):return Trueif not validate_phone(phone):return Trueif not validate_email(email):return Trueif not validate_gender(gender):return Truereturn Falseconn = sqlite3.connect('user_data.db')cursor = conn.cursor()cursor.execute("SELECT * FROM insurance_users")rows = cursor.fetchall()conn.close()dirty_rows = [row for row in rows if is_dirty(row)]print(f"Total: {len(rows)}, Dirty: {len(dirty_rows)}, Clean: {len(rows) - len(dirty_rows)}")# Write CSVwith open('dirty_data.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['id', 'username', 'name', 'phone', 'email', 'gender'])for row in dirty_rows: writer.writerow(row)print("Saved to dirty_data.csv")# Show first 20 dirty rowsfor r in dirty_rows[:20]:print(r)96.1 身份证校验 (check_idcard)
18 位,前 17 位数字,第 18 位数字或 X第 7-14 位为合法 YYYYMMDD日期(年份 1900-2030,含闰年判断)加权校验:系数 [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2],乘积累加后 mod 11 取余,查表[1,0,X,9,8,7,6,5,4,3,2]
6.2 银行卡校验 (check_bankcard)
16-19 位纯数字 Luhn 算法:从右起编号,偶数位 ×2 后若 >9 则减 9,全加和后 mod 10 = 0
6.3 手机号校验 (check_phone)
11 位纯数字 前 3 位 ∈ 合法号段集合(52个号段,涵盖移动/联通/电信/广电)
6.4 IP 校验 (check_ip)
严格 4 段点分十进制,每段 0 ≤ n ≤ 255不允许前导零( 01不合法,单独的0合法)不允许空格、横线、CIDR 后缀等
7. 典型判例
220113196801023453 | |||
57625375973 | 576 不在合法集合 | ||
62170016299699101 | |||
a0:dd:60:11:ec:11 | |||
189.151.89 | |||
420116195101062735 | |||
622200952124488629 |
修复损坏的 PNG 文件原始 PNG 文件头存在两处错误:文件签名错误:前 4 字节不是标准的 89 50 4E 47(‰PNG)IHDR 高度错误:IHDR 中高度字段为 400(0x00000190),但根据解压数据量(1920800 字节)推算,正确高度应为 800;修复后重新计算 IHDR 的 CRC32 校验值修复步骤:data[0:4] = b'x89PNG'# 修正签名data[20:24] = struct.pack('>I', 800) # 修正高度为 800crc = binascii.crc32(data[12:29]) & 0xFFFFFFFF # 重新计算 CRCdata[29:33] = struct.pack('>I', crc) # 写入正确 CRC0SectorVault
题目内容:某企业在终端巡检后发现一台办公终端上曾运行过本地敏感数据扫描工具,但扫描缓存和部分审计发布文件疑似已被清理,管理员保留了该终端的磁盘镜像作为取证材料。请分析附件镜像,恢复被清理的扫描缓存、发布归档及相关线索,依据镜像内的识别规范统计本次巡检范围内的有效敏感数据记录,并按发布策略定位正确归档、推导解压口令,读取其中flag.txt后提交完整的flag{xxx}。
修复损坏的 PNG 文件原始 PNG 文件头存在两处错误:文件签名错误:前 4 字节不是标准的 89 50 4E 47(‰PNG)IHDR 高度错误:IHDR 中高度字段为 400(0x00000190),但根据解压数据量(1920800 字节)推算,正确高度应为 800;修复后重新计算 IHDR 的 CRC32 校验值修复步骤:data[0:4] = b'x89PNG'# 修正签名data[20:24] = struct.pack('>I', 800) # 修正高度为 800crc = binascii.crc32(data[12:29]) & 0xFFFFFFFF # 重新计算 CRCdata[29:33] = struct.pack('>I', crc) # 写入正确 CRC1修复损坏的 PNG 文件原始 PNG 文件头存在两处错误:文件签名错误:前 4 字节不是标准的 89 50 4E 47(‰PNG)IHDR 高度错误:IHDR 中高度字段为 400(0x00000190),但根据解压数据量(1920800 字节)推算,正确高度应为 800;修复后重新计算 IHDR 的 CRC32 校验值修复步骤:data[0:4] = b'x89PNG'# 修正签名data[20:24] = struct.pack('>I', 800) # 修正高度为 800crc = binascii.crc32(data[12:29]) & 0xFFFFFFFF # 重新计算 CRCdata[29:33] = struct.pack('>I', crc) # 写入正确 CRC2InvisibleLeak
题目内容:某金融公司的客户隐私数据近日在暗网论坛被公开出售,但DLP系统未检测到任何异常传输记录。安全应急响应团队(CERT)锁定了一名嫌疑员工,并从其工作站上提取了三份可疑文件:一张公司宣传海报、一份内部通知文档以及一个来历不明的Python编译文件。经初步分析,该员工很可能使用了自研的隐蔽外泄工具。请深入逆向分析外泄工具的工作原理,还原完整的数据外泄链路,提取被窃取的敏感信息。
修复损坏的 PNG 文件原始 PNG 文件头存在两处错误:文件签名错误:前 4 字节不是标准的 89 50 4E 47(‰PNG)IHDR 高度错误:IHDR 中高度字段为 400(0x00000190),但根据解压数据量(1920800 字节)推算,正确高度应为 800;修复后重新计算 IHDR 的 CRC32 校验值修复步骤:data[0:4] = b'x89PNG'# 修正签名data[20:24] = struct.pack('>I', 800) # 修正高度为 800crc = binascii.crc32(data[12:29]) & 0xFFFFFFFF # 重新计算 CRCdata[29:33] = struct.pack('>I', crc) # 写入正确 CRC3推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……




发表评论