超文本传输协议 (HTTP)

URL结构

URL 结构图:方案“http”,用户“admin:password”,主机“inlanefreight.com”,端口“80”,路径“/dashboard.php”,查询字符串“login=true”,片段“status”。

成分 例子 描述
Scheme http:// https:// 用于识别客户端正在访问的协议,以冒号和双斜杠 ( ://)结尾
User Info admin:password@ 这是一个可选组件,包含用于向主机进行身份验证的凭据(以冒号分隔),并以 at 符号 ( ):与主机分隔。@
Host inlanefreight.com 主机表示资源位置。可以是主机名或 IP 地址
Port :80 PortHost之间用冒号 ( )分隔:。如果没有指定端口,http则方案默认为端口80https默认为端口443
Path /dashboard.php 指向正在访问的资源,可以是文件或文件夹。如果没有指定路径,服务器将返回默认索引(例如index.html)。
Query String ?login=true 查询字符串以问号 ( ?) 开头,由一个参数(例如login)和一个值(例如true)组成。多个参数可以用与号 ( &) 分隔。
Fragments #status 客户端的浏览器会处理片段,以定位主要资源中的各个部分(例如页面上的标题或部分)。

HTTP 流

图示为用户访问 inlanefreight.com。浏览器发送 DNS 查询以查找 IP 地址,收到 152.153.81.14,然后向 Web 服务器发出 HTTP 请求,服务器返回“HTTP/1.1 200 OK”。

用户首次inlanefreight.com在浏览器中输入 URL ( ) 时,它会向 DNS(域名系统)服务器发送请求,以解析域名并获取其 IP 地址。DNS 服务器查找 IP 地址inlanefreight.com并返回。所有域名都需要以这种方式解析,因为服务器没有 IP 地址就无法通信。

[!NOTE]

注意:我们的浏览器通常会先在本地“ ”文件中查找记录/etc/hosts,如果请求的域名不存在,则会联系其他 DNS 服务器。我们可以使用“ /etc/hosts”手动添加记录进行 DNS 解析,方法是先添加 IP 地址,再添加域名。

HTTP 请求

HTTP 请求详情:方法“GET”,路径“/users/login.html”,版本“HTTP/1.1”。标头包括主机“inlanefreight.com”,用户代理“Mozilla/5.0”和 Cookie“PHPSESSID=c4ggt4jull9obt7aupa55o8vbf”。

场地 例子 描述
Method GET HTTP 方法或动词,指定要执行的操作类型。
Path /users/login.html 所访问资源的路径。此字段也可以以查询字符串作为后缀(例如?username=user)。
Version HTTP/1.1 第三个也是最后一个字段用于表示 HTTP 版本。

接下来的几行包含 HTTP 标头值对,例如HostUser-AgentCookie以及许多其他可能的标头。这些标头用于指定请求的各种属性。标头以换行符结尾,这是服务器验证请求所必需的。最后,请求可能以请求正文和数据结尾。

[!NOTE]

注意: HTTP 1.X 版本以明文形式发送请求,并使用换行符分隔不同的字段和不同的请求。而 HTTP 2.X 版本则以字典形式的二进制数据发送请求。

HTTP 响应

HTTP 响应详情:版本“HTTP/1.1”,状态“200 OK”。标头包括日期、服务器“Apache/2.4.41”、set-cookie“PHPSESSID=m4u64rqlpfthrvvb12ai9voqgf”以及内容类型“text/html; charset=UTF-8”。

HTTP 响应的第一行包含两个以空格分隔的字段。第一个字段表示HTTP version(eg HTTP/1.1),第二个字段表示HTTP response code(eg 200 OK)。

最后,响应可能以响应主体结尾,主体在标头后以换行符分隔。响应主体通常定义为HTML代码。但是,它也可以响应其他类型的代码

HTTP 标头

通用标题
标题 例子 描述
Date Date: Wed, 16 Feb 2022 10:38:44 GMT 保存消息发出的日期和时间。建议将时间转换为标准UTC时区。
Connection Connection: close 指示请求完成后当前网络连接是否应保持活动状态。此标头的两个常用值是closekeep-aliveclose来自客户端或服务器的值表示它们希望终止连接,而keep-alive标头则指示连接应保持打开状态以接收更多数据和输入。
实体标头
标题 例子 描述
Content-Type Content-Type: text/html 用于描述正在传输的资源类型。该值由客户端浏览器自动添加,并在服务器响应中返回。该charset字段表示编码标准,例如UTF-8
Media-Type Media-Type: application/pdf 类似于media-typeContent-Type用于描述正在传输的数据。此标头在服务器解释我们的输入时起着至关重要的作用。charset字段也可以与此标头一起使用。
Boundary boundary="b4e4fbd93540" 当同一条消息中包含多个内容时,此边界可用作分隔内容的标记。例如,在表单数据中,此边界用于--b4e4fbd93540分隔表单的不同部分。
Content-Length Content-Length: 385 保存正在传递的实体的大小。此标头是必需的,因为服务器使用它来从消息正文中读取数据,并且由浏览器和 cURL 等工具自动生成。
Content-Encoding Content-Encoding: gzip 数据在传递之前可能会经过多种转换。例如,可以压缩大量数据以减小消息大小。所使用的编码类型应在Content-Encoding标头中指定。
请求标头
标题 例子 描述
Host Host: www.inlanefreight.com 用于指定查询资源的主机。可以是域名或 IP 地址。HTTP 服务器可以配置为托管不同的网站,这些网站会根据主机名显示。这使得主机头成为一个重要的枚举目标,因为它可以指示目标服务器上是否存在其他主机。
User-Agent User-Agent: curl/7.77.0 User-Agent头用于描述请求资源的客户端。此标头可以揭示很多有关客户端的信息,例如浏览器、浏览器版本以及操作系统。
Referer Referer: http://www.inlanefreight.com/ 指示当前请求的来源。例如,点击 Google 搜索结果中的链接将生成https://google.comreferer。信任此标头可能很危险,因为它很容易被操纵,从而导致意想不到的后果。
Accept Accept: */* Accept头描述了客户端可以理解的媒体类型。它可以包含多个媒体类型,并以逗号分隔。该*/*值表示接受所有媒体类型。
Cookie Cookie: PHPSESSID=b4e4fbd93540 包含格式为 的 Cookie-值对Cookiename=value是存储在客户端和服务器端的数据,充当标识符。每次请求时,Cookie 都会传递给服务器,从而维护客户端的访问权限。Cookie 还可以用于其他用途,例如保存用户偏好设置或会话跟踪。单个标头中可以包含多个 Cookie,并以分号分隔。
Authorization Authorization: BASIC cGFzc3dvcmQK 这是服务器识别客户端的另一种方法。身份验证成功后,服务器会返回一个客户端独有的令牌。与 Cookie 不同,令牌仅存储在客户端,服务器会根据请求检索令牌。根据所使用的 Web 服务器和应用程序类型,身份验证类型有多种。
响应标头
标题 例子 描述
Server Server: Apache/2.2.14 (Win32) 包含处理请求的 HTTP 服务器的信息。它可用于获取服务器信息(例如其版本),并进一步枚举服务器。
Set-Cookie Set-Cookie: PHPSESSID=b4e4fbd93540 包含客户端识别所需的 Cookie。浏览器会解析这些 Cookie 并将其存储起来,以供将来的请求使用。此标头的格式与Cookie请求标头相同。
WWW-Authenticate WWW-Authenticate: BASIC realm="localhost" 通知客户端访问所请求资源所需的身份验证类型。
安全标头
标题 例子 描述
Content-Security-Policy Content-Security-Policy: script-src 'self' 指示网站对外部注入资源的策略。这些资源可以是 JavaScript 代码,也可以是脚本资源。此标头指示浏览器仅接受来自某些受信任域的资源,从而防止跨站点脚本 (XSS)等攻击。
Strict-Transport-Security Strict-Transport-Security: max-age=31536000 阻止浏览器通过纯文本 HTTP 协议访问网站,并强制所有通信通过安全的 HTTPS 协议进行。这可以防止攻击者嗅探网络流量并访问受保护的信息(例如密码或其他敏感数据)。
Referrer-Policy Referrer-Policy: origin 指示浏览器是否应包含通过标头指定的值Referer。它有助于避免在浏览网站时泄露敏感的 URL 和信息。

完整的标准 HTTP 标头列表

请求方法

方法 描述
GET ?param=value请求特定资源。可以通过 URL 中的查询字符串(例如)向服务器传递附加数据。
POST 向服务器发送数据。它可以处理多种类型的输入,例如文本、PDF 和其他形式的二进制数据。这些数据会附加到请求体中,位于请求头之后。POST 方法通常用于发送信息(例如表单/登录信息)或向网站上传数据(例如图片或文档)。
HEAD 请求向服务器发出 GET 请求时返回的标头。它不返回请求正文,通常用于在下载资源之前检查响应长度。
PUT 在服务器上创建新资源。如果在未进行适当控制的情况下允许此方法,则可能导致上传恶意资源。
DELETE 删除 Web 服务器上的现有资源。如果安全措施不完善,可能会删除 Web 服务器上的关键文件,从而导致拒绝服务 (DoS)。
OPTIONS 返回有关服务器的信息,例如服务器接受的方法。
PATCH 对指定位置的资源应用部分修改。

响应代码

类型 描述
1xx 提供信息并且不影响请求的处理。
2xx 请求成功时返回。
3xx 当服务器重定向客户端时返回。
4xx 表示不适当的请求from the client。例如,请求不存在的资源或请求错误的格式。
5xx 当其本身出现问题时就退货with the HTTP server

以下是上述每种 HTTP 方法类型的一些常见示例:

代码 描述
200 OK 请求成功后返回,响应主体通常包含所请求的资源。
302 Found 将客户端重定向到另一个 URL。例如,在用户成功登录后将用户重定向到其仪表板。
400 Bad Request 遇到格式错误的请求(例如缺少行终止符的请求)时返回。
403 Forbidden 表示客户端没有对资源的适当访问权限。当服务器检测到用户的恶意输入时,也会返回此错误。
404 Not Found 当客户端请求服务器上不存在的资源时返回。
500 Internal Server Error 当服务器无法处理请求时返回。

HTTP 响应状态代码完整列表

CRUD API

增删改查
手术 HTTP 方法 描述
Create POST 将指定的数据添加到数据库表
Read GET 从数据库表中读取指定实体
Update PUT 更新指定数据库表的数据
Delete DELETE 从数据库表中删除指定行

可以在 API 后简单地指定表名(例如/city),然后指定我们的搜索词

image-20250511200932408

为了将其正确格式化为 JSON 格式,我们可以将输出通过管道传输到jq实用程序,实用程序会对其进行正确格式化。我们还将使用 来抑制任何不需要的 cURL 输出-s

image-20250511200959581

增加
1
curl -X POST http://<SERVER_IP>:<PORT>/api.php/city/ -d '{"city_name":"HTB_City", "country_name":"HTB"}' -H 'Content-Type: application/json'

image-20250511201112195

更新
1
curl -X PUT http://<SERVER_IP>:<PORT>/api.php/city/london -d '{"city_name":"New_HTB_City", "country_name":"HTB"}' -H 'Content-Type: application/json'

image-20250511201213565

[!NOTE]

注意: HTTPPATCH方法也可以用于更新 API 条目,而不是PUT。确切地说,PATCH用于部分更新条目(仅修改部分数据,例如仅修改 city_name),而PUT用于更新整个条目。我们也可以使用 HTTPOPTIONS方法来查看服务器接受哪种方法,然后相应地使用相应的方法。

删除
1
curl -X DELETE http://<SERVER_IP>:<PORT>/api.php/city/New_HTB_City

image-20250511201426903

cURL

cURL(客户端 URL)是一个命令行工具和库,主要支持 HTTP 以及许多其他协议。它 不像 Web 浏览器那样渲染 HTML/JavaScript/CSS 代码,而是以原始格式打印出来

1.可以将任何 URL 作为 cURL 的参数,向其发送基本 HTTP 请求

image-20250430234645752

2.可以使用 cURL 下载页面或文件,并使用-O标志将内容输出到文件中。如果要指定输出文件名,可以使用-o标志并指定文件名。否则,我们可以使用-O,cURL 将使用远程文件名

image-20250430234711250

3.注意到 cURL 在处理请求时仍然打印了一些状态。我们可以使用-s标志来关闭这些状态

image-20250430234733870

4.-v在之前的命令中添加 verbose 标志,它就会同时打印请求和响应(-vvv可以更加详细)

image-20250501143813615

5.可以使用该-I标志发送HEAD请求并仅显示响应头。我们还可以使用该-i标志同时显示响应头和响应主体(例如 HTML 代码)。两者的区别在于,cURL-I发送HEAD请求,而 cURL-i发送我们指定的任何请求并打印响应头。

image-20250511164459665

6.使用-H标志设置请求标头。某些标头(例如User-AgentCookie标头)有自己的标志。例如,我们可以使用-A来设置我们的User-Agent

image-20250511164557873

又例如手动设置Authorization。我们可以使用-H标志设置标头,并将使用来自上述 HTTP 请求的相同值,可以-H多次添加标志以指定多个标头

image-20250511172353219

7..可以使用该-h标志来查看 cURL 还有哪些其他选项(可以使用--help all来打印更详细的帮助菜单,或者--help category(例如-h http)打印特定标志的详细帮助。如果我们需要阅读更详细的文档,可以使用man curl来查看完整的 cURL 手册页)

image-20250430234828031

超文本传输安全协议 (HTTPS)

HTTPS 流程

HTTP 到 HTTPS 通信图:用户请求 inlanefreight.com,接收 HTTP 301 重定向到 HTTPS,然后进行 TLS 握手和加密通信。

如果我们输入http://而不是https://来访问一个强制使用 HTTPS 的网站,浏览器会尝试解析域名并将用户重定向到托管目标网站的 Web 服务器。请求80首先发送到端口,这是未加密的 HTTP 协议。服务器检测到这种情况后,会将客户端重定向到安全的 HTTPS 端口443。这是通过301 Moved Permanently响应代码完成的

接下来,客户端(Web 浏览器)发送一个“客户端 hello”数据包,提供自身的相关信息。之后,服务器回复“服务器 hello”,并进行密钥交换以交换 SSL 证书。客户端验证密钥/证书后,再发送自己的密钥/证书。之后,发起加密握手,以确认加密和传输是否正常。

握手成功完成后,正常的 HTTP 通信将继续,之后的通信将被加密

HTTPS 的 cURL

1.cURL 应该自动处理所有 HTTPS 通信标准,执行安全握手,然后自动加密和解密数据。但是,如果我们访问的网站 SSL 证书无效或过期,cURL 默认不会继续进行通信,以防止前面提到的 MITM 攻击

image-20250501143228842

2.要跳过使用 cURL 的证书检查,我们可以使用以下-k标志

image-20250501143325798

浏览器开发者工具

。要在 Chrome 或 Firefox 中打开浏览器开发者工具,我们可以点击 [ CTRL+SHIFT+I] 或直接点击 [ F12]

选项Network卡,负责处理 Web 请求。

如果我们点击网络选项卡并刷新页面,我们应该能够看到页面发送的请求列表,还可以使用Filter URLs来搜索特定的请求,以防网站加载过多而无法处理。

“网络”选项卡显示对 188.166.146.97:31122 的两个 GET 请求。“/”的状态为 304,“favicon.ico”的状态为 404。