zhou12189108 commited on
Commit
11b3fe5
·
1 Parent(s): 0fa57a6

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +50 -0
  2. api.py +78 -0
  3. recaptcha_base.py +50 -0
Dockerfile ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim-bullseye as builder
2
+
3
+ # Build dummy packages to skip installing them and their dependencies
4
+ RUN apt-get update \
5
+ && apt-get install -y --no-install-recommends equivs \
6
+ && equivs-control libgl1-mesa-dri \
7
+ && printf 'Section: misc\nPriority: optional\nStandards-Version: 3.9.2\nPackage: libgl1-mesa-dri\nVersion: 99.0.0\nDescription: Dummy package for libgl1-mesa-dri\n' >> libgl1-mesa-dri \
8
+ && equivs-build libgl1-mesa-dri \
9
+ && mv libgl1-mesa-dri_*.deb /libgl1-mesa-dri.deb \
10
+ && equivs-control adwaita-icon-theme \
11
+ && printf 'Section: misc\nPriority: optional\nStandards-Version: 3.9.2\nPackage: adwaita-icon-theme\nVersion: 99.0.0\nDescription: Dummy package for adwaita-icon-theme\n' >> adwaita-icon-theme \
12
+ && equivs-build adwaita-icon-theme \
13
+ && mv adwaita-icon-theme_*.deb /adwaita-icon-theme.deb
14
+
15
+ FROM python:3.11-slim-bullseye
16
+ COPY --from=builder /*.deb /
17
+ WORKDIR /app
18
+ #RUN echo "deb http://deb.debian.org/debian/ unstable main contrib non-free" >> /etc/apt/sources.list
19
+ RUN apt update
20
+ RUN apt upgrade -y
21
+ RUN apt install -y python3 python3-pip libgl1-mesa-glx wget libglib2.0-dev sudo libpci-dev psmisc
22
+ RUN pip install playwright playwright_recaptcha requests loguru flask Flask-Limiter
23
+ RUN dpkg -i /libgl1-mesa-dri.deb \
24
+ && dpkg -i /adwaita-icon-theme.deb \
25
+ # Install dependencies
26
+ && apt-get update \
27
+ && apt-get install -y --no-install-recommends xvfb dumb-init \
28
+ procps curl vim xauth \
29
+ # Remove temporary files and hardware decoding libraries
30
+ && rm -rf /var/lib/apt/lists/* \
31
+ && rm -f /usr/lib/x86_64-linux-gnu/libmfxhw* \
32
+ && rm -f /usr/lib/x86_64-linux-gnu/mfx/* \
33
+ && useradd --home-dir /app --shell /bin/sh foxer \
34
+ && chown -R foxer:foxer .
35
+
36
+ RUN rm -rf /root/.cache
37
+ RUN chmod 777 -R "/usr/local/lib/python3.11/"
38
+ RUN chmod 777 -R "/app/"
39
+ RUN playwright install firefox --with-deps
40
+
41
+ USER foxer
42
+ RUN playwright install firefox
43
+ COPY recaptcha_base.py .
44
+
45
+ COPY api.py .
46
+ EXPOSE 8081
47
+
48
+ ENTRYPOINT ["/usr/bin/dumb-init", "--"]
49
+ CMD ["/usr/local/bin/python","-u","/app/api.py"]
50
+
api.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import asyncio
3
+ from flask import Flask, jsonify, request, logging as flog
4
+ from flask_limiter.util import get_remote_address
5
+ import recaptcha_base
6
+
7
+ app = Flask(__name__)
8
+
9
+
10
+ def get_ipaddr():
11
+ if request.access_route:
12
+ print(request.access_route[0])
13
+ return request.access_route[0]
14
+ else:
15
+ return request.remote_addr or '127.0.0.1'
16
+
17
+
18
+ handler = flog.default_handler
19
+
20
+
21
+ def get_token():
22
+ default_token = "init_token"
23
+ if os.path.exists("token"):
24
+ return open("token", "r").read().strip()
25
+ return default_token
26
+
27
+
28
+ def check_request(required_data, data):
29
+ token = get_token()
30
+ if not data or any(key not in data for key in required_data):
31
+ print("Error:Invalid Request Data\n" + str(data))
32
+ return False
33
+ if data["token"] != token:
34
+ print("Error:Invalid Token\n" + str(data))
35
+ return False
36
+ return True
37
+
38
+
39
+ @app.errorhandler(429)
40
+ def rate_limit_exceeded(e):
41
+ print(get_remote_address())
42
+ return jsonify(msg="Too many request"), 429
43
+
44
+
45
+ @app.errorhandler(405)
46
+ def method_not_allowed(e):
47
+ print(get_remote_address())
48
+ return jsonify(msg="Unauthorized Request"), 405
49
+
50
+
51
+ @app.route("/", methods=["GET"])
52
+ def index():
53
+ return jsonify(status_code=200, ip=get_ipaddr())
54
+
55
+
56
+ @app.route("/update/token", methods=["POST"])
57
+ def update_token():
58
+ require_data = ["token", "new_token"]
59
+ data = request.get_json(force=True, silent=True)
60
+ if not check_request(require_data, data):
61
+ return jsonify(msg="Unauthorized Request"), 403
62
+ token = open("token", "w+")
63
+ token.write(data["new_token"])
64
+ token.close()
65
+ return jsonify(msg="Token updated successfully", success=True)
66
+
67
+
68
+ @app.route("/api/solve", methods=["POST"])
69
+ def solver_captcha():
70
+ require_data = ["token", "host", "site_key", "action"]
71
+ data = request.get_json(force=True, silent=True)
72
+ if not check_request(require_data, data):
73
+ return jsonify(msg="Unauthorized Request"), 403
74
+ resp = asyncio.run(recaptcha_base.get_token(data["host"], data["site_key"], data["action"]))
75
+ return resp
76
+
77
+
78
+ app.run(host="0.0.0.0", port=8081)
recaptcha_base.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from playwright.sync_api import sync_playwright
2
+ from playwright_recaptcha import recaptchav3
3
+
4
+
5
+ async def route_continuation(route, request, host, sitekey, action):
6
+ # 检查请求的URL,只拦截特定网站的请求
7
+ if request.url == f"https://{host}/":
8
+ print("start to solve")
9
+ # 修改DNS解析结果
10
+ await route.fulfill(status=200,
11
+ body="""
12
+ <!DOCTYPE html>
13
+ <html lang="en">
14
+ <head>
15
+ <meta charset="UTF-8">
16
+ <title>test</title>
17
+ <script src="https://www.recaptcha.net/recaptcha/api.js?render=%%%%%%%%%%%%%%%"></script>
18
+ </head>
19
+ <body>
20
+ <script>
21
+ grecaptcha.ready(function() {
22
+ grecaptcha.execute('%%%%%%%%%%%%%%%', {action: '$$$$$'}).then(function(token) {
23
+ console.log(token);
24
+
25
+ });
26
+ });
27
+ </script>
28
+ </body>
29
+ </html>
30
+ """.replace("%%%%%%%%%%%%%%%", sitekey).replace("$$$$$", action))
31
+ else:
32
+ await route.route.continue_()
33
+
34
+
35
+ async def get_token(host, sitekey, action):
36
+ async with sync_playwright() as p:
37
+ browser = await p.firefox.launch(headless=True)
38
+ try:
39
+ page = await browser.new_page()
40
+ await page.route('**/*', lambda route, request: route_continuation(route, request, host, sitekey, action))
41
+ await page.goto(f"https://{host}/")
42
+ async with recaptchav3.SyncSolver(page) as solver:
43
+ token = await solver.solve_recaptcha()
44
+ except Exception as e:
45
+ print(e)
46
+ token = str(e)
47
+ finally:
48
+ await page.close()
49
+ await browser.close()
50
+ return token