Skip to content

Commit

Permalink
Implement macgonuts_pybind
Browse files Browse the repository at this point in the history
This commit implements python binds for macgonuts_spoof() and
macgonuts_undo_spoof() functions. Besides implementing build automation
for building this bind (--with-pybind/Hefesto or with-pybind/GNUMake).

It adds some documentation about it. Building and usage.
  • Loading branch information
rafael-santiago committed Sep 2, 2023
1 parent 578b68d commit 6f58a75
Show file tree
Hide file tree
Showing 12 changed files with 394 additions and 24 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@
*.Forgefile-*
*.o/
coverage.info
**/binds/py/*.so
**/binds/py/macgonuts.c
**/binds/py/build
86 changes: 86 additions & 0 deletions doc/BINDS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Macgonuts binds

**Abstract**: This document is intended to explain how to use the available `macgonuts` binds.
Details about how to build is not discussed here, take a look at `doc/BUILD.md`.

## Topics

- [What is available until now](#what-is-available-until-now)
- [Using `macgonuts_pybind`](#using-macgonuts_pybind)

## What is available until now

Currently it is only available two function that acts as basic building blocks for managing
spoofing attacks.

Those two function are:

- `macgonuts_spoof()`
- `macgonuts_undo_spoof()`

By using those two functions through the binds, you will be able to easily implement the
spoof stuff at your own program natively without depeding on `macgonuts` command line tool.

Until now `macgonuts` features binds for `Python`.

[``Back``](#topics)

## Using `macgonuts_pybind`

Once it build and well-installed, it is fairly simple to use `macgonuts_pyind` module.
The functions present in this module are:

- `macgonuts_spoof()`
- `macgonuts_undo_spoof()`

The `macgonuts_spoof()` function can receive five arguments:

- `lo_iface` is the name of the interface you are accessing the network.
- `target_addr` is the network address of the target, it can be a `IPv4` or `IPv6` address.
- `addr2spoof` is the address that will be spoofed at target, it can be a `IPv4` or `IPv6` address.
- `fake_pkts_amount` is the total of spoofed packets sent to target, it defaults to one.
- `timeout` is the timeout in `mss` between a spoofed packet and the next, it defauts to no timeout.

The `macgonuts_undo_spoof()` undoes a previous promoted spoof attack against a specific target.
This function expects three arguments:

- `lo_iface` is the name of the interface you are accessing the network.
- `target_addr` is the network address of the target, it can be a `IPv4` or `IPv6` address.
- `addr2spoof` is the address that was spoofed at target, it can be a `IPv4` or `IPv6` address.

Follows the general idea when using `macgonuts` spoofing primitives from `Python`:

```python
import macgonuts_pybind

(...)

# INFO(Rafael): Send one fake ARP packet to 192.168.5.142.
if macgonuts_pybind.macgonuts_spoof('eth0', '192.168.5.142', '192.168.5.1') != 0:
print('error when trying to spoof.\n');
(...)

(...)

# INFO(Rafael): Send 200 fake NDP packets to dead::beef:1 at each 500 mss.
if macgonuts_pybind.macgonuts_spoof('eth1',
'dead::beef::8e',
'dead::beef:1', 200, 500) != 0:
print('error when trying to spoof.\n');
(...)

(...)

# INFO(Rafael): Now undoing all promoted spoofing attacks.
if macgonuts_undo_spoof('eth0', '192.168.5.142', '192.168.5.1') != 0:
print('unable to undo spoof attack done from eth0')
(...)

if macgonuts_undo_spoof('eth1', 'dead::beef:8e', 'dead::beef:1') != 0:
print('unable to undo spoof attack done from eth1')
(...)

(...)
```

[``Back``](#topics)
36 changes: 36 additions & 0 deletions doc/BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ fresh ``macgonuts`` binary to get your stuff done, you can give ``the low-cost b
- [List of all build options](#list-of-all-build-options)
- [Installing the command line tool](#installing-the-command-line-tool)
- [Building the debian package](#building-the-debian-package)
- [Building the binds](#building-the-binds)
- [pybind](#pybind)

## Getting newest macgonuts source code revision

Expand Down Expand Up @@ -243,3 +245,37 @@ you@somewhere-over-the-rainbow:~/macgonuts/src# make deb
```

[``Back``](#topics)

## Building the binds

In this part you can find instructions about how to build the available ``macgonuts`` binds.

[``Back``](#topics)

### pybind

The ``Macgonuts`` ``Python`` bind depends on ``cython``, so in order to install it you can use the following:

```
you@somewhere-over-the-rainbow:~/macgonuts/src# pip install cython
```

Done! Now is time to actually build ``macgonuts_pybind``.

By using the ``developer's`` build and being into ``src`` sub-directory, you need to invoke ``Hefesto`` passing
the option ``--with-pybind``:

```
you@somewhere-over-the-rainbow:~/macgonuts/src# hefesto --with-pybind
```

When using the ``low-cost`` build you also need to be into ``src`` sub-directory and call ``make`` defining the
build parameter ``with-pybind``:

```
you@somewhere-over-the-rainbow:~/macgonuts/src# make with-pybind
```

The ``python`` bind artifacts will be built into ``src/binds/py``.

[``Back``](#topics)
41 changes: 22 additions & 19 deletions doc/CodeOrganization.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ This is the current repo layout:
| +-- ...
+-- src/
| +-- Forgefile.hsl
| +-- ...
| | +-- ...
| +-- binds/
| | +-- ...
| +-- build/
| +-- toolsets.hsl
| +-- cmd/
Expand Down Expand Up @@ -66,24 +68,25 @@ This is the current repo layout:
In order to know more details about each directory level take a look at **Table 1**.

**Table 1**: Directory levels overview.
| **Directory level** | **Here goes** |
|:----------------------:|:------------------------------------------------:|
| toplevel | Main configuration and information files |
| ``.github`` | Files related to github configuration |
| ``.github/workspaces`` | Configuration of ``CI`` stuff |
| ``doc`` | More specific documentation |
| ``doc/man1`` | ``Macgonuts`` tool man page |
| ``etc`` | Miscellaneous stuff |
| ``src`` | Main source (library) |
| ``src/build`` | Build conveniences stuff |
| ``src/cmd`` | Command line tool source code |
| ``src/cmd/hooks`` | Source code for task hooks of ``CLI`` tool |
| ``src/cmd/test`` | Tests for the ``CLI`` tool |
| ``src/freebsd`` | ``FreeBSD`` native code of main source (library) |
| ``src/libs`` | All dependencies used by ``Macgonuts`` code |
| ``src/linux`` | ``Linux`` native code of main source (library) |
| ``src/test`` | Tests for the library |
| ``src/unix`` | Common ``UNIX-like`` codes |
| **Directory level** | **Here goes** |
|:----------------------:|:---------------------------------------------------:|
| toplevel | Main configuration and information files |
| ``.github`` | Files related to github configuration |
| ``.github/workspaces`` | Configuration of ``CI`` stuff |
| ``doc`` | More specific documentation |
| ``doc/man1`` | ``Macgonuts`` tool man page |
| ``etc`` | Miscellaneous stuff |
| ``src`` | Main source (library) |
| ``src/binds`` | ``Macgonuts`` binds for other programming languages |
| ``src/build`` | Build conveniences stuff |
| ``src/cmd`` | Command line tool source code |
| ``src/cmd/hooks`` | Source code for task hooks of ``CLI`` tool |
| ``src/cmd/test`` | Tests for the ``CLI`` tool |
| ``src/freebsd`` | ``FreeBSD`` native code of main source (library) |
| ``src/libs`` | All dependencies used by ``Macgonuts`` code |
| ``src/linux`` | ``Linux`` native code of main source (library) |
| ``src/test`` | Tests for the library |
| ``src/unix`` | Common ``UNIX-like`` codes |

[``Back``](#topics)

Expand Down
7 changes: 4 additions & 3 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

This directory is aimed to more specific documentation. Get your destiny below:

- Do you are wanting to build ``Macgonuts``? Read [BUILD.md](BUILD.md).
- Do you are wanting to learn how to use ``Macgonuts``? Read [MANUAL.md](MANUAL.md).
- Do you are wanting to start coding some stuff? Read [CodeOrganization.md](CodeOrganization.md) and [Codingstyle.md](Codingstyle.md).
- Are you wanting to build ``Macgonuts``? Read [BUILD.md](BUILD.md).
- Are you wanting to learn how to use ``Macgonuts``? Read [MANUAL.md](MANUAL.md).
- Are you wanting to start coding some stuff? Read [CodeOrganization.md](CodeOrganization.md) and [Codingstyle.md](Codingstyle.md).
- Are you wanting to use ``Macgonuts`` spoofing building blocks into your own stuff? Read [BINDS.md](BINDS.md).
12 changes: 11 additions & 1 deletion src/Forgefile.hsl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ macgonuts-static-lib.prologue() {

$includes = hefesto.sys.get_option("includes");
$cflags = hefesto.sys.get_option("cflags");
var option type list;
$option = hefesto.sys.get_option("with-pybind");
if ($option.count() > 0) {
# INFO(Rafael): It is necessary to build macgonuts_pybind .so stuff.
$cflags.add_item("-fPIC");
}
$libraries = hefesto.sys.get_option("libraries");
$ldflags = hefesto.sys.get_option("ldflags");

Expand Down Expand Up @@ -71,8 +77,12 @@ macgonuts-static-lib.epilogue() {
var subprojects type list;
$subprojects.add_item("test");
$subprojects.add_item("cmd");
var option type list;
$option = hefesto.sys.get_option("with-pybind");
if ($option.count() > 0) {
$subprojects.add_item("pybind");
}
if (build_projects($subprojects) == 0) {
var option type list;
$option = hefesto.sys.get_option("coverage");
if ($option.count() > 0) {
var report_path type string;
Expand Down
13 changes: 12 additions & 1 deletion src/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ NATIVE_SRC = $(shell uname -s | tr '[:upper:]' '[:lower:]')
LDFLAGS=-lpthread -laccacia
CFLAGS=-Ilibs/accacia/src -I.

LIBACCACIA_CFLAGS=

ifdef with-pybind
CFLAGS += -fPIC
LIBACCACIA_CFLAGS += -fPIC
endif

SOURCES := $(wildcard *.c)
SOURCES += $(wildcard unix/*.c)
SOURCES += $(wildcard $(NATIVE_SRC)/*.c)
Expand All @@ -24,12 +31,16 @@ MACGONUTS_SHARE_DIR = /usr/local/share/macgonuts

all: setup build_accacia $(BINARY)
cd cmd && $(MAKE)
ifdef with-pybind
ar -r $(LIBDIR)/libmacgonutssock.a
cd binds/py && rm -rf build && rm -f macgonuts.c && python setup.py build_ext --inplace
endif

setup:
@mkdir -p .o

build_accacia:
cd libs/accacia/src && $(CC) -I. -c accacia.c && mkdir -p ../lib &&\
cd libs/accacia/src && $(CC) -I. -c accacia.c $(LIBACCACIA_CFLAGS) && mkdir -p ../lib &&\
$(AR) -r ../lib/libaccacia.a accacia.o && rm accacia.o && cd ../../..

$(BINARY): $(OBJDIR)/$(OBJECTS)
Expand Down
53 changes: 53 additions & 0 deletions src/binds/py/macgonuts.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#
# Copyright (c) 2023, Rafael Santiago
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
#

""" Macgonuts general spoofing utilities binds for Python """

cdef extern from "macgonuts_pybind.h":
int macgonuts_pybind_spoof(char *lo_iface, char *target_addr, char *addr2spoof,
int fake_pkts_amount, int timeout);

cdef extern from "macgonuts_pybind.h":
int macgonuts_pybind_undo_spoof(char *lo_iface, char *target_addr, char *addr2spoof);

def macgonuts_spoof(lo_iface, target_addr, addr2spoof, fake_pkts_amount = 1, timeout = 0):
"""The python wrapper for macgonuts_spoof() C function
By using this function you can easily promote a spoofing attack based on IPv4 or IPv6.
This function receives:
- the local interface label (lo_iface)
- the target IPv4/IPv6 address (target_addr)
- the IPv4/IPv6 address which will be spoofed at the target host (addr2spoof)
- the amount of fake address resolution packets to be sent (fake_pkts_amount, its default is one packet only)
- the timeout amount between the current packet and the next (timeout, its default is no timeout)
It returns zero on success and non-zero value on failure, besides writing some error description to stderr.
"""
return macgonuts_pybind_spoof(bytes(lo_iface, 'ascii'),
bytes(target_addr, 'ascii'),
bytes(addr2spoof, 'ascii'),
fake_pkts_amount, timeout)

def macgonuts_undo_spoof(lo_iface, target_addr, addr2spoof):
"""The python wrapper for macgonuts_undo_spoof() C function
By using this function you can easily undo a previous promoted spoofing attack based on IPv4 or IPV6.
This function receives:
- the local interface used during the spoofing attack (lo_iface)
- the target IPv4/IPv6 address of the spoofing attack (target_addr)
- the IPv4/IPv6 address which was spoofed at the target host (addr2spoof)
It returns zero on success and non-zero value on failure, besides writing some error description to stderr.
"""
return macgonuts_pybind_undo_spoof(bytes(lo_iface, 'ascii'),
bytes(target_addr, 'ascii'),
bytes(addr2spoof, 'ascii'))
Loading

0 comments on commit 6f58a75

Please sign in to comment.