LazyOwn Beacon Network Discovery and Port Scanning: A Technical Deep Dive

The LazyOwn C2 framework provides three built-in beacon commands—hostdiscover, portdiscover, and portservicediscover—that generate Bash scripts to perform ping sweeps, full TCP port scans, and service detection on compromised hosts without requiring external tools like nmap.

The beacon network discovery and port scanning capabilities in LazyOwn enable operators to enumerate target networks directly from a compromised host. According to the grisuno/lazyown source code, these features are implemented as interactive CLI commands that dynamically generate Bash payloads for execution within the beacon's session. This approach eliminates dependencies on external scanning tools while providing manual execution guards to prevent accidental runs on the attacker's workstation.

How Beacon Network Discovery Works in LazyOwn

LazyOwn implements beacon network discovery through three distinct methods in lazyown.py, each designed for specific reconnaissance scenarios.

hostdiscover: Subnet Ping Sweep

The do_hostdiscover method (lines 7808-7863 in lazyown.py) performs a classic ping sweep across a /24 subnet. It constructs a Bash script that iterates through the last octet (1-254), executing ping -c 1 with a 1-second timeout to identify live hosts.

Key implementation details include:

  • Reading the current rhost parameter to determine the subnet
  • Generating a parallelized ping loop using background processes
  • Outputting active hosts in real-time

portdiscover: Full TCP Port Scanning

The do_portdiscover method (lines 7866-7924) scans all 65,535 TCP ports on a single target. It leverages the Bash /dev/tcp pseudo-device to attempt connections without installing additional tools.

The generated script:

  • Loops through seq 0 65535
  • Uses the redirection trick (echo >/dev/tcp/$ip/$port) to test connectivity
  • Echoes only open ports to minimize output noise

portservicediscover: Service-Aware Port Scanning

Extending the previous functionality, do_portservicediscover (lines 7966-8025) adds service identification. After detecting an open port, it executes sudo lsof -i :$port and parses the first field of the output to determine the listening service name.

This method requires elevated privileges on the beacon host to access the lsof service information.

Execution Flow and Safety Controls

Parameter Validation

All discovery commands rely on the rhost entry in self.params, typically set via assign rhost <ip>. The helper check_rhost() from utils.py validates the IP format before script generation.

Interactive Execution Guard

After generating the Bash payload, the methods follow a strict safety protocol:

  1. Display the complete script via print_msg()
  2. Prompt the operator with input("Do you want to execute? (yes/no): ")
  3. If yes: Execute via self.cmd() within the beacon session
  4. If no: Copy to clipboard using copy2clip for manual review

This ensures the operator reviews the payload before it runs on the compromised host.

Command Registration

Each function is decorated with @cmd2.with_category(scanning_category), organizing them under the Scanning group in the LazyOwn interactive CLI.

Practical Usage Examples

Running a Host Discovery Scan

> assign rhost 192.168.1.10
> hostdiscover
#!/bin/bash
for i in $(seq 1 254); do
    timeout 1 bash -c "ping -c 1 192.168.1.$i" &>/dev/null && echo "[+] Host 192.168.1.$i - active" &
done; wait
Do you want to execute? (yes/no): yes

Performing a Full Port Scan

> assign rhost 10.0.0.42
> portdiscover
#!/bin/bash
ip="10.0.0.42"
echo "Escaneo de puertos abiertos en curso..."
echo " "
for port in $(seq 0 65535); do
    (echo >/dev/tcp/$ip/$port) >/dev/null 2>&1 && echo "Puerto $port abierto"
done
Do you want to execute? (yes/no): yes

Detecting Services on Open Ports

> assign rhost 10.0.0.42
> portservicediscover
#!/bin/bash
ip="10.0.0.42"
echo "Escaneo de puertos y servicios abiertos en curso..."
echo " "
for port in $(seq 0 65535); do
    (echo >/dev/tcp/$ip/$port) >/dev/null 2>&1 && {
        service=$(echo "$(sudo lsof -i :$port)" | awk 'NR==2{print $1}')
        [ -n "$service" ] && echo "Puerto $port abierto - Servicio: $service"
    }
done
Do you want to execute? (yes/no): yes

Summary

  • Three built-in commands provide comprehensive beacon-side network reconnaissance: hostdiscover for ping sweeps, portdiscover for TCP scanning, and portservicediscover for service identification.
  • Bash script generation eliminates dependencies on external tools like nmap or masscan, using native shell capabilities such as /dev/tcp redirection.
  • Safety mechanisms require explicit operator confirmation before execution, with clipboard fallback for manual script review.
  • Source locations are centralized in lazyown.py (lines 7808-8025) with helper utilities in utils.py for parameter validation and output formatting, and test coverage demonstrated in test_commands.py (line 100).
  • Execution context runs entirely on the compromised beacon host, not the attacker's workstation, through the self.cmd() method.

Frequently Asked Questions

What is the difference between portdiscover and portservicediscover?

The portdiscover command performs a basic TCP connect scan across all 65,535 ports using Bash /dev/tcp redirection, reporting only open port numbers. The portservicediscover command extends this by executing sudo lsof -i :$port on each open port to identify the associated service name, though this requires root privileges on the beacon host.

How does LazyOwn prevent accidental execution on the attacker's machine?

According to the source code in lazyown.py, each discovery method implements an interactive execution guard. After generating the Bash script, the operator must explicitly respond yes to the prompt "Do you want to execute? (yes/no): ". If the operator selects no, the script is copied to the clipboard via copy2clip instead of being executed, preventing unintended runs on the wrong machine.

Where are the beacon discovery commands defined in the source code?

The three discovery commands are implemented as methods in lazyown.py: do_hostdiscover occupies lines 7808-7863, do_portdiscover spans lines 7866-7924, and do_portservicediscover covers lines 7966-8025. Supporting utilities including check_rhost(), print_msg(), and copy2clip are located in utils.py.

Does LazyOwn require external tools like nmap for network discovery?

No. The beacon network discovery functionality generates pure Bash scripts that rely on built-in shell utilities like ping, timeout, and /dev/tcp redirection. This design ensures reconnaissance capabilities remain available even on minimal compromised hosts that lack specialized scanning tools.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →