Ravindra BagaleCourses & study guides मराठी Track your progress

32. Linux and Network Hardening

32.4 Patching, Users, Permissions and Services

Patching fixes known vulnerabilities – the ones Nessus/OpenVAS found in Chapter 20.

sudo yum check-update                  # what needs updating
sudo yum update -y                     # apply all updates
sudo yum update --security -y          # only security updates (where supported)
sudo yum install -y dnf-automatic 2>/dev/null || true   # automatic updates on newer releases; review before enabling

Users and sudo:

sudo awk -F: '$3==0 {print $1}' /etc/passwd     # only root should have UID 0
sudo awk -F: '($2==""){print $1}' /etc/shadow    # accounts with empty passwords
sudo lastlog | grep -v "Never"                   # who has logged in
sudo userdel -r olduser                          # remove unused accounts
sudo visudo                                      # edit sudo rules safely
sudo chage -M 90 -W 7 deploy                     # password expiry for password users

File permissions:

sudo chmod 600 /etc/ssh/sshd_config
sudo chmod 640 /var/www/html/config.php && sudo chown root:apache /var/www/html/config.php
sudo find / -xdev -perm -4000 -type f 2>/dev/null   # SUID files (privilege escalation, Chapter 26)
sudo find / -xdev -type f -perm -0002 2>/dev/null   # world-writable files

Services: stop and disable what you do not need.

sudo systemctl list-unit-files --type=service --state=enabled
sudo service vsftpd stop && sudo systemctl disable vsftpd
sudo yum remove -y telnet-server rsh-server

Also keep SELinux in enforcing mode on RHEL-family servers (getenforce should print Enforcing) instead of turning it off to "fix" permission errors.

Ravindra Bagale's Tip

When Apache can't read a file, students run chmod 777 or disable SELinux. Both are dangerous! Set the right owner (chown) and the right permissions (640/750), and for SELinux use restorecon -Rv /var/www/html. 777 means leaving the door open for everyone.

Lab

On Metasploitable or your lab server: list all UID 0 accounts, all SUID files and all enabled services. Remove one unneeded service, fix the permissions of your app's config.php to 640, and run sudo yum update -y. Re-run Lynis and compare the hardening index with 32.1.

Extended teaching notes

Why this lesson matters

Hardening is deleting unnecessary risk: fewer packages, fewer open ports, fewer privileged accounts, faster patches, better logs.

Hardening related services

[('SSH', 'Key auth, no root login, Fail2ban or equivalent, SG limited to your IP/VPN.', '', ''), ('SMB / NFS / LDAP / SNMP', 'Do not expose to the internet; patch; strong auth; disable unused versions (e.g. SMBv1).', '', ''), ('SMTP', 'Authenticated relay only; SPF/DKIM/DMARC for your domains.', '', ''), ('DNS', 'Restrict zone transfers; monitor for unexpected records (crt.sh for certs).', '', ''), ('Firewalls', 'Host firewall + cloud SG/NSG; default deny; document every allow.', '', '')]

Real examples

Global: CIS Benchmarks exist for Linux, Windows and clouds. Indian company (sample): a Pune team requires SSH keys only and weekly patch windows for internet-facing hosts.

Mini case study

Suppose we are on a purple-team exercise for an Indian mid-size company (sample data). Red notes a technique from this lesson against a lab clone. Blue must show the control that stops it, the log that would have fired, and the ticket that hardens production. That is the standard this course trains you for.

Defender's worksheet (do this today)

  1. Write the lesson title, date and the exact lab target you are allowed to use.
  2. List three owned systems (VMs, apps, or cloud accounts) where this lesson applies.
  3. Run one safe check from the lesson on a lab system only. Paste the command and output.
  4. Write a two-sentence fix you would give a teammate.
  5. Name one related public advisory (CERT-In, CISA, NVD, or a vendor bulletin) with its date.

Indian workplace (sample data)

Suppose we are a junior analyst at Infosys, TCS, Wipro or a fintech SOC in Bengaluru/Pune. Turn this lesson into one checklist item with an owner, a due date and a place to store evidence (ticket + screenshot).

Global practice

Compare your notes with OWASP, CIS Benchmarks, NIST CSF/IR guidance or a cloud Well-Architected security question. Write five lines on what overlaps.

Everyday analogy

Explain the risk and the fix to a family member without jargon. If they can repeat the warning, you understand it well enough to teach juniors.

Key terms

  • Control: a safeguard (patch, config, process, detection).
  • Finding: a weakness backed by evidence.
  • Remediation: the fix plus how you verified it.
  • Scope: systems you have written permission to touch.
  • Least privilege: only the access the task needs.
  • Defence in depth: several layers so one failure does not end the story.

Common mistakes

  • Skipping written permission "just for a quick scan".
  • Practising on hostel, office or public targets without authorisation.
  • Collecting tool output without writing the fix.
  • Copying attack steps onto production to "verify". Defenders verify with versions, configs and patches.
  • Publishing screenshots that contain secrets, cookies or internal hostnames.

Recap

  • Evidence, fix, owner, date.
  • Own lab only.
  • Fix > spectacle.

Real incident: BeyondTrust Remote Support zero-day CVE-2026-102764 – from a web shell to root, stolen admin access and deleted logs (Oct 2026)

1. What happened

BeyondTrust Remote Support (earlier called Bomgar) is an appliance that IT help desks use to connect to company computers and fix them from far away. Because it can reach so many machines, it also stores and hands out many admin passwords and keys.

  • On 15 October 2026, BeyondTrust disclosed CVE-2026-102764, a critical flaw in Remote Support versions 26.2.3 and earlier. An attacker on the internet without any login could perform file operations on the appliance.
  • Mandiant (Google Threat Intelligence Group) found that a suspected China-nexus espionage group it calls ARMORY CASTLE (earlier tracked as UNC5221) used the flaw as a zero-day in late August 2026, before any patch existed.
  • BeyondTrust says the group hit one BeyondTrust-hosted instance and one self-hosted appliance on 29 August. BeyondTrust's own threat hunting found the hosted case on 28 September and contained it within 27 minutes. The patch (BT26-05) came out on 8 October; hosted (SaaS) customers were patched automatically.
  • On 16 October 2026, CISA said the flaw is being actively exploited and urged everyone to patch. Mandiant warned that wider attacks on unpatched appliances may follow now that the bug is public.
  • BeyondTrust also shared an honest lesson: its sensors did fire when the attacker became root, but an automated triage tool closed those alerts as false positives.

2. How the hack happened (public reporting only – high-level)

  1. The attacker sent requests to the internet-facing appliance and used the flaw to place a small web shell (a hidden script that runs commands) in the appliance's web folder. No password was needed.
  2. The web shell ran as the low-privilege web service account. To become root, the attacker made a copy of the system shell owned by root with the SUID bit set – the same SUID privilege-escalation idea from Chapter 26.
  3. For persistence, the attacker changed the appliance's startup and configuration template so the service account got passwordless sudo. Because the template rebuilds the sudo rules, the backdoor survived reboots and configuration resets.
  4. As root, the attacker tried to read the appliance's stored password vault, then logged in to the admin portal with an Administrator account and raised that account's rights so it could open remote sessions to internal computers.
  5. Through those remote sessions the attacker downloaded internal documents such as software lists, and set up a hidden tunnel through the appliance's own reverse proxy.
  6. Again and again, the attacker deleted system, web and application logs to hide what they did.

3. How to stop it / defend (this lesson: patching, users, permissions and services)

  • Patch internet-facing appliances first, and fast. VPNs, firewalls and remote-support boxes are the favourite door for this kind of group. Watch vendor advisories and the CISA Known Exploited Vulnerabilities (KEV) list, and patch those systems within days, not months.
  • Hide admin pages from the internet. Allow the admin portal only from your office network or VPN (the same idea as allowing SSH only from your IP with firewalld or ufw in 32.3). Expose only the parts that customers and staff really need.
  • Know your SUID files. Save today's list from find / -xdev -perm -4000 -type f and compare it every week. A new SUID file that is just a copy of a shell is a red flag.
  • Guard sudo rules and startup scripts. Review visudo and /etc/sudoers.d/ regularly. A service account should never have NOPASSWD: ALL. Use file-integrity monitoring (for example AIDE or Wazuh FIM) on sudo files, startup scripts and web folders.
  • Get your logs off the box. Forward logs to a central SIEM in near real time (Chapter 31). The attacker deleted local logs, so the off-box copy is often the only proof left. Alert when logs suddenly stop arriving.
  • Don't let a robot close serious alerts alone. Keep high-severity alerts for a human, and hunt for behaviour (new web scripts, a web account starting shells, new admin rights) even when no alert fired.

4. How to take care so it won't happen again (checklist)

  • [ ] If you run self-hosted BeyondTrust Remote Support or Privileged Remote Access, apply BT26-05 now and follow the vendor advisory.
  • [ ] If the appliance was reachable from the internet on a vulnerable version, treat it as possibly compromised: save evidence, rebuild from a clean patched image, then rotate every password and key it stored – after patching, not before.
  • [ ] Keep a list of every internet-facing appliance, its version and owner, and check it against the KEV list every week.
  • [ ] Keep a baseline of SUID files and sudo rules, and compare it on a schedule.
  • [ ] Allow admin portals only from trusted networks, with SSO and strong MFA for every admin.
  • [ ] Confirm that logs are reaching your SIEM every day, and review alerts that were closed automatically.

Source: BeyondTrust Security Team, "ARMORY CASTLE and BT26-05: What Security Teams Need to Know", 15 October 2026 (updated 16 October 2026); Mandiant / Google Threat Intelligence Group, "ARMORY CASTLE Exploits BeyondTrust", 15 October 2026; CISA alert "CISA Urges Patching Critical Vulnerability in BeyondTrust Remote Support", 16 October 2026; The Record, "Suspected Chinese espionage attackers abusing BeyondTrust IT support zero-day", 16 October 2026.

Check if you're safe: Is My Website Hacked? · Website Security Checklist · Password Strength Checker

Real incident: Alpine Linux GitLab – a late, half-applied patch let an attacker get close, so the server was rebuilt from scratch (Oct 2026)

1. What happened

In this lesson you learnt that patching means two things: install the fix quickly, and then check that the fix is really there. This real case shows what goes wrong when either step slips.

  • Alpine Linux is a small Linux system used inside many Docker containers. Its developers keep their code on their own GitLab server. GitLab is a website where teams store code and run automatic build jobs, called CI (continuous integration).
  • A CVE is a public ID number for a security bug. CVE-2026-97229 is a critical bug (score 10 out of 10) in the part of Ruby that reads patterns in CI settings. Ruby is the programming language GitLab is built on. A bad pattern could let an attacker run their own commands on the server. This is called RCE (remote code execution).
  • GitLab released the fix on 12 October 2026. On 13 October Alpine upgraded, but by mistake picked version 19.3.4, which did not have the fix, instead of 19.3.5, which did.
  • On 20 and 21 October, a newly registered account sent specially made CI settings to Alpine's GitLab. GitLab crashed 8 times. In 4 of those crashes the attacker got part of the way and then failed.
  • On 22 October Alpine upgraded again, to 19.3.6. It still did not fix the bug. The fix was a patch to Ruby that GitLab only puts in its own official packages. Alpine's own container image used normal Ruby, so it never got the patch.
  • Alpine found no proof that the attacker ran code. But some logs were gone and there was no record of outgoing connections, so they could not be sure. They closed GitLab on 27 October, rebuilt it from scratch, reset all passwords, 2FA, tokens and stored secrets, and reopened it on 29–30 October.
  • Alpine says its packages, releases and signing keys were not affected. The signing keys were never stored on the GitLab server.

2. How the hack happened (public reporting only – high-level)

  1. A fix for a critical bug was published, so attackers knew the bug existed.
  2. Alpine's server stayed unpatched for over a week because the wrong version was installed.
  3. The attacker made a new account on the public GitLab and probed it.
  4. The attacker downloaded Alpine's own GitLab container image, which suggests they were tuning the attack to that exact build.
  5. The attacker sent crafted CI settings that crashed the server again and again, getting close but not fully succeeding (as far as anyone can tell).
  6. An upgrade that looked correct still left the bug open, because the real fix was inside a bundled part (Ruby) that the custom image did not include.

3. How to stop it / defend (this lesson: patching)

Why: a published fix is also a public map of the bug. The days between the fix and your update are the most dangerous days.

Controls you can use:

  1. Patch critical bugs within a day on anything open to the internet. Alpine now aims for this.
  2. Read the advisory and note the exact fixed version. Then check that the version you installed is that version or newer.
  3. Check the parts inside the app too. If you build your own image, a fix may live in a bundled part, like Ruby, OpenSSL or Java. Updating only the main app is not enough.
  4. Close or limit open sign-up on internal tools, so a stranger cannot create an account and reach risky features.
  5. Keep logs long enough (more than 14 days) and record outgoing connections, so you can prove what did or did not happen.
  6. When you cannot be sure, rebuild. A clean new server, new passwords and new secrets remove anything an attacker may have left behind.
  7. Keep signing keys off the main server, so even a full break-in cannot sign fake releases.

Example 1: see which version of a package is installed.

  1. Open a terminal on your Linux server (RHEL, Rocky or Amazon Linux).
  2. Run rpm -q ruby
  3. Output: one line, like ruby-3.3.12-1.el9.x86_64.
  4. What it means: Ruby 3.3.12 is installed. The advisory says the fix is in 3.3.13 or newer, so this server is still open to the bug.

Example 2: list the security updates that are waiting.

  1. Use the same terminal.
  2. Run sudo dnf updateinfo list --security
  3. Output: one line per waiting fix, like RHSA-2026:8812 Important/Sec. ruby-3.3.13-1.el9.x86_64.
  4. What it means: a security fix for Ruby is ready. Install it with sudo dnf upgrade --security, then run Example 1 again and confirm it now shows 3.3.13.

Example 3: check the version inside a running container (the step Alpine missed).

  1. Find the container name with docker ps. Here it is gitlab.
  2. Run docker exec gitlab ruby --version
  3. Output: like ruby 3.3.12 (2026-07-10 revision 1a2b3c4d5e) [x86_64-linux].
  4. What it means: the server may be patched, but this container still runs the old Ruby. Rebuild or pull a fixed image, restart the container, and check again.

4. How to take care so it won't happen again (checklist)

  • [ ] I install critical security fixes within one day on internet-facing servers.
  • [ ] After every patch, I check the installed version against the advisory.
  • [ ] I also check bundled parts (Ruby, OpenSSL, Java) inside my containers and custom images.
  • [ ] Public sign-up is off, or limited, on internal tools like GitLab.
  • [ ] I keep logs for more than 14 days, including outgoing connections.
  • [ ] If I cannot rule out a break-in, I rebuild and reset all passwords, tokens and secrets.
  • [ ] My signing keys are not stored on the same server as my code tools.
  • [ ] I never reuse my work password on other sites.

Source: Alpine Linux, "GitLab security incident: attempted exploitation of CVE-2026-97229", 28 October 2026 (updated 30 October 2026); Alpine Linux, "GitLab is back: what you need to do", 30 October 2026; BleepingComputer, "Alpine Linux rebuilds GitLab after attempted RCE attack" (Bill Toulas), 1 November 2026.

Ravindra Bagale's Tip

Upgrading is not the same as being fixed. After every security update, run one command to see the real installed version, and compare it with the advisory. Alpine upgraded twice and was still open, because nobody checked the version inside the container.

Check if you're safe: Website Security Checklist · Password Strength Checker