0%

软件安全——第1章

Chapter 1 软件安全概述

1.1 概念

网络空间有两个子空间:代码空间和数据空间

Safety和Security的区别:Safety强调相对于环境的安全,而Security强调相对于其他人的安全。

1.2 任何软件都是不安全的

软件测试无法绝对保证软件安全性的原因:软件规模的增加、开发进度的要求提升使得开发人员难以考虑到所有的安全问题。通常测试案例构成的空间巨大,无法全部进行测试,只能抽取其中的一小部分进行测试。

为尽量减少软件安全问题,一方面应该在开发时开发者尽量多考虑,另一方面也需要一定的测试工作。几乎所有的软件都是带着安全隐患投入运行。任何软件都是不安全的。

1.3 软件不安全的外部表现

  • 软件运行时不稳定,产生错误输出、异常现象、直接崩溃
  • 敌方利用各种手段进行攻击,窃取信息破坏系统等

通常这类软件安全问题的存在需要软件开发方投入大量人力和资金进行软件的维护工作。

1.4 软件安全问题产生原因

安全隐患可分为错误和缺陷两类。错误是软件开发过程中出现的问题,如线程处理不当等,容易发现与修复;缺陷产生于设计阶段,在代码中实例化且难以发现。

从开发者的角度看软件不安全的原因:

  • 软件生产没有严格遵守软件工程流程。在设计之初没有对软件的功能进行完整的考虑,随意改动软件需求规格说明书等。
  • 大多数商业软件的结构复杂,使得维护软件困难。
  • 没有采用科学编码方案,可能产生由编码不一致引起的问题。如乱码等
  • 测试不到位,没有覆盖所有可能的用户输入类型等

从软件工程客观角度看软件不安全的原因:

  • 软件复杂性和工程进度的平衡:工程进度仅按照软件规模进行适度延长,很多问题来不及解决。
  • 安全问题的不可预见性:仅通过对运行状态的简单假设无法覆盖所有运行情况。
  • 软件需求的变动:在变动过程中对安全问题的忽略。
  • 软件组件之间交互的不可预见性:与客户自行安装的第三方组件可能有不兼容的问题。

1.5 软件安全防护手段

  • 安全设计与开发
    • 将安全思想融入到软件开发管理流程之中,在开发阶段就尽可能减少漏洞和缺陷的存在。
    • 优秀范例:微软的SDL-IT(信息技术安全开发生命周期流程)
  • 保障运行环境
    • 保证软件自身的运行环境,加强系统自身的数据完整性校验
    • 含软件完整性校验和系统完整性校验。软件完整性校验指安全软件安装时对系统的重要文件进行校验并保存校验值。系统完整性校验则从更加底层的方面校验。
  • 加强软件自身行为认证
    • 确保软件自身总是向着预期的方式运行。
  • 恶意软件检测与查杀
    • 反病毒软件的安装与使用
  • 黑客攻击防护
    • 防火墙、IDS、IPS、EMET(基于主机的漏洞攻击阻断技术)
  • 系统还原
    • 将关键系统文件进行镜像备份,因此可以在受到攻击时能够还原到原来的状态。如Ghost还原软件
  • 虚拟隔离
    • 在虚拟机中进行风险较大的操作,防止风险转移到主机上。
    • 沙箱技术:可用于隔离风险行为与分析恶意软件

练习题
1. 阅读下面的代码,回答下列问题:(23分)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 这个函数的功能是对输入进行移位加密。如输入为helloworld
// 将其竖着写,每一列写3个字符,再逐行拼接,得到密文为hlodeorlwl
// hlod
// eor
// lwl
char* foo(char* plaintext){
int size = strlen(plaintext);
char* cipher = (char*)malloc(size);
int index = 0;
for(int i=0; i<3; i++){
for(int j=0; j<size / 3; j++)
cipher[index++] = plaintext[j*3+i];
}
return cipher;
}

(1) 本函数使用了malloc库函数,但是没有__________________,这可能会导致________________________。另外,函数也没有检查__________________。(6分)
(2) 当输入的字符串_____________________时,函数的输出可能会出错,原因是___________________________________________________。(5分)
(3) 除了上面提到的问题之外,这个函数还存在什么问题?(4分)
(4) 请对上述第(1)问和第(2)问提到的问题进行修复,写出完整代码。(8分)

答案:
(1) 检查是否分配成功;程序尝试访问空指针导致崩溃;输入字符串指针plaintext是否为空
(2) 长度不是3的倍数;在for循环中内循环次数为size/3,结果是一个整数,总的遍历次数为(size / 3)*3 < size,导致最后的两个字符无法被加密,从而结果错误
(3) 该函数不能加密中文字符串,因为中文字符至少占2字节,程序逐字节进行移位会导致中文字符被拆分,从而出现乱码。
(4) 具体代码略,注意当明文长度不是3的倍数时的处理方式。

解题技巧:常见的安全隐患

  1. malloc没有检查是否成功分配
  2. 缓冲区溢出
  3. 整数溢出
  4. 没有释放空间(不是所有情况)
  5. 线程死锁(考的少)
  6. 逻辑错误(需要对代码进行具体分析