某开源堡垒机历史漏洞分析

2022-9-22 23:55:37 Author: xz.aliyun.com(查看原文) 阅读量:45 收藏

前言

前端时间在某社区看到有师傅发了,我就整理了一下,因为之前看过这套堡垒机的pythonweb,并把目前网上公开的漏洞分析了下,做个记录~~~

水平太cai,请大伙批评指正~~~

分析

  1. 环境搭建(3.5.6-rc6版本)

    在官网下载安装包,tar命令解压,进入目录,以管理员身份运行./setup.sh即可(直接enter选择默认路径)。

    访问主机7190端口:

    搭建环境遇到的问题:用的是centos7虚拟机搭建,遇到ping到主机却telnet不到7190端口的问题,查询资料后关闭centos7防火墙即可。

  2. 漏洞分析

    • 逻辑缺陷

      看webroot:

      python的应用没怎么看过,不过应该是大同小异,路由结构在app/controller/__init__.py:看登录认证相关:

      转到app.controller.auth.DoLoginHandler:

      通过app.model.user.login判断返回信息,这里将username、password和oath参数带入,跟进app.model.user.login:

      然后password判断(代码太长,没有展开):

      逻辑缺陷在于,在用户密码password为空时,没有对应的控制逻辑,导致登录绕过。

      正常请求的json为:

      {"type":2,"username":"admin","password":"admin","captcha":"xcj9","oath":"","remember":false}

      那么将password变为null,即可绕过:

      {"type":2,"username":"admin","password":null,"captcha":"xcj9","oath":"","remember":false}

    • 任意文件读取(后台)

      在app.controller.audit.DoGetFileHandler中,对应路由为:

      通过f参数获取filename信息:

      跟踪filename:

      filename直接就拼接到file,然后open:

      但要满足下列条件:

      if act is None or _type is None or rid is None or filename is None:
                  self.set_status(400)  # 400=错误请求
                  return self.write('invalid param, `rid` and `f` must present.')
      
              if act not in ['size', 'read']:
                  self.set_status(400)
                  return self.write('invalid param, `act` should be `size` or `read`.')
              if _type not in ['rdp', 'ssh', 'telnet']:
                  self.set_status(400)
                  return self.write('invalid param, `type` should be `rdp`, `ssh` or `telnet`.')
      

      这个任意文件读取需要后台管理员权限,属于是鸡肋,且该系统用户均为具有一定权限的用户:

      所以这个不深究了。

    • 存储xss

      这个是我在cve上搜到的,只有一句简单的描述(在老版本上存在):

      对比3.1.0和3.5.6版本登录逻辑的区别,不难找到问题所在:

      可以看到在3.5.6将<>进行实体编码,结合前端显示:

      不难猜测是通过闭合<>达到存储xss的目的。

    • csrf漏洞

      同样也是只有一句简单描述,那么只能自己看了。

      在重置密码app.controller.user.DoResetPasswordHandler中:

      可以通过mode控制执行的模式,重点看mode==2:

      mode==2时,先鉴权,然后获取user_id和password,注意这里不需要传入旧密码,接着往下走就能看到先进行密码强度检查,然后就通过user_id和password重置密码了:

      这里理论上可以制作钓鱼链接发给管理员,重置任意密码。

      利用:

      url:http://192.168.87.149:7190/user/do-reset-password

      post:args={"mode":2,"id":2,"password":"[email protected]"}

      (该漏洞在最新发行版本中仍存在)

    • 未授权漏洞

      看下app/controller/system.py,随便拿个路由来说,方法都会调用app.base.controller.TPBaseHandler.check_privilege鉴权:

      不过app.controller.system.DoGetLogsHandler中没有进行鉴权:

      通过路由可以找到该请求包:

      正常请求(携带cookie):

      删除cookie同样返回数据:

      接着看下逻辑,调用了app.model.syslog.get_logs:

      将sql_filter中key为log_user_name的值带入语句,这里则可以闭合"达到sqli。

  3. 总结

    pythonweb看的不多,不过前段时间经常拿来写点什么小玩意~~~

    自己没耐心了,感觉应该还有不少东西可以学习一下~~~

参考

https://github.com/tp4a/teleport/issues/290

https://github.com/tp4a/teleport/issues/276

https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=teleport+++tp4a


文章来源: https://xz.aliyun.com/t/11721
如有侵权请联系:admin#unsafe.sh