Installing Havoc C2 Framework on Apple Silicon (M3/M4 Max) Kali Linux
Overview
Havoc is a modern post-exploitation Command & Control (C2) framework similar to Cobalt Strike, designed for red team operations and penetration testing. However, installing it on Apple Silicon (M3/M4 Max) running Kali Linux ARM64 presents unique challenges due to library conflicts and architecture-specific issues.
In this guide, you’ll learn:
- How to successfully install Havoc C2 on ARM64 Kali Linux
- Solutions to Python 3.13/3.10 compatibility issues
- Fixing Anaconda library conflicts
- Resolving Qt version mismatches
- Proper configuration for Apple Silicon architecture
What is Havoc? A Command & Control framework for authorized penetration testing, red team operations, and security research. Think Cobalt Strike, but open-source.
Prerequisites
Hardware:
- MacBook Pro with M3/M4/M3 Max/M4 Max chip
- 8GB+ RAM allocated to VM (18GB recommended)
Software:
- Kali Linux ARM64 (latest version)
- Terminal access
- sudo privileges
Knowledge:
- Basic Linux command line
- Understanding of C2 frameworks (helpful but not required)
⚠️ Legal Notice: Only use Havoc on systems you own or have explicit written authorization to test. Unauthorized access is illegal.
The Problem: Why Standard Installation Fails
When following the official Havoc installation guide on Apple Silicon Kali Linux, you’ll encounter three critical issues:
- Python 3.13 incompatibility - Havoc requires Python 3.10, but Kali ships with 3.13
- Anaconda library conflicts - Old libstdc++ from Anaconda breaks compilation
- Qt version mismatch - Binary links to Anaconda’s Qt 5.15.2 instead of system Qt 5.15.17
Let’s fix all of these.
Step 1: Install System Dependencies
First, install the required packages:
1
2
3
4
5
6
7
sudo apt update
sudo apt install -y git build-essential apt-utils cmake libfontconfig1 \
libglu1-mesa-dev libgtest-dev libspdlog-dev libboost-all-dev \
libncurses5-dev libgdbm-dev libssl-dev libreadline-dev libffi-dev \
libsqlite3-dev libbz2-dev mesa-common-dev qtbase5-dev qtchooser \
qt5-qmake qtbase5-dev-tools libqt5websockets5 libqt5websockets5-dev \
qtdeclarative5-dev golang-go nasm mingw-w64
Why these packages?
- Qt5 packages: GUI framework for the client
- Boost libraries: C++ dependencies
- mingw-w64: Cross-compiler for Windows payloads
- golang-go: Required for teamserver
- nasm: Assembler for payload generation
Step 2: Clone Havoc Repository
1
2
3
cd ~/Documents/Apps/
git clone https://github.com/HavocFramework/Havoc.git
cd Havoc
Expected output:
1
2
3
4
Cloning into 'Havoc'...
remote: Enumerating objects: 12345, done.
remote: Total 12345 (delta 0), reused 0 (delta 0), pack-reused 12345
Receiving objects: 100% (12345/12345), 15.23 MiB | 8.45 MiB/s, done.
Step 3: Fix Python 3.10 Requirement
The Problem
Havoc’s CMakeLists.txt specifically requires Python 3.10:
1
set( Python_ADDITIONAL_VERSIONS 3.10 )
Kali Linux 2025+ ships with Python 3.13, which causes build failures:
1
/usr/bin/ld: /usr/lib/aarch64-linux-gnu/libpython3.13.so: undefined reference to `XML_SetAllocTrackerActivationThreshold'
The Solution: Install Python 3.10 via pyenv
Create installation script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
cd ~/Documents/Apps/Havoc
cat > install-python310.sh << 'EOF'
#!/bin/bash
echo "[*] Installing pyenv and Python 3.10 for Havoc"
# Install pyenv dependencies
sudo apt install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
libffi-dev liblzma-dev
# Install pyenv
if [ ! -d "$HOME/.pyenv" ]; then
echo "[*] Installing pyenv..."
curl https://pyenv.run | bash
fi
# Setup pyenv environment
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
# Install Python 3.10.14
echo "[*] Installing Python 3.10.14..."
pyenv install 3.10.14 -s
# Set as local version for Havoc
pyenv local 3.10.14
echo "[*] Python 3.10 installation complete!"
python3 --version
EOF
chmod +x install-python310.sh
Run the installer:
1
./install-python310.sh
Add pyenv to shell config:
For zsh (Kali default):
1
2
3
4
5
6
7
8
9
10
cat >> ~/.zshrc << 'EOF'
# Pyenv for Python version management
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - zsh)"
eval "$(pyenv virtualenv-init -)"
EOF
source ~/.zshrc
For bash:
1
2
3
4
5
6
7
8
9
10
cat >> ~/.bashrc << 'EOF'
# Pyenv for Python version management
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - bash)"
eval "$(pyenv virtualenv-init -)"
EOF
source ~/.bashrc
Verify Python 3.10:
1
2
cd ~/Documents/Apps/Havoc
python3 --version
Expected output:
1
Python 3.10.14
Step 4: Create Build Script (Anaconda-Safe)
The Problem
If you have Anaconda installed, CMake will find Anaconda’s libraries first:
- Old libstdc++ (GLIBCXX 3.4.29 vs required 3.4.32)
- Old Qt 5.15.2 (vs system Qt 5.15.17)
This causes runtime errors:
1
Cannot mix incompatible Qt library (5.15.2) with this library (5.15.17)
The Solution: Force System Libraries
Create build script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
cat > build-havoc-client.sh << 'EOF'
#!/bin/bash
echo "[*] Building Havoc Client with Python 3.10 and System Qt"
# Exclude Anaconda from PATH
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Initialize pyenv AFTER setting clean PATH
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
# Get Python 3.10 paths
PYTHON310_BIN=$(pyenv which python3)
PYTHON310_VERSION=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
if [ "$PYTHON310_VERSION" != "3.10" ]; then
echo "[!] Error: Python 3.10 not found!"
exit 1
fi
PYTHON310_INCLUDE=$(python3 -c "from sysconfig import get_paths; print(get_paths()['include'])")
PYTHON310_LIB=$(python3 -c "from sysconfig import get_config_var; print(get_config_var('LIBDIR'))")/libpython3.10.so
# Force system Qt5
QT5_DIR="/usr/lib/aarch64-linux-gnu/cmake/Qt5"
echo "[*] Using Python: $PYTHON310_BIN"
echo "[*] Qt5 directory: $QT5_DIR"
# Clean previous build
make client-cleanup
# Update submodules
git submodule update --init --recursive
# Create build directory
mkdir -p client/Build
cd client/Build
# Configure with CMake
cmake -DPYTHON_EXECUTABLE="$PYTHON310_BIN" \
-DPYTHON_INCLUDE_DIR="$PYTHON310_INCLUDE" \
-DPYTHON_LIBRARY="$PYTHON310_LIB" \
-DPython3_EXECUTABLE="$PYTHON310_BIN" \
-DPython3_INCLUDE_DIR="$PYTHON310_INCLUDE" \
-DPython3_LIBRARY="$PYTHON310_LIB" \
-DQt5_DIR="$QT5_DIR" \
-DCMAKE_PREFIX_PATH="/usr/lib/aarch64-linux-gnu/cmake" \
..
# Build
cmake --build . -- -j 4
if [ $? -eq 0 ]; then
echo "[*] Build successful!"
echo "[*] Verifying Qt libraries..."
ldd ../Havoc | grep libQt5Core
cd ../..
if [ ! -d "client/Modules" ]; then
git clone https://github.com/HavocFramework/Modules client/Modules --single-branch --branch main
fi
fi
EOF
chmod +x build-havoc-client.sh
Run the build:
1
./build-havoc-client.sh
Expected output:
1
2
3
[*] Build successful!
[*] Verifying Qt libraries...
libQt5Core.so.5 => /usr/lib/aarch64-linux-gnu/libQt5Core.so.5 ✓
❌ Bad output (Anaconda conflict):
1
libQt5Core.so.5 => /home/kali/anaconda3/lib/libQt5Core.so.5 ✗
Step 5: Build Teamserver
The teamserver is written in Go and compiles easily:
1
make ts-build
Expected output:
1
2
3
[*] building teamserver
[*] Installing musl compiler...
[*] Building teamserver binary...
This creates the havoc binary (teamserver).
Step 6: Create Launcher Scripts
The Problem
Even with correct compilation, running the client directly picks up Anaconda libraries at runtime.
The Solution: Environment Override Scripts
Create client launcher:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
cat > start-client.sh << 'EOF'
#!/bin/bash
cd "$(dirname "$0")"
# Override library paths to exclude Anaconda
export LD_LIBRARY_PATH="/usr/lib/aarch64-linux-gnu:/usr/lib:/lib/aarch64-linux-gnu:/lib"
export QT_PLUGIN_PATH="/usr/lib/aarch64-linux-gnu/qt5/plugins"
export QT_QPA_PLATFORM_PLUGIN_PATH="/usr/lib/aarch64-linux-gnu/qt5/plugins/platforms"
# Remove Anaconda Qt variables
unset QTDIR
unset QT_HOME
# Initialize pyenv
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
eval "$(pyenv init -)"
echo "Starting Havoc Client..."
echo "Python: $(python3 --version)"
./client/Havoc
EOF
chmod +x start-client.sh
Create teamserver launcher:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cat > start-server.sh << 'EOF'
#!/bin/bash
cd "$(dirname "$0")"
PROFILE="${1:-./profiles/havoc.yaotl}"
if [ ! -f "$PROFILE" ]; then
echo "Error: Profile not found: $PROFILE"
exit 1
fi
export LD_LIBRARY_PATH="/usr/lib/aarch64-linux-gnu:/usr/lib:/lib/aarch64-linux-gnu:/lib"
echo "Starting Havoc Teamserver..."
echo "Profile: $PROFILE"
./havoc server --profile "$PROFILE" -v --debug
EOF
chmod +x start-server.sh
Step 7: Configure and Run Havoc
Check Default Credentials
1
cat profiles/havoc.yaotl
Default configuration:
1
2
3
4
5
6
7
8
9
10
11
12
13
Teamserver {
Host = "0.0.0.0"
Port = 40056
}
Operators {
user "5pider" {
Password = "password1234"
}
user "Neo" {
Password = "password1234"
}
}
Start Teamserver
Terminal 1:
1
2
cd ~/Documents/Apps/Havoc
sudo ./start-server.sh
Expected output:
1
2
3
4
5
6
Starting Havoc Teamserver...
Profile: ./profiles/havoc.yaotl
[INFO] Havoc Framework [Version: 0.7] [CodeName: Bites The Dust]
[INFO] Time: 2026-01-04 14:00:00
[INFO] Teamserver listening on 0.0.0.0:40056
Start Client
Terminal 2:
1
2
cd ~/Documents/Apps/Havoc
./start-client.sh
Expected output:
1
2
3
4
5
6
Starting Havoc Client...
Python: Python 3.10.14
[info] Havoc Framework [Version: 0.7] [CodeName: Bites The Dust]
[info] Successful created database
[info] loaded config file: client/config.toml
The GUI should launch successfully.
Connect to Teamserver
In the Havoc client GUI:
- Click “New Profile”
- Enter connection details:
- Profile Name: Local Server
- Host:
127.0.0.1 - Port:
40056 - User:
Neo - Password:
password1234
- Click “Save”
- Click “Connect”
Success indicators:
- Status changes to “Connected”
- Teamserver shows:
[INFO] New client connected - Client shows operators panel and session table
Troubleshooting
Issue 1: libstdc++ Version Error
Problem:
1
client/Havoc: /home/kali/anaconda3/lib/libstdc++.so.6: version `GLIBCXX_3.4.30' not found
Cause: Anaconda’s old libstdc++ is being loaded instead of system library.
Solution:
Always use ./start-client.sh which sets LD_LIBRARY_PATH correctly.
Verify:
1
ldd client/Havoc | grep libstdc++
Should show: /usr/lib/aarch64-linux-gnu/libstdc++.so.6
Issue 2: Qt Version Mismatch
Problem:
1
Cannot mix incompatible Qt library (5.15.2) with this library (5.15.17)
Cause: Binary was built linking to Anaconda Qt.
Solution:
Rebuild with clean environment:
1
2
make client-cleanup
./build-havoc-client.sh
Verify correct Qt linkage:
1
ldd client/Havoc | grep libQt5Core
Good output:
1
libQt5Core.so.5 => /usr/lib/aarch64-linux-gnu/libQt5Core.so.5
Bad output:
1
libQt5Core.so.5 => /home/kali/anaconda3/lib/libQt5Core.so.5
Issue 3: Python Version Mismatch
Problem:
Build uses Python 3.13 instead of 3.10.
Cause: Not in Havoc directory where .python-version file exists.
Solution:
1
2
cd ~/Documents/Apps/Havoc
python3 --version # Should be 3.10.14
If still showing 3.13:
1
2
source ~/.zshrc # or ~/.bashrc
pyenv local 3.10.14
Issue 4: Connection Refused
Problem:
Client shows “remote host closed the connection”
Cause: Teamserver not running.
Solution:
- Start teamserver:
sudo ./start-server.sh - Verify listening:
sudo netstat -tlnp | grep 40056 - Check firewall isn’t blocking localhost
Issue 5: Permission Denied on Port 40056
Problem:
1
bind: permission denied
Cause: Ports below 1024 and some teamserver operations require root.
Solution:
1
sudo ./start-server.sh
Key Takeaways
- Python 3.10 is mandatory - Use pyenv to install it alongside system Python
- Anaconda conflicts are real - Override library paths to use system libraries
- Build environment matters - Remove Anaconda from PATH during compilation
- Use launcher scripts - Don’t run binaries directly; they need environment setup
- ARM64 works great - Native compilation on Apple Silicon performs excellently
Quick Reference
Installation Commands
1
2
3
4
5
6
7
8
9
10
11
12
13
# Clone repository
git clone https://github.com/HavocFramework/Havoc.git
cd Havoc
# Install Python 3.10
./install-python310.sh
source ~/.zshrc
# Build client
./build-havoc-client.sh
# Build teamserver
make ts-build
Running Havoc
1
2
3
4
5
# Terminal 1: Start teamserver
sudo ./start-server.sh
# Terminal 2: Start client
./start-client.sh
Default Credentials
- Host:
127.0.0.1 - Port:
40056 - User:
Neoor5pider - Password:
password1234
Verify Build
1
2
3
4
5
6
7
8
9
10
# Check Python version
python3 --version # Should be 3.10.14
# Check Qt linkage
ldd client/Havoc | grep libQt5Core
# Should point to /usr/lib/aarch64-linux-gnu/
# Check C++ library
ldd client/Havoc | grep libstdc++
# Should point to /usr/lib/aarch64-linux-gnu/
Resources
- Havoc GitHub: https://github.com/HavocFramework/Havoc
- Official Docs: https://havocframework.com/docs/
- Wiki: https://github.com/HavocFramework/Havoc/wiki
- Discord Community: https://discord.gg/z3PF3NRDE5
- Python API: https://github.com/HavocFramework/havoc-py
- Modules: https://github.com/HavocFramework/Modules
Support This Content
If this guide helped you get Havoc running on your M3/M4 Mac, consider supporting more tutorials like this!
Your support helps create more in-depth guides and tutorials!
Installation Time: ~30 minutes Difficulty: Intermediate Tested On: MacBook Pro M4 Max, Kali Linux ARM64 2025.1 Havoc Version: 0.7 (Bites The Dust)