配置Mysql
sudo mysql -u root //第一次可以直接进入
alter user 'root'@'localhost' identified by '123456';
create database usr;
配置PHP
进入目录:cd /etc/php/8.2/apache2
执行:sudo vim +904 php.ini
将这行代码前面的注释去除:extension=mysqli
进入到目录:cd /var/www/html/
创建以下文件:vim TestConn.php
TestConn.php测试文件代码
<?php
// 启用错误报告
error_reporting(E_ALL);
ini_set('display_errors', 1);
// 数据库配置
$servername = "localhost";
$username = "root";
$password = "123456"; // 替换为实际密码,修改密码命令,alter user 'root'@'localhost' identified by '123456';
$dbname = "usr"; // 替换为实际数据库名,需要自己创建,命令,create database usr;
try {
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检查连接
if ($conn->connect_error) {
throw new Exception("连接失败: " . $conn->connect_error);
}
// 设置字符集
if (!$conn->set_charset("utf8mb4")) {
throw new Exception("字符集设置失败: " . $conn->error);
}
echo "MySQL连接成功!服务端版本: " . $conn->server_version;
// 关闭连接
$conn->close();
} catch (Exception $e) {
die("数据库错误: " . $e->getMessage());
}
?>
配置apache2服务器
进入目录:cd /etc/apache2/
修改文件:sudo vim +174 apache2.conf
直接添加以下内容
LoadModule php_module modules/libphp.so
测试
先执行这个DROP掉系统的RST包sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
from scapy.all import *
import random
import time
target_ip = "127.0.0.1"
target_port = 80
source_port = random.randint(1024, 65535)
ip = IP(dst=target_ip)
syn = ip / TCP(sport=source_port, dport=target_port, flags="S", seq=1000)
syn_ack = sr1(syn, timeout=2, verbose=0)
if not syn_ack or not syn_ack.haslayer(TCP):
print("未建立TCP连接。")
exit()
server_seq = syn_ack[TCP].seq
server_ack = syn_ack[TCP].ack
# 第三次握手
ack = ip / TCP(sport=source_port, dport=target_port, flags="A", seq=server_ack, ack=server_seq + 1)
send(ack, verbose=0)
# 构造HTTP请求
http_get = "GET /TestConn.php HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n"
http_payload = http_get.encode("UTF-8")
get_request = ip / TCP(sport=source_port, dport=target_port, flags="PA", seq=server_ack, ack=server_seq + 1) / http_payload
send(get_request, verbose=0)
# 接收所有响应数据段
response_data = b""
seq = server_ack
timeout = time.time() + 5 # 最多等待5秒
while time.time() < timeout:
pkt = sniff(filter=f"tcp and src host {target_ip} and port 80", count=1, timeout=1)
if not pkt:
continue
tcp = pkt[0][TCP]
if tcp.sport == target_port and tcp.dport == source_port and tcp.haslayer(Raw):
payload = bytes(tcp[Raw].load)
response_data += payload
# 发送ACK回执
ack_pkt = ip / TCP(sport=source_port, dport=target_port, flags="A",
seq=tcp.ack, ack=tcp.seq + len(payload))
send(ack_pkt, verbose=0)
# 打印HTTP响应
#if response_data:
# print("=== 服务器完整响应内容 ===")
# try:
# print(response_data.decode("utf-8", errors="ignore"))
# except Exception:
# print(response_data)
#else:
# print("未接收到HTTP响应数据。")
老师的http测试文件
from scapy.all import *
import random
target_ip = "172.17.15.200"
target_port = 80
ip = IP(dst=target_ip)
syn = ip / TCP(sport=1024, dport=target_port, flags="S", seq=1000)
syn_ack = sr1(syn, timeout=2, verbose=0)
server_seq = syn_ack[TCP].seq
server_ack = syn_ack[TCP].ack
ack = ip / TCP(sport=1024, dport=target_port, flags="A", seq=server_ack, ack=server_seq + 1)
send(ack, verbose=0)
http_get = "GET /TestConn.php HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n"
http_payload = http_get.encode('utf-8')
get_request = ip / TCP(sport=1024, dport=target_port, flags="PA", seq=server_ack, ack=server_seq + 1) /Raw(load=http_payload)
response = sr1(get_request, timeout=5, verbose=0)
大全套代码
#!/usr/bin/env python3
# scapy_http_capture.py
from scapy.all import *
import random
import time
import sys
target_ip = "127.0.0.1"
target_port = 80
path = "/TestConn.php"
source_port = random.randint(20000, 40000)
timeout_total = 8 # 最大等待秒数
def decode_chunked(data: bytes) -> bytes:
out = b""
i = 0
while True:
# 找到行结束
rn = data.find(b"\r\n", i)
if rn == -1:
break
line = data[i:rn].strip()
try:
size = int(line.split(b";",1)[0], 16)
except:
break
i = rn + 2
if size == 0:
# 跳过尾部可能的 trailer
# 找到最后的 \r\n\r\n
trailer_idx = data.find(b"\r\n\r\n", i)
return out
out += data[i:i+size]
i += size + 2 # 跳过 chunk-data 和 CRLF
return out
def assemble_payloads(payload_map, start_seq):
# payload_map: {seq: bytes}
if not payload_map:
return b""
seqs = sorted(payload_map.keys())
cur = seqs[0]
assembled = b""
for s in seqs:
p = payload_map[s]
if s > cur:
# 有 gap:填补不可见数据(跳过)
cur = s
if s < cur:
# 有重叠,从偏移处拼接
offset = cur - s
if offset < len(p):
assembled += p[offset:]
cur += len(p) - offset
else:
assembled += p
cur += len(p)
return assembled
def parse_http(raw: bytes):
# split headers / body
hdr_end = raw.find(b"\r\n\r\n")
if hdr_end == -1:
return None, raw
headers_raw = raw[:hdr_end].decode("iso-8859-1", errors="ignore")
body = raw[hdr_end+4:]
# parse status + headers
lines = headers_raw.split("\r\n")
status_line = lines[0]
headers = {}
for l in lines[1:]:
if ":" in l:
k, v = l.split(":", 1)
headers[k.strip().lower()] = v.strip()
# handle chunked
if headers.get("transfer-encoding","").lower() == "chunked":
body_decoded = decode_chunked(body)
else:
# respect content-length if present
body_decoded = body
return (status_line, headers), body_decoded
def main():
conf.verbose = 0
ip = IP(dst=target_ip)
syn = ip / TCP(sport=source_port, dport=target_port, flags="S", seq=1000)
print("[*] 发送 SYN,发起三次握手...")
syn_ack = sr1(syn, timeout=2, verbose=0)
if not syn_ack or not syn_ack.haslayer(TCP):
print("[-] 未收到 SYN-ACK,终止。")
sys.exit(1)
server_seq = syn_ack[TCP].seq
server_ack = syn_ack[TCP].ack
# 第三次握手 ACK
ack = ip / TCP(sport=source_port, dport=target_port, flags="A",
seq=server_ack, ack=server_seq + 1)
send(ack, verbose=0)
print("[+] 三次握手完成。")
# 发送 HTTP GET //如需要发送HEAD,把下面的GET改掉即可
http_get = f"GET {path} HTTP/1.1\r\nHost: {target_ip}\r\nConnection: close\r\nUser-Agent: scapy-test\r\n\r\n"
http_payload = http_get.encode("utf-8")
get_request = ip / TCP(sport=source_port, dport=target_port, flags="PA",
seq=server_ack, ack=server_seq + 1) / http_payload
print("[*] 发送 HTTP GET 请求 ->", path)
send(get_request, verbose=0)
# 捕获来自服务器的包,直到收到 FIN 或 超时
payload_map = {} # seq -> bytes
saw_fin = False
start_time = time.time()
print("[*] 开始 sniff 捕获来自服务器的数据包(显示 packet.show())...")
while True:
if time.time() - start_time > timeout_total:
print("[*] 超时,停止捕获。")
break
pkts = sniff(iface="lo",filter=f"tcp and src host {target_ip} and port {target_port}", count=1, timeout=1)
if not pkts:
continue
pkt = pkts[0]
# 实时展示包结构
print("\n--- 捕获到包,结构如下 ---")
pkt.show()
# 检查是否为目标方向与端口
if not pkt.haslayer(TCP):
continue
tcp = pkt[TCP]
# 只处理发送到我们 source_port 的回应
if tcp.dport != source_port:
continue
# 若有 Raw 层则收集载荷
if pkt.haslayer(Raw):
data = bytes(pkt[Raw].load)
payload_map[tcp.seq] = data
# 发送 ACK 回执给服务器(告诉服务器我们已收到)
ack_pkt = ip / TCP(sport=source_port, dport=target_port,
flags="A", seq=tcp.ack, ack=tcp.seq + len(data))
send(ack_pkt, verbose=0)
# 如果看到 FIN 或 RST 表示连接结束
if tcp.flags & 0x01 or tcp.flags & 0x04:
saw_fin = True
print("[*] 观察到 FIN/RST,连接结束信号。")
break
assembled = assemble_payloads(payload_map, None)
if not assembled:
print("[-] 未捕获到任何 HTTP 负载 (Raw)。")
print("提示:若在本机 loopback 上运行仍看不到数据,确保以 root 运行,或绑定实际网卡 IP 再试。")
sys.exit(0)
# 尝试解析 HTTP(头 + body)
parsed, body = parse_http(assembled)
print("\n=== 原始重组后的字节流(前 4096 字节展示) ===")
print(assembled[:4096].decode("utf-8", errors="ignore"))
if parsed is None:
print("\n[-] 无法解析 HTTP headers,直接输出 body(尝试 utf-8 解码):")
try:
print(body.decode("utf-8", errors="ignore"))
except:
print(body)
sys.exit(0)
status, headers = parsed
print("\n=== HTTP 状态行 ===")
print(status)
print("\n=== HTTP Headers ===")
for k, v in headers.items():
print(f"{k}: {v}")
print("\n=== HTTP Body (utf-8 解码,errors='ignore') ===")
try:
print(body.decode("utf-8", errors="ignore"))
except:
print(body)
if __name__ == "__main__":
main()
效果图
需要打开lo接口
浏览器

wireshark

浙公网安备 33010602011771号