---
title: 2023-2024学年下学期期末
---

## 2023-2024学年下学期期末试卷（回忆版）

### 分析题

1. 回答下列问题

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

        <details>
        <summary>答案:</summary>

        简述定义即可, 不赘述

        </details>

        ***

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

        <details>
        <summary>答案:</summary>

        考虑如下情况:

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

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

        </details>

        ***

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

        <details>
        <summary>答案:</summary>

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

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

        （言之有理即可）

        </details>

    ***

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

    1. 简述TCP SYN欺骗攻击的原理 **(2分)**  
        <details>
        <summary>答案:</summary>

        简述定义即可, 不赘述

        </details>

        ***

    2. 假设初始时TCP连接表已被洪泛, 为保证TCP连接表始终被填满, 攻击者应以什么速率发送数据包？**(4分)**  
        <details>
        <summary>答案:</summary>

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

        </details>

        ***

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

        <details>
        <summary>答案:</summary>

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

        </details>

   ***

3. 考虑如下代码:

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

    <details>
    <summary>分析过程</summary>

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

    参数 $\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. 中的 tag, 我们询问了陈志立教授, 得到的回答如下: "1 题中的本意主要是问data变量对应的打印输出, 题目可能不够严谨. 在具体回答时, 也可以把tag的内容用某个符号表示, 比如\<tag\>. "我们感谢陈老师的澄清!

    </details>

    ***

    1. 假设输入长度为19字节时程序运行不会崩溃, 那么输入 "Computer Security" 后, 程序会输出什么？**(3分)**
        <details>
        <summary>答案:</summary>

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

        </details>

        ***

    2. 假设输入长度为19字节时程序不会崩溃, 而输入长度为20字节时程序崩溃, 如果想要修改tag的话, 输入长度应至少为多少字节？为什么？**(4分)**
        <details>
        <summary>答案:</summary>

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

        </details>

        ***

    3. 修改上述代码以避免安全隐患. **(3分)**
        <details>
        <summary>答案:</summary>

        使用安全函数 fgets 即可, 例如:

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

        </details>

    ***

4. 回答下列问题

    1. 三种云服务部署模型分别是什么？**(3分)**
        <details>
        <summary>答案:</summary>

        SaaS, PaaS, IaaS

        </details>

        ***

    2. 若想在云上搭建自己的操作系统, 应该采取哪种部署模型？为什么？**(3分)**
        <details>
        <summary>答案:</summary>

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

        </details>

        ***

    3. 如何加固云上的操作系统？**(4分)**
        <details>
        <summary>答案:</summary>

        参考书上相关章节, 言之有理即可

        </details>

    ***

5. 回答下列问题

    1. 用户认证方法有哪些？**(4分)**
        <details>
        <summary>答案:</summary>

        个人知道的信息, 个人持有的物品, 静态生物特征, 动态生物特征

        </details>

        ***

    2. 为防止明文口令泄露和离线字典攻击, 应如何储存口令相关信息？**(4分)**
        <details>
        <summary>答案:</summary>

        加盐, 简述加盐原理

        </details>

        ***

    3. 假设一个用户有8个属性, 每个属性有10个值, 如果采用基于角色的访问控制, 应设置多少个角色？**(4分)**
        <details>
        <summary>答案:</summary>

        $10^8$ 个

        </details>

        ***

    4. 考虑sql语句:

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

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

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

        </details>

        ***

    5. 为防范(4) 中的攻击, 应采用何种防火墙？为什么？**(4分)**
        <details>
        <summary>答案:</summary>

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

        </details>
