Before version 3.0, the evillimiter-ng code was too monolithic, and using it as a library was very hard and a bad idea, you had to import the MainMenu and pass fake arguments to it, the result?: unclear visual elements spamming the terminal and a lot of code fragmented in various functions, without a centralized API.
Now, in version 3.0, ENG has a clear and simple API, that can be used in your own scripts or big projects, with options to see or hide visual elements, automatically resolve the network data, and more, this documentation shows the basic usage of each function or class.
This is a very simple, but useful, example:
from evillimiter_ng.lib import manager
myeng = manager.CoreLimiter() # Create a CoreLimiter manager
myeng.add("IP_TO_BLOCK") # Replace 'IP_TO_BLOCK' with a real IP from your network
myeng.block(0) # Block the host with id #0, there is only one host in this example
input("Press enter to free the host...")
myeng.free("all") # Free all the spoofed hosts
print("Done!")
myeng.interrupt() # IMPORTANT: Clean all evillimiter-ng firewall rules and stop the scanners.
This small script assumes a "perfect" environment, where all network data will be resolved correctly and no errors will occur. However, the CoreLimiter class includes parameters that the user can pass in case a value cannot be resolved automatically. Keep in mind that if you distribute a program with fixed values, this may cause incompatibilities between devices.
This section shows the parameters you can pass to the CoreLimiter class and how its behavior varies depending on certain possible values.
from evillimiter_ng.lib.errors import EnvnetError
from evillimiter_ng.lib.manager import CoreLimiter
try:
cl = CoreLimiter(
interface = None,
gateway_ip = None,
gateway_mac = None,
netmask = None,
verify_vars = True,
auto_initialize = True,
auto_stop = True,
show_io = False,)
except EnvnetError as e:
print(e)
As you can see, by default, the values for interface gateway_ip
gateway_mac and netmask are None. This might seem like a problem that
would cause a fatal error; however, the verify_vars setting, which is set to true by
default, ensures that during class initialization, evillimiter-ng attempts to resolve these values.
You can even pass just one value as the netmask and set verify_vars to true so that it
only checks for missing values. This is useful for ensuring functionality across different environments and
network hardware; however, if the library cannot obtain a value and that value was not specified, an
EnvnetError is raised.
If you set verify_vars to False and do not pass any network data, errors such as
TypeError or others will
occur during execution.
auto_initialize tells CoreLimiter to start the programs necessary for the library to run—such as
tc and
nftables—on its own, as well as to verify whether the program is running on Linux and as root. When
this
variable is set to False, you must initialize it manually before running any other components.
from evillimiter_ng.lib.envnet import get_default_interface, initialize
from evillimiter_ng.lib.errors import UnsupportedSystem
from evillimiter_ng.lib.manager import CoreLimiter
try:
initialize(get_default_interface())
except (PermissionError, UnsupportedSystem) as e:
print(e)
cl = CoreLimiter(auto_initialize=False)
If your system isn't running Linux, the error evillimiter_ng.lib.errors.UnsupportedSystem occurs,
and if you
run it without root privileges, the standard Python PermissionError occurs.
Just like auto_initialize, if you set auto_stop to False, you must
manually execute the function needed to
stop the library's internal components once your own scripts have finished running.
from evillimiter_ng.lib.envnet import get_default_interface, stop_eng
from evillimiter_ng.lib.manager import CoreLimiter
cl = CoreLimiter(auto_stop=False)
cl.interrupt() # with auto_stop=False, this only stops the scanners and spoofers
stop_eng(get_default_interface())
By default, this variable is set to False, which hides the terminal messages generated by the program. If you set it to True, you can avoid having to type your own messages, but they will be in English.
Only a few of CoreLimiter's methods are intended for use in custom scripts, and those are the ones that will be explained here; the rest are for internal use only or for use in the MainMenu class, which is not part of the library.
These methods are based on the familiar CLI commands. Here, we show the definitions, required values, or those that already have a default value and are optional. Consult the evillimiter-ng CLI help or see the README to learn what each command (or, in this case, function) does. If a function differs significantly from its CLI command, the necessary explanation will be provided in this guide.
Other methods that have already been explained—such as interrupt—will not be mentioned again here.
cl.scan(ip_range = None, intensity = "2", transient = True) -> list[Host] | None
The only notable difference between this method and the CLI command is the transient parameter. In
the
CLI, the scan is always non-transient (False). In the
library, it defaults to True, meaning no progress bar is maintained and the method simply returns
the
list of discovered hosts. Set it to False if you want the scan to print the progress bar to the
terminal
cl.block(hid: str | int, upload: str | None = None, download: str | None = None) -> bool
cl.free(hid: str | int) -> bool
cl.limit(hid: str, rate: str | BitRate, upload: str | None = None, download: str | None = None) -> bool
This method is very similar to the CLI command, with one key difference: the rate parameter accepts
not only a rate string like "100kbit" or "1gbit", but also a BitRate
object
from evillimiter_ng.networking.utils. This is useful if you are building the rate value
programmatically. The upload and download flags work the same as in the CLI.
Returns True on success, False otherwise.
cl.add(ip: str, mac: str | None = None, name: str | None = None) -> bool
Similar to the CLI add command, with an additional optional name parameter. In the CLI,
the
hostname is resolved automatically via DNS; here, if name is not provided, it also attempts to
resolve the hostname automatically. If mac is omitted, it is resolved via ARP.
Returns True on success, False otherwise.
cl.export_json(json_path: str | Path) -> bool
cl.import_json(json_path: str | Path) -> bool
Some CLI functions have not yet been implemented in the library; they may be implemented in future versions if
the need arises beyond the tables generated by certain commands. Other commands simply will not be implemented
in the library, such as sleep, which can be used in Python with the standard time
library, or clear, which
can be called via subprocess.run, which is also part of the standard library.