---
title: 计算机安全_软件工程学院_2024Spring_期末_回忆版
category:
  - 软件工程学院
  - 课程资料
tag:
  - 试卷
author:
  - タクヤマ
---

## 2024春季学期计算机安全期末考试试卷（回忆版）

### 选择题较为零散，未能回忆出来

### 1

(1) 简述数字签名的原理 **(2分)**  

(2) 数字签名技术是如何保证数据的完整性、不可否认性和来源认证的？ **(6分)**  

(3) 数字签名与消息认证技术有什么联系与区别？ **(2分)**  

解：

(1) 简述定义即可，不赘述

(2)

考虑如下情况：Bob要向Alice发送一个带数字签名的消息，进行签名需要用到Bob的私钥：没有Bob的私钥无法修改消息，这保证了完整性；只有Bob的公钥能正确验签，这保证了来源认证与不可否认性。

（按照这个思路分点阐述即可）

(3)

- 联系：两者都用于验证消息的真实性和完整性

- 区别：
  - 数字签名基于非对称加密，提供不可否认性
  - 消息认证技术基于对称加密，无法提供不可否认性

（言之有理即可）

### 2

现在考虑一个TCP SYN欺骗的情景。假设服务器端的TCP连接表有512个表项，对于每个未建立的连接，每隔30s重新发送一次连接请求，重复7次后将表项删除。

(1) 简述TCP SYN欺骗攻击的原理 **(2分)**  

(2) 假设初始时TCP连接表已被洪泛，为保证TCP连接表始终被填满，攻击者应以什么速率发送数据包？**(4分)**  

(3) 假设一个TCP数据包为40字节，忽略成帧消耗，求攻击消耗的带宽 **(4分)**  

解：

(1) 简述定义即可，不赘述

(2)

- 每个表项存活时间：30s × 7 = 210s
- 需在210s内填满512个表项：
  - 速率 = 512 / 210 ≈ 2.44 包/秒

(3)

- 每个TCP包40字节：
  - 带宽 = 2.44 包/秒 × 40 字节/包 × 8 比特/字节 = 780.8 bps

### 3

考虑如下代码：

```c
void hello(char * tag){
    char data[12];
    gets(data);
    printf("your %s is %s\n",tag,data);
}
```  

(1) 假设输入长度为19字节时程序运行不会崩溃，那么输入“Computer Security”后，程序会输出什么？**(3分)**

(2) 假设输入长度为19字节时程序不会崩溃，而输入长度为20字节时程序崩溃，如果想要修改tag的话，输入长度应至少为多少字节？为什么？**(4分)**

(3) 修改上述代码以避免安全隐患。**(3分)**

解：

(1) 对于栈溢出问题，我们首先要对函数调用机制有充分的了解，根据压栈机制，调用函数时被压栈的顺序为：

参数 $\rightarrow$ 返回地址 $\rightarrow$ 旧栈指针 $\rightarrow$ 局部变量

那么什么时候程序会崩溃呢？返回地址被篡改时肯定会崩溃，因为程序返回时会访问到非法的地址；旧的栈指针被篡改时也会崩溃，因为程序虽然能正常返回到原运行位置，但是指示旧栈帧的指针被篡改到非法地址，破坏了上下文，根据压栈顺序，肯定是旧栈帧的指针会先被覆盖。

所以，根据(2)中的题设，输入19字节不崩溃而输入20字节崩溃（注意gets函数会在末尾添加一个'\0'空字符），即可推测栈内分配了20字节空间：当输入为20字节长度时，'\0'空字符添加在第21个字符处，应该正好开始覆盖在旧栈帧的帧指针处，导致崩溃。

在经过实际的gdb测试后，我们得到具体栈帧结构如图所示（以4字节，即32位为一行）：

```c
+---------------------------+
| ...  (main函数的栈帧)      |
+---------------------------+ <--- hello函数栈帧底部 (高地址)
| 参数:  char *tag 指针      |
+---------------------------+
| 返回地址 (ret addr)        |
+---------------------------+
| 旧栈帧的帧指针 (Saved ebp) |
+---------------------------+ <--- 栈顶指针(ESP)在进入函数后移动
| ebx (储存GOT表的位置)      |
+---------------------------+
| 内存padding (16字节对齐?)  |
+---------------------------+
| 局部变量: char data[8]-[11]|
+---------------------------+
| 局部变量: char data[4]-[7] |
+---------------------------+
| 局部变量: char data[0]-[3] |
+---------------------------+ <--- 栈顶 (低地址)
```

那么，我们就能解答此题如下：

(1) 程序会输出 "your \<tag\> is Computer Sec" （data为输入的前12字节）

(2) 要修改tag的话，至少要输入28字节，理由见上述分析与栈帧结构图

(3)

使用安全函数fgets即可，例如：

```c
void hello(char * tag){
    char data[12];
    fgets(data, sizeof(data), stdin);
    printf("your %s is %s\n", tag, data);
}
```  

注：关于（1）中的tag，我们询问了陈志立教授，得到的回答如下：“（1）题中的本意主要是问data变量对应的打印输出，题目可能不够严谨。在具体回答时，也可以把tag的内容用某个符号表示，比如\<tag\>”。我们感谢陈老师的澄清！

### 4

(1) 三种云服务部署模型分别是什么？**(3分)**

(2) 若想在云上搭建自己的操作系统，应该采取哪种部署模型？为什么？**(3分)**

(3) 如何加固云上的操作系统？**(4分)**

解：

(1) SaaS, PaaS, IaaS

(2)

私有云，用户可自主定制硬件、网络及安全策略，满足操作系统底层架构的灵活部署需求，同时资源独享避免与其他租户冲突，适合对数据隐私和合规性要求高的场景

(3) 参考书上相关章节，言之有理即可

### 5

(1) 用户认证方法有哪些？**(4分)**

(2) 为防止明文口令泄露和离线字典攻击，应如何储存口令相关信息？**(4分)**

(3) 假设一个用户有8个属性，每个属性有10个值，如果采用基于角色的访问控制，应设置多少个角色？**(4分)**

(4) 考虑sql语句：

```sql
SELECT * FROM userdata WHERE UID = $_GET["uname"] AND PASSWORD = $_GET["password"];
```

该语句有无安全隐患？攻击者如何在不知道任何用户名和口令的情况下，如何攻击得到全部信息？**(4分)**

(5) 为防范(4) 中的攻击，应采用何种防火墙？为什么？**(4分)**

解：

(1) 个人知道的信息；个人持有的物品；静态生物特征；动态生物特征

(2) 加盐，简述加盐原理

(3) $10^8$ 个

(4)

有隐患，向uname字段输入： OR 1=1 -- 以绕过密码检测

(5) 应采用应用级防火墙，因为要对sql语句进行检查，这是应用层上的机制
