跳转到帖子

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

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

TheHackerWorld官方

某安全数据交换系统的漏洞挖掘

精选回复

发布于

安全数据交换系统中的漏洞挖掘

2023年9月18日马云惹不起马云

本文写于2022 年,分享发现安全数据交换系统漏洞的过程。

我拿到的第一个系统是vmware虚拟机,系统中有Linux的基本信息:

后端管理界面用户名和密码:admin/nxg@LL99 操作系统:root/bo%Fn!71、uninxg/lx$zR9ce

配置网络

根据产品安装文档搭建好环境后,手动设置IP地址和DNS:

手动修改/etc/resolv.conf

名称服务器114.114.114.114

名称服务器8.8.8.8

修改/etc/NetworkManager/NetworkManager.conf 文件并将“dns=none”选项添加到主要部分:

[主要]

#plugins=ifcfg-rh

域名=无

网络IP地址配置文件位于/etc/sysconfig/network-scripts文件夹中:

fs01v0ysoex2862.png

我添加了两张网卡,其中一张用于本地访问:

1

/etc/sysconfig/network-scripts/ifcfg-eth1-1

HWADDR=00:0C:29:4B:16:B4

类型=以太网

PROXY_METHOD=无

BROWSER_ONLY=否

BOOTPROTO=无

IPADDR=192.168.117.100

网关=192.168.117.2

前缀=24

DNS1=114.114.114.114

DNS2=8.8.8.8

DEFROUTE=是

IPV4_FAILURE_FATAL=否

IPV4_DNS_PRIORITY=100

IPV6INIT=否

名称=eth1

UUID=8a47e710-cadd-49b5-b9b7-33a324c4ab66

设备=eth1

启动=否

观察启动命令行:

/home/leagsoft/SafeDataExchange/jdk/bin/java -Dnop -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Dlog4j2.formatMsgNoLookups=true -javaagent:/home/leagsoft/SafeDataExchange/Apache/lib/jdc.jar -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0022 -Dignore.endorsed.dirs=-classpath /home/leagsoft/SafeDataExchange/Apache/bin/bootstrap.jar:/home/leagsoft/SafeDataExchange/Apache/bin/tomcat-juli.jar -Dcatalina.base=/home/leagsoft/SafeDataExchange/Apache -Dcatalina.home=/home/leagsoft/SafeDataExchange/Apache -Djava.io.tmpdir=/home/leagsoft/SafeDataExchange/Apache/temp org.apache.catalina.startup.Bootstrap 启动

/home/leagsoft/SafeDataExchange/Apache 是Tomcat 的安装目录,webapps 目录是部署的应用程序源代码:

2

通过ssh将war包复制到本地电脑,就可以看到整个项目的源码了。

3

源码解密

将war包复制到本地,通过idea打开。发现关键代码的实现是空的,连spring控制器都是空的。初步怀疑是加密的,那么它是如何加密的呢?

4

既然网站能够正常运行,那么在运行时就应该通过一些技术手段来实现。观察启动命令行:

/home/leagsoft/SafeDataExchange/jdk/bin/java

-Dnop -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager

-Dlog4j2.formatMsgNoLookups=true

**-javaagent:/home/leagsoft/SafeDataExchange/Apache/lib/jdc.jar**

-Djdk.tls.ephemeralDHKeySize=2048

-Djava.protocol.handler.pkgs=org.apache.catalina.webresources

-Dorg.apache.catalina.security.SecurityListener.UMASK=0022

-Dignore.endorsed.dirs=

-classpath /home/leagsoft/SafeDataExchange/Apache/bin/bootstrap.jar:/home/leagsoft/SafeDataExchange/Apache/bin/tomcat-juli.jar

-Dcatalina.base=/home/leagsoft/SafeDataExchange/Apache -Dcatalina.home=/home/leagsoft/SafeDataExchange/Apache

-Djava.io.tmpdir=/home/leagsoft/SafeDataExchange/Apache/temp org.apache.catalina.startup.Bootstrap 启动

命令行中有一个javaagent引起了我的注意:

-javaagent:/home/leagsoft/SafeDataExchange/Apache/lib/jdc.jar

将lib文件夹复制到项目中,观察jar包的结构:

5

看来是调用javassist来实现内存修补技术的。找到Agent的入口方法,看看它做了什么:

//

//IntelliJ IDEA 从.class 文件重新创建的源代码

//(由Fernflower 反编译器提供支持)

//

com.leagsoft.declass 包;

导入java.lang.instrument.Instrumentation;

公共类代理{

公共代理() {

}

公共静态无效premain(String args, Instrumentation inst) 抛出异常{

CoreAgent.premain(args, inst);

}

}

跟进CoreAgent.premain:

公共类CoreAgent {

公共CoreAgent() {

}

公共静态无效premain(String args, Instrumentation inst) {

if (inst !=null) {

文件file=new File('././Ini/ec.file');

MapString, String configMap=ECFileConfig.getConfig();

byte[] 字节=IoUtils.readFileToByte(file);

byte[] by=EncryptUtils.de(bytes, ((String)configMap.get('pf')).toCharArray(), 1);

AgentTransformer tran=new AgentTransformer(EncryptUtils.rsk(new String(by)).toCharArray());

inst.addTransformer(tran);

}

}

}

这里可以看到,首先是通过ECFileConfig进行初始化,然后解密读取Ini/ec.file

跟进ECFileConfig.getConfig():

公共类ECFileConfig {

私有静态MapString,字符串configMap=null;

公共ECFileConfig() {

}

私有静态无效iniConfig() {

if (configMap==null) {

INIImpl ini=ECFileIni.getIni();

configMap=ini.getProperties('ECFile');

}

}

公共静态MapString,字符串getConfig(){

iniConfig();

返回配置映射;

}

}

////ECFileIni.getIni();

公共类ECFileIni {

私有静态字符串文件='././Ini/ECFile.ini';

私有静态INIImpl self=null;

静态{

自我=初始化();

}

公共ECFileIni() {

}

私有静态INIImpl init() {

字符串代码=FileEncode.getFileEncode(file);

INIImpl iniFile='asci'.equals(code) ? INIUtil.getInstance(文件) : INIUtil.getInstance(文件,代码);

返回ini 文件;

}

公共静态String getStringProperty(字符串部分,字符串属性){

String rs=self.getStringProperty(节, 属性);

返回'null'.equals(rs) ?空: 卢比;

}

公共静态INIImpl getIni() {

返回自我;

}

}

恰巧我在服务器上发现了这个文件ECFile.ini:

6

我们看一下AgentTransformer的实现:

公共类AgentTransformer 实现ClassFileTransformer {

私有char[] pwd;

公共AgentTransformer(char[] pwd) {

this.pwd=密码;

}

公共byte[] 转换(ClassLoader 加载器,String className,Class?classBeingRedefine,ProtectionDomain 域,byte[] classBuffer){

if (className !=null 域!=null loader !=null) {

String projectPath=domain.getCodeSource().getLocation().getPath();

项目路径=JarUtils.getRootPath(projectPath);

if (StrUtils.isEmpty(projectPath)) {

返回类缓冲区;

} 否则{

className=className.replace('/', '.').replace('\\', '.');

byte[] bytes=JarDecryptor.getInstance().doDecrypt(projectPath, className, this.pwd);

返回字节!=null 字节[0]==-54 字节[1]==-2 字节[2]==-70 字节[3]==-66 ?字节: 类缓冲区;

}

} 否则{

返回类缓冲区;

}

}

AgentTransformer重写了ClassFileTransformer的transform方法,将每个类和密码放入JarDecryptor.doDecrypt中进行解密,最后返回字节码。

我们看一下JarDecryptor.doDecrypt的实现:

7

通过readEncryptedFile方法读取**META-INF/.classes/**下的class文件进行解密。

回到文件目录,在META-INF下发现了很多加密的类字节码文件:

8

这里我写了一个类,并调用JarDecryptor.doDecrypt 来解密所有类:

导入com.leagsoft.declass.util.ECFileConfig;

导入com.leagsoft.declass.util.EncryptUtils;

导入com.leagsoft.declass.util.IoUtils;

导入com.leagsoft.declass.util.StrUtils;

导入java.io.File;

导入java.io.FileOutputStream;

导入java.util.Map;

公共类主要{

私有静态最终字符串ENCRYPT_PATH='UniEx/META-INF/.classes/';

private static Final String DECRYPT_PATH='UniEx-decode/UniExdecrypt/';

私有静态char[] getPassword(){

尝试{

文件file=new File('UniEx/ec.file');

MapString, String configMap=ECFileConfig.getConfig();

byte[] 字节=IoUtils.readFileToByte(file);

字符串pf='UniNXG-KUv1N5FQr9NtPWnK5UpJ8nnM3blCH9jYtGoXeo0bsXowOffDnW2o0DaVo41ZblSF0tNow5dPxVn8odAS9l4QxCiSvGTXhbliZF9W';

byte[] by=EncryptUtils.de(bytes, pf.toCharArray(), 1);

char 密码[]=EncryptUtils.rsk(new String(by)).toCharArray();

System.out.println(密码);

返回密码;

} catch (异常e) {

System.out.println(e);

}

返回空值;

}

公共静态无效主(字符串[] args)抛出异常{

字符密码[]=getPassword();

文件类文件=新文件(ENCRYPT_PATH);

File[] fs=classFiles.listFiles();

for (文件类文件: fs){

System.out.println(classFile.getAbsolutePath());

文件file=new File(ENCRYPT_PATH, classFile.getName());

byte[] 字节=IoUtils.readFileToByte(file);

如果(字节==空){

返回;

} 否则{

char[] pass=StrUtils.merger(new char[][]{password, classFile.getName().toCharArray()});

bytes=EncryptUtils.de(bytes, pass, 1);

System.out.println('正在解密.' + classFile.getName());

尝试{

File outFile=new File(DECRYPT_PATH+ classFile.getName()+'.class');

if (!outFile.exists()){

outFile.createNewFile();

}

FileOutputStream 输出流=new FileOutputStream(outFile);

输出流.write(字节);

}catch(异常e){

}

}

}

}

}

9

运行Main 方法来恢复所有加密的类字节码文件,就完成了。

远程调试Tomcat

修改汤姆

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。