添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

相关资料:

https://github.com/Zimbra-Community/zimbra-tools/blob/master/java-debug-zimbra-intellij-ide.md

详细步骤如下:

1.停止Zimbra服务

su zimbra
zmcontrol stop

2.开启调试模式

cp /opt/zimbra/libexec/zmmailboxdmgr /opt/zimbra/libexec/zmmailboxdmgr.old cp /opt/zimbra/libexec/zmmailboxdmgr.unrestricted /opt/zimbra/libexec/zmmailboxdmgr

此处先备份zmmailboxdmgr,再使用zmmailboxdmgr.unrestricted替换zmmailboxdmgr

3.添加调试信息

su zimbra
zmlocalconfig -e mailboxd_java_options="`zmlocalconfig -m nokey mailboxd_java_options` -Xdebug -Xnoagent -Djava.compiler=NONE -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000"

也可以直接修改/opt/zimbra/conf/localconfig.xml中的mailboxd_java_options属性值

4.关闭防火墙

sudo ufw disable

5.重启服务

zmcontrol start

0x03 本地使用IDEA进行远程调试

1.下载jar文件

本地使用IDEA进行远程调试时,本地和远程的代码需要保持一致,也就是说,我们需要拿到zimbra相关的jar文件

zimbra文件位置:

  • /opt/zimbra/common/jetty_home/lib/
  • /opt/zimbra/common/jetty_home/lib/apache-jsp/
  • 2.批量导入jar文件

    新建java工程,依次选择File->Project Structure...,在Libraries下选择New Project Library->Java,设置为c:\zimbrajar\

    3.添加断点

    External Libraries->zimbrajar下面打开.class文件,在合适的位置添加断点

    4.设置远程调试参数

    顶部菜单栏选择Add Configuration...,在弹出的页面中选择Remote JVM Debug,填入远程调试参数,参数示例:

    -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
    

    使用的JDK选择JDK 5-8

    5.开启Debug模式

    回到IDEA主页面,选择刚才的配置文件,点击Debug图标(快捷键Shift+F9)

    如果远程调试执行成功,断点图标会发生变化,增加一个对号

    此时,Console页面显示如下:

    Connected to the target VM, address: '<host>:<port>', transport: 'socket'
    

    0x04 常用知识

    Zimbra使用Jetty框架作为web容器

    用户在访问jsp文件时,服务器先将JVM不认识的JSP文件解析成java文件,保存路径为:/opt/zimbra/jetty_base/work/zimbra/jsp/org/apache/jsp/

    每个jsp文件被成功访问后,都会注册一个JspServletWrapper实例,我们可以通过调试器查看request变量获得所有已注册的JspServletWrapper实例,也可以通过反射的方式以jsp文件的形式进行枚举

    jsp文件代码示例:

    <%@ page import="java.lang.reflect.Field" %>
    <%@ page import="java.util.concurrent.ConcurrentHashMap" %>
    <%@ page import="java.util.*" %>
        Field f = request.getClass().getDeclaredField("_scope");
        f.setAccessible(true);  
        Object obj1 = f.get(request);
        f = obj1.getClass().getDeclaredField("_servlet");
        f.setAccessible(true);
        Object obj2 = f.get(obj1);
        f = obj2.getClass().getSuperclass().getDeclaredField("rctxt");
        f.setAccessible(true);
        Object obj3 = f.get(obj2);
        f = obj3.getClass().getDeclaredField("jsps");
        f.setAccessible(true);
        ConcurrentHashMap obj4 = (ConcurrentHashMap)f.get(obj3);  
        Enumeration enu = obj4.keys(); 
        while (enu.hasMoreElements()) { 
            out.println(enu.nextElement() + "<br>"); 
    

    整个反射的逻辑来自于跟踪调试的结果,实现逻辑不唯一,枚举JspServletWrapper实例用到了ConcurrentHashMap枚举

    0x05 小结

    在我们搭建好Zimbra漏洞调试环境后,接下来就可以着手对漏洞和Jetty框架进行研究学习。

    LEAVE A REPLY