const TURNSTILE_SOLVER_URL = 'https://herzaj-turnstile-solver.hf.space'; async function getTurnstileToken() { try { const params = new URLSearchParams({ url: 'https://www.subdomainfinder.in', sitekey: '0x4AAAAAAAj7jyMV3Zv9ZMN-' }); const submitResponse = await fetch(`${TURNSTILE_SOLVER_URL}/turnstile?${params}`, { method: 'GET' }); if (!submitResponse.ok) { throw new Error(`Failed to submit task: ${submitResponse.status}`); } const taskData = await submitResponse.json(); const taskId = taskData.task_id; await new Promise(resolve => setTimeout(resolve, 5000)); const resultResponse = await fetch(`${TURNSTILE_SOLVER_URL}/result?id=${taskId}`); if (!resultResponse.ok) { throw new Error(`Failed to get result: ${resultResponse.status}`); } const resultData = await resultResponse.json(); return resultData.value; } catch (error) { throw new Error("Gagal mendapatkan Turnstile token: " + error.message); } } async function findSubdomains(domain, token) { const response = await fetch(`https://api.subdomainfinder.in/?domain=${domain}`, { method: 'GET', headers: { 'X-Secure-Token': token, 'X-Referer': 'https://www.google.com/', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } async function resolveDNS(subdomain) { const response = await fetch(`https://lookup.subdomainfinder.in/resolve?name=${subdomain}&rd=1`, { method: 'GET', headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } async function getIPInfo(ip) { const response = await fetch(`https://ipresolver.subdomainfinder.in/${ip}`, { method: 'GET', headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } function extractIPFromDNS(dnsData) { if (!dnsData || !dnsData.Answer) return null; for (const answer of dnsData.Answer) { if (answer.type === 1 && answer.data) { return answer.data; } } return null; } async function subdo(domain) { const token = await getTurnstileToken(); const subdomainData = await findSubdomains(domain, token); const results = []; for (const sub of subdomainData.data) { try { const dnsData = await resolveDNS(sub.subdomain); const ip = extractIPFromDNS(dnsData); let result = { subdomain: sub.subdomain, ip: ip || 'N/A', cloudflare: sub.cloudflare, dnsStatus: dnsData.Status }; if (ip) { try { const ipInfo = await getIPInfo(ip); if (ipInfo.success && ipInfo.result && ipInfo.result.ip) { result.ipInfo = { location: ipInfo.result.ip.locationName, asn: ipInfo.result.ip.asnName, country: ipInfo.result.ip.location, flag: ipInfo.result.ip.flag }; } } catch (e) { result.ipInfo = null; } } results.push(result); } catch (error) { results.push({ subdomain: sub.subdomain, error: error.message }); } } return { domain: domain, count: subdomainData.count, data: results }; } const handler = async (req, res) => { try { const { domain } = req.query; if (!domain) { return res.status(400).json({ success: false, error: 'Missing required parameter: domain' }); } const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]?\.([a-zA-Z]{2,}\.?)+$/; if (!domainRegex.test(domain)) { return res.status(400).json({ success: false, error: 'Invalid domain format' }); } const result = await subdo(domain); res.json({ success: true, data: { domain: result.domain, total_subdomains: result.count, subdomains: result.data } }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }; module.exports = { name: 'Subdomain Finder', description: 'Find subdomains with IP addresses and location information', type: 'GET', routes: ['api/tools/subdofinder'], tags: ['security', 'subdomain', 'dns', 'recon'], parameters: ['domain', 'key'], enabled: true, main: ['tools', 'Search'], handler };