HacKerQWQ的博客空间

javaweb代码审计(整数溢出,硬编码密码,不安全的随机数生成器)

Word count: 1kReading time: 4 min
2021/12/17 Share

整数溢出漏洞

整数知识

在计算机系统中,整型的位数跟计算机系统的位数有关。使用最高位表示符号,1表示负数,0表示正数

在32位系统中,整型范围为-21474836472147483647,及`-2**31-12**31-1`

十进制 二进制
上界 2147483647 01111111 11111111 11111111 11111111
下界 -2147483648 10000000 00000000 00000000 00000000

在64为系统中,整型范围为-1844674407370955161718446744073709551615,即`-2**64-12**64-1`

十进制 二进制
上界 18446744073709551615
下界 -18446744073709551617

整形溢出

以32位系统为例,当整型的最大值2**31-1再加1时,变为10000000 00000000 00000000 00000000,即-2147483648,这种称为上界溢出

相反当最小值-2**31-1再减1时,变为10000000 00000000 00000000 00000000,即2147483647,称为下界溢出

image-20211218151926274

整型溢出漏洞修复

主要使用以下两个函数判断是否存在整型溢出,作用是判断传入两个参数相加后是否造成溢出

  • Math.addExact(left,right)
  • Math.subtractExact(left,right)

在flow.java定义willAdditionOverflowwillSubtractionOverflow

image-20211218152136696

在test.java中调用

image-20211218152308626

可以看到上界溢出和下界溢出的情况都能判断出来

硬编码密码漏洞

漏洞简介

硬编码漏洞指的是在系统中采用明文的形式存储密码,容易造成身份验证失效、密码泄露等,大大降低了系统的安全性,CSDN的密码泄露时间就是因为硬编码漏洞

image-20211218152709591

  • 漏洞点主要在数据库连接的文件中,文件名如jdbc.propertiesdb.properties

修复方法

将加密的信息放在db.properties中,通过输入流加载属性列表

db.properties

1
2
3
DB_USER=root
DB_PASSWORD=e10adc3949ba59abbe56e057f20f883e
DB_DBS=test

test_dbs.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import jdk.internal.util.xml.impl.Input;

import java.io.InputStream;
import java.util.Properties;

public class test_dbs {
public static void main(String[] args) {
try{
Properties properties = new Properties();
InputStream is = test_dbs.class.getResourceAsStream("/db.properties");
properties.load(is);
String DB_USER = properties.getProperty("DB_USER");
String DB_PASSWORD = properties.getProperty("DB_PASSWORD");
String DB_DBS = properties.getProperty("DB_DBS");
System.out.println("数据库连接信息");
System.out.println("用户名"+DB_USER);
System.out.println("密码:"+DB_PASSWORD);
System.out.println("数据库:"+DB_DBS);
}catch (Exception e){
e.printStackTrace();
}
}
}

运行结果

image-20211218154350892

不安全的随机数生成器漏洞

随机数生成器简介

随机数生成器根据密码学定义分为三种

  1. 统计学伪随机数生成器(PRNG),从一个初始化的种子生成随机数序列
  2. 密码学安全随机数生成器(CSPRNG),给定一部分样本和随机算法,不能计算出随机样本的剩余部分
  3. 真随机数生成器,给定十分复杂或难以捕获的边界条件(如CPU温度,声卡底噪等),来生成随机数

随机数生成器漏洞

问题出现在第一种,即统计学伪随机生成器,由于给定种子,生成序列固定,因此容易被攻击者猜测到接下来的序列是什么而产生安全问题。

主要使用java.util.Random作为生成器,需要注意的是当Random没有给定参数的时候默认使用系统时间的时间戳来作为种子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.Random;

public class testRandom {
public static void main(String[] args) {
System.out.println(System.nanoTime());
System.out.println("**************************");
Random random = new Random(1);
System.out.println(random.nextInt());
System.out.println(random.nextInt());
System.out.println(random.nextInt());
System.out.println("**************************");
Random random1 = new Random(1);
System.out.println(random1.nextInt());
System.out.println(random1.nextInt());
System.out.println(random1.nextInt());
}
}

运行结果

image-20211218155254919

修复方法

使用java.util.SecureRandom来获取密码安全的随机数生成器,SecureRandom收集了随机事件(如,鼠标点击、键盘点击等等)来作为种子,因此安全性要高很多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class testSecureRandom {

public static void main(String[] args) {
try{
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
for (int i=0;i<5;i++){
System.out.println(secureRandom.nextInt());
}
System.out.println("*************************");
SecureRandom secureRandom1 = SecureRandom.getInstance("SHA1PRNG");
for (int i=0;i<5;i++){
System.out.println(secureRandom1.nextInt());
}
}catch (Exception e){
e.printStackTrace();
}

}

}

运行结果

image-20211218155733799

可以看到两次生成随机数列结果不同

CATALOG
  1. 1. 整数溢出漏洞
    1. 1.1. 整数知识
    2. 1.2. 整形溢出
  2. 2. 整型溢出漏洞修复
  3. 3. 硬编码密码漏洞
    1. 3.1. 漏洞简介
    2. 3.2. 修复方法
  4. 4. 不安全的随机数生成器漏洞
    1. 4.1. 随机数生成器简介
    2. 4.2. 随机数生成器漏洞
    3. 4.3. 修复方法