网安实践5.2

moyigeek Lv3

IP 地址国别信息查询系统设计

本实验旨在探讨如何使用xdb文件格式(本项目中设计的一种高效且可自定
义的数据格式,用于存储和查询 IP 地址相关信息)在海量数据集下实现高效的
ip 国别信息查询。实验重点包括理解xdb的数据结构与查询流程,结合 IPv4和
IPv6 的实现代码进行分析。同时,实验将使用pyshark捕获实时网络流量并查询
IP 的国别信息,进一步验证查询的实用性和性能。

完成过程

  1. 理解xdb数据结构
  2. 理解xdb的查询流程
  3. 编译并运行 IPv4 和 IPv6 查询代码,测试不同数据量下的查询时间
  4. 使用pyshark 捕获实时流量,查询ip国别信息

基础知识

xdb数据结构

|Header 数据段| Vector 索引数据段 |地域信息数据段 | 二分索引数据段|

|256 Bytes| 512 KiB | 动态空间 | 动态空间|

Header 256 bytes 段

版本号 缓存策略 文件生成时间 索引起始地址 索引结束地址
2 Bytes 2 Bytes 4 Bytes 4 Bytes 4 Bytes

主要用于存储xdb文件的元数据。
前 16 字节已被使用,剩余字节保留扩展空间(如存储 MD5 哈希值用于数据完
整性校验)。

Vector 索引段(512KB
采用 256x256 的二维数组,根据IP的前两个字节划分。

此部分通过减少二分搜索的范围,大大提高了查询速度,缩小了后续二分查找的
扫描范围。开始位置指向区域二分索引的开始位置,结束位置指向区域二级索引
的结束位置,也就是 vector 索引将整个二分索引分成了 256 × 256 个分区,
便于更快的减少二分索引的查找范围,从而加速查询。每个单元格的空间是固定
的,所以整个 vector 索引段占据的空间为:256 × 256 × 8=524288Bytes=
512 KiB,这个空间是固定的与原始的 IP 数据行数无关。

地域信息段:
存储与每个 IP 段相关的地理信息,编码格式为 UTF-8。
每种唯一的地理信息只需存储一次,避免数据冗余。详细见图2.1。

二分索引段:
包含每个 IP 段的起始 IP、结束 IP、数据长度和数据指针。
每个索引项占用 14 个字节,总空间与 IP 段数成正比。

ipv4每个二分索引项占据 14 个字节,详细字段和空间分布如下:

开始ip 结束ip 地域信息数据长度 地域信息指针
4 Bytes 4 Bytes 2 Bytes 4 Bytes

· IPv4 与 IPv6 存储格式差异及优化设计:
4 Bytes
IPv6 的数据设计与 IPv4 类似,但由于 IPv6 地址长度为 128 位,因此在
存储和查找方式上做了进一步的优化。首先,IPv6 摒弃了 IPv4 中的二级索引
结构,转而直接使用二分查找来定位地址信息(见表 2.7)。这种调整结合优化
后的数据结构,使得系统可以实现对 IPv6 地址的快速定位,达到了 1 微秒级
的查询效率。
为什么在存储时仅保存 IPv6 地址的前 64 位,而不是像 IPv4 那样存储完
整的起始和结束 IP 段?这是基于 IPv6 地址结构的特点而设计的。IPv6 的
128 位地址分为两个 64 位段:高 64 位用于路由,低 64 位用于标识具体节点。
因此,我们只需存储高 64 位地址和前缀长度,就可以精确确定 IPv6 地址段的
范围。

xdb查询流程

  1. 读取 Header 数据段,获取索引起始地址和结束地址。
  2. 读取 Vector 索引段,根据 IP 的前两个字节定位到对应的区域。
  3. 读取二分索引段,根据 IP 的具体值进行二分查找,定位到对应的地域信息。
  4. 读取地域信息段,获取地域信息。

实验结果

  1. 编译并运行 IPv4 和 IPv6 查询代码,测试不同数据量下的查询时间
    1
    2
    3
    make
    chmod +x ip2region
    ./ip2region -test
  1. 使用pyshark 捕获实时流量,查询ip国别信息
    1
    2
    sudo pip install pyshark 
    sudo python3 main.py

任务

  1. IPv6 查询中哈希映射算法的适用性分析
    在 IPv6 查询已经使用二分查找算法的情况下,是否可以通过哈希映射算法
    替代二分查找来提高查询效率?请从多个角度进行分析,尝试实现该算法,并与
    二分查找算法的执行效果进行对比分析,评估其性能差异。你可以根据自己的实
    现过程或分析结果给出最终结论。如果你认为有更高效的实现方法,欢迎附上你
    的代码并分享思考过程。
    在此部分,提供了 IPv6 二分索引项结构的示例,详细代码逻辑见 2.2.2 节。
    查询 IP:2408:8226:a500:43d0:1077:8a4b:a1d0:7790
    查询结果: 中国

  2. Python 与 C++ 程序通信方案优化
    在当前程序中,使用了 Socket 连接来解决 Python 和 C++ 之间的通信问题。
    由于 C++ 的高效性,它能够在一秒钟内解析 1,000,000 个 IP 地址,并在高流
    量情况下保持稳定和可靠的输出。然而,使用 Socket 进行通信并不是最优的方
    案。请写出一种更加高效的解决方案,并附加操作过程。
    可使用的参考思路:一种更高效的方案是使用 Python 的 FFI(外部函数接口),
    直接在 Python 中调用 C++ 的类和方法,从而避免通过 Socket 进行通信,并
    且不需要多次加载数据库。这种方式能够显著提升性能。以下是实现方案:
    将 C++ 库编译成共享库(.so 文件),使 Python 能够直接调用。
    使用 Python 的 ctypes 或 cffi 库加载这个共享库,并在 Python 中调用 C++
    类的方法

修改main.cc,将C++代码封装为C接口,供Python调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
extern "C" {
IP2Region* IP2Region_new(const char* ipv4db, const char* ipv6db) {
std::string ipv4db_str(ipv4db);
std::string ipv6db_str(ipv6db);
return new IP2Region(ipv4db_str, ipv6db_str);
}

const char* IP2Region_search(IP2Region* ip2region, const char* ipStr) {
static std::string result;
try {
result = ip2region->search(std::string(ipStr));
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return nullptr;
}
return result.c_str();
}

void IP2Region_free(IP2Region* ip2region) {
delete ip2region;
}

}

python使用cffi库调用C++代码,先定义C++类的Python封装,然后调用C++代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ffi = cffi.FFI()
ffi.cdef("""
typedef struct IP2Region IP2Region;
IP2Region* IP2Region_new(const char* ipv4db, const char* ipv6db);
const char* IP2Region_search(IP2Region* ip2region, const char* ipStr);
void IP2Region_free(IP2Region* ip2region);
""")

ip2region_lib = ffi.dlopen(lib_path)

# 定义C++类的Python封装
class Ip2Region:
def __init__(self):
self.obj = ip2region_lib.IP2Region_new(ipv4_xdb.encode('utf-8'), ipv6_xdb.encode('utf-8'))
if not self.obj:
raise Exception('init ip2region failed')

def search(self, ip):
result = ip2region_lib.IP2Region_search(self.obj, ip.encode('utf-8'))
if result == ffi.NULL:
raise Exception('search ip failed')
return ffi.string(result).decode('utf-8')

def __del__(self):
ip2region_lib.IP2Region_free(self.obj)

实时分析流量的CDN

了解CDN的作用功能,如何查询CDN,如何确定主流境外服务提供商的
CDN地址范围,如谷歌(重点)、推特、脸书、github等,实时检测分析流量
的使用CDN服务的情况。

CDN(Content Delivery Network,内容分发网络)是一种分布式服务器网
络,其目的是通过将内容分发到更接近用户的服务器节点来加速网站和应用程序
的加载速度,提高访问性能,并降低服务器负载。

查询CDN

任务:查询下列网站的CDN

网站 CDN服务提供商
www.geekflare.com Cloudflare、BunnyCDN、Fastly
www.github.com Fastly
www.youtube.com Google
www.bilibili.com ChinaNetCenter/Wangsu
www.facebook.com Facebook
www.taobao.com Alibaba
www.zhihu.com Tencent Cloud
www.qq.com Tencent Cloud Akamai
www.yahoo.com Amazon CloudFront YAHOO
  1. 使用在线工具查询CDN(推荐)
    例如,CDNFinder可以提供整个网站或者特定域名使用的CDN服务。
  2. 使用命令行工具查询CDN
    首先需要找出域名的IP地址,使用DNSrecordlookup或者DNSWatch找到
    对应的IP地址,下面使用在线工具找到IP所有者,可以使用whois等工具

获取官方网站的IP地址范围

大型网站会定期发布它的所有IP地址,对此我们可以定期爬取更新,缓存
在我们本地。
任务:仿照附件findIP.py文件编写脚本爬取以下官方网站的IP地址文件
(1)Cloudflare

1
2
3
4
5
6
7
8
9
def get_cloudflare_ips():
url = "https://www.cloudflare.com/ips-v4"
response = requests.get(url)
ip_list = response.text.split("\n")

with open("cloudflare_ips.txt", "w") as file:
file.write(f"Total IPs: {len(ip_list)}\n")
file.write("\n".join(ip_list))
print("Cloudflare IP addresses have been written to cloudflare_ips.txt")

(2)Amazonaws

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def get_aws_ips():
url = "https://ip-ranges.amazonaws.com/ip-ranges.json"
response = requests.get(url)
data = response.json()

ip_list = []
max_num = 100 #太多了,只取前100个,虚拟机跑太慢
for prefix in data["prefixes"]:
if "ip_prefix" in prefix:
network = ipaddress.IPv4Network(prefix["ip_prefix"])
ip_list.extend(str(ip) for ip in network)
max_num -= 1
if max_num == 0:
break

with open("aws_ips.txt", "w") as file:
file.write(f"Total IPs: {len(ip_list)}\n")
file.write("\n".join(ip_list))
print("AWS IP addresses have been written to aws_ips.txt")

实时流量分析

在本实验中,我们是用pyshark库进行抓取我们网口动态的流量,对其进- 12
行包的抓取与分析。
任务:尝试运行Capture_demo.py文件,得到实时流量抓取DNS请求结果。

任务

我们最终的目的是实现实时抓取流量,并且解析到使用CDN的情况,所以
需要构建一个常用的CDN_PROVIDER的列表进行对比,所以构建出这个列表十
分关键。
任务:根据上面得到的DNS解析结果(可以将域名或者主机名输出保存为文本
文件),结合CDN查询工具,编写自动化查询CDN的代码,查询10个及以上
的解析到的主机名对应CDN服务提供商并生成列表(避免无效)。
例如:huadong.taobao.com, Alibaba
g.alicdn.com, Alibaba
(附代码及生成列表)

数字证书来源分析

实验要求

  1. 学习数字证书的格式与构成

本实验要求学生了解并掌握常见数字证书的格式(如 X.509 标准)及其构成
元素。学生需要熟悉数字证书中的基本字段,如证书的版本、序列号、颁发者信
息、有效期、公钥信息等,并理解这些字段的含义和作用。特别是,要理解证书
的签名算法和签名值部分,以及如何通过这些信息来验证证书的有效性。
2. 理解数字证书的作用

数字证书在网络通信中起着至关重要的作用,主要用于身份认证、信息加密
和数据完整性保护。通过学习数字证书的工作原理,学生需要理解如何通过公钥
加密实现数据的保密性和完整性验证,如何通过数字证书保证通信双方的身份可
信,并且理解证书链及其在建立信任关系中的作用。
3. 抓包并分析网络流量中的数字证书

学生需要使用网络抓包工具(如 Wireshark)对 HTTPS 等加密协议进行抓
包,捕获包含数字证书的网络通信流量。通过分析抓包数据,提取出数字证书并
展示证书的基本内容。学生需学会如何识别并解读数字证书的各项信息,如证书
的颁发机构、有效期、公钥等。
4. 判断数字证书的颁发机构是否为境内机构

在分析数字证书内容的基础上,学生需要识别证书中的颁发机构(Certificate
Authority, CA),并判断该颁发机构是否为境内的认证机构。学生可以通过比对
证书颁发机构的名称与公共信任证书库中的相关信息,判断其地理位置和法律管
辖区,并结合国际和国内证书颁发机构的特点,分析证书的可信度及其可能带来
的安全风险。

实验过程

  1. 使用wireshark 寻找数字证书
    以bing.com 为例,具体演示wireshark获取网站数字证书的过程。首先,使
    用火狐浏览器访问网站bing.com,同时打开wireshark并监听ens33端口进行抓

在wireshark 中设置过滤条件进行过滤,找到包含数字证书的流量数据,设
置的过滤条件为tls.handshake.type == 11

从上图中可以看出,访问网站bing.com的过程中产生了包含数字证书的流量
数据。继续跟随该数据包的通信过程,右键点击第一条数据,并选择跟随TLS
流,查看其完整的通信流程。

从前面的通信数据报文可以看出,此处的确是与网站bing.com交互并进行身- 15
份认证而产生的相关网络流量。回到之前的那个数据报文,点开第一个TLS层
信息可以看到本层数据为握手协议中的Certificate信息。继续点开下面Certificate
的具体信息,此处的数字证书是以十六进制数据的形式保存的,这正是我们要找
的数字证书数据。

  1. 导出数字证书
    任务:将提取到的十六进制数据转换成CRT格式的数字证书,并确定数字证书
    的颁发机构信息

在上述任务中,我们已经提取到了数字证书的十六进制数据,接下来就是从
中提取出完整的数字证书。右键点击上面的数字证书数据,并选择复制值,将三
个数字证书的十六进制数据保存到文本文档中。

接下来写个脚本,将十六进制的数据读入并处理,再转换成PEM格式的数
字证书输出即可。运行脚本ca.py,在得到可视化的数字证书文件后,单击打开
并查看其中的Issuer字段信息。以第一个数字证书文件为例,可以看到该证书的
颁发机构为Microsoft Corporation,该颁发机构所属国家为US(美国),因此该
证书的颁发机构为境外机构。

  1. 自动化实现数字证书的提取
    任务:尝试补全analyze.py脚本文件,得到各类网站的数字证书信息,并与手动
    提取的证书文件进行比较。
    在前述过程中,我们已通过Wireshark手动提取了网络通信中的数字证书文
    件信息。基于此,是否可以进一步实现自动化提取数字证书的过程?即通过脚本
    实时监听网络通信数据,并从中提取数字证书,再将其转换为可视化的数字证书
    文件进行输出?
    为此,我们可以通过编写Python脚本来自动化这一流程。通过使用Python
    的网络分析库,结合SSL/TLS协议的解析工具,可以实现对网络流量的实时捕
    获与数字证书的提取。具体的实现方法可以参考附件中的脚本文件。此方法相比
    手动操作具有明显的优势,能够显著提高证书提取的效率和准确性,尤其适用于
    需要处理大量网络数据流的场景。
  • Title: 网安实践5.2
  • Author: moyigeek
  • Created at : 2024-11-15 10:37:25
  • Updated at : 2025-12-11 11:16:47
  • Link: https://blog.moyihust.eu.org/2024/11/15/网安实践5-2/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments