跳转到帖子
  • 游客您好,欢迎来到黑客世界论坛!您可以在这里进行注册。

    赤队小组-代号1949(原CHT攻防小组)在这个瞬息万变的网络时代,我们保持初心,创造最好的社区来共同交流网络技术。您可以在论坛获取黑客攻防技巧与知识,您也可以加入我们的Telegram交流群 共同实时探讨交流。论坛禁止各种广告,请注册用户查看我们的使用与隐私策略,谢谢您的配合。小组成员可以获取论坛隐藏内容!

    TheHackerWorld官方

Java利用技巧——通过反射修改属性


cnhackteam7

推荐的帖子

0x00 前言

在上篇文章《Zimbra漏洞调试环境搭建》 提到了通过反射枚举JspServletWrapper实例的实现,本文将要以此为例,详细介绍实现的思路和细节,便于以此类推,实现其他功能。

0x01 简介

本文将要介绍以下内容:

反射中的常用操作

获得类的所有字段

获得类的所有方法

调用类的方法

枚举JspServletWrapper实例的实现细节

0x02 反射中的常用操作

1.获得类的所有字段

getField():

能够获取本类以及父类中的公众的字段

getDeclaredField():

能够获取本类中的所有字段

这里以津布拉环境为例,给出示例代码

(1)获取request对象的所有字段

%@个页面导入='java.lang.reflect.Field' %

%

Field[] fields=request.getClass().getDeclaredFields();

for(int I=0;我字段。长度;i ) {

out.println(fields[i].getName()'

');

}

%

(2)获取request对象的父类的所有字段

%@个页面导入='java.lang.reflect.Field' %

%

Field[] fields=request.getClass().getSuperclass().getDeclaredFields();

for(int I=0;我字段。长度;i ) {

out.println(fields[i].getName()'

');

}

%

2.获得类的所有方法

getMethods():

能够获取本类以及父类或者父接口中的公共方法(公共修饰符修饰的)

getDeclaredMethods():

能够获取本类中的所有方法,包括私人的、受保护的、默认以及公众的的方法

这里以津布拉环境为例,给出示例代码

(1)获取request对象的所有方法

%@个页面导入='java.lang.reflect.Field '%

%@个页面导入='java.lang.reflect.Method '%

%

方法[]方法=请求。getclass().getDeclaredMethods();

对于(方法方法:方法){

out.print(method.getName()'

');

}

%

(2)获取request对象的父类的所有方法

%@个页面导入='java.lang.reflect.Field '%

%@个页面导入='java.lang.reflect.Method '%

%

方法[]方法=请求。getclass().getSuperclass().getDeclaredMethods();

对于(方法方法:方法){

out.print(method.getName()'

');

}

%

3.调用类的指定方法

这里以津布拉环境为例,给出示例代码

搭建好津布拉漏洞调试环境后,定位请求对象的getHeader(字符串名称)方法,代码细节如下:

公共字符串getHeader(字符串名称){

org。月食。码头。http。元数据。请求元数据=这个._元数据;

返回元数据==null?null : metadata.getFields().获取(名称);

}

对照代码细节,参数类型为线

调用请求对象的getHeader(字符串名称)方法,参数为'用户代理,实现代码如下:

%@个页面导入='java.lang.reflect.Field '%

%@个页面导入='java.lang.reflect.Method '%

%

方法m1=request.getClass().getDeclaredMethod('getHeader ',字符串。类);

out.println(m1.invoke(请求,'用户代理'));

%

0x03 枚举JspServletWrapper实例的实现细节

1.下断点

选择文件servlet-api-3.1.jar,依次选中javax。http-http servlet。类,在合适的位置下断点,当运行到断点时,可以查看请求对象的完整结构,如下图

2-1.png

查看请求对象的结构,我们最终定位到了JspServletWrapper实例的位置,直观的映射为:请求-_范围-_ servlet-RCT XT-JSP

接下来,我们需要按照这个映射,通过多次反射最终获得JspServletWrapper实例

(1)读取request对象的所有字段

%@个页面导入='java.lang.reflect.Field' %

%

Field[] fields=request.getClass().getDeclaredFields();

for(int I=0;我字段。长度;i ) {

out.println(fields[i].getName()'

');

}

%

在回显的结果中能够找到_范围

(2)从request对象获得_scope实例并再次枚举字段

%@个页面导入='java.lang.reflect.Field' %

%

字段f=request.getClass().getDeclaredField(' _ scope ');

f。设置可访问性(true);

Object obj1=f.get(请求);

Field[] fields=obj1.getClass().getDeclaredFields();

for(int I=0;我字段。长度;i ) {

out.println(fields[i].getName()'

');

}

%

在回显的结果中能够找到_servlet

(3)获得_servlet实例并再次枚举字段

%@个页面导入='java.lang.reflect.Field' %

%

字段f=request.getClass().getDeclaredField(' _ scope ');

f。设置可访问性(true);

Object obj1=f.get(请求);

f=obj1.getClass().getDeclaredField(' _ servlet ');

f。设置可访问性(true);

object obj 2=f . get(obj 1);

Field[] fields=obj2.getClass().getDeclaredFields();

for(int I=0;我字段。长度;i ) {

out.println(fields[i].getName()'

');

}

%

回显的结果为:serialVersionUID

这里没有rctxt字段

尝试寻找原因:开启调试器,定位至关键位置,如下图

2-2.png

从图中可以看到,_servlet的类为JettyJspServlet

JettyJspServlet继承自JspServlet,成员变量只有serialVersionUID,这与我们通过访问jsp页面得到的结果一致

查看JspServlet的相关实现代码,如下图

2-3.png

从图中可以看到,rctxt为JspServlet的成员变量,属性为私人的,所以子类JettyJspServlet无法继承成员变量rctxt

这里我们可以直接选取_servlet实例的父类进行枚举字段

(4)选取_servlet实例的父类进行枚举字段

%@个页面导入='java.lang.reflect.Field' %

%

字段f=request.getClass().getDeclaredField(' _ scope ');

f。设置可访问性(true);

Object obj1=f.get(请求);

f=obj1.getClass().getDeclaredField(' _ servlet ');

f。设置可访问性(true);

object obj 2=f . get(obj 1);

f=obj2.getClass().getSuperclass().getDeclaredField(' rctxt ');

f。设置可访问性(true);

object obj 3=f . get(obj 2);

Field[] fields=obj3.getClass().getDeclaredFields();

for(int I=0;我字段。长度;i ) {

out.println(fields[i].getName()'

');

}

%

在回显的结果中能够找到JSP

(5)获得jsps实例并枚举字段

开启调试器,查看JSP的类型,如下图

2-4.png

从图中可以看到,JSP的类为并发哈希表,这里只需要枚举出所有钥匙即可

添加需要导入的包后,得出最终实现代码:

%@个页面导入='java.lang.reflect.Field' %

%@个页面导入=' Java。util。并发。并发哈希表' %

%@个页面导入=' Java . util . * ' ' %

%

字段f=request.getClass().getDeclaredField(' _ scope ');

f。设置可访问性(true);

Object obj1=f.get(请求);

f=obj1.getClass().getDeclaredField(' _ servlet ');

f。设置可访问性(true);

object obj 2=f . get(obj 1);

f=obj2.getClass().getSuperclass().getDeclaredField(' rctxt ');

f。设置可访问性(true);

object obj 3=f . get(obj 2);

f=obj3.getClass().getDeclaredField(' JSP ');

f。设置可访问性(true);

并发hashmap obj 4=(并发hashmap)f . get(obj 3);

枚举enu=obj 4。keys();

while (enu.hasMoreElements()) {

out.println(enu.nextElement()'

');

}

%

补充:删除指定JspServletWrapper的实例

只需要调用并发哈希表的去除方法即可

示例代码:

%@个页面导入='java.lang.reflect.Field' %

%@个页面导入=' Java。util。并发。并发哈希表' %

%@个页面导入=' Java . util . * ' ' %

%

字段f=request.getClass().getDeclaredField(' _ scope ');

f。设置可访问性(true);

Object obj1=f.get(请求);

f=obj1.getClass().getDeclaredField(' _ servlet ');

f。设置可访问性(true);

object obj 2=f . get(obj 1);

f=obj2.getClass().getSuperclass().getDeclaredField(' rctxt ');

f。设置可访问性(true);

object obj 3=f . get(obj 2);

f=obj3.getClass().getDeclaredField(' JSP ');

f。设置可访问性(true);

并发hashmap obj 4=(并发hashmap)f . get(obj 3);

obj 4。移除('/test。JSP’);

%

0x04 小结

本文介绍了通过反射枚举JspServletWrapper实例的具体实现,记录思路和细节,便于以此类推,修改其他内容。

留下回复

链接帖子
意见的链接
分享到其他网站

黑客攻防讨论组

黑客攻防讨论组

    You don't have permission to chat.
    • 最近浏览   0位会员

      • 没有会员查看此页面。
    ×
    ×
    • 创建新的...