3. HTTP协议安全测试基础

好,咱们进入正题。数据采集,说白了就是跟服务器“对话”。你发个请求,它回个响应。就这么简单?嗯,但里面的门道可不少。

我个人习惯,在开始任何安全测试之前,先搞清楚目标网站的“语言”。这个语言就是HTTP协议。你连它怎么说话都听不懂,怎么找漏洞?

3.1 HTTP请求与响应:你问它答

HTTP请求,就像你敲门。你得告诉服务器:你要干嘛(方法),找谁(URL),带什么礼物(Headers),以及有没有小纸条(Body)。

响应呢,就是服务器开门后的反应:状态码告诉你“我在家”还是“滚远点”,Headers告诉你它家有什么规矩,Body就是它给你的东西。

一个典型的请求长这样:

POST /login HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Cookie: sessionid=abc123

username=admin&password=123456

响应呢,大概是这样:

HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: sessionid=def456; Path=/

<html>...</html>

我在项目中遇到过,很多新手只盯着Body看,忽略了Headers。其实Headers里藏着大量信息——服务器类型、认证方式、甚至安全策略。你想想看,一个X-Frame-Options: DENY就告诉你这页面防点击劫持,多重要的线索。

核心要点:

  • 请求方法:GET(拿数据)、POST(交数据)、PUT(改数据)、DELETE(删数据)
  • 状态码:2xx成功、3xx重定向、4xx客户端错、5xx服务器错
  • Headers:User-Agent、Cookie、Content-Type、Referer 是重点关注对象

3.2 使用Requests库抓取页面:Python的瑞士军刀

Python的requests库,我用了快十年了。它把复杂的HTTP操作简化成了几行代码。说白了,就是让你用Python写“浏览器”的行为。

安装很简单:

pip install requests

最基本的用法:

import requests

# 发个GET请求
response = requests.get('https://example.com')
print(response.status_code)  # 200
print(response.text)         # HTML内容

# 带参数的GET
params = {'keyword': '安全测试', 'page': 1}
response = requests.get('https://example.com/search', params=params)
print(response.url)  # 自动拼接参数

嗯,这里要注意。我刚开始用的时候,经常忘记处理异常。网络请求嘛,随时可能超时或断开。所以,我建议你养成好习惯:

try:
    response = requests.get('https://example.com', timeout=5)
    response.raise_for_status()  # 检查状态码
except requests.exceptions.Timeout:
    print('请求超时了,换个代理试试?')
except requests.exceptions.HTTPError as e:
    print(f'服务器返回了错误:{e}')

我的小技巧:

抓取前先设置User-Agent。很多服务器会拦截默认的Python-requests。我一般用Chrome的UA字符串,伪装成正常浏览器。

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.get(url, headers=headers)

3.3 处理Cookies和Session:保持“登录状态”

为什么需要Session?因为HTTP是无状态的。服务器记不住你是谁。你每次请求都得证明“我是我”。Cookies就是你的身份证。

我曾经踩过一个坑:手动从响应头里提取Cookie,再拼到下一个请求里。又麻烦又容易出错。后来发现,requests.Session自动帮你干这事。

用Session对象:

session = requests.Session()

# 第一次请求:登录
login_data = {'username': 'admin', 'password': 'secret'}
response = session.post('https://example.com/login', data=login_data)

# 第二次请求:自动携带Cookie
response = session.get('https://example.com/dashboard')
# 服务器会认为你已经登录了

为什么会这样?因为Session对象内部维护了一个CookieJar。你第一次请求返回的Set-Cookie,它会自动存起来。后续所有请求,自动带上这些Cookie。

手动操作Cookie也不难:

# 获取Cookie
cookies = session.cookies.get_dict()
print(cookies)  # {'sessionid': 'abc123'}

# 设置自定义Cookie
session.cookies.set('token', 'my_custom_token')

# 或者直接传参
response = requests.get(url, cookies={'sessionid': 'abc123'})

避坑指南:

我曾经遇到过,某些网站会校验Cookie的Domain和Path。你用Session对象时,它会自动处理。但如果你手动设置Cookie,一定要检查Domain是否匹配。否则服务器会直接忽略你的Cookie,返回302让你重新登录。

3.4 实战:抓取一个需要登录的页面

咱们来点实际的。假设你要抓取某个论坛的“我的帖子”页面。这页面必须登录后才能看。

完整流程:

import requests

session = requests.Session()
session.headers.update({
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
})

# 第一步:获取登录页,可能有个CSRF Token
login_page = session.get('https://forum.example.com/login')
# 假设你用正则或BeautifulSoup提取token
# csrf_token = extract_token(login_page.text)

# 第二步:提交登录表单
login_data = {
    'username': 'test_user',
    'password': 'test_pass',
    # 'csrf_token': csrf_token  # 如果有的话
}
response = session.post('https://forum.example.com/login', data=login_data)

# 检查是否登录成功
if '欢迎回来' in response.text:
    print('登录成功!')

# 第三步:访问需要登录的页面
my_posts = session.get('https://forum.example.com/my-posts')
print(my_posts.text)

关键点总结:

组件 作用 我的建议
Session对象 自动管理Cookie 所有需要登录的请求都用它
Headers 伪装成浏览器 至少设置User-Agent和Referer
异常处理 防止程序崩溃 try-except是标配
CSRF Token 防止跨站请求伪造 先GET获取,再POST提交

嗯,到这里,数据采集的基础你已经掌握了。说白了就是三步:发请求、收响应、管好Cookie。下一章咱们会深入解析HTML,从响应里提取真正有用的数据。

记住,安全测试的第一步,就是能像浏览器一样跟服务器对话。你连对话都做不到,怎么发现它说话时的漏洞?

额外提醒:

抓取频率别太快。我见过有人1秒发100个请求,结果IP直接被封了。加个time.sleep(1),对大家都好。