Hardening a Linux Server¶
1. Recon First¶
For a CTF, Grab n Crack
Grab the Hashes for Cracking (swap out the IP)¶
scp root@server_ip:/etc/passwd ./passwd
scp root@server_ip:/etc/shadow ./shadow
Unshadow¶
unshadow passwd shadow > combined.txt
Run John¶
john combined.txt
Review and Note¶
john --show combined.txt
SSH in and Change Passwords¶
ssh root@server_ip
passwd username
Document Normal Running Processes¶
ps aux > processes.txt
OS Info¶
cat /etc/os-release
2. Least Privilege¶
Review Current Permissions¶
Audit the current user accounts, groups, and their permissions on each server.
cat /etc/passwd
getent passwd
Checking GUID/SUID files¶
find / -perm -4000 -type f 2>/dev/null
find / -perm -2000 -type f 2>/dev/null
Checking for writeable directories¶
find / -type d -writable 2>/dev/null
Find writable directories in the PATH¶
echo $PATH | tr ':' '\n' | while read p; do find "$p" -writable -type d 2>/dev/null; done
Adjust Permissions¶
Adjust the permissions so that users and services have only the necessary rights to perform their duties. Use usermod
and groupmod
for this. In Windows, you can manage user permissions through the Local Users and Groups Manager or PowerShell.
Add User to a Group¶
sudo usermod -aG groupName username
Remove User from sudo¶
sudo gpasswd -d username sudo
sudo deluser username sudo
Create a New Group¶
sudo groupadd groupName
Delete a Group¶
sudo groupdel groupName
Adjust Group Privileges¶
sudo visudo
# %groupName ALL=(ALL) NOPASSWD: ALL
%groupName ALL=(ALL) NOPASSWD: /usr/bin/somecommand
Modify File Permissions (Read-Only)¶
sudo chmod 444 /path/to/file
Modify Owner or Group¶
sudo chown ownerName:groupName /path/to/file
Remove or Disable Unnecessary Accounts¶
Identify accounts that are no longer in use or unnecessary. Use userdel
on Linux or Remove-LocalUser
in PowerShell for Windows to remove them. For disabling, use usermod -L
on Linux or Disable-LocalUser
in PowerShell for Windows.
Remove User¶
sudo userdel -r userName
Lock/Disable User¶
sudo usermod -L userName
3. Secure Remote Access¶
Implement Secure Protocols
sudo nano /etc/ssh/sshd_config
Disable SSH Root Login¶
Find PermitRootLogin yes
and change it to no¶
PermitRootLogin no
Find PasswordAuthentication
and make sure it says no.¶
PasswordAuthentication no
Ensure Public Key Authentication¶
PubkeyAuthentication yes
Limit Remote Access (replacing IP_ADDRESS
with the actual IP address)¶
AllowUsers *@IP_ADDRESS
Restart SSH Service¶
sudo systemctl restart sshd
Add/Change Port 22 to 5574¶
Port 5574
Restart SSH Service¶
sudo systemctl restart sshd
4. Firewall Configuration¶
Ubuntu Firewall¶
List Running Services for Ubuntu Firewall¶
sudo systemctl --type=service --state=active
Deny All Other Incoming Traffic (first make sure you've allowed all necessary services)¶
sudo ufw default deny incoming
Allow Essential Services¶
sudo ufw default allow outgoing
sudo ufw allow 5574/tcp
sudo ufw allow <other necesary ports>
Enable UFW¶
sudo ufw enable
Check Status¶
sudo ufw status
Whitelist Team IPs¶
sudo ufw insert 1 allow from <team IP range>
5. Disable Unnecessary Services¶
systemctl disable [serviceName]
systemctl stop [serviceName]
Automated UFW Script
#!/bin/bash
list_services() {
echo "Listing running services..."
systemctl --type=service --state=active
}
configure_firewall() {
echo -e "\nConfiguring firewall rules..."
ufw default deny incoming
ufw default allow outgoing
echo "Default rules set: Deny incoming, Allow outgoing."
}
allow_services() {
echo -e "\nAllowing essential services..."
# Example to allow a specific service
while true; do
read -p "Enter service/port to allow (or type 'done' to finish): " service
[[ "$service" == "done" ]] && break
ufw allow "$service"
done
}
enable_ufw() {
echo -e "\nEnabling UFW..."
ufw enable
}
check_status() {
echo -e "\nChecking UFW status..."
ufw status
}
whitelist_ips() {
echo -e "\nWhitelisting team IPs..."
while true; do
read -p "Enter IP range to allow (or type 'done' to finish): " ip_range
[[ "$ip_range" == "done" ]] && break
ufw insert 1 allow from "$ip_range"
done
}
main() {
list_services
configure_firewall
allow_services
enable_ufw
check_status
whitelist_ips
echo -e "\nFirewall configuration completed."
}
# Execute the main function
main
6. Audit and Monitoring¶
- Enable Logging: Ensure logging is enabled for critical services. This can often be configured within the service's configuration file or through the operating system's logging facilities.
Save Off Logs Periodically¶
cp /var/log/auth.log auth.log_backup
chmod 700 auth.log_backup
Compare New Logs with Old¶
diff /var/log/auth.log auth.log_backup
- Review Logs: Regularly check the logs for any signs of suspicious activity. Tools like
logwatch
can help. Set up Fail2Ban
7. File System Permissions¶
- Review and Apply Permissions: Use
chmod
andchown
on Linux to set the correct permissions and ownership for files and directories. - Use ACLs: For more granular control, utilize Access Control Lists (ACLs) with
setfacl
.
8. Situational Awareness¶
Processes running¶
ps -elf
Network connections, routing tables, interface statistics, masquerade connections, and multicast memberships.¶
netstat -pantu
Why
To identify open ports and listening services, which can reveal services that may be vulnerable or critical to the system's operation. The -pantu options break down to show all listening (-l) and non-listening sockets (-a), TCP (-t) and UDP (-u) sockets, and the process (-p) using each socket.
Who is logged in¶
w
last
Why
To identify recent user activity and potentially find usernames or patterns of use that could be leveraged for further access or understanding of typical system usage.
Distribution-specific OS Release Info¶
cat /etc/*release*
Why
To identify the exact version of the operating system, which can be crucial for tailoring exploits to specific vulnerabilities known to exist in that version.
System Info: Kernal Version and Architecture¶
uname -a
Why
Similar to /etc/*release*
, but focused on the kernel and hardware level. This can identify potential vulnerabilities or compatibility for kernel-level exploits.
All Network Interfaces and Configs¶
/sbin/ifconfig -a
Why
To understand the network topology, identify internal and external IP addresses, and find potential network interfaces that could be used for lateral movement or identifying hidden networks.
More Powerful Version of netstat
¶
ss -tulpn
Why
To identify listening ports and the applications using them. The -tulpn options specify TCP sockets (-t), UDP sockets (-u), listening sockets (-l), processes (-p), and numerical addresses (-n). This command is especially useful for identifying services and their state, which can lead to discovering vulnerabilities or misconfigurations.