Skip to main content

Distributed Nuclei scanner with gRPC server and web UI

Project description

Nuclei gRPC Server

A Python-based gRPC server that allows remote execution of Nuclei commands with:

  • Authentication - Token-based authentication with login/logout
  • Command Execution - Real-time streaming of command output
  • File Transfer - Upload/download files with progress streaming
  • Containerized - Docker image with Nuclei pre-installed

Features

Authentication Service

  • Login with username/password
  • Token validation
  • 24-hour token expiry

Command Executor Service

  • Execute arbitrary shell commands remotely
  • Stream output line-by-line in real-time
  • Environment variable support
  • Exit code tracking

File Transfer Service

  • Upload files from client to server
  • Download files from server to client
  • List files in directories
  • Directory traversal protection
  • 64KB chunked streaming

Quick Start

Prerequisites

  • Python 3.11+
  • Docker (for containerized deployment)

Installation

  1. Clone/download the project
cd recon_tasks
  1. Install dependencies
pip3 install -r requirements.txt
  1. Generate gRPC code (if not already done)
python3 -m grpc_tools.protoc \
    -I./proto \
    --python_out=./nuclei_server \
    --grpc_python_out=./nuclei_server \
    ./proto/nuclei.proto

Running the Server

Direct execution:

python3 -m nuclei_server.server

Docker:

docker build -t nuclei-grpc .
docker run -p 50051:50051 nuclei-grpc

The server will start on localhost:50051 with default credentials:

  • Username: admin | Password: admin123
  • Username: user | Password: user123

Using the Client

Login

python3 client.py login admin admin123

Execute Nuclei Command

python3 client.py exec "nuclei -u https://target.com -t cves/"
python3 client.py exec "nuclei -l targets.txt -t tech-detect" --env TARGET_ENV production

File Operations

Upload file:

python3 client.py upload /path/to/templates.json --as custom-templates.json

Download file:

python3 client.py download results.json --to ./local-results.json

List files:

python3 client.py list
python3 client.py list --dir /some/subdir

Validate Token

python3 client.py validate

Project Structure

recon_tasks/
├── Dockerfile                 # Multi-stage Docker build
├── requirements.txt           # Python dependencies
├── proto/
│   └── nuclei.proto          # gRPC service definitions
├── nuclei_server/
│   ├── __init__.py
│   ├── auth.py               # Authentication manager
│   ├── executor.py           # Command executor with streaming
│   ├── server.py             # gRPC server implementation
│   ├── nuclei_pb2.py         # Auto-generated (proto messages)
│   └── nuclei_pb2_grpc.py    # Auto-generated (gRPC services)
├── client.py                 # gRPC client CLI
├── generate_proto.sh         # Proto generation script
└── README.md

API Reference

Auth Service

Login

request = LoginRequest(username="admin", password="admin123")
response = stub.Login(request)
# response.token - Use this for subsequent requests

Validate

request = ValidateRequest(token="<token>")
response = stub.Validate(request)
# response.valid - Token validity
# response.username - Associated username

NucleiExecutor Service

ExecuteCommand (Streaming)

request = ExecuteRequest(
    command="nuclei -u https://target.com",
    token="<token>",
    env_vars={"PROXY": "http://proxy:8080"}
)
for response in stub.ExecuteCommand(request):
    print(response.output)  # Streamed output
    print(response.error)   # Streamed errors
    if response.completed:
        print(f"Exit code: {response.exit_code}")

FileTransfer Service

UploadFile (Streaming)

def file_generator(filepath, token):
    with open(filepath, 'rb') as f:
        while True:
            chunk = f.read(64*1024)
            if not chunk:
                break
            yield UploadRequest(
                filename=os.path.basename(filepath),
                data=chunk,
                token=token
            )

response = stub.UploadFile(file_generator("file.txt", token))

DownloadFile (Streaming)

request = DownloadRequest(filename="results.json", token=token)
with open("results.json", 'wb') as f:
    for response in stub.DownloadFile(request):
        f.write(response.data)

ListFiles

request = ListFilesRequest(token=token, directory="")
response = stub.ListFiles(request)
for file_info in response.files:
    print(f"{file_info.name}: {file_info.size} bytes")

Security Notes

⚠️ Development Only: This implementation uses:

  • Insecure gRPC channel (no TLS)
  • Simple SHA256 password hashing (use bcrypt in production)
  • In-memory token storage (use Redis in production)

For production:

  1. Enable TLS/SSL certificates
  2. Use bcrypt for password hashing
  3. Move to distributed token store
  4. Add rate limiting
  5. Add audit logging
  6. Implement RBAC (Role-Based Access Control)

Example Workflow

# Start server
python3 -m nuclei_server.server &

# In another terminal, login
python3 client.py login admin admin123

# Execute nuclei scan
python3 client.py exec "nuclei -u https://example.com -silent"

# Upload templates
python3 client.py upload ./templates/custom.json --as templates.json

# Download results
python3 client.py download results.json --to ./scan-results.json

# List uploaded files
python3 client.py list

Troubleshooting

Proto files not generated:

python3 -m grpc_tools.protoc \
    -I./proto \
    --python_out=./nuclei_server \
    --grpc_python_out=./nuclei_server \
    ./proto/nuclei.proto

Module import errors: Ensure you're running from the project root directory and the virtual environment is activated.

Connection refused:

  • Check server is running: python3 -m nuclei_server.server
  • Verify port 50051 is open
  • Check firewall settings

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nuclei_grpc-1.0.0.tar.gz (21.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nuclei_grpc-1.0.0-py3-none-any.whl (23.2 kB view details)

Uploaded Python 3

File details

Details for the file nuclei_grpc-1.0.0.tar.gz.

File metadata

  • Download URL: nuclei_grpc-1.0.0.tar.gz
  • Upload date:
  • Size: 21.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for nuclei_grpc-1.0.0.tar.gz
Algorithm Hash digest
SHA256 5c88f4ec279ed0d96551f5829939ebb728f19d18aa13b0487ac8af4f2364981b
MD5 0704761e24f726aa0e95203bcfe71877
BLAKE2b-256 9db9b12d80a2d48b010f67ad75f974621cc28dcc39006d75e822a97df1f4593a

See more details on using hashes here.

File details

Details for the file nuclei_grpc-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: nuclei_grpc-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 23.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for nuclei_grpc-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f2082e77c127ade3296b3c12580c40cd0d23b21a9602df3f098fc83c1966d9bb
MD5 bd86494b183ced0bd52d9f7bc2be5076
BLAKE2b-256 6044eef05348b3696c0835b8850de2af3bd048220a257706dcfcb7fc289ed880

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page