资讯动态

抓包分析教程

发布时间:2026/8/4 12:29:37 来源:尧图企业网站定制
Wireshark抓包文件分析完整指南 目录分析概述第一步文件解压与验证第二步数据包基础分析第三步目标会话定位第四步TCP流重组第五步HTTP协议解析第六步数据提取与解码第七步JSON数据处理总结与技巧分析概述场景描述我们有一个Wireshark抓包文件.pcapng.gz需要从中提取试题答案数据。分析目标识别与特定IP的通信会话重组TCP数据流解析HTTP协议提取JSON数据结构化输出试题信息使用工具Python Scapy: 数据包解析库gzip: 文件解压json: JSON数据处理第一步文件解压与验证1.1 为什么需要解压原始文件: 1.pcapng.gz (压缩格式) 目标文件: 1.pcapng (Wireshark格式)1.2 解压代码importgzipimportshutil input_file1.pcapng.gzoutput_file1.pcapng# 使用gzip模块解压withgzip.open(input_file,rb)asf_in:withopen(output_file,wb)asf_out:shutil.copyfileobj(f_in,f_out)1.3 验证文件importos# 检查文件大小file_sizeos.path.getsize(output_file)print(f文件大小:{file_size/1024:.2f}KB)# 检查文件魔数Magic Numberwithopen(output_file,rb)asf:magicf.read(4)print(f文件魔数:{magic.hex()})# pcapng文件魔数: 0a0d0d0a 知识点:.pcapng.gz是gzip压缩的pcapng文件pcapng是Wireshark的新一代抓包格式魔数用于验证文件格式第二步数据包基础分析2.1 读取数据包fromscapy.allimportrdpcap# 读取所有数据包packetsrdpcap(1.pcapng)print(f总数据包数:{len(packets)})2.2 协议统计fromcollectionsimportCounter protocol_counterCounter()forpktinpackets:ifIPinpkt:ifTCPinpkt:protocol_counter[TCP]1elifUDPinpkt:protocol_counter[UDP]1elifICMPinpkt:protocol_counter[ICMP]1ifARPinpkt:protocol_counter[ARP]1print(协议分布:)forproto,countinprotocol_counter.items():print(f{proto}:{count}个包)2.3 IP地址分析src_ipsCounter()dst_ipsCounter()forpktinpackets:ifIPinpkt:src_ips[pkt[IP].src]1dst_ips[pkt[IP].dst]1print(源IP TOP 10:)forip,countinsrc_ips.most_common(10):print(f{ip}:{count}个包) 知识点:rdpcap()读取所有数据包到内存Counter用于统计频率Scapy使用分层结构IP in pkt检查是否存在IP层第三步目标会话定位3.1 筛选目标IP的数据包target_ip125.46.78.164target_packets[]forpktinpackets:ifIPinpkt:# 检查是否与目标IP相关ifpkt[IP].srctarget_iporpkt[IP].dsttarget_ip:target_packets.append(pkt)print(f找到{len(target_packets)}个相关数据包)3.2 分析会话信息# 统计端口使用src_portsCounter()dst_portsCounter()forpktintarget_packets:ifTCPinpkt:src_ports[pkt[TCP].sport]1dst_ports[pkt[TCP].dport]1print(f源端口:{src_ports.most_common(5)})print(f目标端口:{dst_ports.most_common(5)})3.3 识别应用层协议# 根据端口号判断协议common_ports{80:HTTP,443:HTTPS,8080:HTTP-Proxy,8095:Custom-App# 自定义应用}forport,countindst_ports.most_common(5):protocolcommon_ports.get(port,Unknown)print(f端口{port}:{protocol}({count}个包)) 知识点:端口号帮助识别应用层协议8095是自定义应用端口TCP会话由四元组标识(源IP, 源端口, 目标IP, 目标端口)第四步TCP流重组4.1 为什么需要流重组问题: TCP数据可能被分片一个HTTP响应可能分成多个TCP包 解决: 按序列号重组TCP流4.2 重组TCP流stream_data{True:b,# 接收方向从目标IPFalse:b# 发送方向到目标IP}forpktintarget_packets:ifIPinpktandTCPinpktandRawinpkt:# 判断数据方向direction(pkt[IP].srctarget_ip)# 提取载荷Payloadpayloadbytes(pkt[Raw].load)# 按方向拼接数据stream_data[direction]payloadprint(f接收数据:{len(stream_data[True])}字节)print(f发送数据:{len(stream_data[False])}字节)4.3 理解TCP序列号# 查看TCP序列号fori,pktinenumerate(target_packets[:5],1):ifTCPinpktandRawinpkt:print(f包{i}:)print(f 序列号:{pkt[TCP].seq})print(f 确认号:{pkt[TCP].ack})print(f 载荷长度:{len(pkt[Raw].load)})print(f TCP标志:{pkt[TCP].flags}) 知识点:TCP是流式协议数据可能分片序列号SEQ标识数据位置确认号ACK表示已接收的数据Scapy的Raw层包含应用层数据第五步HTTP协议解析5.1 HTTP响应结构HTTP/1.1 200 OK\r\n - 状态行 Server: nginx/1.25.1\r\n - 响应头 Content-Type: application/json\r\n Transfer-Encoding: chunked\r\n \r\n - 空行分隔符 [响应体] - 数据部分5.2 解析HTTP头部# 解码字节数据http_textstream_data[True].decode(utf-8,errorsignore)# 分离头部和主体header_endhttp_text.find(\r\n\r\n)ifheader_end0:headershttp_text[:header_end]bodyhttp_text[header_end4:]# 跳过\r\n\r\nprint(HTTP头部:)print(headers[:300])5.3 处理Chunked传输编码importre# Chunked格式:# 900d\r\n - 块大小十六进制# [数据内容]\r\n - 块数据# 0\r\n - 结束标记chunked_patternre.compile(r^([0-9a-fA-F])\r\n,re.MULTILINE)chunks[]pos0whileposlen(body):matchchunked_pattern.match(body,pos)ifmatch:# 解析块大小十六进制转十进制chunk_sizeint(match.group(1),16)ifchunk_size0:# 结束标记break# 提取块数据chunk_startmatch.end()chunk_databody[chunk_start:chunk_startchunk_size]chunks.append(chunk_data)# 移动到下一个块poschunk_startchunk_size2# 2 跳过\r\nelse:break# 合并所有块json_data.join(chunks)print(fJSON数据长度:{len(json_data)}字符) 知识点:HTTP使用\r\n作为行分隔符\r\n\r\n分隔头部和主体Chunked编码用于流式传输块大小是十六进制表示第六步数据提取与解码6.1 字符编码处理# 常见编码问题原始数据-字节(bytes)-字符串(str)# UTF-8解码textdata.decode(utf-8,errorsignore)# errors参数:# - strict: 严格模式遇到错误抛异常# - ignore: 忽略错误字节# - replace: 用?替换错误字节6.2 十六进制查看# 查看原始字节的十六进制表示datastream_data[True][:100]# 方法1: hex()方法hex_strdata.hex()print(十六进制:,hex_str)# 方法2: 格式化输出foriinrange(0,len(hex_str),32):hex_linehex_str[i:i32]formatted .join([hex_line[j:j2]forjinrange(0,len(hex_line),2)])print(f{formatted})6.3 ASCII预览# 尝试不同编码encodings[utf-8,gbk,gb2312,iso-8859-1]forencodinginencodings:try:textdata.decode(encoding)print(f{encoding}解码成功:)print(f{text[:100]})except:print(f{encoding}解码失败) 知识点:网络数据本质是字节流需要正确的编码才能转为字符串UTF-8是最常用的编码十六进制查看有助于调试第七步JSON数据处理7.1 解析JSONimportjsontry:datajson.loads(json_data)print(JSON解析成功)exceptjson.JSONDecodeErrorase:print(fJSON解析失败:{e})# 尝试修复查找JSON对象边界first_bracejson_data.find({)last_bracejson_data.rfind(})iffirst_brace0andlast_bracefirst_brace:json_cleanjson_data[first_brace:last_brace1]datajson.loads(json_clean)print(JSON修复成功)7.2 遍历JSON结构# 理解JSON结构{item:{examActiveDto:{examQuestions:{MULTISELECT:[...],SINGLE:[...],JUDGE:[...]}}}}# 遍历数据questionsdata[item][examActiveDto][examQuestions]forqtype,q_listinquestions.items():print(f题型:{qtype})forqinq_list:print(f 题目:{q[content]})print(f 分值:{q[score]})7.3 提取关键信息# 提取正确答案forqinquestions[MULTISELECT]:correct_answers[]foroptinq[examQuestionOptions]:ifopt[answerFlag]:# 正确答案标记correct_answers.append(opt[optionContent])print(f题目:{q[content]})print(f正确答案:{, .join(correct_answers)}) 知识点:JSON是Web API最常用的数据格式json.loads()解析JSON字符串嵌套结构需要逐层访问answerFlag字段标识正确答案总结与技巧 分析流程总结1. 文件解压 - gzip解压 2. 数据包读取 - rdpcap() 3. 协议分析 - 统计协议分布 4. 会话定位 - 筛选目标IP 5. 流重组 - TCP序列号重组 6. HTTP解析 - 分离头部和主体 7. 编码处理 - UTF-8解码 8. JSON提取 - 解析数据结构️ 常用工具函数快速查看数据包defquick_analyze(pcap_file):packetsrdpcap(pcap_file)print(f总包数:{len(packets)})print(f时间范围:{packets[0].time}-{packets[-1].time})# 协议统计statsCounter()forpktinpackets:ifTCPinpkt:stats[TCP]1ifUDPinpkt:stats[UDP]1ifICMPinpkt:stats[ICMP]1returnstats提取HTTP流defextract_http_stream(packets,target_ip):stream{True:b,False:b}forpktinpackets:ifIPinpktandTCPinpktandRawinpkt:ifpkt[IP].srctarget_iporpkt[IP].dsttarget_ip:direction(pkt[IP].srctarget_ip)stream[direction]bytes(pkt[Raw].load)returnstream⚠️ 常见问题1. 数据包丢失症状: TCP流不完整 原因: 抓包时丢包 解决: 检查TCP序列号是否连续2. 编码错误症状: UnicodeDecodeError 原因: 编码不匹配 解决: 尝试多种编码使用errorsignore3. JSON解析失败症状: JSONDecodeError 原因: 数据不完整或格式错误 解决: 查找JSON边界清理多余字符 进阶学习Wireshark过滤器显示过滤器:ip.addr 125.46.78.164跟踪TCP流: 右键 - Follow - TCP Streamtshark命令行工具tshark-r1.pcapng-Yip.addr125.46.78.164-TjsonScapy高级功能会话重组:sessions()过滤器:sniff(filtertcp port 8095)数据包构造: 构造自定义数据包其他工具dpkt: 另一个Python抓包库pyshark: tshark的Python封装n2dps: 网络数据包分析平台实战练习练习1: 分析HTTPS流量目标: 提取HTTPS握手信息 提示: 查找Client Hello和Server Hello练习2: 提取DNS查询目标: 统计DNS查询域名 提示: 使用DNS层解析练习3: 重组文件传输目标: 从FTP流量中提取传输的文件 提示: 注意TCP流的方向和数据重组参考资源Scapy官方文档Wireshark用户手册TCP/IP详解 卷1HTTP权威指南 恭喜您已经掌握了抓包文件分析的核心技能

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价