Peppo Writeup - Proving Grounds
Created October 8, 2026 • Last updated October 8, 2026 • 3 min read
Peppo leaks a username through the Ident protocol and that same user turns out to use their own name as their SSH password, landing in a restricted shell. Escaping rbash through the ed editor reveals docker group membership, which is enough on its own to mount the host filesystem and chroot in as root.
Reconnaissance
Nmap
Scan all TCP ports and fingerprint the services.
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u7 113/tcp open ident FreeBSD identd 8080/tcp open http WEBrick httpd 1.4.2 (Ruby 2.6.6) 10000/tcp open http "Hello World"
Explain command
| -p- | Scan all 65535 TCP ports. |
| -sC -sV | Run default scripts and probe service versions. |
Port 113 runs Ident (RFC 1413), a protocol that reports which system user owns a given TCP connection.
Ident enumeration
Query Ident for every other open port to find out who's running what.
$TARGET_IP:22 root $TARGET_IP:113 nobody $TARGET_IP:8080 <unknown> $TARGET_IP:10000 eleanor
The service on port 10000 runs as eleanor, a valid system username.
Exploitation
Lazy credentials over SSH
Try the username as its own password.
eleanor@$TARGET_IP's password: -rbash: PATH is unset or has an invalid value
The username-as-password combo logs in, but lands in a restricted bash (rbash) shell.
Escaping the restricted shell
Check what's available inside it.
/home/eleanor/bin chmod chown ed ls mv ping sleep touch
PATH is locked to a single directory, cd is disabled, and only a handful of binaries are reachable. ed, a line editor, supports ! to run shell commands, which is a classic rbash escape.
!/bin/bash
That spawns a real bash shell, but it still inherits the broken PATH. Fix it manually.
uid=1000(eleanor) gid=1000(eleanor) groups=1000(eleanor),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),999(docker)
All standard commands work now, and the flag is readable.
Privilege Escalation
Dead ends, then the docker group
The usual checks come up empty.
Sorry, user eleanor may not run sudo on peppo. <standard SUID binaries only> <default system cron entries only>
The id output from earlier already showed the answer: 999(docker). Docker group membership is effectively root, since a container can mount the host filesystem.
REPOSITORY TAG IMAGE ID CREATED SIZE redmine latest 0c8429c66e07 6 years ago 542MB postgres latest adf2b126dda8 6 years ago 313MB
Any local image works as the container base. Mount the host's / into the container and chroot into it.
root@container:/# whoami root
The container's root is the host's root once chrooted into the mounted filesystem.
Related
References
-
Docker group membership to root via a bind-mounted host filesystem.
-
Restricted shell escape using the ed line editor's shell command.