团队声明
该检测方法为我安全实验室研发,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。基于人工智能检测代码在知识星球,知识星球会员免费获取。
文章概要
随着网络技术的发展,内网代理工具(例如,VPN、SOCKS代理等)被广泛应用于绕过网络限制或增强隐私保护。然而,恶意用户也利用这些工具进行攻击、窃取数据或绕过监控。本研究旨在使用机器学习技术检测内网代理工具的流量特征,以辅助网络安全。
内网引言
内网代理工具提供了一种在互联网中创建隧道的方法。由于其加密和混淆机制,传统的流量分析方法很难检测这些工具的活动。因此,新的检测方法是必要的。
先前的研究已经探讨了多种基于规则的流量分析方法。但由于内网代理工具持续地进行更新和改进,这些传统方法常常失效。今天我们就来聊聊frp工具。
frp是一个高性能、跨平台的反向代理应用,主要用于内网穿透,帮助开发者将内网服务暴露给公网,从而能够轻松地实现远程访问和管理。
以下是frp的一些关键特性和组件:
1. 主要组件:
-
frps:frp服务器,通常部署在有公网IP的机器上。
-
frpc:frp客户端,部署在内网环境中的机器上,用于连接到frps。
2. 特性:
反向代理:不需要修改防火墙或路由器配置,就可以将内网服务暴露到公网。
-
多种协议支持:支持TCP、UDP、HTTP、HTTPS和Websocket。
-
认证与加密:通过TLS保证连接的安全性。
-
流量复用:减少多次的握手过程,提高传输效率。
-
负载均衡:支持将同一个端口的流量分发到多个后端服务。
-
插件系统:可以扩展其功能,例如,进行身份验证或修改请求。
-
自定义域名:允许为内网Web服务配置自定义域名。
-
健康检查:检查后端服务的健康状态,如果服务不可用,可以自动移除。
-
压缩支持:可以选择是否压缩传输数据。
3. 使用场景:
-
远程管理:例如,您在家中有一个没有公网IP的NAS设备,但您希望在外部访问它。使用frp,您可以轻松实现这一目标。
-
开发与测试:本地开发时,可以使用frp将你的开发环境暴露给外部用户或客户进行测试。
-
内网集群访问:在没有VPN的情况下,访问内网中的多台机器。
4. 安全性:
虽然frp在设计时考虑到了安全性(如使用TLS进行加密),但任何允许外部访问内部资源的工具都增加了风险。因此,建议仔细配置其安全性设置,并定期检查更新以确保获得任何安全修复。
特征分析
这里也不是说frp好欺负,而是我们准备通过系列文章,把内网工具都欺负一遍。废话不多说开始欺负了,通过上面的介绍我们了解到了frp支持TCP UDP等协议并且它是支持TLS流量加密的。通过Wireshark抓包分析。
在未开启TLS流量加密的前提下,数据包的明文的。通过源码分析我们知道frp工具客户端和服务端在连接时会有登录信息。该登录信息保存在登录信息结构体中。也就是图中我标记的三个数据包,这三个数据包在建立连接的是否发送的是认证数据。
{"version":"0.28.2","hostname":"","os":"darwin","arch":"amd64","user":"","privilege_key":"144fa23b09635f403ccd18","timestamp":1567119104,"run_id":"","pool_count":1}
这里记载了frp的版本信息,主机名称,操作系统类型,系统架构,用户,key,时间戳,run_id和pool_count等信息。这个信息也是众多安全公司流量分析设备在采集信息时候,区分frp的规则信息。这足以对付一般的渗透测试人员,但是对于高手来说都是会隐藏特征的。这部分我们将会在星球为大家讲解。那么刚才我们提到了frp工具还支持TLS流量加密。那么加密以后的流量特征就没有了吗?经过研究我们发现TLS加密以后第一个认证字节内容为0x17。
特征工程
tcpdump -i eth0 '(port 7000) and (tcp[0:1] = 0x17 or udp[0:1] = 0x17) and
(tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x70726976 or udp[32:4] = 0x70726976)'
然后对于数据进行标记:
import pandas as pd
import json
# 载入数据
data = pd.read_csv("frp_features.txt", sep="t", header=None, names=["payload", "tls_type"])
# 标记数据
labels = []
features = {"payload_length": [], "tls_header": []}
for _, row in data.iterrows():
payload = row["payload"]
tls_type = row["tls_type"]
# 检查是否使用了TLS加密
features["tls_header"].append(1 if tls_type == 0x17 else 0)
try:
decoded_data = bytes.fromhex(payload).decode('utf-8')
json_data = json.loads(decoded_data)
keys_to_check = ["version", "hostname", "os", "arch", "user", "privilege_key", "timestamp", "run_id", "pool_count"]
if all(key in json_data for key in keys_to_check):
labels.append(1)
else:
labels.append(0)
except:
labels.append(0)
features["payload_length"].append(len(str(payload)))
df = pd.DataFrame(features)
df["label"] = labels
df.to_csv("enhanced_frp_features.csv", index=False)
数据准备
import pandas as pd
from sklearn.model_selection import train_test_split
data = pd.read_csv("frp_labels.csv")
data['payload_length'] = data['payload'].apply(len)
X = data[['payload_length']]
y = data['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
模型选择
from sklearn.ensemble import IsolationForest
# 训练模型
clf = IsolationForest(contamination=0.05, random_state=42) # contamination参数表示数据集中异常值的比例
clf.fit(X_train[y_train == 1])
预测评估
y_pred = clf.predict(X_test)
# 转换预测的标签 (-1为异常,1为正常)
y_pred = [0 if x == -1 else 1 for x in y_pred]
from sklearn.metrics import classification_report, confusion_matrix
print(classification_report(y_test, y_pred))
print(confusion_matrix(y_test, y_pred))
加入星球
源代码、工具、更多知识在星球。
推荐书籍
关注我们
原文始发于微信公众号(小白嘿课):【前沿】如何通过机器学习检测内网代理 & 内网穿透 & 流量转发 & 流量加密工具(一)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论