automator: put inside own folder and convert to docker compose

master
EmaMaker 2021-12-08 20:38:40 +01:00
parent bef53a1d36
commit de3df999c8
47 changed files with 47 additions and 408 deletions

11
Automator/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
# syntax=docker/dockerfile:1
FROM python:3.10-bullseye
WORKDIR .
COPY . .
#RUN pip3 install --upgrade pip
#RUN pip3 install -r requirements.txt
#CMD [ "./colab_automator.sh"]
#CMD ["python3", "-u", "main.py"]
CMD ["python3", "-u", "account_server_test.py"]

View File

@ -0,0 +1,16 @@
import socket
acc = ""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(("server", 12345))
s.send(b"givacc")
acc = s.recv(1024)
print(acc)
s.close()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(("server", 12345))
s.send(b"remacc|t788egrvdp@wwjmp.com")
print(s.recv(1024))
s.close()

View File

View File

@ -0,0 +1,12 @@
services:
bot:
build: .
volumes:
- ./code:/code
- ./account_data:/account_data
networks:
- qwaccountserver_default
networks:
qwaccountserver_default:
external: true

View File

View File

@ -210,8 +210,9 @@ def get_google_account():
# Assumes the account server is already running on localhost:12345
def socket_request_new_account():
import socket
from utils import global_vars
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", 12345))
s.connect((global_vars.QWACCOUNTSERVER_HOSTNAME_DOCKER, 12345)) #ip
s.send(b"givacc")
account = s.recv(1024).decode("utf-8")
s.close()

4
Automator/start.sh Normal file
View File

@ -0,0 +1,4 @@
#!/bin/bash
#sudo docker compose up
sudo docker compose up --build --scale 1

View File

View File

@ -3,4 +3,5 @@ TEST_ACCOUNT = False
# email, password, gcloud shell link
# TEST_ACCOUNT = ('student-01-474fc01a4ea5@qwiklabs.net', 'PkR9NJR4ms5D', 'https://accounts.google.com/AddSession?service=accountsettings&sarp=1&continue=https%3A%2F%2Fconsole.cloud.google.com%2Fhome%2Fdashboard%3Fproject%3Dqwiklabs-gcp-03-676b378e29e0#Email=student-01-474fc01a4ea5@qwiklabs.net')
TEST_QWIKLABS_ACCOUNT = False
# TEST_QWIKLABS_ACCOUNT = "i3z8qtab@xojxe.com"
# TEST_QWIKLABS_ACCOUNT = "i3z8qtab@xojxe.com"
QWACCOUNTSERVER_HOSTNAME_DOCKER = "server" #using hostname, much simpler

Binary file not shown.

View File

@ -1,14 +0,0 @@
06prgzamm96@esiix.com
jhv8mtemi@esiix.com
6bgfngq6@yoggm.com
fohxil@xojxe.com
b4d0o0y5pg@esiix.com
i3z8qtab@xojxe.com
l5wbup@1secmail.com
ryysw0@1secmail.net
m5l7868ar@wwjmp.com
ue8oqa0lf0j@1secmail.net
17k2l9@1secmail.com
c5xm6j@1secmail.net
mud0ud@esiix.com
t788egrvdp@wwjmp.com

View File

@ -1,98 +0,0 @@
''' This file needs to be run outside of the GShellAutomator script
Starts a TCP server on localhost, to which GSA asks for accounts and reports problems
Command list:
givacc: Client is requesting a qwiklabs account to use. Take one from the available list and return it, then put it in the suspended list
remacc: Client reported the account is not working anymore, and it needs to be delete (TODO: make this script test is the account is really unusable)
'''
import time
import json
import socket
import random
import threading
from multiprocessing import Process, Manager
def handle_clients(available_list, suspended_dict, todelete_list):
while True:
(clientsocket, address) = socket.accept()
command = clientsocket.recv(1024).decode("utf-8").split("|")
if command[0] != "":
if command[0] == "givacc":
account_valid = False
while not account_valid:
account = available_list[random.randint(0, len(available_list)-1)]
if (not account in suspended_dict.keys() ) and (not account in todelete_list):
account_valid = True
suspended_dict[account] = time.time()
clientsocket.send(account.encode("utf-8"))
print("[AccountServer] Received a request for a new account, choose", account)
elif command[0] == "remacc":
del suspended_dict[command[1]]
todelete_list.append(command[1])
clientsocket.close()
print("[AccountServer] Received a request to delete", account, "adding to list!")
if __name__ == "__main__":
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind(("localhost", 12345))
socket.listen(5)
with Manager() as manager:
available = open('src/qwiklabs/account_server/qwiklabs_available_accounts.txt', 'r+')
suspended = open('src/qwiklabs/account_server/qwiklabs_suspended.txt', 'r+')
todelete = open('src/qwiklabs/account_server/qwiklabs_todelete.txt', 'r+')
# create the list from the files
available_list = manager.list([line.strip() for line in available.readlines()])
try:
suspended_dict = manager.dict(json.loads(suspended.read()))
except:
suspended_dict = manager.dict({})
todelete_list = manager.list([line.strip() for line in todelete.readlines()])
p = Process(target=handle_clients, args=(available_list, suspended_dict, todelete_list))
p.start()
last_update_time = time.time()
while True:
tounsuspend = []
for account in suspended_dict:
if time.time()-suspended_dict[account] > 3600: #time is stored in seconds, so this is 3600 after an hour os first being suspened
tounsuspend.append(account)
print("Unsuspend", account, "as enough time as passed")
for account in tounsuspend:
del suspended_dict[account]
#update list
if time.time() - last_update_time > 5:
last_update_time = time.time()
#print("Cyclic update of files")
available = open('src/qwiklabs/account_server/qwiklabs_available_accounts.txt', 'r+')
suspended = open('src/qwiklabs/account_server/qwiklabs_suspended.txt', 'r+')
todelete = open('src/qwiklabs/account_server/qwiklabs_todelete.txt', 'r+')
#clear files, update with data loaded from the program
available.truncate(0)
suspended.truncate(0)
todelete.truncate(0)
#put data in there
available.writelines([(l + "\n") for l in available_list])
suspended.write(json.dumps(dict(suspended_dict)))
todelete.writelines([(l + "\n") for l in todelete_list])
#close files for it to take effect
available.close()
suspended.close()
todelete.close()

View File

@ -1,13 +0,0 @@
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", 12345))
s.send(b"givacc")
print(s.recv(1024))
s.close()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", 12345))
s.send(b"remacc|06prgzamm96@esiix.com")
print(s.recv(1024))
s.close()

View File

@ -1,14 +0,0 @@
06prgzamm96@esiix.com
jhv8mtemi@esiix.com
6bgfngq6@yoggm.com
fohxil@xojxe.com
b4d0o0y5pg@esiix.com
i3z8qtab@xojxe.com
l5wbup@1secmail.com
ryysw0@1secmail.net
m5l7868ar@wwjmp.com
ue8oqa0lf0j@1secmail.net
17k2l9@1secmail.com
c5xm6j@1secmail.net
mud0ud@esiix.com
t788egrvdp@wwjmp.com

View File

@ -1 +0,0 @@
06prgzamm96@esiix.com

View File

@ -1,193 +0,0 @@
from utils import browser_manager
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.common.alert import Alert, Command
from selenium.webdriver.common.keys import Keys
import requests
import os
import urllib
# recaptcha libraries
import pydub
import speech_recognition as sr
from bs4 import BeautifulSoup
from utils.global_vars import PROXY
class QL_CreateAccount:
def create_account(self):
self.info = RandomNameGenerator(self.proxy).get_person_info()
self.driver = browser_manager.start_browser()
self.temp_mail = TempMail()
self.temp_mail_address = self.temp_mail.get_new_temp_mail()
self.sign_up()
self.accept_eula()
print("Account created!".format(self.info, self.temp_mail_address))
def sign_up(self):
print("[+] Creating a new account for with mail [{}:{}]".format(self.info, self.temp_mail_address))
self.driver.get("https://www.qwiklabs.com/users/sign_up")
time.sleep(1.5)
#accept goddamn cookies
browser_manager.clickButton(self.driver, By.XPATH, '/html/body/div[2]/div/button')
time.sleep(2)
browser_manager.inputText(self.driver, By.CSS_SELECTOR, "#user_first_name", self.info[0], after_delay=1.5)
browser_manager.inputText(self.driver, By.CSS_SELECTOR, "#user_last_name", self.info[1], after_delay=1.5)
browser_manager.inputText(self.driver, By.CSS_SELECTOR, "#user_email", self.temp_mail_address, after_delay=1.5)
browser_manager.inputText(self.driver, By.CSS_SELECTOR, "#user_company_name", self.info[2], after_delay=1.5)
browser_manager.inputText(self.driver, By.CSS_SELECTOR, "#user_password", "hellogoodbye", after_delay=1.5)
browser_manager.inputText(self.driver, By.CSS_SELECTOR, "#user_password_confirmation", "hellogoodbye", after_delay=1.5)
time.sleep(10)
self.resolve_captcha('/html/body/div[1]/div[1]/div[2]/form[2]/div[8]/div/div/iframe', "recaptcha-checkbox", "/html/body/div[4]/div[4]", "recaptcha-audio-button")
time.sleep(5)
self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/form[2]/div[9]/button').click()
def resolve_captcha(self, frame1_xpath, checkbox_classname, frame2_container_xpath, audio_id):
# switch to recaptcha frame
# frames = self.driver.find_elements_by_tag_name("iframe")
# self.driver.switch_to.frame(frames[0])
self.driver.switch_to.frame(self.driver.find_element_by_xpath(frame1_xpath))
browser_manager.delay(self.driver)
# click on checkbox to activate recaptcha
self.driver.find_element_by_class_name(checkbox_classname).click()
# switch to recaptcha audio control frame
self.driver.switch_to.default_content()
frame2_container = browser_manager.waitForElement(self.driver, By.XPATH, frame2_container_xpath)
# Sometimes the captcha gets accepted right away
if frame2_container is False:
return
frames = frame2_container.find_elements_by_tag_name("iframe")
self.driver.switch_to.frame(frames[0])
browser_manager.delay(self.driver)
# click on audio challenge
self.driver.find_element_by_id(audio_id).click()
# switch to recaptcha audio challenge frame
self.driver.switch_to.default_content()
frames = self.driver.find_elements_by_tag_name("iframe")
self.driver.switch_to.frame(frames[-1])
browser_manager.delay(self.driver)
# get the mp3 audio file
src = self.driver.find_element_by_id("audio-source").get_attribute("src")
print("[INFO] Audio src: %s" % src)
# download the mp3 audio file from the source
urllib.request.urlretrieve(src, os.path.normpath(os.getcwd() + "\\sample.mp3"))
browser_manager.delay(self.driver)
# load downloaded mp3 audio file as .wav
try:
sound = pydub.AudioSegment.from_mp3(os.path.normpath(os.getcwd() + "\\sample.mp3"))
sound.export(os.path.normpath(os.getcwd() + "\\sample.wav"), format="wav")
sample_audio = sr.AudioFile(os.path.normpath(os.getcwd() + "\\sample.wav"))
except Exception:
print("[ERR] Please run program as administrator or download ffmpeg manually, "
"http://blog.gregzaal.com/how-to-install-ffmpeg-on-windows/")
# translate audio to text with google voice recognition
r = sr.Recognizer()
with sample_audio as source:
audio = r.record(source)
key = r.recognize_google(audio)
print("[INFO] Recaptcha Passcode: %s" % key)
# key in results and submit
self.driver.find_element_by_id("audio-response").send_keys(key.lower())
self.driver.find_element_by_id("audio-response").send_keys(Keys.ENTER)
self.driver.switch_to.default_content()
browser_manager.delay(self.driver)
# self.driver.find_element_by_id("recaptcha-verify-button").click()
# browser_manager.delay(self.driver)
def accept_eula(self):
self.driver.get(self.temp_mail.get_confirmation_link())
time.sleep(5)
#insert password
browser_manager.inputText(self.driver, By.CSS_SELECTOR, "#user_password", "hellogoodbye", after_delay=1.5)
browser_manager.clickButton(self.driver, By.XPATH, "/html/body/div[2]/div[1]/div[2]/form/div[4]/button")
time.sleep(10)
browser_manager.clickButton(self.driver, By.XPATH, '/html/body/div[2]/div/button')
time.sleep(2)
self.resolve_captcha('/html/body/div[1]/form/div/div/div/div/div/iframe', "recaptcha-checkbox", "/html/body/div[4]/div[4]", "recaptcha-audio-button")
time.sleep(5)
browser_manager.clickButton(self.driver, By.XPATH, '/html/body/div[1]/form/input[5]')
time.sleep(1000)
class RandomNameGenerator():
def __init__(self):
self.proxyDict = {
"socks" : PROXY,
"socksVersion" : 5
}
def get_person_info(self):
if PROXY:
r = requests.get('https://randomuser.me/api', proxies=self.proxyDict)
else:
r = requests.get('https://randomuser.me/api')
firstname = r.json()['results'][0]['name']['first']
lastname = r.json()['results'][0]['name']['last']
#use city as company
company = r.json()['results'][0]['location']['city']
return (firstname, lastname, company)
# get a temp mail from https://www.1secmail.com/api/ and handle it using requests
class TempMail:
def __init__(self):
self.proxyDict = {
"socks" : PROXY,
"socksVersion" : 5
}
# Open a new tab, head over to temp-mail.org, click the delete button and get a new temp mail
def get_new_temp_mail(self):
self.email = requests.get('https://www.1secmail.com/api/v1/?action=genRandomMailbox', proxies=self.proxyDict).json()[0]
return self.email
# Wait for qwiklabs confirmation email to arrive, click it
def get_confirmation_link(self):
arrived = False
while arrived == False:
print('Waiting for confirmation email')
fetched_msg = requests.get('https://www.1secmail.com/api/v1/?action=getMessages&login=' + self.email.split('@')[0] + '&domain='+self.email.split('@')[1], proxies=self.proxyDict)
arrived = fetched_msg.text != '[]'
time.sleep(2)
print('Email arrived')
msg_id = fetched_msg.json()[0]['id']
email = requests.get('https://www.1secmail.com/api/v1/?action=readMessage&login=' + self.email.split('@')[0] + '&domain='+self.email.split('@')[1] + '&id=' + str(msg_id))
body = email.json()['body']
soup = BeautifulSoup(body, 'html.parser')
a = ""
for link in soup.find_all('a'):
if 'confirmation' in link.get('href'):
a = link.get('href')
print("Here's the confirmation link " + a)
return a

View File

@ -1,72 +0,0 @@
from utils import browser_manager
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.common.alert import Command
class QL_DeleteAccount:
def __init__(self, account):
self.account = account
def delete_account(self):
self.driver = browser_manager.start_browser()
self.sign_in()
self.delete()
def sign_in(self):
print("[+] Signing in using account [{}:{}]".format(self.account[0], self.account[1]))
self.driver.get("https://www.qwiklabs.com/users/sign_in")
time.sleep(1.5)
#accept goddamn cookies
browser_manager.clickButton(self.driver, By.XPATH, '/html/body/div[2]/div/button')
time.sleep(2)
browser_manager.inputText(self.driver, By.CSS_SELECTOR, "#user_email", self.account[0])
time.sleep(1.5)
browser_manager.inputText(self.driver, By.CSS_SELECTOR, "#user_password", self.account[1])
time.sleep(1.5)
browser_manager.clickButton(self.driver, By.CSS_SELECTOR, "#new_user > div.form-actions > button")
time.sleep(5)
def delete(self):
# Click on profile icon, it's under a shadow-dom element
root1 = self.driver.find_element_by_css_selector("#my_account")
shadow = browser_manager.expand_shadow_element(self.driver, root1)
profile = shadow.find_element_by_css_selector('.ql-icon-button')
profile.click()
time.sleep(2)
# head over to settings
settings = self.driver.find_element_by_css_selector('#settings')
settings.click()
time.sleep(2)
#accept goddamn cookies
browser_manager.clickButton(self.driver, By.XPATH, '/html/body/div[2]/div/button')
time.sleep(2)
# select 'security' tab
root1 = browser_manager.waitForElement(self.driver, By.XPATH, '/html/body/ql-drawer-container/ql-drawer/ql-sidenav/ql-sidenav-item[4]')
shadow = browser_manager.expand_shadow_element(self.driver, root1)
root1.click()
time.sleep(2)
# button = shadow.find_element_by_css_selector('.sidenav-item')
# button.click()
browser_manager.clickButton(self.driver, By.XPATH, '/html/body/ql-drawer-container/ql-drawer-content/main/div[3]/div[2]/div/a')
time.sleep(5)
#delete history
browser_manager.clickButton(self.driver, By.CSS_SELECTOR, '#delete_account_history_are_you_sure > div > div > div > a:nth-child(2)')
time.sleep(8)
# finally accept the deletition of the account
al = self.driver.switch_to.alert
al.accept()
print("Account {} deleted!".format(self.account))