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),对大家都好。