目录
前言:
(一)整数溢出漏洞
0x01 整数溢出漏洞介绍
1.1 上界溢出
1.2 下界溢出
0x02 整数溢出漏洞修复
(二)硬编码密码漏洞
修复案例:
(三)不安全的随机数生成器
前言:
本次总结的漏洞在实战情况下,可能只是一个环节,包括我们经常遇到的WAF绕过,技术偏逆向破解,但是在web渗透测试中有一定的利用价值。
(一)整数溢出漏洞
         计算机程序中的整数都是有范围的,不同的数据类型范围也不同,这是由编译器决定的,超过这个范围就有可能会出现整数溢出的情况。 
 
         比如说Java 的 
 int 
 是 
 32 
 位有符号整数类型,其最大值是 
 0x7fffffff 
 ,最小值是0x80000000,即 
 int 
 表示的数的范围是在-
 2147483648 
 ~
  2147483647 
 之间。当 
 int 
 类型的运算结果超出了这个范围时则发生了溢出,而且不会有任何异常抛出。整数溢出一般可以分为上界溢出和下界溢出两种。
 
 
0x01 整数溢出漏洞介绍
1.1 上界溢出
int 类型二进制存储的第一位为符号位,0 表示正数, 1 表示负数, 2147483647 这个数字的二进制表达为 01111111 11111111 11111111 11111111 ,加 1 以后的值为 1000000000000000 00000000 00000000 ,发生上界溢出,而 10000000 00000000 00000000 00000000 表示的是-2147483648 这个数字
1.2 下界溢出
int 类型二进制存储的第一位为符号位, 0 表示正数, 1 表示负数, -2147483648 这个数字的二进制表达为 10000000 00000000 00000000 00000000 ,减 1 以后的值为 0111111111111111 11111111 11111111 ,发生下界溢出,而 01111111 11111111 11111111 11111111 表示的是 2147483647 这个数字。 Java 程序溢出运行的案例如图 1-1 所示:1
  0x02 整数溢出漏洞修复
在 Java 8 版本中,可以使用新的“ Math#addExact() and Math#subtractExact()”方法,该方法将监测“ ArithmeticException ”溢出
public static boolean willAdditionOverflow(int left, int right) { 
     try { 
             Math.addExact(left, right); 
             return false; 
         } catch (ArithmeticException e) { 
         return true; 
         } 
    } 
public static boolean willSubtractionOverflow(int left, int right) { 
     try { 
             Math.subtractExact(left, right); 
             return false; 
         } catch (ArithmeticException e) { 
             return true; 
         } 
} 
(二)硬编码密码漏洞
硬编码密码是指在系统中采用明文的形式存储密码,通常会导致严重的身份验证失败,这对于系统管理员而言可能很难检测到,一旦检测到,也很难修复。硬编码密码会造成密码泄露,其主要出现在以下几个方面
- 开发人员的安全意识不强:将代码托管到 github 等互联网平台,可能会造成源代码泄露,任何有该代码权限的人都能读取此密码。
 - 程序员可以简单地将后端凭证硬编码到前端软件中:该程序的任何用户都可以提取密码。因为从二进制文件中提取密码非常简单,所以会对带有硬编码密码的客户端系统构成很大的威胁。
 
          以下代码是使用硬编码的密码连接到数据库的示例:
 
 
DriverManager.getConnection(url,"scott","tiger"); 
 
          攻击者可以通过 javap –c 
  命令来访问反汇编的代码,反汇编的代码将包含所使用的密码值。
 
 
javap -c ConnMngr.class 
22: ldc #36; //String jdbc:mysql://ixne.com/rxsql 
24: ldc #38; //String scott 
26: ldc #17; //String tiger 
         程序员在编写程序时应尽量避免对密码进行硬编码,而采用对密码加以模糊化或先经过 hash 
 处理再存储,或在外部资源文件中进行处理的方法。
 
 
修复案例:
         在上述修复代码中,首先将数据库连接的用户名密码加密放入 db.properties 
 文件中,如图 1-2 
 所示
 
 
  然后通过代码读取数据库配置文件,最后进行数据库的连接,这样就避免了硬编码产生的漏洞。
         示例:读取 properties 
 属性文件到输入流中,从输入流中加载属性列表,获取数据库连接属性值,然后进行数据库连接,这样就不会出现硬编码漏洞了。
 
 
// 读取 properties 属性文件到输入流中
InputStream is = PropertiesTest.class.getResourceAsStream("/db.properties"); 
// 从输入流中加载属性列表
properties.load(is); 
// 获取数据库连接属性值
DRIVER_CLASS = properties.getProperty("DRIVER_CLASS"); 
DB_URL = properties.getProperty("DB_URL"); 
DB_USER = properties.getProperty("DB_USER"); 
DB_PASSWORD = properties.getProperty("DB_PASSWORD"); 
// 加载数据库驱动类
Class.forName(DRIVER_CLASS); 
(三)不安全的随机数生成器
随机数是专门的随机试验的结果。产生随机数有多种不同的方法,这些方法被称为随机数发生器。随机数最重要的特性是:它所产生的后面的那个数与前面的那个数毫无关系。根据密码学原理,随机数生成器分为以下三类。
- 统计学伪随机数生成器(PRNG):伪随机数生成器从一个初始化的种子值开始计算得到序列,从种子开始,然后从种子中计算出后续值,当种子确定后生成的随机数也是确定的,但其输出结果很容易预测,因此容易复制数值流。
 - 密码学安全随机数生成器(CSPRNG):密码学安全伪随机性是统计学伪随机数生成器的一个特例,给定随机样本的一部分和随机算法,不能有效地演算出随机样本的剩余部分。
 - 真随机数生成器:其定义为随机样本不可重现。实际上只要给定边界条件,真随机数并不存在。可是如果产生一个真随机数样本的边界条件十分复杂且难以捕捉(比如计算机当地的本底辐射波动值),则可以认为用这个方法演算出来了真随机数。
 
使用计算机产生真随机数的方法是获取 CPU 频率与温度的不确定性,以及统计一段时间内的运算次数每次都会产生不同的值,系统时间的误差以及声卡的底噪等。在实际应用中往往使用伪随机数就足够了。计算机或计算器产生的随机数有很长的周期性。实际上它们不真正地随机,因为它们是可以计算出来的,但是它们具有类似于随机数的统计特征。这样的发生器称为伪随机数发器。
          Java 中的“
  java.util.Random
  ”工具类 
  LCG 
  线性同余法伪随机数生成器,可以根据种子和算法生成随机数。此算法的缺陷就是可预测性,攻击者可能会猜测将要生成的下一个值,并使用此猜测来模拟其他用户或访问敏感信息。“java.util.Random
  ”工具类没带参数构造函数生成的 Random 
  对象的种子默认是当前系统时间的毫秒数,故进入到 
  Random 
  类中查看其种子默认是当前的系统时间,如图 3-1 
  所示。 
 
 
   
  Random 函数的使用方式:
 
 
  
Random random = new Random(); 
int r = random.nextInt(); // 生成一个随机数 
只要种子一样,其输出的随机序列也是一样的,如设置两个随机数列种子都是 1,则输出的随机数列也是完全相同的,如图 3-2 所示。
   
“java.util.Random ”不是加密安全的。可以使用 SecureRandom 来获取密码安全的伪随机数生成器,以供对安全敏感的应用程序使用。“java.Security.SecureRandom ”工具类提供加密的强随机数生成器(RNG) ,要求种子必须是不可预知的,产生非确定性输出。操作系统收集了一些随机事件,比如鼠标点击、键盘点击,等等。SecureRandom 使用这些随机事件作为种子。SecureRandom 函数的使用方式:
SecureRandom secureRandom2 = SecureRandom.getInstance("SHA1PRNG"); 
int r = secureRandom2.nextInt(); // 生成一个随机数 
  
 使用 SecureRandom 生成伪随机,因为 SecureRandom 使用鼠标点击、键盘点击等等这些随机事件作为种子,故其生成的随机数列完全不同,安全性要高,所以建议使用“ java.Security.SecureRandom ”工具类来代替“ java.util.Random ”工具类,如图 3 -3 所示。
   








![[附源码]SSM计算机毕业设计医院仪器设备管理系统JAVA](https://img-blog.csdnimg.cn/8a914466953c40bda7057f121eb92829.png)


![[MySQL]-压力测试_TPCC-MySQL](https://img-blog.csdnimg.cn/92f821b3268a48a79694ea74fcdc1433.png#pic_center)






