Giter Site home page Giter Site logo

python_cookielib_0day's Introduction

Python Cookielib 0-day PoC

先上PoC (PHP 版)


    header('Set-Cookie: test=123; max-age=a');  //  PoC 1
    header('Set-Cookie: test=123; domain=;');  //  PoC 2
    

PoC 浏览器端验证

PoC 1/2 在Python Requests 库中的验证

Cookielib 0-day PoC 反Python 爬虫的应用

PoC Demo Source for PHP


    <?php

    session_start();

    if (!isset($_SESSION['username'])) {
        $_SESSION['username'] = 'root';

        echo 'Reflash for get tips .SID = ' . session_id();

        header('Set-Cookie: PHPSESSID=' . session_id() . '; max-age=a');  // PoC 1
    } else {
        echo 'Your username is ' . $_SESSION['username'];

        session_destroy();
    }

    ?>

Demo 代码不作演示,请自行测试效果

Cookieslib 0-day 源码分析

上面的PoC 导致Cookielib 解析Set-Cookie 数据包头出现异常的代码在lib/cookielib.py 第1415 行和1434 行


    if k == "domain":                  #  lib/cookielib.py:1411
        if v is None:                  #  lib/cookielib.py:1412
            _debug("   missing value for domain attribute")
            bad_cookie = True
            break                      #  lib/cookielib.py:1415
        # RFC 2965 section 3.3.3
        v = v.lower()
    if k == "expires":
        if max_age_set:
            # Prefer max-age to expires (like Mozilla)
            continue
        if v is None:
            _debug("   missing or invalid value for expires "
                  "attribute: treating as session cookie")
            continue
    if k == "max-age":                 #  lib/cookielib.py:1426
        max_age_set = True
        try:
            v = int(v)                 #  lib/cookielib.py:1429
        except ValueError:
            _debug("   missing or invalid (non-numeric) value for "
                  "max-age attribute")
            bad_cookie = True
            break                      #  lib/cookielib.py:1434

Cookielib 在解析Cookie 数据时,会对Cookie 的设置(比如:Cookie 使用域,Cookie 过期时间等)进行解析.先回顾PoC 1


    header('Set-Cookie: test=123; max-age=a');  //  PoC 1

当代码执行到lib/cookielib.py 第1426 行时,判断Cookie 设置属性是否为max-age ,接下来会把max-age 的值尝试用int() 转换,PoC 1 中填写一个字符,导致1429 行代码v = int(v) int() 转换失败,触发异常,退出对当前的Cookie 进行处理.也就是说,Cookielib 丢弃掉这条Cookie 记录,没有完全返回服务器端给我们的Set-Cookie 记录

再看看PoC 2 的代码


    header('Set-Cookie: test=123; domain=;');  //  PoC 2

domain 的值为空,导致lib/cookielib.py 第1412 行代码判断成立,执行到break 语句,跳过当前的Cookie 处理

第二个Cookieslib 0-day 源码分析

前面触发问题是来源于函数_normalized_cookie_tuples() 的代码,往上追溯,到_cookies_from_attrs_set()


    def _cookies_from_attrs_set(self, attrs_set, request):
        cookie_tuples = self._normalized_cookie_tuples(attrs_set)

        cookies = []
        for tup in cookie_tuples:
            cookie = self._cookie_from_cookie_tuple(tup, request)    #  lib/cookielib.py:1555
            if cookie: cookies.append(cookie)                        #  lib/cookielib.py:1556
        return cookies
        

_cookies_from_attrs_set() 函数通过_normalized_cookie_tuples1() 把Set-Cookies 处理好之后,得到cookie_tuples ,前面的两个PoC 会让Set-Cookies 的记录没有正确返回到cookie_tuples .接下来,CookieLib 通过_cookie_from_cookie_tuple 对cookie 的设置进行进一步处理,问题产生在lib/cookielib.py:1472


    def _cookie_from_cookie_tuple(self, tup, request):
        # standard is dict of standard cookie-attributes, rest is dict of the
        # rest of them
        name, value, standard, rest = tup

        domain = standard.get("domain", Absent)
        path = standard.get("path", Absent)
        port = standard.get("port", Absent)
        expires = standard.get("expires", Absent)

        # set the easy defaults
        version = standard.get("version", None)  #  lib/cookielib.py:1469
        if version is not None:
            try:
                version = int(version)           #  lib/cookielib.py:1472
            except ValueError:
                return None  # invalid version, ignore cookie
        secure = standard.get("secure", False)
        # (discard is also set if expires is Absent)
        discard = standard.get("discard", False)
        comment = standard.get("comment", None)
        comment_url = standard.get("commenturl", None)

lib/cookielib.py 1469行代码尝试获取Cookie 的设置,这里是要获取version 字段的值,接下来判断version 字段是否能被int() 函数转换成数值,同样的道理,把值换成字符串即可产生异常,导致lib/cookielib.py:1472 触发异常,执行return None .回去看代码lib/cookielib.py:1555 ,cookie = None ,导致lib/cookielib.py:1556 的判断失效,没有把这个经过处理的Cookie 添加到要返回的结果列表

PoC 如下:


    header('Set-Cookie: test=123; version=a;');  //  PoC 3

python_cookielib_0day's People

Contributors

lcatro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.