Hack the Box INSANE题 ArtificialUniversity题解
字数 1823 2025-08-20 18:18:16

Hack the Box INSANE难度题目ArtificialUniversity题解

0x00 题目概述

这是一个Flask框架构建的Web应用程序,模拟了一个购物网站系统。题目难度为INSANE级别,涉及多个漏洞的串联利用,包括逻辑漏洞、路径穿越、SSRF、XSS和gRPC服务中的代码执行漏洞。

0x01 系统架构分析

路由结构

用户侧路由:

  • /register - 用户注册
  • /login - 用户登录
  • /product/<product_id> - 查看商品
  • /checkout - 下单
  • /checkout/success - 支付回调
  • /subs - 查看订单
  • /logout - 登出

管理员侧路由(需admin权限):

  • /admin/users - 查看用户列表
  • /admin/products - 查看所有商品
  • /admin/orders - 查看所有订单
  • /admin/view-pdf - 查看PDF
  • /admin/api-health - 查看API接口状态
  • /admin/product-stream - 获取新产品
  • /admin/save-product - 保存产品
  • /admin/saved-products - 查看已保存产品

配置文件分析

config.py中关键配置:

class Config(object):
    SECRET_KEY = os.urandom(50).hex()
    ADMIN_EMAIL = "ed@artificialuniversity.htb"
    ADMIN_PASS = os.urandom(32).hex()

管理员凭据是随机生成的,无法爆破。

0x02 漏洞分析与利用链

1. 逻辑漏洞+路径穿越

漏洞点1: 价格可控

/checkout路由中,当不传入product_id时,价格参数完全可控:

@web.route("/checkout", methods=["GET"])
def checkout():
    product_id = request.args.get("product_id")
    if product_id and not session.get("loggedin"):
        return render_template("error.html", title="Error", error="Must have an account in order to purchase"), 200
    
    price = request.args.get("price")  # 价格可控
    title = request.args.get("title")
    user_id = request.args.get("user_id")
    email = request.args.get("email")
    
    if not product_id and (not price or not title or not user_id or not email):
        return render_template("error.html", title="Error", error="Missing external order details"), 400
    
    db_session = Database()
    payment_link = None
    
    if product_id:
        # 正常流程
    else:
        product_data = {
            "title": title,
            "price": int(price)  # 可设置为负数
        }
        payment_link, payment_id = generate_payment_link(product_data["price"])
        order_id = db_session.create_order(title, user_id, email, int(price), payment_id)

漏洞点2: 支付回调中的路径穿越

/checkout/success路由中的bot_runner函数会访问PDF文件,但payment_id可控:

def bot_runner(email, password, payment_id):
    # ...
    client.get(f"http://127.0.0.1:1337/static/invoices/invoice_{payment_id}.pdf")
    # ...

通过设置payment_id..admin/xxx#,浏览器会解析为http://127.0.0.1:1337/admin#pdf,而后端实际接收到的是http://127.0.0.1:1337/admin

利用步骤:

  1. 访问/checkout不传product_id,设置price=-1创建负价订单
  2. /checkout/success回调中设置payment_id=..admin/xxx#实现路径穿越
  3. 利用bot自动登录管理员账号后访问admin路由

2. SSRF漏洞利用

漏洞点1: /admin/view-pdf

@web.route("/admin/view-pdf", methods=["GET"])
def admin_view_pdf():
    pdf_url = request.args.get("url")
    response = requests.get(pdf_url)  # SSRF

漏洞点2: /admin/api-health

@web.route("/admin/api-health", methods=["GET", "POST"])
def api_health():
    url = request.form.get("url")
    status_code = get_url_status_code(url)  # 使用curl实现的SSRF

def get_url_status_code(url):
    curl_args = ["curl", "-o", "/dev/null", "-w", "%{http_code}", url]
    result = subprocess.run(curl_args, capture_output=True, text=True, check=True)

3. PDF.js漏洞利用(CVE-2024-4367)

题目使用的Firefox 125.0.1版本存在PDF.js漏洞(CVE-2024-4367),允许通过特制PDF执行任意JavaScript代码。

利用方法:

  1. 构造恶意PDF触发XSS
  2. 通过XSS自动提交表单访问/admin/api-health
  3. 利用curl的SSRF功能攻击内网服务

4. gRPC服务代码执行

内网gRPC服务(50051端口)存在任意代码执行漏洞:

class ProductService(product_pb2_grpc.ProductServiceServicer):
    def GenerateProduct(self):
        if hasattr(self, "price_formula"):
            price = eval(self.price_formula)  # 任意代码执行
            
    def DebugService(self, request, context):
        input_dict = {k: v.string_value for k, v in request.input.items()}
        self.UpdateService(input_dict, self)  # 可设置price_formula属性

利用链:

  1. 通过DebugService设置price_formula属性
  2. 调用GetNewProducts触发GenerateProduct执行eval

5. 完整利用链

  1. 初始访问:

    • 利用逻辑漏洞创建负价订单
    • 通过路径穿越访问admin接口
  2. 权限提升:

    • 利用/admin/view-pdf的SSRF和PDF.js漏洞执行XSS
    • 通过XSS自动提交表单访问/admin/api-health
  3. 内网横向移动:

    • 构造gopher协议请求攻击内网gRPC服务
    • 通过DebugService设置price_formula
    • 调用GetNewProducts触发代码执行

0x03 防御建议

  1. 修复逻辑漏洞:

    • 价格参数应由服务端计算,不可由客户端控制
    • 支付回调应验证payment_id格式
  2. 防止路径穿越:

    • 规范化路径处理
    • 验证文件名不包含特殊字符
  3. SSRF防护:

    • 限制URL访问范围(协议、域名、端口)
    • 使用白名单机制
  4. gRPC服务安全:

    • 避免使用eval等危险函数
    • 对输入参数进行严格过滤
    • 限制服务访问权限
  5. 组件安全:

    • 及时更新存在漏洞的组件版本
    • 实施最小权限原则

0x04 参考链接

Hack the Box INSANE难度题目ArtificialUniversity题解 0x00 题目概述 这是一个Flask框架构建的Web应用程序,模拟了一个购物网站系统。题目难度为INSANE级别,涉及多个漏洞的串联利用,包括逻辑漏洞、路径穿越、SSRF、XSS和gRPC服务中的代码执行漏洞。 0x01 系统架构分析 路由结构 用户侧路由: /register - 用户注册 /login - 用户登录 /product/<product_id> - 查看商品 /checkout - 下单 /checkout/success - 支付回调 /subs - 查看订单 /logout - 登出 管理员侧路由(需admin权限): /admin/users - 查看用户列表 /admin/products - 查看所有商品 /admin/orders - 查看所有订单 /admin/view-pdf - 查看PDF /admin/api-health - 查看API接口状态 /admin/product-stream - 获取新产品 /admin/save-product - 保存产品 /admin/saved-products - 查看已保存产品 配置文件分析 config.py 中关键配置: 管理员凭据是随机生成的,无法爆破。 0x02 漏洞分析与利用链 1. 逻辑漏洞+路径穿越 漏洞点1: 价格可控 在 /checkout 路由中,当不传入 product_id 时,价格参数完全可控: 漏洞点2: 支付回调中的路径穿越 /checkout/success 路由中的 bot_runner 函数会访问PDF文件,但 payment_id 可控: 通过设置 payment_id 为 ..admin/xxx# ,浏览器会解析为 http://127.0.0.1:1337/admin#pdf ,而后端实际接收到的是 http://127.0.0.1:1337/admin 。 利用步骤: 访问 /checkout 不传 product_id ,设置 price=-1 创建负价订单 在 /checkout/success 回调中设置 payment_id=..admin/xxx# 实现路径穿越 利用bot自动登录管理员账号后访问admin路由 2. SSRF漏洞利用 漏洞点1: /admin/view-pdf 漏洞点2: /admin/api-health 3. PDF.js漏洞利用(CVE-2024-4367) 题目使用的Firefox 125.0.1版本存在PDF.js漏洞(CVE-2024-4367),允许通过特制PDF执行任意JavaScript代码。 利用方法: 构造恶意PDF触发XSS 通过XSS自动提交表单访问 /admin/api-health 利用curl的SSRF功能攻击内网服务 4. gRPC服务代码执行 内网gRPC服务(50051端口)存在任意代码执行漏洞: 利用链: 通过 DebugService 设置 price_formula 属性 调用 GetNewProducts 触发 GenerateProduct 执行 eval 5. 完整利用链 初始访问: 利用逻辑漏洞创建负价订单 通过路径穿越访问admin接口 权限提升: 利用 /admin/view-pdf 的SSRF和PDF.js漏洞执行XSS 通过XSS自动提交表单访问 /admin/api-health 内网横向移动: 构造gopher协议请求攻击内网gRPC服务 通过 DebugService 设置 price_formula 调用 GetNewProducts 触发代码执行 0x03 防御建议 修复逻辑漏洞: 价格参数应由服务端计算,不可由客户端控制 支付回调应验证 payment_id 格式 防止路径穿越: 规范化路径处理 验证文件名不包含特殊字符 SSRF防护: 限制URL访问范围(协议、域名、端口) 使用白名单机制 gRPC服务安全: 避免使用 eval 等危险函数 对输入参数进行严格过滤 限制服务访问权限 组件安全: 及时更新存在漏洞的组件版本 实施最小权限原则 0x04 参考链接 CVE-2024-4367详情 gRPC安全最佳实践 SSRF防御指南