Java代码安全01--调试与反调试

一、Java调试

1.1、概念

在软件开发的过程中,可以说调试是一项基本技能。

在安全领域,例如代码审计或者编写利用工具的过程中,合理地使用调试器可以解决很多棘手的问题。

尤其是在代码审计中,静态分析代码难度高,如果利用调试器做到动态调试去审计,则会大大降低难度。

在编写某些漏洞的 EXP 以及武器化利用工具时,则要反复验证回显是否有效,寻找回显利用代码等。

因此合理地利用调试功能将会极大地提高我们的工作效率。 

1.2、调试方式

~以调试模型启动Java进程
	
	需要配置一些设置,但是可以通过debug修改任意变量值

~对于一些已经在运行的线上Java进程,无法使用上边的方式可以使用附加的方式。
	
	但是这种方式存在一个缺点,debug无法修改任意变量值

1.3、调试工具

~JDB
	
	JDB用法是一个Java自带的调试器,使用不如idea方便,但是在一些特定的环境下,
	
	IDEA是无法调试的,仅仅可以通过JDB调试。实际的操作过程之中,很少有人用JDB进行调试

~IDEA
	
	IDEA相对于JDB,使用简单,不需要记一些命令。虽然一些特殊场景无法调试,
	
	但是足以应对工作之中95%以上的场景,推荐使用。

二、IDEA具体的调试方法

2.1、存在源代码的情况下


使用IDEA加载源代码,然后直接在源代码右键,选择debug即可。

在这里插入图片描述

这里说一下,假设没有源代码的怎么办?
	
直接反编译(IDEA自带反编译的功能),简单易上手。

2.2、不存在源码,但是有jar包

直接将jar包拖进IDEA之中(会自动反编译),

或者直接将整个文件夹加载到IDEA之中,这个文件夹可以不是标准的Java项目

在这里插入图片描述


我们创建一个 IDEA 的启动参数,在菜单栏中 Run-Edit Configurations,

进入对话框,点击对话框左上角的 + 号,选择 Remote JVM Debug,如图 

在这里插入图片描述

在弹出的对话框中,填写远程被调试的 JVM 的 IP 地址和端口号即可。

远程 JVM 的 启动调试参数也可以从对话框中复制。

在这里插入图片描述

添加完成后点击保存即可。点击菜单栏-Debug 你刚才保存的配置名称,

IDEA 就会自动连接到目标 JVM 中。 

在这里插入图片描述

成功链接,

在这里插入图片描述

直接点击这个箭头指向的 “ 红色按钮 ” 停止调试,

在这里插入图片描述

对于一个jar包,比如这个lib文件夹下的,直接右击选择箭头指向的,

即可自动反编译,

在这里插入图片描述

在之后,这个ons.jar就可以直接打开了,反编译的代码一般没什么问题

在这里插入图片描述

假设存在我们存在这个jar包的源代码,也可以直接选择箭头指向,进行加载。

2.3、单个class文件

我们知道jar包就是一堆class文件,按照一定目录结构的一个zip包,

IDEA 支持对于 Jar 包可以自动反编译并添加断点,

但是对于单个 Class 文件,却只会自动反编译,并不允许我们调 试添加断点。 

	~首先反编译 Class 文件,找到 Class 文件的全限定名,例如 com.unicodesec.MyClass。 
	
	~根据全限定名,创建目录,例如创建 com 目录,在 com 目录中创建 unicodesec 目录,
	
		在 unicodesec 目录中放入我们的 Class 文件。 
		
	~回到 com 目录中,对 com 目录进行 zip 压缩,并将压缩包的后缀名改成 jar。
		
		随后只需要将 jar 包添加到 IDEA 中,按照上面的 Jar 包调试即可。 

三、反调试

3.1、场景

	
	上面着重讲了 IDEA 的调试技巧。对于某些恶意样本而言,

	我们无法调试。又或者说, 我们自己写的 Java 恶意样本,

	如何不被安全研究人员很轻松的反编译并分析其中的逻辑。 
	

3.2、IDEA调试的原理

先讲一下 IDEA 是怎么通过协议向被调试的 Java 进程下断点的。

IDEA 等 IDE 对于 Java 的调试,主要是通过行号作为下断点的条件。

如果去掉 Class 文件行号这一属性,则 无法使用 IDE 调试。只能通过 Jdb 并通过方法断点来调试。 
IDEA 通过 LineNumberTable 属性,向被调试的 Java 进程发送断点指令。

那么我们只需要去掉 Class 文件的 LineNumberTable 属性,

就可以防止该 Class 文件 被调试。像这类辅助调试的信息,被称为 debug symbol。 
我们在编译 java 代码的时候,

也可以指定编译器参数 -g 以去掉 class 的 debug symbol。 

这样编译后的 Java Class 就无法下断点,自然就无法调试了。即使下了方法断点,

也因为没有机器码与源码行号的对应关系,也无法使用单步调试。 

3.3、如何解决


新建一个 java 文件,将代码抠出来,粘贴到新建的 java 文件中。

根据反编译引擎的不同,代码可能也无法使用,需要做修改。 

  当然,也发现一款工具可以实现恢复行号表的功能。官方介绍如下:
  
		http://dirty-joe.com/ 
	
  虽然工具比较老,但是只要能达到功能就好。直接下载并恢复行号表。 


如果是 Jar 包中的 class 被去掉符号信息而无法调试,

可以先使用 Zip 工具解压 Jar,再调用上述工具从命令行批量转换。

转换后的 class 文件再通过 7zip 工具打包成 zip,并改后缀为 jar 即可。 

おすすめ

転載: blog.csdn.net/weixin_43970718/article/details/120730178