目录
— 5 —
强化内存分配器
hardened_malloc是一种硬化的内存分配器,可为堆内存损坏漏洞提供实质性的保护。它很大程度上基于OpenBSD的malloc设计,但具有许多改进。
可以通过LD_PRELOAD环境变量针对每个应用程序使用hardened_malloc。例如,假设您编译的库位于/usr/lib/libhardened_malloc.so,则可以执行:
LD_PRELOAD="/usr/lib/libhardened_malloc.so" $program
通过全局预加载该库,也可以在系统范围内使用它,这是使用它的推荐方法。为此,请编辑/etc/ld.so.preload并插入:
/usr/lib/libhardened_malloc.so
尽管大多数应用程序都可以正常工作,但hardened_malloc可能会破坏某些应用程序。建议使用以下选项编译hardened_malloc以最大程度地减少损坏:
CONFIG_SLAB_QUARANTINE_RANDOM_LENGTH=0 CONFIG_SLAB_QUARANTINE_QUEUE_LENGTH=0 CONFIG_GUARD_SLABS_INTERVAL=8
您还应该使用sysctl设置以下内容,以适应hardened_malloc创建的大量保护页:
vm.max_map_count=524240
Whonix项目[7]为基于Debian的发行版提供了hardened_malloc软件包。
— 6 —
强化编译标志
编译自己的程序可以带来很多好处,因为它使您能够优化程序的安全性。但是,执行完全相反的操作并降低安全性很容易,如果您不确定自己在做什么,请跳过本节。在基于源的发行版(例如Gentoo)上,这将是最简单的,但也可以在其他发行版上这样做。
某些编译选项可用于添加其他漏洞利用缓解措施,从而消除整个类别的常见漏洞。您可能听说过常规保护,例如位置独立可执行文件,堆栈粉碎保护程序,立即绑定,只读重定位和FORTIFY_SOURCE,但是本节将不做介绍,因为它们已被广泛采用。相反,它将讨论诸如控制流完整性和影子堆栈之类的现代漏洞利用缓解措施。
本节涉及主要用C或C ++编写的本机程序。您必须使用Clang编译器,因为这些功能在GCC上不可用。请记住,由于未广泛采用这些缓解措施,因此某些应用程序在启用它们后可能无法运行。
控制流完整性(CFI)是一种缓解漏洞利用的方法,旨在防止诸如ROP或JOP之类的代码重用攻击。由于更广泛采用的缓解措施(例如NX)使过时的利用技术过时了,因此使用这些技术利用了很大一部分漏洞。Clang支持细粒度的前沿CFI,这意味着它可以有效缓解JOP攻击。Clang的CFI本身并不能减轻ROP;您还必须使用下面记录的单独机制。要启用此功能,必须应用以下编译标志:-flto -fvisibility=hidden -fsanitize=cfi
影子堆栈通过将程序复制到其他隐藏堆栈中来保护程序的返回地址。然后比较主堆栈和影子堆栈中的返回地址,看两者是否不同。如果是这样,则表明存在攻击,程序将中止,从而减轻了ROP攻击。Clang具有称为ShadowCallStack的功能,可以完成此操作,但是,仅在ARM64上可用。要启用此功能,必须应用以下编译标志:-fsanitize=shadow-call-stack
如果上述ShadowCallStack不是一个选项,则可以选择使用具有相似目标的SafeStack。但是,不幸的是,此功能有许多漏洞,因此效果不甚理想。如果仍然希望启用此功能,则必须应用以下编译标志:-fsanitize=safe-stack
最常见的内存损坏漏洞之一是未初始化的内存。Clang有一个选项可以使用零或特定模式自动初始化变量。建议将变量初始化为零,因为使用其他模式比利用漏洞缓解功能更适合发现错误。要启用此功能,必须应用以下编译标志:-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang 但该选项的存在目前正在辩论[8]中。
— 7 —
内存安全语言
用内存安全语言编写的程序会自动受到保护,免受各种安全漏洞的影响,这些安全漏洞包括缓冲区溢出,未初始化的变量,售后使用等。Microsoft和Google的安全研究人员进行的研究证明,已发现的大多数漏洞都是内存安全问题。这样的内存安全语言的示例包括Rust,Swift和Java,而内存不安全语言的示例包括C和C ++。如果可行,应使用内存安全替代品替换尽可能多的程序。
— 8 —
Root账户
root可以执行任何操作,并且可以访问您的整个系统。因此,应尽可能将其锁定,以使攻击者无法轻松获得root用户访问权限。
/etc/securetty
/etc/securetty文件指定允许您以root用户身份登录的位置。该文件应保留为空,以便任何人都不能从终端上这样做。
限制su
su可让您从终端切换用户。默认情况下,它尝试以root用户身份登录。要将su的使用限制在wheel组中,请编辑/etc/pam.d/su和/etc/pam.d/su-l并添加:
auth required pam_wheel.so use_uid
您应该在wheel组中拥有尽可能少的用户。
锁定root账户
要锁定root帐户以防止任何人以root身份登录,请执行:
passwd -l root
在执行此操作之前,请确保您具有获取根的替代方法(例如,从活动USB引导并更改为文件系统的chroot),以免您无意中将自己锁定在系统之外。
拒绝通过SSH的远程root登陆
为了防止某人通过SSH以root身份登录,请编辑/etc/ssh/sshd_config并添加:
PermitRootLogin no
增加散列回合数
您可以增加shadow使用的哈希回合数,从而通过迫使攻击者计算更多的哈希值来破解您的密码,从而提高哈希密码的安全性。默认情况下,shadow使用5000次回合,但是您可以将其增加到任意数量。尽管配置的回合越多,登录速度就越慢。编辑/etc/pam.d/passwd并添加回合选项。
password required pam_unix.so sha512 shadow nullok rounds=65536
这使shadow执行65536次散列回合。
应用此设置后,密码不会自动重新加密,因此您需要使用以下方法重置密码:
passwd $username
限制Xorg root访问
默认情况下,某些发行版以root用户身份运行Xorg,这是一个问题,因为Xorg包含大量古老而又复杂的代码,这增加了巨大的攻击面,并使其更有可能拥有可以获取root特权的漏洞利用程序。要阻止它作为root用户执行,请编辑/etc/X11/Xwrapper.config并添加:
needs_root_rights = no
安全访问root
恶意软件可以使用多种方法来嗅探root帐户的密码。因此,访问根帐户的传统方式是不安全的,最好根本不访问根,但这实际上是不可行的。本节详细介绍了访问根帐户的最安全方法。在安装操作系统后,应立即应用这些说明,以确保该软件不含恶意软件。
您绝对不能使用普通用户帐户访问root,因为root可能已被盗用。您也不能直接登录到根帐户。通过执行以下操作,创建一个单独的“管理员”用户帐户,该帐户仅用于访问root用户,而不能用于访问其他用户:
useradd admin
执行并来设置一个非常强的密码:
passwd admin
仅允许该帐户使用您首选的权限提升机制。例如,如果使用sudo,则通过执行以下命令来添加sudoers异常:
visudo -f /etc/sudoers.d/admin-account
然后输入:
admin ALL=(ALL) ALL
确保没有其他帐户可以访问sudo(或您的首选机制)
现在,要实际登录到该帐户,请先重新启动-例如,这可以防止受损的窗口管理器执行登录欺骗。当提供登录提示时,请通过按键盘上的以下组合键来激活安全注意键:
Alt + SysRq + k
这将杀死当前虚拟控制台上的所有应用程序,从而克服登录欺骗攻击。现在,您可以安全地登录到您的管理员帐户,并使用root用户执行任务。完成后,注销管理员帐户,然后重新登录到非特权用户帐户。
— 9 —
防火墙
防火墙可以控制传入和传出的网络流量,并且可以用来阻止或允许某些类型的流量。除非有特殊原因,否则应始终阻止所有传入流量。建议设置严格的iptables或nftables防火墙。火墙必须针对您的系统进行微调,并且没有一个适合所有防火墙的规则集。建议您熟悉创建防火墙规则。Arch Wiki[9]和手册页[10]都是很好的资源。
这是基本iptables配置的示例,该配置禁止所有传入的网络流量:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:TCP - [0:0]
:UDP - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
COMMIT
但是,您不应尝试在实际系统上使用此示例。它仅适用于某些台式机系统。
— 10 —
身份标识
为了保护隐私,最好最大程度地减少可追溯到您的信息量。
主机名和用户名
请勿在主机名或用户名中添加唯一标识的内容。将它们保留为通用名称,例如“host”和“user”,以便它们无法识别您。
Timezones / Locales / Keymaps
如果可能,应将您的时区设置为“ UTC”,将区域设置和键盘映射设置为“ US”。
机器ID
一个独一无二的机器ID被存储在/var/lib/dbus/machine-id (systemd系统是保存在/etc/machine-id)这些应编辑为通用名称,例如Whonix ID。
b08dfa6083e7567a1921a715000001fb
MAC地址欺骗
MAC地址是分配给网络接口控制器(NIC)的唯一标识符。每次您连接到网络时(WIFI或以太网)则您的MAC地址已暴露。这使人们可以使用它来跟踪您并在本地网络上唯一地标识您。
但您不应该完全随机化MAC地址。拥有完全随机的MAC地址是显而易见的,并且会对您脱颖而出的行为产生不利影响。
MAC地址的OUI(组织唯一标识符)部分标识芯片组的制造商。对MAC地址的这一部分进行随机化处理可能会为您提供以前从未使用过的OUI,数十年来从未使用过的OUI或在您所在的地区极为罕见的OUI,因此使您脱颖而出,很明显地表明您在欺骗MAC地址。
MAC地址的末尾标识您的特定设备,并且可以用来跟踪您的设备。仅对MAC地址的这一部分进行随机化可防止您被跟踪,同时仍使MAC地址看起来可信。
要欺骗这些地址,请首先执行以下命令找出您的网络接口名称:
ip a
接下来,安装macchanger并执行:
macchanger -e $network_interface
要在每次引导时随机分配MAC地址,您应该为您的特定初始化系统创建一个初始化脚本。这是systemd的一个示例:
[Unit]
Description=macchanger on eth0
Wants=network-pre.target
Before=network-pre.target
BindsTo=sys-subsystem-net-devices-eth0.device
After=sys-subsystem-net-devices-eth0.device
[Service]
ExecStart=/usr/bin/macchanger -e eth0
Type=oneshot
[Install]
WantedBy=multi-user.target
上面的示例在启动时欺骗了eth0接口的MAC地址。将eth0替换为您的网络接口。
时间攻击
几乎每个系统都有不同的时间。这可用于时钟偏斜指纹攻击,几毫秒的差异足以使用户被暴露识别。
ICMP时间戳:
ICMP时间戳会在查询答复中泄漏系统时间。阻止这些攻击的最简单方法是利用防火墙阻止传入连接,或者使内核忽略ICMP请求。
TCP时间戳:
TCP时间戳也会泄漏系统时间。内核尝试通过对每个连接使用随机偏移量来解决此问题,但这不足以解决问题。因此应该禁用TCP时间戳,可以通过使用sysctl设置以下内容来完成:
net.ipv4.tcp_timestamps=0
TCP初始化序号:
TCP初始序列号(ISN)是泄漏系统时间的另一种方法。为了减轻这种情况,您必须安装tirdad内核模块,该模块会生成用于连接的随机ISN。
时间同步:
时间同步对于匿名性和安全性至关重要。错误的系统时钟可能使您遭受时钟偏斜指纹攻击,或者可以用来为您提供过时的HTTPS证书,从而绕过证书到期或吊销。
最流行的时间同步方法NTP是不安全的,因为它未经加密和未经身份验证,因此攻击者可以轻易地拦截和修改请求。NTP还会以NTP时间戳格式泄漏本地系统时间,该格式可用于时钟偏斜指纹识别,如前所述。
因此,您应该卸载所有NTP客户端并禁用systemd-timesyncd(如果正在使用)。您可以通过安全连接(HTTPS或最好是Torion服务)连接到受信任的网站,而不是NTP,并从HTTP标头中提取当前时间。达到此目的的工具是sdwdate或我自己的安全时间同步工具。
按键指纹
可以通过他们在键盘上输入键的方式来对人进行指纹识别。您可以通过键入速度,在两次按键之间的暂停,每次按键被按下和释放的确切时间等方式来唯一地进行指纹识别。可以使用KeyTrac在线进行测试。
Kloak是一种工具,旨在通过混淆按键和释放事件之间的时间间隔来克服这种跟踪方法。当按键被按下时,它会引入随机延迟,然后由应用程序选择。
— 11 —
文件权限
默认情况下,文件的权限是非常宽松的。您应该在整个系统中搜索权限不当的文件和目录,并对其进行限制。例如,在诸如Debian之类的某些发行版中,用户的Home目录是全局可读的。
这可以通过执行以下操作来限制:
chmod 700 /home/$user
另外一些示例是/boot,/usr /src和/ {,usr /} lib/modules 它们包含内核映像,System.map和其他各种文件,所有这些文件都可能泄漏有关内核的敏感信息。
chmod 700 /boot /usr/src /lib/modules /usr/lib/modules
在基于Debian的发行版中,必须使用dpkg-statoverride保留文件许可权。否则,它们将在更新期间被覆盖。
Whonix的SUID Disabler和Permission Hardener会自动应用本节中详细介绍的步骤。
setuid / setgid
Setuid / SUID允许用户使用二进制文件所有者的特权执行二进制文件。这通常用于允许非特权用户使用通常仅为root用户保留的某些功能。因此,许多SUID二进制文件都有特权升级安全漏洞的历史记录。Setgid / SGID类似,但适用于组而不是用户。要使用setuid或setgid位查找系统上的所有二进制文件,请执行:
find / -type f \( -perm -4000 -o -perm -2000 \)
然后,您应该删除不使用的程序上的所有不必要的setuid / setgid位,或将其替换为功能。要删除setuid位,请执行:
chmod u-s $path_to_program
要删除setgid位,执行:
chmod g-s $path_to_program
要向文件添加功能,请执行:
setcap $capability+ep $path_to_program
或者,要删除不必要的功能,请执行:
setcap -r $path_to_program
umask
umask设置新创建文件的默认文件权限。默认的umask是0022,它不是很安全,因为它为系统上的每个用户提供了对新创建文件的读取访问权限。要使所有者以外的任何人都不可读新文件,请编辑/etc/profile并添加:
umask 0077
— 12 —
核心转储
核心转储包含特定时间(通常是该程序崩溃时)该程序的已记录内存。它们可能包含敏感信息,例如密码和加密密钥,因此必须将其禁用。
禁用它们的方法主要有三种:sysctl,systemd和ulimit。
sysctl
通过sysctl设置以下设置:
kernel.core_pattern=|/bin/false
systemd
创建/etc/systemd/coredump.conf.d/disable.conf并添加如下内容:
[Coredump]
Storage=none
ulimit
编辑/etc/security/limits.conf并添加如下内容:
* hard core 0
setuid进程
即使在进行了这些设置之后,以提升的特权运行的进程仍可能会转储其内存。
为了防止他们这样做,请通过sysctl设置以下内容:
fs.suid_dumpable=0
— 13 —
Swap
与核心转储类似,交换或分页将部分内存复制到磁盘,其中可能包含敏感信息。应该将内核配置为仅在绝对必要时进行交换,相应的sysctl设置:
vm.swappiness=1
— 14 —
PAM
PAM是用于用户身份验证的框架。这就是您登录时使用的机制。您可以通过要求使用强密码或在失败的登录尝试后强制执行延迟验证来使其更加安全。
要强制使用强密码,可以使用pam_pwquality。它强制执行密码的可配置策略。例如,如果您希望密码至少包含16个字符(最小),与旧密码(difok)至少6个不同的字符,至少3个数字(dcredit),至少2个大写字母(ucredit),至少2个字符小写字母(lcredit)和至少3个其他字符(ocredit),然后编辑/etc/pam.d/passwd并添加:
password required pam_pwquality.so retry=2 minlen=16 difok=6 dcredit=-3 ucredit=-2 lcredit=-2 ocredit=-3 enforce_for_root
password required pam_unix.so use_authtok sha512 shadow
要强制执行延迟验证,可以使用pam_faildelay。要在两次失败的登录尝试之间添加至少4秒的延迟以阻止暴力破解尝试,请编辑/etc/pam.d/system-login并添加:
auth optional pam_faildelay.so delay=4000000
4000000 是4秒(以微秒为单位)。
— 15 —
Microcode更新
Microcode更新对于修复关键的CPU漏洞(如Meltdown和Spectre等)至关重要。大多数发行版都将这些发行版包含在其软件仓库中,例如Arch Linux和Debian。
— 16 —
IPv6隐私扩展
IPv6地址是从计算机的MAC地址生成的,从而使您的IPv6地址是唯一的,并直接绑定到计算机。隐私扩展会生成一个随机的IPv6地址,以减轻这种形式的跟踪。请注意,如果您开启了MAC地址欺骗机制或禁用了IPv6,则无需执行这些步骤。
要启用这些功能,请通过sysctl设置以下设置:
net.ipv6.conf.all.use_tempaddr=2
net.ipv6.conf.default.use_tempaddr=2
NetworkManager
要为NetworkManager启用隐私扩展,请编辑/etc/NetworkManager/NetworkManager.conf并添加:
[connection]
ipv6.ip6-privacy=2
systemd-networkd
要为systemd-networkd启用隐私扩展,请创建/etc/systemd/network/ipv6-privacy.conf并添加:
[Network]
IPv6PrivacyExtensions=kernel