JAVA代码审计篇-用友NC65鉴权绕过分析
首先我们知道用友NC有很多注入漏洞都是基于一个鉴权绕过的前提下进行的注入 也就是用 pageId=login 来绕过鉴权,但是在网上找了找发现都是关于注入漏洞部分的分析,都没有提到鉴权部分的分析(很烦)于是只能自己分析下。
查看PortalLoginFilter类 发现继承了AbstractLfwLoginFilter 并且没有重写doFilter 所以我们就看他的父类AbstractLfwLoginFilter中的doFilter方法。
这里查看AbstractLfwLoginFilter的doFilter方法
在这里,前两个
构造请求包进行测试验证
没有加pageId的情况下 没有走到功能点 302响应 被重定向到 /portal 。
加入参数pageId=login 或者pageId=passwordmng 可以看到是参数错误导致的500报错也就是成功绕过鉴权。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
首先我们知道用友NC有很多注入漏洞都是基于一个鉴权绕过的前提下进行的注入 也就是用 pageId=login 来绕过鉴权,但是在网上找了找发现都是关于注入漏洞部分的分析,都没有提到鉴权部分的分析(很烦)于是只能自己分析下。
查看PortalLoginFilter类 发现继承了AbstractLfwLoginFilter 并且没有重写doFilter 所以我们就看他的父类AbstractLfwLoginFilter中的doFilter方法。
这里查看AbstractLfwLoginFilter的doFilter方法
在这里,前两个
if 判断条件满足,即可直接进入后续的 doFilter 流程并放行请求。首先关注第一个判断条件,其调用的 isToLogin 方法仅依据从可控的请求参数 pageId 的取值进行判断。当 pageId 等于 login 或 passwordmng 时,方法直接返回 `true`,从而绕过登录校验,导致鉴权绕。this.isToLogin(req, res)
private boolean isToLogin(HttpServletRequest req, HttpServletResponse res) {
String pageId = req.getParameter("pageId");
return pageId != null && (pageId.equals("login") || pageId.equals("passwordmng"));
}
构造请求包进行测试验证
没有加pageId的情况下 没有走到功能点 302响应 被重定向到 /portal 。
加入参数pageId=login 或者pageId=passwordmng 可以看到是参数错误导致的500报错也就是成功绕过鉴权。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
modelConfig.getConfigValue(ESCAPE_URL) 用于从配置文件中读取免鉴权访问的路径白名单,并将该配置与当前请求的 URL 进行匹配判断。然而在匹配过程中,代码采用 indexOf 的方式进行字符串包含判断,而非严格的路径匹配。同时,请求 URL 的构造中包含了 `req.getQueryString()`,即将用户可控的请求参数一并纳入匹配范围。 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
PortalLogger.debug((String)LfwResBundle.getInstance().getStrByID("ds", "AbstractLfwLoginFilter-000000"));
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
WebContext webCtx = LfwRuntimeEnvironment.getWebContext();
String currentUrl = req.getRequestURI();
String loginURL = this.getLoginJspName();
if (webCtx != null) {
LfwRuntimeEnvironment.getWebContext().setResponse(res);
} 在上述逻辑下,攻击者可通过在请求参数中加入配置文件中定义的免鉴权路径关键字,使请求 URL 命中免鉴权规则,从而导致鉴权绕过。
经过搜索发现在以下配置文件中存在很多免鉴权的路径。
随便选取其中的一个路径构造请求包进行测试如 pt/oncelogin/getAuth ,500返回确实没有被鉴权拦截。
更换其他接口地址试一下320响应了,被鉴权拦截 上述接口确实为免鉴权路径。
接下来使用构造一个参数值为pt/oncelogin/getAuth的请求包进行测试确实绕过鉴权。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
内存解密远控木马
通过分析,发现shellcode成功加载后:
● 将在内存中解压缩PE文件;
● 解压缩PE文件的MD5是69CECFC2549EAF971FA04212EC4A121D,与笔者《金眼狗(APT-Q-27)滥用AWS S3存储桶分发最新恶意载荷》文章中释放的远控木马Hash相同;
● 解压缩后的PE文件是一款隶属于金眼狗组织的远控木马,具备检查运行环境、内置C2地址、判断管理员权限、创建服务、远控指令等功能;
letsvpn-latest.exe
文件名称:letsvpn-latest.exe
文件大小:23015744 字节
文件版本:3.16.4.0
MD5 :3D8F35E54A3DD41286738C8C2A9823BB
SHA1 :D8FE5C317D695733EC312C432CC39E861E46BF4B
SHA256:124E8F7CA958FD8CB2A3BAF91681513F93F73D9CFA4EFEA6F4A1F165D8CBC8D9
释放文件
通过分析,发现此样本运行后,将从文件资源段中提取载荷数据,并将载荷数据拆分成多个文件,释放至%APPDATA%\Crash目录中。
进一步分析,发现释放的文件均携带了数字签名,根据数字签名名称可确定与此次攻击活动相关的样本为libcurl.dll和qr.dll样本。
创建计划任务
通过分析,发现此样本将通过Windows Task Scheduler COM接口创建计划任务,计划任务将在用户登录时触发:
● MicrosoftEdgeUpdate_QR:C:\Windows\System32\rundll32.exe "C:\Users\admin\AppData\Roaming\Crash\qr.dll",StartQR
● MicrosoftEdgeUpdate_TenioDL:C:\Users\admin\AppData\Roaming\Crash\Crash.exe
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
通过分析,发现shellcode成功加载后:
● 将在内存中解压缩PE文件;
● 解压缩PE文件的MD5是69CECFC2549EAF971FA04212EC4A121D,与笔者《金眼狗(APT-Q-27)滥用AWS S3存储桶分发最新恶意载荷》文章中释放的远控木马Hash相同;
● 解压缩后的PE文件是一款隶属于金眼狗组织的远控木马,具备检查运行环境、内置C2地址、判断管理员权限、创建服务、远控指令等功能;
letsvpn-latest.exe
文件名称:letsvpn-latest.exe
文件大小:23015744 字节
文件版本:3.16.4.0
MD5 :3D8F35E54A3DD41286738C8C2A9823BB
SHA1 :D8FE5C317D695733EC312C432CC39E861E46BF4B
SHA256:124E8F7CA958FD8CB2A3BAF91681513F93F73D9CFA4EFEA6F4A1F165D8CBC8D9
释放文件
通过分析,发现此样本运行后,将从文件资源段中提取载荷数据,并将载荷数据拆分成多个文件,释放至%APPDATA%\Crash目录中。
进一步分析,发现释放的文件均携带了数字签名,根据数字签名名称可确定与此次攻击活动相关的样本为libcurl.dll和qr.dll样本。
创建计划任务
通过分析,发现此样本将通过Windows Task Scheduler COM接口创建计划任务,计划任务将在用户登录时触发:
● MicrosoftEdgeUpdate_QR:C:\Windows\System32\rundll32.exe "C:\Users\admin\AppData\Roaming\Crash\qr.dll",StartQR
● MicrosoftEdgeUpdate_TenioDL:C:\Users\admin\AppData\Roaming\Crash\Crash.exe
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
某远oa-xrdController.do后台-文件复制漏洞
漏洞复现
1.查看补丁
存在漏洞的Controller为xrdController首先看看补丁与漏洞代码有何不同 重点关注 checkIsSign 方法中的 fileName 参数 在有漏洞的版本之中直接通过接收 http的参数来拼接路径 (所以这个时候我们通过传入 ../../ 就能达到目录穿越的效果) 然而在补丁之中则是通过
2.漏洞分析
由下述代码可以得知 http 需要接受 两个参数 一个是 summaryId 另外一个参数则是 attList ( attList fildData[0] 则是我们需要传入的 fileid , fildData[1]则是我们传入的 filename 通过 $ 符号分割)
接着我们来看一下 创建文件夹 与 创建文件的 两个方法 createDir 与 decrypt 可以看到都是很耿直的方法没有经过任何过滤。
getFile 传入的就是fileid
所以这个时候理论上我们只需要再上传一个文件拿到fileid即可 这里我们采用 fileUpload.do 的 processUpload 方法上传 回包记录 fileid
3.构造POC
这个时候就可以开始构造最终POC 这里是有一点小鸡肋的 我们得知道 web的绝对路径 才可以写入web目录
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
漏洞复现
1.查看补丁
存在漏洞的Controller为xrdController首先看看补丁与漏洞代码有何不同 重点关注 checkIsSign 方法中的 fileName 参数 在有漏洞的版本之中直接通过接收 http的参数来拼接路径 (所以这个时候我们通过传入 ../../ 就能达到目录穿越的效果) 然而在补丁之中则是通过
fileName = (new File(Strings.getCanonicalPath(fileName))).getName(); 来获取 fileName 从而限制传参达到过滤的效果
2.漏洞分析
由下述代码可以得知 http 需要接受 两个参数 一个是 summaryId 另外一个参数则是 attList ( attList fildData[0] 则是我们需要传入的 fileid , fildData[1]则是我们传入的 filename 通过 $ 符号分割)
接着我们来看一下 创建文件夹 与 创建文件的 两个方法 createDir 与 decrypt 可以看到都是很耿直的方法没有经过任何过滤。
getFile 传入的就是fileid
/seeyon/xrdController.do?method=checkIsSign&summaryId=123&attList={fildData[0]}${fildData[1]}所以这个时候理论上我们只需要再上传一个文件拿到fileid即可 这里我们采用 fileUpload.do 的 processUpload 方法上传 回包记录 fileid
3.构造POC
这个时候就可以开始构造最终POC 这里是有一点小鸡肋的 我们得知道 web的绝对路径 才可以写入web目录
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
现代C2框架中Beacon级联机制深度解析:TCP与SMB协议下的树状代理网络构建
基础概念
1.1 级联协议
当然并非所有的通信协议协议都能承当级联网络的基底,在现代C2框架中常常将TCP、SMB作为Windows内网域中的级联协议。
TCP Beacon之所以成为通用选择,不仅因为其全双工特性,更在于它的协议无状态性为封装提供了最大自由度,充当着不同协议的通用胶合层,适用在不同的操作系统。具体体现为当父Beacon作为gateway,将Team Server的HTTP/DNS流量转换为内部私有协议,再通过TCP socket连接透传给子Beacon。除此之外,在AD域中也存在TCP+SMB的组合形成级联。
SMB Beacon(命名管道)的价值在于利用Windows域的信任基础设施,与TCP一样,SMB也可以充当着不同协议的通用胶合层,但它更多的是用在Windows上。在AD环境中,SMB流量比异常的TCP端口连接更"正常"——文件共享、组策略更新、认证票据交换都依赖445端口。更关键的是,SMB级联支持无端口监听:子Beacon通过连接父Beacon暴露的命名管道实现反向级联,这在主机层不留TCP监听端口,规避了端口扫描的风险。
由上面的两条规则很容易就构造出一个级联网络拓扑图出来。注意:在实际的C2服务器编写中,监听器(listener)才是与各个gateway保持着物理连接的角色,为了描述方便我下图中的拓扑结构忽略了监听器。
从图片中可以找到以下路径
1. 路径1:server<->getway1<->pivot1<->pivot4
2. 路径2:server<->getway1<->pivot2
3. 路径3:server<->getway2<->pivot3
4. 路径4:server<->getway3
其中路径1是非常典型的三级网络,路径3是典型的二级网络,下文将围绕这两条路径编写代码和运行过程的分析,不过在进行代码编写之前,有必要说几个定义:
(一)Gateway (网关节点):与 Teamserver 建立直连连接的 Agent,作为整个代理树的根锚点,所有来自子树的流量必须经过Gateway上报。
(二)Pivot (跳板节点):通过父节点间接注册到 Server 的 Agent,处于代理链中间层或末端
(三)寻路算法(路由算法):基于源路由 思想的逐跳封装,即从目标节点从下往上寻找父亲节点,直到寻找到Gateway节点
(四)连接上游(Upstream):维护与父节点的唯一连接(很好的体现了规则1),作为控制通道和数据出口,主要负责接收来自上游的数据、识别指令以及下行转发
(五)管理下游 (Children):维护到多个子节点的连接池(体现了规则2),实现代理链的纵向扩展,主要负责 上行封装 以及 本地自治
(六)级联网络(多级代理):一种基于树形拓扑构建的分层代理架构,通过严格遵循"单父多子"的约束规则,将原本直接暴露的C2通信链路重构为逐跳封装的代理链。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
基础概念
1.1 级联协议
当然并非所有的通信协议协议都能承当级联网络的基底,在现代C2框架中常常将TCP、SMB作为Windows内网域中的级联协议。
TCP Beacon之所以成为通用选择,不仅因为其全双工特性,更在于它的协议无状态性为封装提供了最大自由度,充当着不同协议的通用胶合层,适用在不同的操作系统。具体体现为当父Beacon作为gateway,将Team Server的HTTP/DNS流量转换为内部私有协议,再通过TCP socket连接透传给子Beacon。除此之外,在AD域中也存在TCP+SMB的组合形成级联。
SMB Beacon(命名管道)的价值在于利用Windows域的信任基础设施,与TCP一样,SMB也可以充当着不同协议的通用胶合层,但它更多的是用在Windows上。在AD环境中,SMB流量比异常的TCP端口连接更"正常"——文件共享、组策略更新、认证票据交换都依赖445端口。更关键的是,SMB级联支持无端口监听:子Beacon通过连接父Beacon暴露的命名管道实现反向级联,这在主机层不留TCP监听端口,规避了端口扫描的风险。
由上面的两条规则很容易就构造出一个级联网络拓扑图出来。注意:在实际的C2服务器编写中,监听器(listener)才是与各个gateway保持着物理连接的角色,为了描述方便我下图中的拓扑结构忽略了监听器。
从图片中可以找到以下路径
1. 路径1:server<->getway1<->pivot1<->pivot4
2. 路径2:server<->getway1<->pivot2
3. 路径3:server<->getway2<->pivot3
4. 路径4:server<->getway3
其中路径1是非常典型的三级网络,路径3是典型的二级网络,下文将围绕这两条路径编写代码和运行过程的分析,不过在进行代码编写之前,有必要说几个定义:
(一)Gateway (网关节点):与 Teamserver 建立直连连接的 Agent,作为整个代理树的根锚点,所有来自子树的流量必须经过Gateway上报。
(二)Pivot (跳板节点):通过父节点间接注册到 Server 的 Agent,处于代理链中间层或末端
(三)寻路算法(路由算法):基于源路由 思想的逐跳封装,即从目标节点从下往上寻找父亲节点,直到寻找到Gateway节点
(四)连接上游(Upstream):维护与父节点的唯一连接(很好的体现了规则1),作为控制通道和数据出口,主要负责接收来自上游的数据、识别指令以及下行转发
(五)管理下游 (Children):维护到多个子节点的连接池(体现了规则2),实现代理链的纵向扩展,主要负责 上行封装 以及 本地自治
(六)级联网络(多级代理):一种基于树形拓扑构建的分层代理架构,通过严格遵循"单父多子"的约束规则,将原本直接暴露的C2通信链路重构为逐跳封装的代理链。
beacon> help connect
Use: connect [target]
connect [target] [port]
Connect to a TCP Beacon and re-establish control of it. All requests for
connected Beacon will go through this Beacon.
Use 'unlink' to disconnect from a TCP Beacon.
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke