Add files via upload

This commit is contained in:
sijiyo 2023-07-21 19:09:00 +08:00 committed by GitHub
commit 94d9f32e3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 218774 additions and 0 deletions

26395
geetest3_fullpage/jiyan.js Normal file

File diff suppressed because one or more lines are too long

32
geetest3_fullpage/mian.py Normal file
View File

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
import random,threading, execjs, requests, time, json
def main():
frist_time = str(round(time.time() * 1000))
url = "https://www.geetest.com/demo/gt/register-fullpage?t=" + str(round(time.time() * 1000))
res = requests.get(url).json()
gt = res['gt']
challenge = res['challenge']
with open('jiyan.js', 'r', encoding='utf-8') as f:
js = execjs.compile(f.read())
key = js.call('get_key')
w = js.call('get_w1', gt, challenge, key)
url = "https://apiv6.geetest.com/get.php?gt=" + gt + "&challenge=" + challenge + "&lang=zh-cn&pt=0&client_type=web&w=" + w + "&callback=geetest_" + str(
round(time.time() * 1000))
res = requests.get(url).text
res = json.loads(res[res.index("(") + 1:res.rindex(")")])
s = res['data']['s']
w = js.call('get_w2',s,str(random.randint(500, 3000)),gt,challenge,frist_time,key)
url = "https://api.geetest.com/ajax.php?gt=" + gt + "&challenge=" + challenge + "&lang=zh-cn&pt=0&client_type=web&w=" + w + "&callback=geetest_" + str(
round(time.time() * 1000))
res = requests.get(url).text
res = json.loads(res[res.index("(") + 1:res.rindex(")")])
print(res)
if __name__ == '__main__':
for i in range(1):
thr = threading.Thread(target=main)
thr.start()
time.sleep(2)

Binary file not shown.

Binary file not shown.

92
geetest3_slide/gap.py Normal file
View File

@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
import cv2,os
from PIL import Image
class SlideCrack(object):
def __init__(self, gap, bg, out):
self.gap = gap
self.bg = bg
self.out = out
@staticmethod
def clear_white(img):
# 清除图片的空白区域,这里主要清除滑块的空白
img = cv2.imread(img)
rows, cols, channel = img.shape
min_x = 255
min_y = 255
max_x = 0
max_y = 0
for x in range(1, rows):
for y in range(1, cols):
t = set(img[x, y])
if len(t) >= 2:
if x <= min_x:
min_x = x
elif x >= max_x:
max_x = x
if y <= min_y:
min_y = y
elif y >= max_y:
max_y = y
img1 = img[min_x:max_x, min_y: max_y]
return img1
def template_match(self, tpl, target):
th, tw = tpl.shape[:2]
result = cv2.matchTemplate(target, tpl, cv2.TM_CCOEFF_NORMED)
# 寻找矩阵(一维数组当作向量,用Mat定义) 中最小值和最大值的位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
tl = max_loc
br = (tl[0] + tw, tl[1] + th)
cv2.rectangle(target, tl, br, (0, 0, 255), 2)
cv2.imwrite(self.out, target)
return tl[0]
@staticmethod
def image_edge_detection(img):
edges = cv2.Canny(img, 100, 200)
return edges
def discern(self):
img1 = self.clear_white(self.gap)
img1 = cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY)
slide = self.image_edge_detection(img1)
back = cv2.imread(self.bg, 0)
back = self.image_edge_detection(back)
slide_pic = cv2.cvtColor(slide, cv2.COLOR_GRAY2RGB)
back_pic = cv2.cvtColor(back, cv2.COLOR_GRAY2RGB)
x = self.template_match(slide_pic, back_pic)
# 输出横坐标, 即 滑块在图片上的位置
return x
def get_gap():
# 滑块图片
# image1 = "img/tukuai.png"
image1 = r'./img/slide.png'
# 背景图片
# image2 = "img/beijing.png"
image2 = r'./img/bg.png'
# 处理结果图片,用红线标注
#image3 = "img/show_image.png"
image3 = r'./img/show_image.png'
sc = SlideCrack(image1, image2, image3)
os.remove('./img/oldbg.png')
os.remove('./img/oldallbg.png')
os.remove('./img/newallbg.png')
return sc.discern()
def restore_picture():
img_list = ["./img/oldbg.png", "./img/oldallbg.png"]
for index, img in enumerate(img_list):
image = Image.open(img)
s = Image.new("RGBA", (260, 160))
ut = [39, 38, 48, 49, 41, 40, 46, 47, 35, 34, 50, 51, 33, 32, 28, 29, 27, 26, 36, 37, 31, 30, 44, 45, 43,42,12, 13, 23, 22, 14, 15, 21, 20, 8, 9, 25, 24, 6, 7, 3, 2, 0, 1, 11, 10, 4, 5, 19, 18, 16, 17]
height_half = 80
for inx in range(52):
c = ut[inx] % 26 * 12 + 1
u = height_half if ut[inx] > 25 else 0
l_ = image.crop(box=(c, u, c + 10, u + 80))
s.paste(l_, box=(inx % 26 * 10, 80 if inx > 25 else 0))
if index == 0:
s.save("./img/bg.png")
else:
s.save("./img/newallbg.png")

BIN
geetest3_slide/img/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

2276
geetest3_slide/jiyan.js Normal file

File diff suppressed because one or more lines are too long

47
geetest3_slide/mian.py Normal file
View File

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
import threading,execjs, requests, time, json
from urllib import request
from gap import *
from trace import *
def get_image():
url = "https://www.geetest.com/demo/gt/register-slide?t=" + str(round(time.time() * 1000))
res = requests.get(url).json()
gt = res['gt']
challenge = res['challenge']
res = requests.get("https://api.geetest.com/ajax.php?gt=" + gt + "&challenge=" + challenge + "&lang=zh-cn&pt=0&w=&callback=geetest_" + str(
round(time.time() * 1000))).text
url = "https://api.geetest.com/get.php?is_next=true&type=slide3&gt=" + gt + "&challenge=" + challenge + "&lang=zh-cn&https=true&protocol=https%3A%2F%2F&offline=false&product=embed&api_server=api.geetest.com&isPC=true&autoReset=true&width=100%25&callback=geetest_" + str(
round(time.time() * 1000))
res = requests.get(url).text
res = json.loads(res[res.index("(") + 1:res.rindex(")")])
challenge = res['challenge']
s = res['s']
request.urlretrieve('https://static.geetest.com/' + res['fullbg'], 'img/oldallbg.png')
request.urlretrieve('https://static.geetest.com/' + res['bg'], 'img/oldbg.png')
request.urlretrieve('https://static.geetest.com/' + res['slice'], 'img/slide.png')
restore_picture()
distance = get_gap()
track = get_track(distance - 5)
return gt, challenge, s, distance, track
def main():
gt, challenge, s, distance, track = get_image()
with open('jiyan.js', 'r', encoding='utf-8') as f:
js = execjs.compile(f.read())
passtime = track[-1][-1]
track = js.call('get_encode_trace', track, s)
w = js.call('get_w', distance - 5, track, challenge, challenge[:32], passtime, str(random.randint(100, 200)),gt)
url = "https://api.geetest.com/ajax.php?gt=" + gt + "&challenge=" + challenge + "&lang=zh-cn&pt=0&w=" + w + "&callback=geetest_" + str(
round(time.time() * 1000))
res = requests.get(url).text
res = json.loads(res[res.index("(") + 1:res.rindex(")")])
print(res)
if __name__ == '__main__':
for i in range(1):
thr = threading.Thread(target=main)
thr.start()
time.sleep(2)

47
geetest3_slide/trace.py Normal file
View File

@ -0,0 +1,47 @@
import random
def __ease_out_expo(sep):
'''
轨迹相关操作
'''
if sep == 1:
return 1
else:
return 1 - pow(2, -10 * sep)
def get_track(distance):
"""
根据滑动距离生成滑动轨迹
:param distance: 需要滑动的距离
:return: 滑动轨迹<type 'list'>: [[x,y,t], ...]
x: 已滑动的横向距离
y: 已滑动的纵向距离, 除起点外, 均为0
t: 滑动过程消耗的时间, 单位: 毫秒
"""
if not isinstance(distance, int) or distance < 0:
raise ValueError(f"distance类型必须是大于等于0的整数: distance: {distance}, type: {type(distance)}")
# 初始化轨迹列表
slide_track = [
[random.randint(-50, -10), random.randint(-50, -10), 0],
[0, 0, 0],
]
# 共记录count次滑块位置信息
count = 30 + int(distance / 2)
# 初始化滑动时间
t = random.randint(50, 100)
# 记录上一次滑动的距离
_x = 0
_y = 0
for i in range(count):
# 已滑动的横向距离
x = round(__ease_out_expo(i / count) * distance)
# 滑动过程消耗的时间
t += random.randint(10, 20)
if x == _x:
continue
slide_track.append([x, _y, t])
_x = x
slide_track.append(slide_track[-1])
return slide_track

View File

@ -0,0 +1,57 @@
const NodeRSA = require('node-rsa');
const crypto = require('crypto');
const CryptoJS = require("crypto-js");
function get_key() {
var s4 = "";
for (i = 0; i < 4; i++) {
s4 = s4 + ((1 + Math["random"]()) * 65536 | 0)["toString"](16)["substring"](1);
}
return s4;
}
function MD5_Encrypt(word) {
return CryptoJS.MD5(word).toString();
}
function AES_Encrypt(key, word) {
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, CryptoJS.enc.Utf8.parse(key), {
iv: CryptoJS.enc.Utf8.parse("0000000000000000"),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return CryptoJS.enc.Hex.stringify(CryptoJS.enc.Base64.parse(encrypted.toString()));
}
function RSA_encrypt(data) {
const public_key_1 = '00C1E3934D1614465B33053E7F48EE4EC87B14B95EF88947713D25EECBFF7E74C7977D02DC1D9451F79DD5D1C10C29ACB6A9B4D6FB7D0A0279B6719E1772565F09AF627715919221AEF91899CAE08C0D686D748B20A3603BE2318CA6BC2B59706592A9219D0BF05C9F65023A21D2330807252AE0066D59CEEFA5F2748EA80BAB81';
const public_key_2 = '10001';
const public_key = new NodeRSA();
public_key.importKey({
n: Buffer.from(public_key_1, 'hex'),
e: parseInt(public_key_2, 16),
}, 'components-public');
const encrypted = crypto.publicEncrypt({
key: public_key.exportKey('public'),
padding: crypto.constants.RSA_PKCS1_PADDING
}, Buffer.from(data));
return encrypted.toString('hex');
}
function get_w(captchaId, lot_number, detail_time, distance) {
romdon_key = get_key()
pow_msg = "1|0|md5|" + detail_time + "|" + captchaId + "|" + lot_number + "||" + romdon_key
xiyu = {
"setLeft": distance,
"userresponse": distance / (.8876 * 340 / 300),
"device_id": "D00D",
"lot_number": lot_number,
"pow_msg": pow_msg,
"pow_sign": MD5_Encrypt(pow_msg),
"geetest": "captcha",
"lang": "zh",
"ep": "123",
'cuel': '632729377',
"em": {"ph": 0, "cp": 0, "ek": "11", "wd": 1, "nt": 0, "si": 0, "sc": 0}
}
xiyu = JSON.stringify(xiyu).replace(" ", "").replace("'", '"')
w = AES_Encrypt(romdon_key, xiyu)+ RSA_encrypt(romdon_key)
return w
}

48
geetest4_fullpage/mian.py Normal file
View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
import re, requests, time, uuid, execjs, json
from lxml import etree
from urllib import request
def get_captchaId():
url = "https://www.geetest.com/adaptive-captcha-demo"
res = requests.get(url).text
js_url = re.search(r'preload" href="(/_next/static/[^"]+\.js)" as="script"/>', res).group(1)
res = requests.get("https://www.geetest.com" + js_url).text
captchaId = re.search('captchaId:"([0-9a-z]+)"', res).group(1)
return captchaId
def main(captchaId, challenge):
url = "https://gcaptcha4.geetest.com/load?captcha_id=" + captchaId + "&challenge=" + challenge + "&client_type=web&risk_type=ai&lang=zh&callback=geetest_" + str(
round(time.time() * 1000))
res = requests.get(url).text
res = json.loads(res[res.index("(") + 1:res.rindex(")")])
lot_number = res['data']['lot_number']
detail_time = res['data']["pow_detail"]["datetime"]
with open('jiyan.js', 'r', encoding='utf-8') as f:
js = execjs.compile(f.read())
key = js.call('get_key')
w = js.call('get_w', captchaId, lot_number, detail_time)
url = "https://gcaptcha4.geetest.com/verify"
params = {
"callback": "geetest_" + str(round(time.time() * 1000)),
"captcha_id": captchaId,
"client_type": "web",
"lot_number": lot_number,
"risk_type": "ai",
"payload": res['data']['payload'],
"process_token": res['data']['process_token'],
"payload_protocol": "1",
"pt": "1",
"w": w
}
res = requests.get(url, params=params).text
res = json.loads(res[res.index("(") + 1:res.rindex(")")])
print('fullpage4:',res)
if __name__ == '__main__':
captchaId = get_captchaId()
challenge = str(uuid.uuid4())
main(captchaId, challenge)

Binary file not shown.

Binary file not shown.

89
geetest4_slide/gap.py Normal file
View File

@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
import cv2
class SlideCrack(object):
def __init__(self, gap, bg, out):
"""
init code
:param gap: 缺口图片
:param bg: 背景图片
:param out: 输出图片
"""
self.gap = gap
self.bg = bg
self.out = out
@staticmethod
def clear_white(img):
# 清除图片的空白区域,这里主要清除滑块的空白
img = cv2.imread(img)
rows, cols, channel = img.shape
min_x = 255
min_y = 255
max_x = 0
max_y = 0
for x in range(1, rows):
for y in range(1, cols):
t = set(img[x, y])
if len(t) >= 2:
if x <= min_x:
min_x = x
elif x >= max_x:
max_x = x
if y <= min_y:
min_y = y
elif y >= max_y:
max_y = y
img1 = img[min_x:max_x, min_y: max_y]
return img1
def template_match(self, tpl, target):
th, tw = tpl.shape[:2]
result = cv2.matchTemplate(target, tpl, cv2.TM_CCOEFF_NORMED)
# 寻找矩阵(一维数组当作向量,用Mat定义) 中最小值和最大值的位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
tl = max_loc
br = (tl[0] + tw, tl[1] + th)
# 绘制矩形边框,将匹配区域标注出来
# target目标图像
# tl矩形定点
# br矩形的宽高
# (0,0,255):矩形边框颜色
# 1矩形边框大小
cv2.rectangle(target, tl, br, (0, 0, 255), 2)
cv2.imwrite(self.out, target)
return tl[0]
@staticmethod
def image_edge_detection(img):
edges = cv2.Canny(img, 100, 200)
return edges
def discern(self):
img1 = self.clear_white(self.gap)
img1 = cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY)
slide = self.image_edge_detection(img1)
back = cv2.imread(self.bg, 0)
back = self.image_edge_detection(back)
slide_pic = cv2.cvtColor(slide, cv2.COLOR_GRAY2RGB)
back_pic = cv2.cvtColor(back, cv2.COLOR_GRAY2RGB)
x = self.template_match(slide_pic, back_pic)
# 输出横坐标, 即 滑块在图片上的位置
return x
def get_gap():
# 滑块图片
image1 = "img/slide.png"
# 背景图片
image2 = "img/bg.png"
# 处理结果图片,用红线标注
image3 = "img/show_image.png"
sc = SlideCrack(image1, image2, image3)
return sc.discern()

BIN
geetest4_slide/img/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

189539
geetest4_slide/img/tracks.json Normal file

File diff suppressed because it is too large Load Diff

59
geetest4_slide/jiyan.js Normal file
View File

@ -0,0 +1,59 @@
const NodeRSA = require('node-rsa');
const crypto = require('crypto');
const CryptoJS = require("crypto-js");
function get_key() {
var s4 = "";
for (i = 0; i < 4; i++) {
s4 = s4 + ((1 + Math["random"]()) * 65536 | 0)["toString"](16)["substring"](1);
}
return s4;
}
function MD5_Encrypt(word) {
return CryptoJS.MD5(word).toString();
}
function AES_Encrypt(key, word) {
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, CryptoJS.enc.Utf8.parse(key), {
iv: CryptoJS.enc.Utf8.parse("0000000000000000"),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return CryptoJS.enc.Hex.stringify(CryptoJS.enc.Base64.parse(encrypted.toString()));
}
function RSA_encrypt(data) {
const public_key_1 = '00C1E3934D1614465B33053E7F48EE4EC87B14B95EF88947713D25EECBFF7E74C7977D02DC1D9451F79DD5D1C10C29ACB6A9B4D6FB7D0A0279B6719E1772565F09AF627715919221AEF91899CAE08C0D686D748B20A3603BE2318CA6BC2B59706592A9219D0BF05C9F65023A21D2330807252AE0066D59CEEFA5F2748EA80BAB81';
const public_key_2 = '10001';
const public_key = new NodeRSA();
public_key.importKey({
n: Buffer.from(public_key_1, 'hex'),
e: parseInt(public_key_2, 16),
}, 'components-public');
const encrypted = crypto.publicEncrypt({
key: public_key.exportKey('public'),
padding: crypto.constants.RSA_PKCS1_PADDING
}, Buffer.from(data));
return encrypted.toString('hex');
}
function get_w(captchaId, lot_number, detail_time, distance, passtime, track) {
romdon_key = get_key()
pow_msg = "1|0|md5|" + detail_time + "|" + captchaId + "|" + lot_number + "||" + romdon_key
xiyu = {
"setLeft": distance,
"track": track,
"passtime": passtime,
"userresponse": distance / (.8876 * 340 / 300),
"device_id": "D00D",
"lot_number": lot_number,
"pow_msg": pow_msg,
"pow_sign": MD5_Encrypt(pow_msg),
"geetest": "captcha",
"lang": "zh",
"ep": "123",
'cuel': '632729377',
"em": {"ph": 0, "cp": 0, "ek": "11", "wd": 1, "nt": 0, "si": 0, "sc": 0}
}
xiyu = JSON.stringify(xiyu).replace(" ", "").replace("'", '"')
w = AES_Encrypt(romdon_key, xiyu)+ RSA_encrypt(romdon_key)
return w
}

60
geetest4_slide/mian.py Normal file
View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
import re, requests, time, uuid, execjs,json
from lxml import etree
from urllib import request
from gap import *
from trace import *
def get_captchaId():
url = "https://www.geetest.com/adaptive-captcha-demo"
res = requests.get(url).text
HTML = etree.HTML(res)
js_url = HTML.xpath("//link[contains(@href, 'adaptive-captcha-demo')]")[0].attrib["href"]
res = requests.get("https://www.geetest.com" + js_url).text
captchaId = re.search('captchaId:"([0-9a-z]+)"', res).group(1)
return captchaId
def get_image(captchaId, challenge):
url = "https://gcaptcha4.geetest.com/load?captcha_id=" + captchaId + "&challenge=" + challenge + "&client_type=web&risk_type=slide&pt=1&lang=zho&callback=geetest_" + str(
round(time.time() * 1000))
res = requests.get(url).text
res = json.loads(res[res.index("(") + 1:res.rindex(")")])
request.urlretrieve('https://static.geetest.com/' + res['data']['bg'], 'img/bg.png')
request.urlretrieve('https://static.geetest.com/' + res['data']['slice'], 'img/slide.png')
distance = get_gap()
track = get_track(distance)
return res, distance, track
def main(captchaId, challenge):
res, distance, track = get_image(captchaId, challenge)
lot_number = res['data']['lot_number']
passtime = track[-1][-1]
detail_time = res['data']["pow_detail"]["datetime"]
with open('jiyan.js', 'r', encoding='utf-8') as f:
js = execjs.compile(f.read())
key = js.call('get_key')
w = js.call('get_w', captchaId, lot_number, detail_time, distance, passtime, track)
url = "https://gcaptcha4.geetest.com/verify"
params = {
"callback": "geetest_" + str(round(time.time() * 1000)),
"captcha_id": captchaId,
"client_type": "web",
"lot_number": lot_number,
"risk_type": "slide",
"payload": res['data']['payload'],
"process_token": res['data']['process_token'],
"payload_protocol": "1",
"pt": "1",
"w": w
}
res = requests.get(url, params=params).text
res = json.loads(res[res.index("(") + 1:res.rindex(")")])
print(res)
if __name__ == '__main__':
captchaId = get_captchaId()
challenge = str(uuid.uuid4())
main(captchaId, challenge)

33
geetest4_slide/trace.py Normal file
View File

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
import random
def __ease_out_expo(x):
if x == 1:
return 1
else:
return 1 - pow(2, -10 * x)
def get_track(distance):
if not isinstance(distance, int) or distance < 0:
raise ValueError(f"distance类型必须是大于等于0的整数: distance: {distance}, type: {type(distance)}")
# 初始化轨迹列表
slide_track = [[random.randint(20, 60), random.randint(10, 40), 0]]
# 共记录count次滑块位置信息
count = 30 + int(distance / 2)
# 初始化滑动时间
t = random.randint(50, 100)
# 记录上一次滑动的距离
_x = 0
_y = 0
for i in range(count):
# 已滑动的横向距离
x = round(__ease_out_expo(i / count) * distance)
# 滑动过程消耗的时间
t = random.randint(10, 20)
if x == _x:
continue
slide_track.append([x - _x, _y, t])
_x = x
slide_track.append([0, 0, random.randint(200, 300)])
return slide_track