macspoofer 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,73 @@
1
+ name: MacSpoofer CI
2
+
3
+ on:
4
+ push:
5
+ branches: [dev, master]
6
+ pull_request:
7
+ branches: [dev, master]
8
+
9
+ jobs:
10
+ lint:
11
+ name: Lint & Format
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.11"
21
+
22
+ - name: Install ruff
23
+ run: pip install ruff
24
+
25
+ - name: Run ruff lint
26
+ run: ruff check .
27
+
28
+ - name: Run ruff format check
29
+ run: ruff format --check .
30
+
31
+ test:
32
+ name: Test
33
+ runs-on: ubuntu-latest
34
+
35
+ steps:
36
+ - name: Checkout code
37
+ uses: actions/checkout@v4
38
+
39
+ - name: Running setup script
40
+ run: |
41
+ sudo chmod +x setup.sh
42
+ sudo ./setup.sh
43
+
44
+ - name: Create dummy interface (wlan0)
45
+ run: |
46
+ sudo ip link add wlan0 type dummy
47
+ sudo ip link set wlan0 up
48
+ echo "Created dummy interface:"
49
+ ip link show wlan0
50
+
51
+ - name: Get initial MAC
52
+ id: get_mac
53
+ run: |
54
+ OLD_MAC=$(ip link show wlan0 | awk '/ether/ {print $2}')
55
+ echo "old_mac=$OLD_MAC" >> $GITHUB_OUTPUT
56
+
57
+ - name: Run MacSpoofer in CI mode
58
+ run: |
59
+ echo "Spoofing MAC on dummy wlan0..."
60
+ sudo python3 ./main.py -i wlan0 --ci
61
+
62
+ - name: Verify MAC change
63
+ run: |
64
+ OLD_MAC="${{ steps.get_mac.outputs.old_mac }}"
65
+ NEW_MAC=$(ip link show wlan0 | awk '/ether/ {print $2}')
66
+ echo "Old MAC: $OLD_MAC"
67
+ echo "New MAC: $NEW_MAC"
68
+ if [[ "$NEW_MAC" == "$OLD_MAC" ]]; then
69
+ echo "MAC was not Spoofed!"
70
+ exit 1
71
+ else
72
+ echo "MAC Spoofed successfully!"
73
+ fi
@@ -0,0 +1,49 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build:
10
+ name: Build Package
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.11"
20
+
21
+ - name: Install build tools
22
+ run: pip install build
23
+
24
+ - name: Build package
25
+ run: python -m build
26
+
27
+ - name: Upload build artifacts
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ publish:
34
+ name: Publish to PyPI
35
+ needs: build
36
+ runs-on: ubuntu-latest
37
+ environment: pypi
38
+ permissions:
39
+ id-token: write
40
+
41
+ steps:
42
+ - name: Download build artifacts
43
+ uses: actions/download-artifact@v4
44
+ with:
45
+ name: dist
46
+ path: dist/
47
+
48
+ - name: Publish to PyPI
49
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,6 @@
1
+ __pycache__
2
+ manuf
3
+ vendors/
4
+ dist/
5
+ build/
6
+ *.egg-info/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022-2026 Daniel Kirshner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.4
2
+ Name: macspoofer
3
+ Version: 1.0.0
4
+ Summary: A command-line tool to spoof your network interface's MAC address on Linux systems.
5
+ Project-URL: Homepage, https://github.com/DanielKirshner/MacSpoofer
6
+ Project-URL: Repository, https://github.com/DanielKirshner/MacSpoofer
7
+ Project-URL: Issues, https://github.com/DanielKirshner/MacSpoofer/issues
8
+ Author: Daniel Kirshner
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: linux,mac,mac-address,network,security,spoofer
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: System Administrators
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Security
23
+ Classifier: Topic :: System :: Networking
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: art>=6.0
26
+ Requires-Dist: pretty-errors>=1.2.25
27
+ Requires-Dist: rich>=14.0.0
28
+ Description-Content-Type: text/markdown
29
+
30
+ # MAC Address Spoofer
31
+
32
+ ![CI (master)](https://github.com/DanielKirshner/MacSpoofer/actions/workflows/linux-ci.yml/badge.svg?branch=master)
33
+
34
+ A command-line tool to spoof your network interface's MAC address on Linux systems.
35
+
36
+ ![MacSpoofer Demo](demo/demo.gif)
37
+
38
+ ## What is a MAC Address?
39
+
40
+ A **Media Access Control (MAC) address** is a unique identifier assigned to a network interface controller (NIC) for use as a network address in communications within a network segment. This identifier is used in most IEEE 802 networking technologies, including Ethernet, Wi-Fi, and Bluetooth.
41
+
42
+ Changing your MAC address can be useful for:
43
+ - **Privacy** - Prevent tracking across networks
44
+ - **Testing** - Simulate different network devices
45
+ - **Bypassing restrictions** - Some networks filter by MAC address
46
+
47
+ ## MAC Address Structure
48
+
49
+ A MAC address is a **12-digit hexadecimal number** (6 bytes), typically represented in colon-hexadecimal notation (e.g., `00:1A:2B:3C:4D:5E`).
50
+
51
+ | Bytes | Name | Description |
52
+ |-------|------|-------------|
53
+ | First 3 bytes | **OUI** (Organizationally Unique Identifier) | Identifies the manufacturer |
54
+ | Last 3 bytes | **NIC** (Network Interface Controller) | Device-specific identifier |
55
+
56
+ ## Features
57
+
58
+ - 🎲 **Random MAC generation** - Generate safe, locally-administered unicast addresses
59
+ - 🏭 **Vendor spoofing** - Mimic devices from Samsung, Apple, Intel, Microsoft, Huawei, Google, or Cisco
60
+ - 🖥️ **Interactive TUI** - Easy to use text interface
61
+ - ⚡ **Auto mode** - Non-interactive operation for scripts
62
+ - 🔧 **CI mode** - Designed for automated testing pipelines
63
+
64
+ ## Compatibility
65
+
66
+ The tool is compatible with **Linux distributions only**.
67
+
68
+ Tested on:
69
+ - **Ubuntu** - 16.04.7, 18.04.6, 20.04.6, 22.04.5, 24.04.2
70
+ - **Debian** - 8, 9, 10, 11, 12
71
+ - **Kali** - 2021.4a, 2022.4, 2023.4, 2024.4, 2025.1
72
+ - **Raspbian** - 8, 9, 10, 11, 12
73
+
74
+ ## Installation
75
+
76
+ ### Via pip (recommended)
77
+
78
+ ```bash
79
+ pip install macspoofer
80
+ ```
81
+
82
+ ### From source
83
+
84
+ ```bash
85
+ chmod +x setup.sh
86
+ sudo ./setup.sh
87
+ ```
88
+
89
+ ## Usage
90
+
91
+ ### Find Your Interface Name
92
+
93
+ ```bash
94
+ ifconfig -a
95
+ # or
96
+ ip link show
97
+ ```
98
+
99
+ ### Interactive Mode (TUI)
100
+
101
+ ```bash
102
+ sudo macspoofer -i <interface>
103
+ # or
104
+ sudo python3 main.py -i <interface>
105
+ ```
106
+
107
+ ### Auto Mode (Non-Interactive)
108
+
109
+ ```bash
110
+ sudo macspoofer -i <interface> --auto
111
+ # or
112
+ sudo python3 main.py -i <interface> --auto
113
+ ```
114
+
115
+ ### Command Line Options
116
+
117
+ | Option | Description |
118
+ |--------|-------------|
119
+ | `-i <interface>` | Network interface name (e.g., `wlan0`, `eth0`) **[Required]** |
120
+ | `--auto` | Non-interactive mode: generate and apply a random unicast MAC |
121
+ | `--ci` | CI mode: for automated testing |
122
+ | `--help` | Show help message and usage examples |
123
+ | `--version` | Show version information |
124
+
125
+
126
+ ## Resources
127
+
128
+ - [MAC Vendor Lookup API](https://macvendors.com/) - Look up manufacturer by MAC address
129
+ - [Wireshark Vendor Database](https://github.com/wireshark/wireshark/blob/master/manuf) - Comprehensive list of known manufacturers
130
+
131
+ > 💡 Want more vendors? Feel free to open a PR to add more vendor OUIs!
132
+
133
+ ## License
134
+
135
+ [MIT License](LICENSE)
136
+
137
+ ---
138
+
139
+ **© 2022-2026 Daniel Kirshner. All rights reserved.**
@@ -0,0 +1,110 @@
1
+ # MAC Address Spoofer
2
+
3
+ ![CI (master)](https://github.com/DanielKirshner/MacSpoofer/actions/workflows/linux-ci.yml/badge.svg?branch=master)
4
+
5
+ A command-line tool to spoof your network interface's MAC address on Linux systems.
6
+
7
+ ![MacSpoofer Demo](demo/demo.gif)
8
+
9
+ ## What is a MAC Address?
10
+
11
+ A **Media Access Control (MAC) address** is a unique identifier assigned to a network interface controller (NIC) for use as a network address in communications within a network segment. This identifier is used in most IEEE 802 networking technologies, including Ethernet, Wi-Fi, and Bluetooth.
12
+
13
+ Changing your MAC address can be useful for:
14
+ - **Privacy** - Prevent tracking across networks
15
+ - **Testing** - Simulate different network devices
16
+ - **Bypassing restrictions** - Some networks filter by MAC address
17
+
18
+ ## MAC Address Structure
19
+
20
+ A MAC address is a **12-digit hexadecimal number** (6 bytes), typically represented in colon-hexadecimal notation (e.g., `00:1A:2B:3C:4D:5E`).
21
+
22
+ | Bytes | Name | Description |
23
+ |-------|------|-------------|
24
+ | First 3 bytes | **OUI** (Organizationally Unique Identifier) | Identifies the manufacturer |
25
+ | Last 3 bytes | **NIC** (Network Interface Controller) | Device-specific identifier |
26
+
27
+ ## Features
28
+
29
+ - 🎲 **Random MAC generation** - Generate safe, locally-administered unicast addresses
30
+ - 🏭 **Vendor spoofing** - Mimic devices from Samsung, Apple, Intel, Microsoft, Huawei, Google, or Cisco
31
+ - 🖥️ **Interactive TUI** - Easy to use text interface
32
+ - ⚡ **Auto mode** - Non-interactive operation for scripts
33
+ - 🔧 **CI mode** - Designed for automated testing pipelines
34
+
35
+ ## Compatibility
36
+
37
+ The tool is compatible with **Linux distributions only**.
38
+
39
+ Tested on:
40
+ - **Ubuntu** - 16.04.7, 18.04.6, 20.04.6, 22.04.5, 24.04.2
41
+ - **Debian** - 8, 9, 10, 11, 12
42
+ - **Kali** - 2021.4a, 2022.4, 2023.4, 2024.4, 2025.1
43
+ - **Raspbian** - 8, 9, 10, 11, 12
44
+
45
+ ## Installation
46
+
47
+ ### Via pip (recommended)
48
+
49
+ ```bash
50
+ pip install macspoofer
51
+ ```
52
+
53
+ ### From source
54
+
55
+ ```bash
56
+ chmod +x setup.sh
57
+ sudo ./setup.sh
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ ### Find Your Interface Name
63
+
64
+ ```bash
65
+ ifconfig -a
66
+ # or
67
+ ip link show
68
+ ```
69
+
70
+ ### Interactive Mode (TUI)
71
+
72
+ ```bash
73
+ sudo macspoofer -i <interface>
74
+ # or
75
+ sudo python3 main.py -i <interface>
76
+ ```
77
+
78
+ ### Auto Mode (Non-Interactive)
79
+
80
+ ```bash
81
+ sudo macspoofer -i <interface> --auto
82
+ # or
83
+ sudo python3 main.py -i <interface> --auto
84
+ ```
85
+
86
+ ### Command Line Options
87
+
88
+ | Option | Description |
89
+ |--------|-------------|
90
+ | `-i <interface>` | Network interface name (e.g., `wlan0`, `eth0`) **[Required]** |
91
+ | `--auto` | Non-interactive mode: generate and apply a random unicast MAC |
92
+ | `--ci` | CI mode: for automated testing |
93
+ | `--help` | Show help message and usage examples |
94
+ | `--version` | Show version information |
95
+
96
+
97
+ ## Resources
98
+
99
+ - [MAC Vendor Lookup API](https://macvendors.com/) - Look up manufacturer by MAC address
100
+ - [Wireshark Vendor Database](https://github.com/wireshark/wireshark/blob/master/manuf) - Comprehensive list of known manufacturers
101
+
102
+ > 💡 Want more vendors? Feel free to open a PR to add more vendor OUIs!
103
+
104
+ ## License
105
+
106
+ [MIT License](LICENSE)
107
+
108
+ ---
109
+
110
+ **© 2022-2026 Daniel Kirshner. All rights reserved.**
Binary file
@@ -0,0 +1,3 @@
1
+ """MAC Address Spoofer - A CLI tool to spoof network interface MAC addresses on Linux."""
2
+
3
+ __version__ = "1.0.0"
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env python3
2
+ """MAC Address Spoofer - CLI entry point."""
3
+
4
+ import asyncio
5
+
6
+ from rich import print
7
+
8
+ from macspoofer.modules.args_parser import ArgumentParser
9
+ from macspoofer.modules.error_config import configure_pretty_errors
10
+ from macspoofer.spoofer import run_spoofer_logic
11
+ from macspoofer.utils.exceptions import CustomException
12
+
13
+
14
+ async def _async_main() -> None:
15
+ """Async application entry point."""
16
+ try:
17
+ configure_pretty_errors()
18
+ args = ArgumentParser().parse_args()
19
+ await run_spoofer_logic(args)
20
+ except KeyboardInterrupt:
21
+ print("\n[-] [bold red]Stopped.")
22
+ except CustomException as e:
23
+ print(f"\n[-] [bold red]{e}")
24
+ except ModuleNotFoundError:
25
+ print("\n[-] [bold red]Missing one of the pip packages.")
26
+ except Exception as e:
27
+ print(f"\n[-] [bold red]Error occurred: {e}")
28
+
29
+
30
+ def main() -> None:
31
+ """Synchronous wrapper for the CLI entry point (used by pyproject.toml scripts)."""
32
+ asyncio.run(_async_main())
33
+
34
+
35
+ if __name__ == "__main__":
36
+ main()
File without changes
@@ -0,0 +1,71 @@
1
+ """Command-line argument parsing for MAC Address Spoofer."""
2
+
3
+ import argparse
4
+ from dataclasses import dataclass
5
+
6
+ VERSION = "0.0.0"
7
+
8
+
9
+ @dataclass
10
+ class SpooferArgs:
11
+ """Parsed command-line arguments for the spoofer."""
12
+
13
+ interface: str
14
+ auto: bool = False
15
+ ci: bool = False
16
+
17
+
18
+ class ArgumentParser:
19
+ """Handles command-line argument parsing."""
20
+
21
+ def __init__(self) -> None:
22
+ self._parser = self._create_parser()
23
+
24
+ def _create_parser(self) -> argparse.ArgumentParser:
25
+ """Create and configure the argument parser."""
26
+ parser = argparse.ArgumentParser(
27
+ description="MAC Address Spoofer - Change your network interface MAC address",
28
+ formatter_class=argparse.RawDescriptionHelpFormatter,
29
+ )
30
+ self._add_arguments(parser)
31
+ return parser
32
+
33
+ def _add_arguments(self, parser: argparse.ArgumentParser) -> None:
34
+ """Add all command-line arguments to the parser."""
35
+ parser.add_argument(
36
+ "-i",
37
+ dest="interface",
38
+ required=True,
39
+ help="Network interface name (e.g., wlan0, eth0)",
40
+ )
41
+
42
+ parser.add_argument(
43
+ "--auto",
44
+ action="store_true",
45
+ help="Non-interactive mode: generate and apply a safe random unicast MAC",
46
+ )
47
+
48
+ parser.add_argument(
49
+ "--ci",
50
+ action="store_true",
51
+ help="CI mode: for automated testing (similar to --auto)",
52
+ )
53
+
54
+ parser.add_argument(
55
+ "--version",
56
+ action="version",
57
+ version=f"MAC Address Spoofer v{VERSION}",
58
+ )
59
+
60
+ def parse_args(self) -> SpooferArgs:
61
+ """Parse command-line arguments.
62
+
63
+ Returns:
64
+ SpooferArgs dataclass with parsed values
65
+ """
66
+ args = self._parser.parse_args()
67
+ return SpooferArgs(
68
+ interface=args.interface,
69
+ auto=args.auto,
70
+ ci=args.ci,
71
+ )
@@ -0,0 +1,18 @@
1
+ """Pretty error output configuration."""
2
+
3
+ import pretty_errors
4
+
5
+
6
+ def configure_pretty_errors() -> None:
7
+ """Configure pretty_errors for enhanced error display.
8
+
9
+ Sets up formatting options for better error readability including
10
+ separator characters, full filename display, and context lines.
11
+ """
12
+ pretty_errors.configure(
13
+ separator_character="*",
14
+ filename_display=pretty_errors.FILENAME_FULL,
15
+ line_color=pretty_errors.RED + "> " + pretty_errors.default_config.line_color,
16
+ lines_before=3,
17
+ lines_after=3,
18
+ )
@@ -0,0 +1,100 @@
1
+ """Network interface management for MAC spoofing."""
2
+
3
+ import contextlib
4
+ from collections.abc import AsyncIterator
5
+ from enum import StrEnum
6
+
7
+ from macspoofer.utils import shell_utils
8
+ from macspoofer.utils.exceptions import CustomException, ErrorCode
9
+
10
+
11
+ class InterfaceState(StrEnum):
12
+ """Network interface state values."""
13
+
14
+ UP = "up"
15
+ DOWN = "down"
16
+
17
+
18
+ class NetworkInterface:
19
+ """Represents a network interface for MAC address manipulation.
20
+
21
+ This class encapsulates operations on a network interface,
22
+ including state management and MAC address spoofing.
23
+
24
+ Attributes:
25
+ name: The interface name (e.g., 'eth0', 'wlan0')
26
+ """
27
+
28
+ def __init__(self, name: str) -> None:
29
+ """Initialize a NetworkInterface.
30
+
31
+ Args:
32
+ name: The interface name (e.g., 'eth0', 'wlan0')
33
+ """
34
+ self.name = name
35
+
36
+ async def set_state(self, state: InterfaceState) -> None:
37
+ """Set the interface to the specified state.
38
+
39
+ Args:
40
+ state: Desired interface state (UP or DOWN)
41
+
42
+ Raises:
43
+ CustomException: If the state change fails
44
+ """
45
+ try:
46
+ await shell_utils.execute_command(["ip", "link", "set", "dev", self.name, state])
47
+ except CustomException as err:
48
+ raise CustomException(
49
+ message=f"Failed to set interface {self.name} to {state}",
50
+ error_code=ErrorCode.INTERFACE_STATE_FAILED,
51
+ ) from err
52
+
53
+ async def up(self) -> None:
54
+ """Bring the interface up."""
55
+ await self.set_state(InterfaceState.UP)
56
+
57
+ async def down(self) -> None:
58
+ """Bring the interface down."""
59
+ await self.set_state(InterfaceState.DOWN)
60
+
61
+ async def set_mac_address(self, mac: str) -> None:
62
+ """Set the MAC address of the interface.
63
+
64
+ Note: The interface should be down before changing the MAC address.
65
+
66
+ Args:
67
+ mac: New MAC address (format: 'xx:xx:xx:xx:xx:xx')
68
+
69
+ Raises:
70
+ CustomException: If setting the MAC address fails
71
+ """
72
+ try:
73
+ await shell_utils.execute_command(
74
+ ["ip", "link", "set", "dev", self.name, "address", mac]
75
+ )
76
+ except CustomException as err:
77
+ raise CustomException(
78
+ message=f"Failed to set MAC address {mac} on {self.name}",
79
+ error_code=ErrorCode.MAC_SPOOF_FAILED,
80
+ ) from err
81
+
82
+ @contextlib.asynccontextmanager
83
+ async def disable_temporarily(self) -> AsyncIterator[None]:
84
+ """Async context manager to temporarily bring the interface down and back up.
85
+
86
+ Usage:
87
+ async with interface.disable_temporarily():
88
+ await interface.set_mac_address(new_mac)
89
+ """
90
+ try:
91
+ await self.down()
92
+ yield
93
+ finally:
94
+ await self.up()
95
+
96
+ def __str__(self) -> str:
97
+ return self.name
98
+
99
+ def __repr__(self) -> str:
100
+ return f"NetworkInterface({self.name!r})"