Kali 1 17.128
先DROP sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
代码
from scapy.all import *
import random
# 第一部分:DNS查询获取IP地址
pkt1 = IP(dst="192.168.17.129")/UDP(sport=12345, dport=53)/DNS(id=1000, qr=0, rd=1, qd=DNSQR(qname="www.hxl.com"))
# 发送请求+等回包
ans1 = sr1(pkt1, timeout=5, verbose=0)
if not ans1 or not ans1.haslayer(DNS) or not ans1[DNS].an:
print("DNS查询失败")
exit()
# 看回包
ans1.show()
# 提取解析结果到baidu变量中
baidu = ans1[DNS].an[0].rdata
print(f"DNS解析结果: www.hxl.com -> {baidu}")
# 使用DNS解析的地址作为目标
target = str(baidu) # 确保是字符串类型
dport = 8000 # HTTP默认端口
sport = random.randint(1024, 65535)
print(f"开始与 {target}:{dport} 建立TCP连接...")
# 1. 发送SYN包(第一次握手)
syn = IP(dst=target)/TCP(sport=sport, dport=dport, flags='S', seq=1000)
print("发送SYN包...")
syn_ack = sr1(syn, timeout=5, verbose=0)
if not syn_ack:
print("SYN-ACK 未收到,连接失败")
exit()
print("收到SYN-ACK包")
# 记录服务器序列号
server_seq = syn_ack.seq
server_ack = syn_ack.ack
# 2. 发送ACK包(第三次握手)
ack = IP(dst=target)/TCP(sport=sport, dport=dport, flags='A', seq=server_ack, ack=server_seq + 1)
print("发送ACK包完成三次握手...")
send(ack, verbose=0)
print("TCP 连接建立成功")
# 3. 发送HTTP GET请求
# HTTP请求发送到DNS解析的目标地址,Host头使用域名
http_get = f"GET / HTTP/1.1\r\nHost: www.hxl.com\r\nUser-Agent: Scapy-HTTP-Client/1.0\r\nConnection: close\r\n\r\n"
http_payload = http_get.encode('utf-8')
print("发送HTTP GET请求...")
pack3 = IP(dst=target) / TCP(sport=sport, dport=dport, flags="PA", seq=server_ack, ack=server_seq + 1) / Raw(load=http_payload)
response = sr1(pack3, timeout=10, verbose=0)
if response:
print("收到HTTP响应:")
response.show()
# 提取HTTP响应内容
if response.haslayer(Raw):
http_response = response[Raw].load.decode('utf-8', errors='ignore')
print("\nHTTP响应内容:")
print("=" * 50)
# 只打印前1000个字符避免输出过长
print(http_response[:1000] + "..." if len(http_response) > 1000 else http_response)
print("=" * 50)
else:
print("未收到HTTP响应")
# 4. 发送FIN包关闭连接(可选)
print("发送FIN包关闭连接...")
fin = IP(dst=target)/TCP(sport=sport, dport=dport, flags='FA', seq=server_ack + len(http_payload), ack=server_seq + 1)
fin_ack = sr1(fin, timeout=5, verbose=0)
if fin_ack:
# 回复最后的ACK
final_ack = IP(dst=target)/TCP(sport=sport, dport=dport, flags='A', seq=fin_ack.ack, ack=fin_ack.seq + 1)
send(final_ack, verbose=0)
print("连接正常关闭")
else:
print("连接关闭超时")
print("程序执行完毕")
Kali2 17.129
-
先启动Python的Web服务器
python -m http.server 8000在8000端口启动web服务器 -
启动Python代码监听53端口
from scapy.all import *
import socket
# 1. 占用53端口(需root权限)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('0.0.0.0', 53))
print("B机:Listening on UDP port 53 ...")
while True:
data, addr = sock.recvfrom(1024) # 接收A机的DNS查询
client_ip, client_port = addr
# 解析查询的DNS事务ID和域名
dns_query = DNS(data)
query_id = dns_query.id
query_domain = dns_query.qd.qname.decode() # 提取查询的域名,如www.张三.com
# 2. 构造DNS响应:解析到B机自身IP,TTL为1000+学号
ttl = 1000 + 17 # 假设学号是123,需替换为自己的学号
resp = IP(dst=client_ip) / UDP(sport=53, dport=client_port) / DNS(
id=query_id, # 与查询ID保持一致
qr=1, # 1表示响应
aa=1, rd=1, ra=1,
qd=DNSQR(qname=query_domain), # 匹配查询的域名
an=DNSRR(
rrname=query_domain,
type="A",
ttl=ttl,
rdata="192.168.17.129" # B机自身IP
)
)
send(resp) # 发送响应
浙公网安备 33010602011771号