I am trying to create a raw socket using jnetpcap jar files to do IP spoofing in java using UDP protocol. When I tried the below code, I got a null pointer exception in object creation for the udp header. I decompiled the class files in the jar files to understand the problem but ended up in native method call in my back-trace. Help me to find the reason for this error.
need to execute only in Administrator mode in cmd.
Compiling command in cmd:
javac -cp .;"C:\Users\kabilan-pt2837\eclipse-workspace\Study\jnetpcap\jnetpcap.jar" -Xlint RawUdpPacketSender.java
execution command in cmd:
java -cp .;"C:\Users\kabilan-pt2837\eclipse-workspace\Study\jnetpcap\jnetpcap.jar" -Djava.library.path=%JNETPCAP_HOME% RawUdpPacketSender
Where %JNETPCAP_HOME% is an environmental variable pointing the location of the jar and dll files of JNETPCAP
Code in JAVA:
RawUdpPacketSender.java
import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jnetpcap.Pcap;
import org.jnetpcap.PcapIf;
import org.jnetpcap.packet.JMemoryPacket;
import org.jnetpcap.packet.JPacket;
import org.jnetpcap.protocol.JProtocol;
import org.jnetpcap.protocol.lan.Ethernet;
import org.jnetpcap.protocol.network.Ip4;
import org.jnetpcap.protocol.tcpip.Udp;
public class RawUdpPacketSender {
private static Logger logger = Logger.getLogger(RawUdpPacketSender.class.getName());
private Pcap pcap = null;
private int headerLength = getHeaderLength();
private int UDP_SOURCE_PORT = 9091;
private byte[] sourceMacAddress;
private byte[] destinationMacAddress;
public RawUdpPacketSender() {
String macAddress = System.getProperty("gateway_mac_address", "");
//Destination MAC address needs to be configured. This can be retrieved using ARP, but it's not easy
destinationMacAddress = hexStringToByteArray(macAddress);
try {
pcap = createPcap();
} catch (IOException e) {
logger.log(Level.SEVERE, "Failed to start pcap library.", e);
}
}
public void sendPacket(URI destination, byte[] packet)
throws IOException {
int port = destination.getPort();
InetAddress address = InetAddress.getByName(destination.getHost());
byte[] destinationAddress = address.getAddress();
System.out.println(port+" "+address.getHostAddress());
sendPacket(destinationAddress, port, packet);
}
private Pcap createPcap() throws IOException {
PcapIf device = getPcapDevice();
if (device == null) {
return null;
}
sourceMacAddress = device.getHardwareAddress(); //Use device's MAC address as the source address
StringBuilder errorBuffer = new StringBuilder();
int snapLen = 64 * 1024;
int flags = Pcap.MODE_NON_PROMISCUOUS;
int timeout = 10 * 1000;
Pcap pcap = Pcap.openLive(device.getName(), snapLen, flags, timeout,
errorBuffer);
if (logger.isLoggable(Level.INFO)) {
logger.info(String.format("Pcap starts for device %s successfully.", device));
}
return pcap;
}
private PcapIf getPcapDevice() {
List<PcapIf> allDevs = new ArrayList<PcapIf>();
StringBuilder errorBuffer = new StringBuilder();
int r = Pcap.findAllDevs(allDevs, errorBuffer);
if (r == Pcap.NOT_OK || allDevs.isEmpty()) {
logger.log(Level.SEVERE, String.format("Can't read list of devices, error is %s",
errorBuffer.toString()));
return null;
}
String deviceName = System.getProperty("raw_packet_network_interface", "eth0");
for (PcapIf device : allDevs) {
if (deviceName.equals(device.getName())) {
return device;
}
}
return allDevs.get(0);
}
private int getHeaderLength() {
return 14 + 20 + 8; //Ethernet header + IP v4 header + UDP header
}
private void sendPacket(byte[] destinationAddress, int port, byte[] data) throws IOException {
int dataLength = data.length;
int packetSize = headerLength + dataLength;
JPacket packet = new JMemoryPacket(packetSize);
packet.order(ByteOrder.BIG_ENDIAN);
packet.setUShort(12, 0x0800);
packet.scan(JProtocol.ETHERNET_ID);
Ethernet ethernet = packet.getHeader(new Ethernet());
ethernet.source(sourceMacAddress);
ethernet.destination(destinationMacAddress);
ethernet.checksum(ethernet.calculateChecksum());
//IP v4 packet
packet.setUByte(14, 0x40 | 0x05);
packet.scan(JProtocol.ETHERNET_ID);
Ip4 ip4 = packet.getHeader(new Ip4());
ip4.type(Ip4.Ip4Type.UDP);
ip4.length(packetSize - ethernet.size());
byte[] sourceAddress = InetAddress.getLocalHost().getAddress();
ip4.source(sourceAddress);
ip4.destination(destinationAddress);
ip4.ttl(32);
ip4.flags(0);
ip4.offset(0);
ip4.checksum(ip4.calculateChecksum());
//UDP packet
packet.scan(JProtocol.IP4_ID);
Udp udp = packet.getHeader(new Udp());
// This is where I'm getting the null pointer exception
System.out.println(udp);
udp.source(UDP_SOURCE_PORT);
udp.destination(port);
udp.length(packetSize - ethernet.size() - ip4.size());
udp.checksum(udp.calculateChecksum());
packet.setByteArray(headerLength, data);
packet.scan(Ethernet.ID);
if (pcap.sendPacket(packet) != Pcap.OK) {
throw new IOException(String.format(
"Failed to send UDP packet with error: %s", pcap.getErr()));
}
}
private byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character
.digit(s.charAt(i + 1), 16));
}
return data;
}
public static void main(String[] args) throws IOException {
RawUdpPacketSender sender = new RawUdpPacketSender();
byte[] packet = "Hello".getBytes();
URI destination = URI.create("udp://192.168.159.192:9090");
System.out.println(destination+" "+packet);
sender.sendPacket(destination, packet);
}
}
Result obtained while executing the about program in cmd in administrator mode:
Apr 08, 2019 12:15:41 PM RawUdpPacketSender createPcap
INFO: Pcap starts for device <flags=0, addresses=[[addr=[INET6:FE80:0000:0000:0000:B825:ACBF:F18D:9FE9], mask=[0], broadcast=[0], dstaddr=null], [addr=[INET6:FE80:0000:0000:0000:B825:ACBF:F18D:9FE9], mask=[0], broadcast=[0], dstaddr=null]], name=\Device\NPF_{E7240CA2-66F1-42D6-9ECE-AE7BF28010E4}, desc=Microsoft> successfully.
udp://192.168.159.192:9090 [B@27bc2616
9090 192.168.159.192
null
Exception in thread "main" java.lang.NullPointerException
at RawUdpPacketSender.sendPacket(RawUdpPacketSender.java:118)
at RawUdpPacketSender.sendPacket(RawUdpPacketSender.java:44)
at RawUdpPacketSender.main(RawUdpPacketSender.java:145)