"if not friend, why friend shaped?"
Friend is a command and control (C2) framework that believes in the power of friendship... and remote system administration. Just because it can execute arbitrary commands across distributed systems doesn't mean it can't be adorable while doing it.
Friend operates on a simple principle: everything looks friendlier when it's designed with care. Our C2 framework may have the capability to orchestrate complex distributed operations, but at its heart, it's just trying to help friends stay connected across networks.
The question isn't "Should I trust this system with my infrastructure?"
The question is "If not friend, why friend shaped?"
Friend consists of three main components that work together in perfect harmony, like good friends should:
graph LR
GUI["<b>GUI</b><br/>โข Textual TUI<br/>โข Task mgmt<br/>โข Real-time monitoring"]
CMD["<b>C2<br/></b>โข REST API<br/>โข Task queue<br/>โข Connection tracking"]
BCN["<b>Beacon<br/></b> โข Heartbeat<br/>โข Cmd exec<br/>โข Result reporting"]
GUI <--> CMD
CMD <--> BCN
The friendly neighborhood coordinator
The Command Server is the heart of Friend - a FastAPI-based REST service that manages all your beacon friends. It's like a really good friend who always remembers everyone's birthdays and keeps track of who owes who money.
Key Features:
- Connection Management: Tracks active beacon connections with heartbeat monitoring
- Task Distribution: Queues and distributes commands to registered beacons
- Real-time Status: Provides live status updates on all connections and tasks
- RESTful API: Clean HTTP endpoints for all operations
API Endpoints:
GET /register - Register a new beacon friend
GET /heartbeat/{id} - Beacon check-in and task retrieval
POST /update_task/{id} - Submit task results
POST /add_task/{id} - Queue new task for beacon
GET /status - View all connections and tasks
Communication Flow:
sequenceDiagram
participant G as GUI
participant C as Command Server
participant B as Beacon
Note over B: Beacon Startup
B->>C: GET /register
C->>B: UUID assigned
Note over B: Heartbeat Loop
loop Every few seconds
B->>C: GET /heartbeat/{id}
C->>B: Task or empty response
end
Note over G: User sends command
G->>C: POST /add_task/{id}?command=ls
C->>C: Queue task for beacon
Note over B: Next heartbeat
B->>C: GET /heartbeat/{id}
C->>B: Task: uid=... command='ls'
Note over B: Execute & report
B->>B: Execute 'ls' command
B->>C: POST /update_task/{id}
Note over G: View results
G->>C: GET /status
C->>G: All connections & tasks
The helpful friend who does what you ask
Written in C for maximum compatibility and minimal footprint, the Beacon is your reliable friend on remote systems. It's like that friend who always answers when you call and never complains about helping you move.
Key Features:
- Persistent Connection: Maintains connection to command server via heartbeat
- Command Execution: Executes shell commands using
popen()with full output capture - JSON Communication: Structured communication protocol with the command server
- Automatic Reconnection: Resilient connection handling
- Cross-platform: Runs on any system with libcurl and cjson
Dependencies:
libcurl- HTTP communication with command servercjson- JSON parsing and generation
The friendly face you interact with
A beautiful Textual-based TUI that makes managing your beacon friends a joy. It's like having a really well-organized friend who color-codes everything and always knows what's happening.
Key Features:
- Live Connection Monitoring: Real-time view of all beacon friends
- Interactive Task Management: Send commands and view results instantly
- Full Output Viewing: Click any task to see complete output in a modal
- Status Indicators: Visual status indicators (๐ข Online, ๐ก Stale, ๐ด Offline)
- Keyboard Shortcuts: Efficient navigation and control
The fastest way to see Friend in action:
cd command
uv run fastapi run app.pyServer will be available at http://localhost:8000
cd beacon
cmake -B build
cmake --build build
./build/beaconcd gui
uv run main.pyOnce Friend's GUI is running, you'll see a friendly interface with:
- Connections Panel: Shows all your beacon friends with status indicators
- Tasks Panel: Displays tasks for the selected connection
- Command Input: Type commands to send to your selected beacon friend
- Select a Connection: Click on any beacon in the connections table
- Send Commands: Type in the command input box and press Enter
- View Results: Click on any task row to see full output
- Monitor Status: Watch real-time status updates
r- Refresh all datac- Clear log messagesq- Quit the applicationt- Send test command to first available beacon
Try these friendly commands with your beacon friends:
# System information
whoami
uname -a
uptime
# File operations
ls -la
pwd
cat /etc/hostname
# Process monitoring
ps aux
top -n 1
# Network information
ifconfig
netstat -tuln.
โโโ beacon/
โ โโโ CMakeLists.txt
โ โโโ main.c
โโโ command/
โ โโโ app.py
โ โโโ pyproject.toml
โ โโโ README.md
โ โโโ uv.lock
โโโ gui/
โ โโโ main.py
โ โโโ pyproject.toml
โ โโโ README.md
โ โโโ uv.lock
โโโ LICENSE
โโโ pyproject.toml
โโโ README.md
cd beacon
cmake -B build
cmake --build buildRequirements: CMake, libcurl-dev, libcjson-dev
# Command server
cd command
uv sync
uv run app.py
# GUI application
cd gui
uv sync
python main.pyRequirements: Python 3.8+, uv package manager
Friend uses a custom string-based protocol for task communication:
Format: uid=UUID('...') command='...'
Example: uid=UUID('123e4567-e89b-12d3-a456-426614174000') command='ls -la'
from enum import Enum
class TaskStatus(Enum):
ERROR = -1 # โ Task failed
COMPLETE = 0 # โ
Task completed successfully
PENDING = 2 # โณ Task queued/in progressBeacons maintain connection through:
- Registration: Initial UUID assignment via
/register - Heartbeat: Periodic check-ins via
/heartbeat/{id}(retrieves pending tasks) - Result Submission: Task completion via
/update_task/{id}
- No authentication or encryption by default
- Commands execute with beacon process privileges
- All communication in plaintext HTTP
- For production use, implement:
- TLS/HTTPS encryption
- Authentication mechanisms
- Command validation and sanitization
- Network access controls
- System Administration: Managing multiple servers
- DevOps Automation: Distributed deployment and monitoring
- Research: Understanding C2 architectures and defenses
- Education: Learning about distributed systems
- Red Team Exercises: Authorized penetration testing
Friend's design philosophy embraces the idea that powerful tools don't have to be intimidating. By presenting complex C2 functionality through a friendly, approachable interface, Friend demonstrates that:
- Accessibility: Complex systems can have intuitive interfaces
- Transparency: Clear communication beats obfuscation
- Usability: Good UX makes powerful tools more valuable
- Education: Learning is easier when tools are approachable
Friend welcomes contributions from all friends! Whether you're fixing bugs, adding features, or improving documentation, every bit helps make Friend more friend-shaped.
- Clarity over cleverness: Code should be readable and well-documented
- Safety first: Always consider security implications
- User experience matters: Friendly interfaces make better tools
- Test thoroughly: Good friends are reliable friends
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
Friend is open source software. Use responsibly, use ethically, and remember - if not friend, why friend shaped?
Friend is provided for educational and authorized testing purposes only. Users are responsible for ensuring their use complies with applicable laws and regulations. The developers assume no responsibility for misuse of this software.
Remember: True friends don't use each other without permission.
Made with โค๏ธ by friends, for friends
"if not friend, why friend shaped?"