Tag: misconfiguration

  • Hardening Microcomputer Operating Systems

    IoT Security

    IoT Security involves safeguarding Internet of Things (IoT) devices and the networks they connect to from unauthorized access, misuse, data breaches, and other cyber threats. IoT devices frequently operate with limited computing power, minimal built-in security, and are deployed in large numbers, making them attractive targets for attackers seeking to exploit vulnerabilities.

    A major challenge is that many IoT devices are not adequately secured by default. Common issues include weak or hardcoded passwords, outdated firmware, insufficient encryption, and inadequate patching mechanisms. This exposes devices such as smart cameras, wearable technology, industrial sensors, and home automation systems to risks like malware infections, botnet recruitment, and data theft.

    However, awareness of these risks is growing. In recent years, governments, industry groups, and standards organizations have implemented laws, regulations, security standards, and best practices to improve IoT security. Examples include requirements for stronger authentication, regular software updates, encrypted communication, and transparency about how data is collected and stored. These measures are expected to significantly reduce the number of insecure devices in the coming years.

    Ultimately, IoT security is not just about protecting individual devices; it also involves safeguarding entire ecosystems from personal smart home networks to critical infrastructure across industries such as healthcare, transportation, and energy. As IoT adoption expands, robust security practices will be essential to maintain user trust and ensure the safe integration of billions of connected devices into daily life.


    Initial IoT Devices Security Steps

    After purchasing an IoT device with inadequate security measures, the risk of exploitation begins almost immediately. Studies have shown that unsecured IoT devices can be discovered and compromised by automated scanning tools or malicious actors within just a few minutes of being connected to the internet. Once compromised, these devices may be used in a botnet, subjected to surveillance, or manipulated in ways that threaten your data, privacy, and network security.

    To mitigate these risks, it’s important to take proactive steps before and after connecting the device to the internet. Here are some key actions you can take:

    • Check Manufacturer Information: Visit the manufacturer’s website for details on security features, firmware updates, and recommended setup practices.
    • Review Security Advisories: Many vendors provide security advisories, patch releases, or guides to help configure devices more securely.

    Practical Steps to Secure IoT Devices

    • Change Default Passwords: Replace factory-set credentials with strong, unique passwords. Default passwords are widely known and are often the first thing attackers try.
    • Update Firmware and Applications: Always install the latest updates to close known vulnerabilities. Enable automatic updates if supported to ensure security patches are applied promptly.
    • Enable Logging: Turn on activity logs to track access attempts, configuration changes, or unusual behavior. Logs can help identify suspicious activity early.
    • Disable Unused Features and Services: Shut down unnecessary services, such as remote management, Bluetooth, or Universal Plug and Play (UPnP). Each unnecessary feature is a potential entry point for attackers.
    • Enable Multi-Factor Authentication (MFA): If available, require MFA for logins. This adds an extra layer of security even if your password is compromised.
    • Block Unused Ports: Restrict network access by closing or filtering ports that the device does not use. This reduces exposure to external attacks.
    • Connect to Wi-Fi Carefully: Place IoT devices on a separate network or VLAN rather than your main network. If one device is compromised, it will be harder for it to spread to other systems, such as laptops and phones. For some devices, consider not connecting them to the internet if connectivity isn’t essential.
    • Review Application Permissions: Check what kind of data the device’s companion app collects (e.g., location, microphone, contacts) and restrict permissions to only what is necessary.
    • Turn Devices Off When Not in Use: Shutting down devices when not in use minimizes their exposure to online threats.
    • Monitor Device Activity: Use your router’s interface or a network monitoring tool to watch for unusual traffic patterns. Early detection of suspicious behavior can prevent larger compromises.

    By implementing these steps, you create multiple layers of defense that significantly reduce the likelihood of exploitation of your IoT devices. This approach, often called “defense in depth,” ensures that if one safeguard fails, others remain in place to protect your devices and network.


    Vulnerabilities vs Misconfiguration

    A misconfiguration occurs when a system, application, or device is set up incorrectly, deviating from security best practices (e.g., using weak or hard-coded passwords, having permissive firewall rules, running unnecessary services, or exposing interfaces unnecessarily). While a vulnerability is a flaw or weakness in software, hardware, or protocols that can be exploited to compromise security (e.g., an outdated SSH version with known exploits or design flaws in interfaces).

    Top IoT Vulnerabilities/Misconfiguration

    • Weak or Hard-Coded Passwords
      • Type: Misconfiguration
      • Why: Choosing a weak password or leaving a default/hard-coded password is a configuration choice. These passwords can be easily guessed or cracked by attackers.
    • Insecure Service
      • Type: Could be vulnerability or misconfiguration, depending on context
        • If the service itself has a flaw (like an old SSH version with a known exploit):
          • Type: Vulnerability
          • Why: The service contains inherent security flaws that attackers can exploit.
        • If it’s running unnecessarily or open to the network without need:
          • Type: Misconfiguration
          • Why: Running unnecessary services or exposing them to the network without proper justification is a configuration error.
    • Insecure Configuration
      • Type: Misconfiguration
      • Why: By definition, misconfiguration occurs when system settings are insecure (e.g., permissive firewall rules, open ports). These settings leave systems vulnerable to attacks.
    • Insecure Interface
      • Type: Usually a vulnerability, if the interface itself has design flaws
        • If the interface itself has design flaws:
            • Type: Vulnerability
        • Why: Design flaws in interfaces can allow attackers to exploit vulnerabilities.
        • If it’s exposed unnecessarily:
          • Type: Misconfiguration
          • Why: Exposing an interface that should be protected is a configuration error.
    • Lack of Updates
      • Type: Misconfiguration (or operational issue)
      • Why: Not applying patches is a configuration/maintenance failure that leaves systems exposed to known vulnerabilities.
    • Use Outdated Modules
      • Type: Misconfiguration (or operational issue)
      • Why: Similar to lack of updates; continuing to use old libraries or modules is a choice/configuration oversight. These outdated components may contain security flaws.
    • Poor Physical Security
      • Type: Misconfiguration (or security control failure)
      • Why: Leaving hardware unprotected is a misconfiguration of physical security measures. Proper physical security controls are essential to prevent unauthorized access to devices.

    By understanding these classifications and their underlying reasons, you can better identify and address potential security issues in your IoT devices, thereby enhancing overall system security.


    Changing the default password

    You can change the password of the user pi using the passwd command, keep in mind that the ssh will not drop

    passwd # Linux command used to change the password of the currently logged-in user

    (RPi) passwd
    Changing password for pi.
    Current password: 
    New password: 
    Retype new password: 
    passwd: password updated successfully

    or, one-liner, if you use a different username, you need to change pi to your username, this will bypass the password security controls like password length

    (RPi) # Indicates the command is executed on the Raspberry Pi device
    echo # Prints the string to standard output
    ‘pi:P@ssw0rd!’ # String in the format username:password to update the password
    | # Pipe operator; passes the output of echo as input to the next command
    sudo # Run the command with superuser (administrator) privileges
    chpasswd # Linux command that reads username:password pairs and updates user passwords

    (RPi) echo 'pi:P@ssw0rd!' | sudo chpasswd

    Force user to change password next login

    You can change the expiry information of the user pi using passwd --expire <user>, and use chage -l <user> to check the info

    sudo # Run the command with superuser (administrator) privileges
    passwd # Linux command used to change a user’s password
    –expire # Option to immediately expire the user’s password, forcing a reset on next login
    pi # The username of the account whose password will be expired (default Raspberry Pi user)

    (RPi) sudo passwd --expire pi
    passwd: password expiry information changed.

    Then

    chage # Linux command used to view or modify user password aging information
    -l # Option to list the current password aging settings for a user
    pi # The username of the account whose password aging information is being displayed

    (RPi) chage -l pi
    Last password change                    : password must be changed
    Password expires                    : password must be changed
    Password inactive                    : password must be changed
    Account expires                        : never
    Minimum number of days between password change        : 0
    Maximum number of days between password change        : 99999
    Number of days of warning before password expires    : 7

    Remove nopasswd feature

    The nopasswd feature allows a user to run the command as a sudo user without having to enter a password. This can be disabling or removing the 010_pi-nopasswd

    sudo # Run the command with superuser (administrator) privileges
    rm # Linux command to remove/delete files
    /etc/sudoers.d/ # Directory containing additional sudo configuration files
    010_* # Wildcard pattern matching all files starting with “010_” in the directory

    (RPi) sudo rm /etc/sudoers.d/010_*

    Or,

    sudo # Run the command with superuser (administrator) privileges
    visudo # Open the sudoers file in a safe editor that checks for syntax errors before saving

    sudo visudo

    change this 

    Defaults        env_reset

    to 

    Defaults        env_reset,timestamp_timeout=0

    Update & upgrade Raspberry Pi OS

    Use the apt-get update to update the package sources list (It does not install or upgrade any package). Then, apt-get upgrade to install or upgrade the packages currently installed on the system from /etc/apt/sources.list

    sudo # Run the command with superuser (administrator) privileges
    apt-get # Linux package management command used to handle software packages
    update # Option to refresh the local package index with the latest versions available from repositories

    (RPi) sudo apt-get update

    Then

    sudo # Run the command with superuser (administrator) privileges
    apt-get # Linux package management command used to handle software packages
    update # Option to install the latest versions of all currently installed packages

    (RPi) sudo apt-get upgrade

    Or one liner

    sudo # Run the command with superuser (administrator) privileges
    apt-get # Linux package management command used to handle software packages
    update # Option to refresh the local package index with the latest versions available from repositories
    && # Logical AND operator; runs the next command only if the previous one succeeds
    sudo # Run the following command with superuser privileges
    apt-get # Linux package management command
    upgrade # Option to install the latest versions of all currently installed packages

    (RPi) sudo apt-get update && sudo apt-get upgrade

    Enable Logging

    Debain OS 12 has a new way of logging using systemd-journald which it saves the logs in a centralized journal, you can access the logs using journalctl command, or you can replace that with classic logging using rsyslog

    Reviewing the last 2 hours logs

    journalctl # Linux command to query and display system logs managed by systemd
    –since # Option to filter logs starting from a specific time
    “2 hour ago” # Time specification; shows logs from the last 2 hours

    (RPi) journalctl --since "2 hour ago"

    Classic Logs, install rsyslog

    sudo # Run the command with superuser (administrator) privileges
    apt-get # Linux package management command used to handle software packages
    install # Option to install a specified package
    rsyslog # System logging daemon package to collect and manage logs

    (RPi) sudo apt-get install rsyslog

    Start the rsyslog service

    sudo # Run the command with superuser privileges
    systemctl # Command to control systemd services
    start # Option to start the specified service immediately
    rsyslog # The logging service to be started

    (RPi) sudo systemctl start rsyslog

    Enable it when the system starts

    sudo # Run the command with superuser privileges
    systemctl # Command to control systemd services
    enable # Option to configure the service to start automatically at boot
    rsyslog # The logging service to be enabled

    (RPi) sudo systemctl enable rsyslog

    Review the logs

    tail # Linux command to view the last lines of a file
    /var/log/syslog # Path to the system log file where rsyslog writes messages

    (RPi) tail /var/log/syslog

    Configure SSH key-based authentication

    The best practice is not to use a password, but key-based authentication

    First, you need to create ssh-key (Enter the needed info)

    ssh-keygen   # Generate a new SSH key pair (private + public) on the host machine

    (Host) ssh-keygen

    You need to copy the public key to the Raspberry Pi

    cat # Command to display the contents of a file
    ~/.ssh/id_rsa.pub # Path to the host’s public SSH key
    | # Pipe operator: send the output of the previous command to the next command
    ssh # Command to connect to a remote machine via SSH
    pi@jdoe.local # Remote username (pi) and host (jdoe.local)
    ‘ # Start of the remote command in single quotes
    mkdir -p .ssh/ # On the remote machine: create the .ssh directory if it doesn’t exist (-p avoids errors)
    && # Logical AND: run next command only if previous succeeds
    cat >> .ssh/authorized_keys # Append the incoming key to the authorized_keys file on the remote machine
    ‘ # End of the remote command

    (Host) cat ~/.ssh/id_rsa.pub | ssh pi@jdoe.local 'mkdir -p .ssh/ && cat >> .ssh/authorized_keys'

    or

    ssh-copy-id # Utility to copy a public SSH key to a remote host’s authorized_keys
    -i # Option to specify the identity (public key file) to copy
    ~/.ssh/id_rsa.pub # Path to the host’s public SSH key to copy
    pi@jdoe.local # Remote username (pi) and host (jdoe.local)

    (Host) ssh-copy-id -i ~/.ssh/id_rsa.pub pi@jdoe.local

    ssh to the Pi

    ssh # The SSH command used to securely connect to a remote machine
    pi@jdoe.local # Specifies the remote username (pi) and hostname or IP address (jdoe.local)

    (Host) ssh pi@jdoe.local

    You need to re-configure sshd

    sudo # Run the following command with superuser (root) privileges
    nano # Opens the nano text editor in the terminal
    /etc/ssh/sshd_config # Path to the SSH server configuration file on the Pi

    (RPi) sudo nano /etc/ssh/sshd_config

    Change the values of these (Remove # at the beginning) and save the file

    PermitRootLogin no
    PasswordAuthentication no
    ChallengeResponseAuthentication no
    UsePAM no

    Now, you need to reload sshd service

    sudo # Run the following command with superuser (root) privileges
    systemctl # The systemd command to control system services
    reload # Reload the service configuration without fully stopping the service
    sshd # The SSH daemon (server) service

    (RPi) sudo systemctl reload sshd

    If you try to connect without a key, it will output Permission denied (publickey)

    ssh # Command to connect to a remote machine via SSH
    pi@jdoe.local # Remote username (pi) and hostname (jdoe.local)
    -o # Option flag to specify a configuration setting for this SSH session
    PubKeyAuthentication=no # Disable public key authentication for this session (forces password login)

    (Host) ssh pi@jdoe.local -o PubKeyAuthentication=no

    Current Connections

    You can check current connections using the netstat command

    sudo # Run the following command with superuser (root) privileges
    netstat # Network statistics tool that shows network connections, routing tables, interface stats, etc.
    -t # Show TCP connections only
    -u # Show UDP connections only
    -p # Show the PID and name of the program using each socket
    -l # Show only listening sockets (services waiting for connections)
    -a # Show all sockets (both listening and non-listening)
    -n # Show numerical addresses instead of resolving hostnames

    (RPi) sudo netstat -tuplan
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      569/sshd: /usr/sbin 
    tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      1221/cupsd          
    tcp6       0      0 :::22                   :::*                    LISTEN      569/sshd: /usr/sbin 
    tcp6       0      0 ::1:631                 :::*                    LISTEN      1221/cupsd          
    tcp6       0    476 2601:1d3:xxxx:xxxx:c:22 2601:1d3:xxxx:xxx:52976 ESTABLISHED 2246/sshd: pi [priv
    udp        0      0 0.0.0.0:5353            0.0.0.0:*                           357/avahi-daemon: r 
    udp        0      0 0.0.0.0:68              0.0.0.0:*                           477/dhcpcd          
    udp        0      0 0.0.0.0:631             0.0.0.0:*                           1223/cups-browsed   
    udp        0      0 0.0.0.0:56974           0.0.0.0:*                           357/avahi-daemon: r 
    udp6       0      0 :::5353                 :::*                                357/avahi-daemon: r 
    udp6       0      0 :::47980                :::*                                357/avahi-daemon: r 
    udp6       0      0 :::546                  :::*                                477/dhcpcd          

    Disable a service

    You can disable a service using the systemctl command. Let’s say that you want to stop, then disable the xyz service. So, you will use systemctl stop xyz, then systemctl disable xyz

    systemctl # The systemd command to manage services, units, and dependencies
    –reverse # Shows reverse dependencies: which units depend on the specified unit
    list-dependencies # List all dependencies (or reverse dependencies with –reverse) for the specified unit
    cups.* # Target unit(s): all services matching the pattern “cups.*” (CUPS printing services)

    (RPi) systemctl --reverse list-dependencies cups.*
    cups.socket
    ● ├─cups.service
    ● └─sockets.target
    ●   └─basic.target
    ●     └─multi-user.target
    ●       └─graphical.target

    cups.service
    ● └─cups-browsed.service

    cups.path
    ● ├─cups.service
    ● └─multi-user.target
    ●   └─graphical.target

    Next

    sudo # Run the following command with superuser (root) privileges
    systemctl # The systemd command to manage services, units, and their states
    stop # Stop the specified service(s) or unit(s) immediately
    cups # Target unit/service (CUPS, Common Unix Printing System)
    cups.service # Explicitly stop the main CUPS service unit
    cups.socket # Stop the socket unit for CUPS (handles incoming connections)
    cups.path # Stop any path-based triggers for CUPS

    (RPi) sudo systemctl stop cups cups.service cups.socket cups.path

    Then

    sudo # Run the following command with superuser (root) privileges
    systemctl # The systemd command to manage services, units, and their states
    disable # Disable the specified unit(s) from starting automatically at boot
    cups # Target unit/service (CUPS, Common Unix Printing System)
    cups.service # Explicitly stop the main CUPS service unit
    cups.socket # Stop the socket unit for CUPS (handles incoming connections)
    cups.path # Stop any path-based triggers for CUPS

    (Physical or VM) sudo systemctl disable cups cups.service cups.socket cups.path

    Block a Port or IP

    You can configure the host-based firewall ufw in Raspberry Pi OS, which is a frontend for iptables. ufw may need to be installed. Be extra careful, any mistake may block your connection. To check the list of apps, you can use sudo ufw app list

    Example (Enabling only SSH)

    Install the UFW and iptables

    sudo # Run the following command with superuser (root) privileges
    apt-get # Debian/Ubuntu package manager command (handles installing, updating, removing packages)
    install # Tells apt-get to install the following package(s)
    ufw # Installs UFW (Uncomplicated Firewall) for easier firewall management
    iptables # Installs iptables, the low-level Linux firewall tool used by UFW and for custom rules

    Deny all incoming connection to the system

    sudo # Run the following command with superuser (root) privileges
    ufw # Uncomplicated Firewall command-line tool
    default # Modify default firewall policy
    deny # Action to take on incoming connections (block)
    incoming # Applies the action to incoming traffic

    (RPi) sudo ufw default deny incoming

    sudo # Run the following command with superuser (root) privileges
    ufw # Uncomplicated Firewall command-line tool
    default # Modify default firewall policy
    allow # Permit traffic (action to take)
    outgoing # Apply this action to outgoing connections

    (RPi) sudo ufw default allow outgoing

    sudo # Run the following command with superuser (root) privileges
    ufw # Uncomplicated Firewall command-line tool
    allow # Permit traffic (action to take)
    ssh # Service name to allow (default TCP port 22, used for remote SSH connections)

    (RPi) sudo ufw allow ssh

    sudo # Run the following command with superuser (root) privileges
    ufw # Uncomplicated Firewall command-line tool
    enable # Turn on the firewall with all the currently defined rules

    (RPi) sudo ufw enable

    To check the UFW logs

    sudo # Run the following command with superuser (root) privileges
    ufw # Uncomplicated Firewall command-line tool
    status # Display the current status of the firewall (active or inactive)
    verbose # Show detailed information, including default policies and all configured rules

    (RPi) sudo ufw status verbose

    Then

    sudo # Run the following command with superuser (root) privileges
    less # Open a file in a scrollable, read-only pager (you can navigate with arrows, page up/down)
     /var/log/ufw* # Path to all UFW log files (the asterisk * includes ufw.log and any rotated logs like ufw.log.1)

    (RPi) sudo less /var/log/ufw*

    Disable Bluetooth (not applicable)

    If the Bluetooth feature is not needed, you can disable it

    sudo # Run the following command with superuser (root) privileges
    echo # Print the text or string provided to standard output
    “dtoverlay=disable-bt” # The text/string to append; in this case, a device tree overlay that disables Bluetooth
    >> # Append operator: adds the output to the end of the specified file without overwriting it
    /boot/config.txt # The target file where the string will be appended (Raspberry Pi boot configuration file)

    (RPi) sudo echo "dtoverlay=disable-bt" >> /boot/config.txt

    Disable WiFi (not applicable)

    If the WiFi feature is not needed, you can disable it

    sudo # Run the following command with superuser (root) privileges
    echo # Print the text or string provided to standard output
    “dtoverlay=disable-wifi” # The text/string to append; in this case, a device tree overlay that disables Wi-Fi
    >> # Append operator: adds the output to the end of the specified file without overwriting it
    /boot/config.txt # The target file where the string will be appended (Raspberry Pi boot configuration file)

    (RPi) sudo echo "dtoverlay=disable-wifi" >> /boot/config.txt

    Backup

    If you want to backup a target folder, you can use the rsync command

    rsync # Remote file synchronization tool for copying files and directories efficiently
    -avzPi # Combined options: (a) Archive mode: preserves symbolic links, permissions, timestamps, etc. (v) Verbose: shows detailed output of what is being copied. (z) Compress: compress data during transfer for efficiency. (P) Partial + progress: keeps partially transferred files and shows progress. (i) Itemize changes: shows a summary of what changes were made to files
    -e ssh # Specifies the remote shell to use (SSH) for secure transfer
    pi@192.168.10.2:/home/ # Source: user ‘pi’ on host ‘192.168.10.2’, path ‘/home/’
    /destination # Destination path on the local host where files will be copied

    (Host) rsync -avzPi -e ssh pi@192.168.10.2:/home/ /destination

    If you want to do a full backup, it’s recommended that you do it on a running system, not remotely (You can use the dd command with gzip).

    To perform a full backup

    sudo # Run the following command with superuser (root) privileges
    dd # Disk dump tool: copies raw data from one location to another
    if=/dev/mmcblk0 # Input file: the entire SD card (mmcblk0 is the main storage device for Raspberry Pi)
    bs=4M # Block size: read/write 4 megabytes at a time (improves performance)
    status=progress # Show ongoing progress while copying
    | # Pipe operator: send the output of dd to the next command
    gzip # Compress the raw disk image using gzip
    > pi.gz # Redirect the compressed output to a file named pi.gz

    (RPi) sudo dd if=/dev/mmcblk0 bs=4M status=progress | gzip > pi.gz 

    To restore from a full backup

    gunzip # Decompress gzip-compressed files
    –stdout # Output decompressed data to standard output (do not create a file)
    > pi.gz # Redirect standard output to pi.gz (this actually overwrites pi.gz instead of sending to dd)
    | # Pipe operator: send output from left side to right side (does not work correctly with ‘> pi.gz’)
    sudo # Run the following command with superuser (root) privileges
    dd # Disk copy tool: writes raw data to a device
    of=/dev/mmcblk0 # Output file: the SD card device
    bs=4M # Block size: write 4 MB at a time
    status=progress # Show ongoing progress while writing

    (RPi) gunzip --stdout > pi.gz | sudo dd of=/dev/mmcblk0 bs=4M status=progress