fourmovie commited on
Commit
f6ffef2
·
1 Parent(s): 613fc97
Files changed (8) hide show
  1. Dockerfile +25 -0
  2. README.md +1 -3
  3. api_test.py +26 -0
  4. cache/cache.json +10 -0
  5. endpoints/cloudflare.js +79 -0
  6. endpoints/turnstile.js +72 -0
  7. index.js +154 -0
  8. package.json +16 -0
Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:20-slim
2
+
3
+ RUN apt update && apt install -y \
4
+ wget gnupg xvfb \
5
+ fonts-liberation libnss3 libxss1 libxcomposite1 libxrandr2 libgbm1 \
6
+ && wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
7
+ && apt install -y ./google-chrome-stable_current_amd64.deb \
8
+ && rm google-chrome-stable_current_amd64.deb \
9
+ && apt clean && rm -rf /var/lib/apt/lists/*
10
+
11
+ RUN mkdir -p /app/cache && chmod 777 -R /app
12
+
13
+ WORKDIR /app
14
+
15
+ COPY package*.json ./
16
+ RUN npm install --production
17
+
18
+ COPY . .
19
+
20
+ EXPOSE 7860
21
+
22
+ CMD rm -f /tmp/.X99-lock && \
23
+ Xvfb :99 -screen 0 1024x768x24 & \
24
+ export DISPLAY=:99 && \
25
+ npm start
README.md CHANGED
@@ -3,10 +3,8 @@ title: Cf
3
  emoji: 🏢
4
  colorFrom: purple
5
  colorTo: purple
6
- sdk: gradio
7
  sdk_version: 5.49.1
8
- app_file: app.py
9
- pinned: false
10
  license: apache-2.0
11
  short_description: bypass cf
12
  ---
 
3
  emoji: 🏢
4
  colorFrom: purple
5
  colorTo: purple
6
+ sdk: docker
7
  sdk_version: 5.49.1
 
 
8
  license: apache-2.0
9
  short_description: bypass cf
10
  ---
api_test.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import httpx
3
+
4
+ async def main():
5
+ async with httpx.AsyncClient(timeout=30.0) as client:
6
+ resp1 = await client.post(
7
+ "http://localhost:8080/cloudflare",
8
+ json={
9
+ "domain": "https://olamovies.watch/generate",
10
+ "mode": "iuam",
11
+ },
12
+ )
13
+ print(resp1.json())
14
+
15
+ resp2 = await client.post(
16
+ "http://localhost:8080/cloudflare",
17
+ json={
18
+ "domain": "https://lksfy.com/",
19
+ "siteKey": "0x4AAAAAAA49NnPZwQijgRoi",
20
+ "mode": "turnstile",
21
+ },
22
+ )
23
+ print(resp2.json())
24
+
25
+ if __name__ == "__main__":
26
+ asyncio.run(main())
cache/cache.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "{\"domain\":\"https://v2links.org\",\"mode\":\"iuam\"}": {
3
+ "timestamp": 1758616160392,
4
+ "value": {
5
+ "cf_clearance": "qqs5f4MpFMgA0v78Qmh_HYDWoKhbwqlQ57bTW5KeIr8-1758616161-1.2.1.1-D5PdpmheHl.26ssIRKQBsXzPtPPkSXntEZ_H9FUJVt7MMTS_BEE8iH.E48MDzKtFBLwZqRYxE_1GLo1gj3ChXrwatOGEJcmGRUwavy2qvGgUPizn7qufd.sW0ULfhaRO7Gz_H_eO1TU3iEqCzltEUDNk0SviKRFkF8ozbvJ91MW_qmO.qrjQorbu_jxcgJv5BHs6rTNOitWtVDAmYMDukASq0viHXIUAIvTM.LIfQ88",
6
+ "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
7
+ "elapsed_time": 5.028
8
+ }
9
+ }
10
+ }
endpoints/cloudflare.js ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ async function cloudflare(data, page) {
2
+ return new Promise(async (resolve, reject) => {
3
+ if (!data.domain) return reject(new Error("Missing domain parameter"))
4
+
5
+ const startTime = Date.now()
6
+ let isResolved = false
7
+ let userAgent = null
8
+
9
+ const cl = setTimeout(() => {
10
+ if (!isResolved) {
11
+ isResolved = true
12
+ const elapsedTime = (Date.now() - startTime) / 1000
13
+ resolve({
14
+ cf_clearance: null,
15
+ user_agent: userAgent,
16
+ elapsed_time: elapsedTime,
17
+ })
18
+ }
19
+ }, 20000)
20
+
21
+ try {
22
+ if (data.proxy?.username && data.proxy?.password) {
23
+ await page.authenticate({
24
+ username: data.proxy.username,
25
+ password: data.proxy.password,
26
+ })
27
+ }
28
+
29
+ page.removeAllListeners("request")
30
+ page.removeAllListeners("response")
31
+ await page.setRequestInterception(true)
32
+
33
+ page.on("request", async (req) => {
34
+ try {
35
+ await req.continue()
36
+ } catch (_) {}
37
+ })
38
+
39
+ page.on("response", async (res) => {
40
+ try {
41
+ const url = res.url()
42
+ if (url.includes("/cdn-cgi/challenge-platform/")) {
43
+ const headers = res.headers()
44
+ if (headers["set-cookie"]) {
45
+ const match = headers["set-cookie"].match(/cf_clearance=([^;]+)/)
46
+ if (match) {
47
+ const cf_clearance = match[1]
48
+ const userAgent = (await res.request().headers())["user-agent"]
49
+ const elapsedTime = (Date.now() - startTime) / 1000
50
+
51
+ if (!isResolved) {
52
+ isResolved = true
53
+ clearTimeout(cl)
54
+
55
+ resolve({
56
+ cf_clearance,
57
+ user_agent: userAgent,
58
+ elapsed_time: elapsedTime,
59
+ })
60
+ }
61
+ }
62
+ }
63
+ }
64
+ } catch (_) {}
65
+ })
66
+
67
+ await page.goto(data.domain, { waitUntil: "domcontentloaded" })
68
+ userAgent = await page.evaluate(() => navigator.userAgent)
69
+ } catch (err) {
70
+ if (!isResolved) {
71
+ isResolved = true
72
+ clearTimeout(cl)
73
+ reject(err)
74
+ }
75
+ }
76
+ })
77
+ }
78
+
79
+ module.exports = cloudflare
endpoints/turnstile.js ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ async function turnstile({ domain, proxy, siteKey }, page) {
2
+ if (!domain) throw new Error("Missing domain")
3
+ if (!siteKey) throw new Error("Missing siteKey")
4
+
5
+ const timeout = global.timeOut || 60000
6
+ let resolved = false
7
+ let timeoutId
8
+
9
+ try {
10
+ if (proxy?.username && proxy?.password) {
11
+ await page.authenticate({
12
+ username: proxy.username,
13
+ password: proxy.password,
14
+ }).catch(() => {})
15
+ }
16
+
17
+ const htmlContent = `
18
+ <!DOCTYPE html>
19
+ <html><body>
20
+ <div class="turnstile"></div>
21
+ <script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback" defer></script>
22
+ <script>
23
+ window.onloadTurnstileCallback = function() {
24
+ turnstile.render('.turnstile', {
25
+ sitekey: '${siteKey}',
26
+ callback: function(token) {
27
+ window.turnstileToken = token
28
+ }
29
+ })
30
+ }
31
+ </script>
32
+ </body></html>
33
+ `
34
+
35
+ await page.setRequestInterception(true)
36
+ page.removeAllListeners("request")
37
+
38
+ page.on("request", async (request) => {
39
+ const url = request.url().split('?')[0]
40
+ if ([domain, domain + "/"].includes(url) && request.resourceType() === "document") {
41
+ await request.respond({
42
+ status: 200,
43
+ contentType: "text/html",
44
+ body: htmlContent,
45
+ })
46
+ } else {
47
+ await request.continue()
48
+ }
49
+ })
50
+
51
+ timeoutId = setTimeout(() => {
52
+ if (!resolved) throw new Error("Timeout")
53
+ }, timeout)
54
+
55
+ await page.goto(domain, { waitUntil: "domcontentloaded", timeout: 30000 })
56
+
57
+ await page.waitForFunction(() => window.turnstileToken, { timeout })
58
+ const token = await page.evaluate(() => window.turnstileToken)
59
+
60
+ resolved = true
61
+ clearTimeout(timeoutId)
62
+
63
+ if (!token) throw new Error("No token received")
64
+ return token
65
+
66
+ } catch (e) {
67
+ clearTimeout(timeoutId)
68
+ throw e
69
+ }
70
+ }
71
+
72
+ module.exports = turnstile
index.js ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require('express')
2
+ const { connect } = require("puppeteer-real-browser")
3
+ const fs = require("fs")
4
+ const path = require("path")
5
+
6
+ const app = express()
7
+ const port = process.env.PORT || 7860
8
+ const authToken = process.env.authToken || null
9
+
10
+ global.browserLimit = Number(process.env.browserLimit) || 20
11
+ global.timeOut = Number(process.env.timeOut) || 60000
12
+
13
+ const CACHE_DIR = path.join(__dirname, "cache")
14
+ const CACHE_FILE = path.join(CACHE_DIR, "cache.json")
15
+ const CACHE_TTL = 5 * 60 * 1000
16
+
17
+ function loadCache() {
18
+ if (!fs.existsSync(CACHE_FILE)) return {}
19
+ try {
20
+ return JSON.parse(fs.readFileSync(CACHE_FILE, "utf-8"))
21
+ } catch {
22
+ return {}
23
+ }
24
+ }
25
+
26
+ function saveCache(cache) {
27
+ try {
28
+ if (!fs.existsSync(CACHE_DIR)) fs.mkdirSync(CACHE_DIR, { recursive: true })
29
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2))
30
+ } catch {}
31
+ }
32
+
33
+ function readCache(key) {
34
+ const cache = loadCache()
35
+ const entry = cache[key]
36
+ if (entry && Date.now() - entry.timestamp < CACHE_TTL) return entry.value
37
+ return null
38
+ }
39
+
40
+ function writeCache(key, value) {
41
+ const cache = loadCache()
42
+ cache[key] = { timestamp: Date.now(), value }
43
+ saveCache(cache)
44
+ }
45
+
46
+ app.use(express.json())
47
+ app.use(express.urlencoded({ extended: true }))
48
+
49
+ // Root endpoint sederhana
50
+ app.get('/', (req, res) => {
51
+ res.status(200).json({
52
+ message: 'Cloudflare Solver API',
53
+ port: port,
54
+ status: 'active'
55
+ })
56
+ })
57
+
58
+ async function createBrowser(proxyServer = null) {
59
+ const connectOptions = {
60
+ headless: true,
61
+ turnstile: true,
62
+ connectOption: {
63
+ defaultViewport: null,
64
+ args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']
65
+ }
66
+ }
67
+
68
+ if (proxyServer) {
69
+ connectOptions.args = [...(connectOptions.connectOption.args || []), `--proxy-server=${proxyServer}`]
70
+ }
71
+
72
+ const { browser } = await connect(connectOptions)
73
+ const page = (await browser.pages())[0] || await browser.newPage()
74
+
75
+ await page.setRequestInterception(true)
76
+ page.on('request', (req) => {
77
+ if (["image", "stylesheet", "font", "media"].includes(req.resourceType())) {
78
+ req.abort()
79
+ } else {
80
+ req.continue()
81
+ }
82
+ })
83
+
84
+ return { browser, page }
85
+ }
86
+
87
+ const turnstile = require('./endpoints/turnstile')
88
+ const cloudflare = require('./endpoints/cloudflare')
89
+
90
+ app.post('/cloudflare', async (req, res) => {
91
+ const data = req.body
92
+
93
+ if (!data?.mode) return res.status(400).json({ message: 'Bad Request' })
94
+ if (authToken && data.authToken !== authToken) return res.status(401).json({ message: 'Unauthorized' })
95
+ if (global.browserLimit <= 0) return res.status(429).json({ message: 'Too Many Requests' })
96
+
97
+ let cacheKey, cached
98
+ if (data.mode === "iuam") {
99
+ cacheKey = JSON.stringify(data)
100
+ cached = readCache(cacheKey)
101
+ if (cached) return res.status(200).json({ ...cached, cached: true })
102
+ }
103
+
104
+ global.browserLimit--
105
+ let browser = null
106
+
107
+ try {
108
+ const proxyServer = data.proxy ? `${data.proxy.hostname}:${data.proxy.port}` : null
109
+ const { browser: br, page } = await createBrowser(proxyServer)
110
+ browser = br
111
+
112
+ let result
113
+ switch (data.mode) {
114
+ case "turnstile":
115
+ result = await turnstile(data, page)
116
+ .then(token => ({ token }))
117
+ .catch(err => ({ code: 500, message: err.message }))
118
+ break
119
+
120
+ case "iuam":
121
+ result = await cloudflare(data, page)
122
+ .then(r => ({ ...r }))
123
+ .catch(err => ({ code: 500, message: err.message }))
124
+
125
+ if (!result.code) writeCache(cacheKey, result)
126
+ break
127
+
128
+ default:
129
+ result = { code: 400, message: 'Invalid mode' }
130
+ }
131
+
132
+ res.status(result.code ?? 200).json(result)
133
+ } catch (err) {
134
+ res.status(500).json({ code: 500, message: err.message })
135
+ } finally {
136
+ if (browser) await browser.close().catch(() => {})
137
+ global.browserLimit++
138
+ }
139
+ })
140
+
141
+ app.use((req, res) => {
142
+ res.status(404).json({ message: 'Not Found' })
143
+ })
144
+
145
+ if (process.env.NODE_ENV !== 'development') {
146
+ const server = app.listen(port, () => {
147
+ console.log(`Server running on port ${port}`)
148
+ })
149
+ server.timeout = global.timeOut + 10000
150
+ }
151
+
152
+ if (process.env.NODE_ENV === 'development') {
153
+ module.exports = app
154
+ }
package.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "cf-bypass",
3
+ "version": "1.0",
4
+ "description": "get the cf_clearance cookie from any website",
5
+ "scripts": {
6
+ "start": "node index.js",
7
+ "dev": "nodemon index.js"
8
+ },
9
+ "dependencies": {
10
+ "express": "^5.1.0",
11
+ "puppeteer-real-browser": "^1.4.0"
12
+ },
13
+ "devDependencies": {
14
+ "nodemon": "^3.1.10"
15
+ }
16
+ }