diff --git a/src/network-services-pentesting/5671-5672-pentesting-amqp.md b/src/network-services-pentesting/5671-5672-pentesting-amqp.md index a65ae14ccc5..14429528f58 100644 --- a/src/network-services-pentesting/5671-5672-pentesting-amqp.md +++ b/src/network-services-pentesting/5671-5672-pentesting-amqp.md @@ -139,6 +139,40 @@ for method, props, body in ch.consume('loot', inactivity_timeout=5): Swap the routing key for `audit.#` or `payments.*` to focus on sensitive flows, then republish forged messages by flipping `basic_publish` arguments—handy for replay attacks against downstream microservices. +### Consumer-side command injection (message bus -> RCE) + +Treat every message broker as a potential **code-delivery primitive** when downstream consumers turn message data into shell commands, SQL, template input, or config updates. The critical anti-pattern is a worker that reads attacker-controlled content from a queue/topic and feeds it into a shell, for example `bash -c "$MESSAGE"`, `sh -c`, `os.system`, `subprocess(..., shell=True)`, `Runtime.exec`, or `Command::new("bash").arg("-c").arg(message)`. + +Typical exploitation chain: + +1. Gain **publish capability** to a queue/topic: + - Direct broker access with weak/default credentials or no auth + - Access to an HTTP publish feature such as RabbitMQ Management `POST /api/exchanges/%2F//publish` + - SSRF into an internal broker or debug endpoint that can speak raw TCP to the broker + - Compromise of any producer service that already writes to the target queue/topic +2. **Locate the sink** in source/config: + - Workers calling shells after deserializing messages + - "task runners" that accept commands over the queue + - Consumers that rebuild config files and then execute hooks/reload scripts +3. Publish a **benign probe** first (`id`, `whoami`, `uname -a`) to confirm execution without destroying the worker +4. Upgrade to a reverse shell or data theft once the execution path is confirmed + +Things to look for during source review: + +- Consumer groups named `update`, `jobs`, `tasks`, `commands`, `hooks`, `admin`, `dns`, or `sync` +- Supervisor/systemd entries launching both a broker consumer and a privileged helper in the same container +- Log lines showing a worker executes each message and then republishes results to a second queue/topic + +Example RabbitMQ publish through the management API: + +```bash +curl -u user:pass -H 'content-type: application/json' \ + -X POST http://TARGET:15672/api/exchanges/%2F/amq.default/publish \ + -d '{"properties":{},"routing_key":"update","payload":"id","payload_encoding":"string"}' +``` + +The same pattern appears outside AMQP. In Kafka, once you can reach the broker and craft a valid **Produce** request for the attacker-controlled topic, any consumer that forwards the message body to `bash -c` becomes an RCE sink. If the only reachable primitive is SSRF, check whether it can send **raw TCP bytes** or follow a `gopher://` redirect so you can still speak the broker protocol. + ## Other RabbitMQ ports In [https://www.rabbitmq.com/networking.html](https://www.rabbitmq.com/networking.html) you can find that **rabbitmq uses several ports**: @@ -172,5 +206,7 @@ In [https://www.rabbitmq.com/networking.html](https://www.rabbitmq.com/networkin - [CVE-2024-51988 – RabbitMQ HTTP API queue deletion bug](https://www.cve.news/cve-2024-51988/) - [GHSA-gh3x-4x42-fvq8 – RabbitMQ logs Authorization header](https://github.com/rabbitmq/rabbitmq-server/security/advisories/GHSA-gh3x-4x42-fvq8) - [rabbitmqadmin v2 (rabbitmqadmin-ng)](https://github.com/rabbitmq/rabbitmqadmin-ng) +- [Apache Kafka Protocol Guide](https://kafka.apache.org/41/design/protocol/) +- [HTB: Sorcery](https://0xdf.gitlab.io/2026/04/25/htb-sorcery.html) {{#include ../banners/hacktricks-training.md}}