Midnight Sun CTF 2020 Quals Shithappens

haproxy

global
  daemon
  log 127.0.0.1 local0 debug

defaults
  log               global
  retries           3
  maxconn           2000
  timeout connect   5s
  timeout client    50s
  timeout server    50s

resolvers docker_resolver
  nameserver dns 127.0.0.11:53

frontend internal_access
  bind 127.0.0.1:8080
  mode http
  use_backend test

frontend internet_access
  bind *:80
  errorfile 403 /etc/haproxy/errorfiles/403custom.http
  http-response set-header Server Server
  http-request deny if METH_POST
  http-request deny if { path_beg /admin }
  http-request deny if { cook(IMPERSONATE) -m found }
  http-request deny if { hdr_len(Cookie) gt 69 }
  mode http
  use_backend test

backend test
  balance roundrobin
  mode http
  server flaskapp app:8282 resolvers docker_resolver resolve-prefer ipv4

题目给出了haproxy的设置具体语义去文档看看就懂了,我们可以收获以下信息

  • http method不可以是POST
  • url路径不能以/admin开头
  • cookie中必须包含IMPERSONATE
  • cookie长度不能大于69
    同时我们可以看到这是个flask的应用

bypass

  • 第一步method好解决,用head访问//admin方法可以获取
    Set-Cookie: IMPERSONATE=admin; Path=/
    Set-Cookie: KEY=0be40039bcd8286eab237f481641b16e5e3ab442e0bc1135f08c143b22dc1efc; Path=/
    
  • 第二步这个cookie的长度已经大于69了,但是HTTP 1.1支持分行传递cookie,所以可以
    Cookie: KEY=0be40039bcd8286eab237f481641b16e5e3ab442e0bc1135f08c143b22dc1efc;
    Cookie: IMPERSONATE=admin
    

flask cookie解析问题

其实也不是flask的问题,只是haproxy和flask解析cookie结果不一样导致的bypass。正好最近在学nodejs,我就先拿express试了一下,发现这样解析是没有问题的

然后再拿flask试一下发现本来应该错误的cookie被正确解析了

看一下源码,找到flask中request类的cookies方法,往下调可以找到解析cookie的正则

_cookie_re = re.compile(
    br"""
    (?P<key>[^=;]+)
    (?:\s*=\s*
        (?P<val>
            "(?:[^\\"]|\\.)*" |
             (?:.*?)
        )
    )?
    \s*;
""",
    flags=re.VERBOSE,
)

key中是不可以有=或者;的,所以传入这样的cookie时,=不会被匹配,然后后边的IMPERSONATE=admin;被正常解析

posted @ 2020-04-05 16:04  MustaphaMond  阅读(165)  评论(2编辑  收藏