0%

twisted历史漏洞

twisted历史版本的一些CVE,漏洞细节和复现

CVE-2016-1000111
httpoxy漏洞
Twisted 16.3.1以前的版本有 RFC 3875 第 4.1.18 节命名空间冲突的问题,因此不会保护 CGI 应用程序免受 HTTP_PROXY 环境变量中不可信客户端数据的影响,这可能允许远程攻击者重定向 CGI 应用程序的出站 HTTP通过 HTTP 请求中精心设计的代理标头将流量传输到任意代理服务器,也就是httpoxy问题。
关键代码:twcgi.py 119行

1
2
3
if title not in (b'content-type', b'content-length'):
envname = b"HTTP_" + envname
env[envname] = header

RFC 3875 4.18节中要求HTTP请求头 标头字段名转换为大写,包含所有出现的”-“替换为”_“,并在前面加上”HTTP_”。

1.访问开启CGI服务的twisted应用,请求头中加上Proxy: 10.10.10.128:8080 字段
2.服务端根据RFC要求 将10.10.10.128:8080写入应用的环境变量中,即env[‘HTTP_PROXY’]=10.10.10.128:8080,污染应用环境变量
3.当该应用使用HTTP_PROXY环境变量请求时,请求的数据会被恶意代理

复现
1.配置cgi
修改/etc/apache2/apache2.conf,加入ScriptAlias /cgi-bin/ /var/www/cgi-bin/, 将/var/www/cgi-bin/映射到/cgi-bin/

1
2
3
ln -s /etc/apache2/mods-available/cgid.conf /etc/apache2/mods-enabled/cgid.conf
ln -s /etc/apache2/mods-available/cgid.load /etc/apache2/mods-enabled/cgid.load
ln -s /etc/apache2/mods-available/cgi.load /etc/apache2/mods-enabled/cgi.load

修改 /etc/apache2/conf-available/serve-cgi-bin.conf

1
2
3
4
5
6
<Directory "/var/www/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Require all granted
AddHandler cgi-script .cgi .pl .py
</Directory>

重启apache2
service apache2 restart
在/var/www/cgi-bin/中创建hello.py

1
2
3
4
5
6
#!/usr/bin/env python
import cgitb
cgitb.enable()
print "Content-Type: text/html"
print
print "Hello World!"

2.配置twisted

1
2
3
4
5
6
7
8
9
from twisted.internet import reactor, endpoints
from twisted.web import static, server, twcgi


root = static.File("/var/www/")
root.putChild(b"cgi-bin", twcgi.CGIDirectory("/var/www/cgi-bin"))
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8080)
endpoint.listen(server.Site(root))
reactor.run()

把web服务起来,访问 http://localhost:8080/cgi-bin/hello.py
3.修改请求头

可以看到应用环境变量已经被污染

修复
https://github.com/twisted/twisted/pull/482/files

总结:该CVE是httpoxy衍生出来的漏洞,总体利用条件还是比较苛刻的:需要应用使用CGI,应用向外请求并使用应用的HTTP_PROXY环境变量作为代理。

CVE-2019-12387
在twisted 19.2.1版本以前,在发起请求时没有对请求方法和URI字段进行检查,导致了CRLF注入的发生。
关键代码 cllient.py 84行

1
2
method = getattr(self.factory, 'method', b'GET')
self.sendCommand(method, self.factory.path)

复现
1.复现脚本

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from twisted.python import log
from twisted.internet.defer import Deferred
from twisted.internet import reactor
from twisted.internet.protocol import Protocol
from twisted.web.client import Agent, ResponseDone
from twisted.web.resource import Resource
from twisted.web.server import Site

class WriteToStdout(Protocol):
def connectionMade(self):
self.onConnLost = Deferred()

def dataReceived(self, data):
# get redirect data
print("Got some:", data)

def connectionLost(self, reason):
if not reason.check(ResponseDone):
reason.printTraceback()
else:
print("Response done")
self.onConnLost.callback(None)

class New(Resource):
def __init__(self, data):
data = 'http://' + data.decode()
self.data = data
url = data.encode("ascii")
agent = Agent(reactor)
d = agent.request(b"GET", url)
def cbResponse(response):
proto = WriteToStdout()
response.deliverBody(proto)
return proto.onConnLost
d.addCallback(cbResponse)
d.addErrback(log.err)

def render_GET(self, request):
return self.data.encode()

class checkPage(Resource):
def getChild(self, path, request):
if path == '':
return self
else:
print(path)
return New(path)
def render_GET(self, request):
return 'require parameters'.encode()

if __name__ == "__main__":
resource = checkPage()
factory = Site(resource)
reactor.listenTCP(8000, factory)
reactor.run()

上述代码简要介绍:
请求localhost:8000/<目标url>,请求服务端,使其访问目标url,模拟了日常生活中登录跳转的情况。
10.10.10.128:8000 上运行上述twisted服务
10.10.10.1:8081运行另一个web服务

访问

服务端打印目标网页10.10.10.1:8081信息

2.利用CRLF
由于19.2.1前的版本没有检查client请求时的请求方法和URL,使用CRLF构造xss的payload

服务端收到的URL如下

修复
https://github.com/twisted/twisted/commit/6c61fc4503ae39ab8ecee52d10f10ee2c371d7e2
增加_ensureValidMethod和_ensureValidURI方法对请求方法和url进行校验

CVE-2020-10108
当出现两个Content-Length的标头时,Twisted Web 忽略了第一个标头。 当第二个内容长度设置为零时,它会导致 Twisted Web 将请求正文解释为流水线请求。
https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3

CVE-2020-10109
当出现Content-Length和Transfer-Encoding标头时,Content-Length优先,请求正文的其余部分被 Twisted Web 解释为流水线请求。
https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3

修复
https://github.com/twisted/twisted/compare/twisted-19.10.0...twisted-20.3.0

后两个CVE均是HTTP走私造成的问题

https://github.com/twisted/twisted/compare/twisted-19.10.0...twisted-20.3.0
https://blog.csdn.net/ai953166219/article/details/79271247https://httpoxy.org/https://www.cvedetails.com/vulnerability-list/vendor_id-16756/product_id-55543/version_id-554609/Twistedmatrix-Twisted--.html
https://github.com/twisted/twisted/commit/6c61fc4503ae39ab8ecee52d10f10ee2c371d7e2
https://hackerone.com/reports/52042
https://bishopfox.com/blog/twisted-version-19-10-0-advisory
https://wooyun.js.org/drops/CRLF%20Injection%E6%BC%8F%E6%B4%9E%E7%9A%84%E5%88%A9%E7%94%A8%E4%B8%8E%E5%AE%9E%E4%BE%8B%E5%88%86%E6%9E%90.html