VISA_or_MC - Writeup by AI
一、题目信息
- 题目来源: Bugku Crypto
- 题目名称: VISA_or_MC
- 题目类型: 密码学/编码转换
二、考点分析
核心知识点
信用卡卡号识别规则
- VISA 卡:以数字 4 开头,16 位
- MasterCard: 以数字 5 开头,16 位(本题中所有 5 开头的都算 MC)
二进制编码转换
- 将卡片类型转换为二进制位(0/1)
- 每 8 位二进制转换为一个 ASCII 字符
数据分类与统计
考点权重表
| 考点 | 权重 | 说明 |
|---|---|---|
| 信用卡卡号规则 | 30% | 识别 VISA 和 MC 的前缀差异 |
| 二进制编码 | 40% | 理解 0/1 序列到文本的转换 |
| 数据分析能力 | 30% | 从大量数据中发现规律 |
三、解题思路
1. 初步分析
题目提供了一个包含 272 个信用卡卡号的文件file.txt,题目名称"VISA_or_MC"暗示需要区分 VISA 卡和 MasterCard。
2. 识别规则
通过查询信用卡卡号规则:
- VISA: 以 4 开头
- MasterCard: 以 51-55 开头(但本题放宽到所有 5 开头)
3. 发现规律
统计发现:
- VISA 卡(4 开头): 136 张
- MasterCard(5 开头): 136 张
- 总计:272 张,刚好全部可以分类
4. 编码转换
将卡片类型转换为二进制:
- VISA (4 开头) → 0
- MasterCard (5 开头) → 1
生成 272 位二进制序列,每 8 位转换为一个 ASCII 字符,得到 34 个字符的 flag。
四、详细步骤
步骤 1: 读取文件并统计
withopen('file.txt','r')asf:lines=f.readlines()# 共 272 行卡号步骤 2: 识别卡片类型
defidentify_card_type(card):card=card.replace('-','')# 移除连字符iflen(card)!=16:return'UNKNOWN'ifcard[0]=='4':return'VISA'elifcard[0]=='5':return'MC'else:return'UNKNOWN'步骤 3: 生成二进制序列
遍历所有卡号,根据类型生成 0/1 序列:
binary_sequence=""forlineinlines:card=line.strip().replace('-','')ifcard[0]=='4':binary_sequence+='0'# VISAelifcard[0]=='5':binary_sequence+='1'# MC步骤 4: 二进制解码
将 272 位二进制序列转换为 ASCII 文本:
defbinary_to_text(binary_str):chars=[]foriinrange(0,len(binary_str),8):byte=binary_str[i:i+8]char_code=int(byte,2)if32<=char_code<=126:chars.append(chr(char_code))return''.join(chars)步骤 5: 获取 Flag
解码结果:shellmates{XXX}
五、完整代码
#!/usr/bin/env python3# -*- coding: utf-8 -*-defidentify_card_type(card_number):"""识别信用卡类型"""card=card_number.replace('-','')iflen(card)!=16:return'UNKNOWN'ifcard[0]=='4':return'VISA'elifcard[0]=='5':return'MC'else:return'UNKNOWN'defbinary_to_text(binary_str):"""将二进制字符串转换为文本"""chars=[]foriinrange(0,len(binary_str),8):byte=binary_str[i:i+8]iflen(byte)==8:char_code=int(byte,2)if32<=char_code<=126:chars.append(chr(char_code))return''.join(chars)defmain():# 读取文件withopen('file.txt','r')asf:lines=f.readlines()print(f"总卡数:{len(lines)}")# 统计visa_count=0mc_count=0forlineinlines:card=line.strip()ifnotcard:continuecard_type=identify_card_type(card)ifcard_type=='VISA':visa_count+=1elifcard_type=='MC':mc_count+=1print(f"VISA 卡 (4 开头):{visa_count}")print(f"MasterCard (5 开头):{mc_count}")# 生成二进制序列binary_sequence=""forlineinlines:card=line.strip().replace('-','')ifcard[0]=='4':binary_sequence+='0'elifcard[0]=='5':binary_sequence+='1'print(f"二进制序列长度:{len(binary_sequence)}bits")# 解码flag=binary_to_text(binary_sequence)print(f"Flag:{flag}")if__name__=='__main__':main()六、运行结果
============================================================ CTF 题目:VISA_or_MC ============================================================ 总卡数:272 VISA 卡 (4 开头): 136 张 MasterCard (5 开头): 136 张 有效卡片总数:272 === 生成二进制序列 === 规则:VISA(4 开头)=0, MasterCard(5 开头)=1 二进制序列长度:272 bits 可转换为字节数:34 bytes === 解码结果 === Flag: shellmates{XXX} === 验证 Flag 格式 === ✓ Flag 格式正确! 最终答案:shellmates{XXX}