网安自测题:掌握核心知识点的实用练习

Part A · 概念题(30 分,凭记忆作答)

要求:请用自己的话回答,不要背定义。

1. SQL 注入为什么能发生?攻击者利用它能做到哪三件事?

  • 发生原因: 开发者在编写代码时,没有将用户输入的"数据"与 SQL 语句的"代码"进行严格的分离,直接把用户的输入拼接到了 SQL 查询语句中,导致数据库把用户输入的内容当成了可执行的 SQL 命令来运行。

  • 能做到的三件事:

    1. 数据窃取: 绕过登录验证,或者直接读取数据库中的敏感信息(如管理员密码、用户隐私数据)。

    2. 数据篡改/破坏: 修改、删除数据库中的数据,甚至执行 DROP TABLE 删库。

    3. 权限提升/系统控制: 利用数据库的高权限,写入木马文件,或者执行系统命令,进而控制整个服务器。

2. XSS 有哪三种类型?各举一个触发场景。

  • 反射型 XSS: 恶意代码作为请求参数发给服务器,服务器直接将其反射回浏览器执行。

    • 场景: 搜索框。用户搜索 <script>alert(1)</script>,服务器把搜索词直接显示在页面上,导致脚本执行。
  • 存储型 XSS: 恶意代码被服务器存储到数据库中,其他用户访问该页面时触发。

    • 场景: 留言板或评论区。攻击者发布一条带有恶意脚本的留言,所有查看该留言的用户都会中招。
  • DOM 型 XSS: 漏洞发生在浏览器端,前端 JavaScript 代码从 URL 或 DOM 中获取数据并直接输出到页面,不经过服务器。

    • 场景: 前端通过 location.hash 获取内容并使用 innerHTML 渲染到页面上。

3. HTTP 中 Cookie 和 Session 的区别?为什么要配合使用?

  • 区别:

    • 存储位置: Cookie 存储在客户端浏览器;Session 存储在服务器端。

    • 安全性: Cookie 容易被篡改或窃取;Session 相对安全。

    • 生命周期: Cookie 可以设置长期保存;Session 通常随浏览器关闭或超时失效。

  • 配合使用的原因: HTTP 是无状态协议。为了识别用户,服务器需要给用户发一个"凭证"。如果只发 Session ID 给客户端,客户端需要有个地方存,Cookie 正好充当了这个存储容器。所以通常是将 Session ID 存放在 Cookie 中,每次请求时浏览器自动带上 Cookie,服务器通过这个 ID 找到对应的 Session 数据,从而维持用户的登录状态。

4. 文件上传漏洞常见的绕过手段有哪些?至少写 3 种。

  1. 前端绕过: 修改前端 JS 代码,或者直接使用 Burp Suite 抓包修改文件后缀名(如将 .php 改为 .jpg 绕过前端检查)。

  2. MIME 类型绕过: 抓包修改 Content-Type 字段,比如将 application/x-php 改为 image/jpeg 绕过服务器对文件类型的检查。

  3. 黑名单绕过: 利用服务器黑名单不全的漏洞,使用特殊后缀(如 .php3、.phtml、.php5),或者利用大小写(.PHP)、双写(.pphphp)、空格/点号绕过(如 1.php. 在 Windows 下)。

  4. %00 截断: 在文件名后加 %00 截断后面的后缀检查(针对低版本 PHP)。

  5. .htaccess 文件: 上传 .htaccess 文件,将特定后缀(如 .jpg)解析为 PHP 执行。

5. CSRF 和 XSS 的区别?为什么 CSRF 需要「用户已登录」这个前提?

  • 区别:

    • XSS(跨站脚本): 攻击者利用网站漏洞,在受害者浏览器中执行恶意脚本,窃取用户数据或冒充用户操作。攻击的是用户对网站的信任。

    • CSRF(跨站请求伪造): 攻击者诱导受害者点击链接,利用受害者当前已登录 的身份,以受害者的名义向目标网站发送恶意请求。攻击的是网站对用户浏览器的信任。

  • 需要"已登录"前提的原因: CSRF 的核心是"借刀杀人"。它本身无法获取用户的 Cookie 或 Session,而是依赖浏览器在发送请求时会自动携带目标网站的 Cookie(即用户的身份凭证)。如果用户没有登录,服务器就不会携带有效的 Session,请求就会被服务器拒绝,CSRF 攻击也就无法生效。


Part B · 实战题(30 分,本地 DVWA · Low 难度)

要求:每个任务记录操作步骤 + 你理解的漏洞成因。

注:以下为标准 DVWA 靶场 Low 难度的典型解题思路,实际操作时请结合本地环境记录。

1. 暴力破解:用 Burp Intruder 拿到正确密码。

  • 操作步骤:

    1. 在 DVWA 中设置安全级别为 Low,进入 Brute Force 页面。

    2. 输入任意用户名(如 admin)和密码(如 123),开启 Burp Suite 代理拦截。

    3. 点击 Login,在 Burp 中抓到请求包,发送到 Intruder。

    4. 在 Intruder 的 Positions 标签中,清除所有变量,将 password 参数的值选中并添加为 payload 位置。

    5. 在 Payloads 标签中,加载一个常用密码字典(如 passwords.txt)。

    6. 点击 Start Attack 开始爆破。观察返回结果,通常成功登录的响应长度(Length)与其他失败请求不同,据此找到正确密码。

  • 漏洞成因: 应用程序没有对登录尝试次数进行限制(无验证码、无锁定机制),且允许用户使用弱口令,使得攻击者可以进行无限次的自动化密码猜测。

2. 命令注入:让服务器执行 whoami 与 ipconfig(或 ifconfig)。

  • 操作步骤:

    1. 进入 Command Injection 页面。在输入框中输入 127.0.0.1 点击提交,可以看到服务器返回了 ping 的结果。

    2. 尝试拼接命令。输入 127.0.0.1 && whoami。

    3. 页面返回了当前执行命令的用户权限(如 www-data 或 apache)。

    4. 继续输入 127.0.0.1 && ipconfig(Windows)或 127.0.0.1 && ifconfig(Linux)。

  • 完整 Payload:

    • 127.0.0.1 && whoami

    • 127.0.0.1 && ipconfig(或 ifconfig)

  • 漏洞成因: 应用程序直接将用户输入拼接到系统命令中执行,没有对特殊字符(如 &、&&、|、;)进行过滤或转义,导致攻击者可以执行任意系统命令。

3. 文件包含:读取目标系统的一个敏感文件。

  • 操作步骤:

    1. 进入 File Inclusion 页面。点击页面上的文件链接,观察 URL,例如 ?page=file1.php。

    2. 尝试修改 URL 中的参数,利用路径穿越读取系统文件。

  • 文件路径与 Payload:

    • 目标路径: Linux 系统下的 /etc/passwd 文件(存放用户账户信息)。

    • Payload: 在 URL 中输入 ?page=../../../../../../etc/passwd。

    • Windows 目标路径(可选): C:\Windows\win.ini,Payload 为 ?page=../../../../../../Windows/win.ini。

  • 漏洞成因: 应用程序没有对包含的文件路径进行严格的校验和过滤,允许用户通过 ../ 等相对路径符号跳出原本的目录限制,从而包含并读取服务器上的任意敏感文件。

Part C · 代码题(20 分,读代码找问题)

C1 登录查询代码

1. 这段代码有什么漏洞?

这段代码存在严重的 SQL 注入漏洞 。

原因分析: 代码在第 2 行直接通过 $_GET['id'] 获取用户输入,并在第 4 行将该输入直接拼接到了 SQL 查询语句 $sql 中。程序没有对用户输入进行任何过滤、转义或类型检查,导致用户输入的"数据"被数据库当作了"代码"来执行。

2. 攻击者传入 id=1' OR '1'='1 会发生什么?为什么?

  • 会发生什么: 攻击者将成功绕过身份验证,查询出数据库中 users 表里的所有用户记录(通常是返回第一行,即管理员账号)。

  • 为什么: 拼接后的 SQL 语句变成了:

    SELECT first_name, last_name FROM users WHERE user_id = '1' OR '1'='1'

    由于 '1'='1' 永远为真(True),整个 WHERE 子句的条件恒成立。这意味着数据库会返回 users 表中的所有行,而不再仅仅匹配 user_id = 1 的那一条记录。

3. 给出两种修复方案。

  • 方案一:使用预处理语句(Prepared Statements)与参数化查询(推荐)

    这是最根本的修复方法。将 SQL 语句模板与数据分离,数据库会预先编译 SQL 语句,用户输入的数据只能作为参数值传入,无法改变 SQL 语句的结构。

    php

    复制代码
    $stmt = $conn->prepare("SELECT first_name, last_name FROM users WHERE user_id = ?");
    $stmt->bind_param("s", $id); // 's' 表示字符串类型
    $stmt->execute();
    $result = $stmt->get_result();
  • 方案二:对用户输入进行严格的类型转换与转义

    如果 user_id 是数字类型,可以强制将其转换为整数;如果是字符串,则使用 mysqli_real_escape_string 进行转义。

    php

    复制代码
    // 方案二 A:强制类型转换(适用于数字型 ID)
    $id = intval($_GET['id']);
    
    // 方案二 B:转义特殊字符(适用于字符串)
    $id = mysqli_real_escape_string($conn, $_GET['id']);

(注:实际开发中强烈建议使用方案一,方案二在应对复杂字符集时仍有绕过风险。)


C2 文件上传校验代码

1. 这种校验能被绕过吗?怎么绕?

  • 能被绕过。

  • 绕过方法: 代码在第 1 行仅通过 $_FILES['file']['type'](即 HTTP 请求头中的 Content-Type)来校验文件类型。这个值完全由客户端(浏览器或攻击者) 控制。攻击者可以使用 Burp Suite 等抓包工具拦截上传请求,将文件的 Content-Type 从 application/x-php 修改为 image/jpeg,而文件的实际后缀名(如 shell.php)保持不变。服务器由于只检查了 Content-Type,就会误以为这是合法的图片,从而将其上传并保存到服务器上。

2. 你会怎么修?

修复的核心原则是:永远不要信任客户端提交的任何数据(包括 MIME 类型),必须在服务器端进行严格的综合校验。

  • 修复方案一:检查文件扩展名(白名单机制)

    在服务器端获取文件的后缀名,并严格限定只允许上传特定的后缀(如 jpg, png, gif),采用白名单而非黑名单。

    php

    复制代码
    $allowed_ext = ['jpg', 'jpeg', 'png', 'gif'];
    $ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
    if (!in_array($ext, $allowed_ext)) {
        die("只允许上传图片文件");
    }
  • 修复方案二:检查文件真实内容(魔术字节/Magic Bytes)

    利用 finfo 或 getimagesize() 函数,读取文件头部的二进制数据(Magic Bytes),判断其是否真的是图片,而不是伪装成图片的脚本文件。

    php

    复制代码
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime = finfo_file($finfo, $_FILES['file']['tmp_name']);
    if ($mime !== 'image/jpeg' && $mime !== 'image/png') {
        die("文件内容不是合法的图片");
    }
  • 修复方案三:重命名文件

    上传后不要使用用户提供的文件名(因为可能包含 ../ 或特殊字符),而是由服务器生成一个随机的文件名(如 md5(uniqid()) . '.jpg'),并存储在非 Web 根目录的路径下,防止恶意脚本被直接解析执行。

Part D · 情景题(20 分,开放作答)

1. 写出你接下来的信息收集步骤(至少 5 步),并说明每步想得到什么信息。

  • 步骤一:WHOIS 与 DNS 信息查询

    • 操作: 查询域名的注册信息、注册人、邮箱、NS 记录等(由于目标给的是 IP,此步可能略过,但如果是域名则必须做)。

    • 想得到的信息: 获取目标的所有者信息、注册时间、以及可能的子域名线索。

  • 步骤二:端口扫描与服务识别(Nmap)

    • 操作: 使用 Nmap 对 192.168.1.100 进行全端口扫描(如 nmap -p- -sV -sC 192.168.1.100)。

    • 想得到的信息: 发现目标开放了哪些端口(如 80, 8080, 22, 3306 等),以及每个端口上运行的服务和版本号(如 Apache 2.4.49, OpenSSH 7.2)。这直接决定了后续的攻击面。

  • 步骤三:Web 目录与敏感文件扫描

    • 操作: 针对发现的 Web 端口(如 80, 8080),使用目录扫描工具(如 Dirsearch, Gobuster)进行扫描。

    • 想得到的信息: 发现隐藏的后台登录页(如 /admin)、备份文件(如 www.zip)、配置文件(如 .git、robots.txt)或未授权的 API 接口。

  • 步骤四:Web 指纹识别与组件版本探测

    • 操作: 使用 Wappalyzer 插件或 WhatWeb 工具,识别目标网站使用的 CMS(如 WordPress, ThinkPHP)、开发语言(PHP, Java)、中间件(Nginx, Tomcat)及前端框架。

    • 想得到的信息: 确定目标使用的具体技术栈和版本,以便去漏洞库(如 CVE, Exploit-DB)查找对应的已知漏洞(Nday)。

  • 步骤五:操作系统与网络拓扑探测

    • 操作: 通过 TTL 值、Nmap 的 -O 参数或 Web 报错信息判断目标操作系统(Windows 或 Linux)。

    • 想得到的信息: 确定目标操作系统类型,这有助于选择正确的提权方式和利用工具。

  • 步骤六(可选):搜索引擎与公开信息搜集(OSINT)

    • 操作: 利用 Google Hacking(如 site:192.168.1.100)、GitHub 代码搜索等。

    • 想得到的信息: 寻找泄露的账号密码、API 密钥或内部网络架构信息。

2. 如果 80 端口没发现漏洞,但 8080 端口跑着一个登录框,你会怎么测试?(说思路即可)

  • 思路一:弱口令与暴力破解测试

    • 尝试常见的默认口令(如 admin/admin, admin/123456, root/root)。如果系统没有验证码或登录次数限制,可以尝试使用 Burp Suite Intruder 加载字典进行暴力破解。
  • 思路二:SQL 注入测试

    • 在用户名和密码输入框中尝试输入 ' OR '1'='1 或 admin' -- 等 payload,看是否能绕过登录验证。
  • 思路三:查看前端源码与 JS 文件

    • 查看登录页面的 HTML 源码,寻找隐藏的输入框、注释掉的代码或硬编码的凭据。

    • 分析引用的 JavaScript 文件,看是否有 API 接口地址泄露、加密逻辑(如 MD5 加盐)或者前端路由信息,尝试直接调用 API 绕过前端登录。

  • 思路四:尝试其他 HTTP 方法

    • 除了 POST 请求,尝试使用 GET、PUT、OPTIONS 等方法访问登录接口,看是否有意外的响应或信息泄露。
  • 思路五:撞库测试

    • 如果之前通过信息收集拿到了该目标相关的用户名或邮箱,可以尝试使用这些信息配合常见密码进行撞库测试。
  • 思路六:检查是否存在其他漏洞

    • 测试登录框是否存在 CSRF (跨站请求伪造)、XSS (跨站脚本)或 用户名枚举(通过错误提示判断用户名是否存在)。
  • 思路七:分析 8080 端口服务

    • 确认 8080 端口运行的具体服务(如 Tomcat 管理后台、Jenkins、WebLogic 等)。如果是已知的中间件,直接查找该版本对应的已知漏洞进行利用(例如 Tomcat 的弱口令部署 WAR 包)。
相关推荐
数字化顾问1 小时前
(142页PPT)PLM+ERP系统选型及建设方案建议书(附下载方式)
数据库
木白CPP1 小时前
[QNX] 深入理解 Resource Manager 接口设计
linux·服务器·数据库
AlfredZhao1 小时前
别再 rm 日志了:Linux 下安全清空日志文件的正确姿势
linux
Shadow(⊙o⊙)1 小时前
MySQL C/C++链接MySQL使用
数据库·sql·mysql
星恒随风1 小时前
Linux开发工具详解(二):Git版本控制、GitHub协作与GDB调试实战
linux·笔记·git·学习·github
2401_868534781 小时前
简要说明PON下行和上传数据方式
运维·服务器·网络
weixin_403810131 小时前
iOS 自动化脚本怎么输入文字:代理、输入法与快捷指令三级方案
运维·ios·自动化
Mortalbreeze1 小时前
MySQL 基础篇(五):数据操作基础 —— CRUD
linux·服务器·数据库·mysql
Shadow(⊙o⊙)1 小时前
mysql为创建普通用户并创建库赋权
数据库·sql·mysql