Привет XXS! Сегодня мы начнем проверять большой список доменов на наличие вордпресс.
(Статья будет максимально короткая и минимально информативная)
На днях я столкнулся с нуждой парсить сайты и найти все на wordpress, пришлось писать небольшую программку, может ее кто доработает и скинет мне код с интересной cve или 0day)
тааак, что то я затянул!
сама программа:
Она ищет сайты из списка доменов с вордпресом и без cloudflare
собственно на этом все, надеюсь мой кривой говнокод будет хоть комуто полезен
(Статья будет максимально короткая и минимально информативная)
На днях я столкнулся с нуждой парсить сайты и найти все на wordpress, пришлось писать небольшую программку, может ее кто доработает и скинет мне код с интересной cve или 0day)
тааак, что то я затянул!
сама программа:
Python:
import requests
import argparse
from urllib.parse import urlparse
from concurrent.futures import ThreadPoolExecutor
import socket
import struct
import threading
import os
import time
write_lock = threading.Lock()
def check_site(url, output_file):
try:
if not url.startswith(('http://', 'https://')):
test_url = 'http://' + url
else:
test_url = url
parsed = urlparse(test_url)
base_url = f"{parsed.scheme}://{parsed.netloc}"
wp_urls = [
f"{base_url}/wp-login.php",
f"{base_url}/wp-content/",
f"{base_url}/wp-json/",
f"{base_url}/readme.html"
]
is_wordpress = False
for wp_url in wp_urls:
try:
response = requests.get(wp_url, timeout=10, allow_redirects=True)
if response.status_code == 200:
if "wp-content" in response.text or "WordPress" in response.text:
is_wordpress = True
break
except:
continue
if not is_wordpress:
print(f"[-] Not WordPress: {base_url}")
return
cloudflare_indicators = [
"cloudflare", "cf-ray", "__cfduid",
"__cf_bm", "cf-cache-status", "cloudflare-nginx"
]
try:
response = requests.get(base_url, timeout=10)
headers = str(response.headers).lower()
using_cloudflare = any(cf in headers for cf in cloudflare_indicators)
if not using_cloudflare:
try:
ip = socket.gethostbyname(parsed.netloc)
if is_cloudflare_ip(ip):
using_cloudflare = True
except:
pass
except Exception as e:
print(f"[!] Error checking Cloudflare for {base_url}: {str(e)}")
return
if using_cloudflare:
print(f"[-] Using Cloudflare: {base_url}")
return
print(f"[+] Found WordPress without Cloudflare: {base_url}")
with write_lock:
try:
with open(output_file, 'a') as f:
f.write(f"{base_url}\n")
f.flush()
os.fsync(f.fileno())
print(f"[✓] Saved to file: {base_url}")
except Exception as e:
print(f"[!] Failed to save {base_url}: {str(e)}")
except Exception as e:
print(f"[!] Error processing {url}: {str(e)}")
def is_cloudflare_ip(ip):
"""Проверяет принадлежит ли IP к Cloudflare"""
try:
ip_num = struct.unpack("!I", socket.inet_aton(ip))[0]
cloudflare_ranges = [
("173.245.48.0", "173.245.63.255"),
("103.21.244.0", "103.21.247.255"),
("103.22.200.0", "103.22.203.255"),
("103.31.4.0", "103.31.7.255"),
("141.101.64.0", "141.101.127.255"),
("108.162.192.0", "108.162.255.255"),
("190.93.240.0", "190.93.255.255"),
("188.114.96.0", "188.114.111.255"),
("197.234.240.0", "197.234.243.255"),
("198.41.128.0", "198.41.255.255"),
("162.158.0.0", "162.159.255.255"),
("104.16.0.0", "104.31.255.255")
]
for start, end in cloudflare_ranges:
start_num = struct.unpack("!I", socket.inet_aton(start))[0]
end_num = struct.unpack("!I", socket.inet_aton(end))[0]
if start_num <= ip_num <= end_num:
return True
except:
pass
return False
def main():
parser = argparse.ArgumentParser(description='Find WordPress sites without Cloudflare')
parser.add_argument('-i', '--input', required=True, help='Input file with URLs')
parser.add_argument('-o', '--output', default='wordpress_no_cloudflare.txt', help='Output file')
parser.add_argument('-t', '--threads', type=int, default=10, help='Number of threads')
args = parser.parse_args()
with open(args.output, 'w') as f:
f.write("")
print(f"Starting scan of {args.input} with {args.threads} threads")
print(f"Results will be saved in real-time to: {args.output}\n")
with open(args.input, 'r') as f:
urls = [line.strip() for line in f.readlines() if line.strip()]
print(f"Loaded {len(urls)} URLs to check\n")
with ThreadPoolExecutor(max_workers=args.threads) as executor:
futures = []
for url in urls:
future = executor.submit(check_site, url, args.output)
futures.append(future)
for future in futures:
try:
future.result()
except Exception as e:
print(f"[!] Thread error: {str(e)}")
print("\n[+] Scan completed! All results saved.")
if __name__ == "__main__":
main()
собственно на этом все, надеюсь мой кривой говнокод будет хоть комуто полезен

