I have a python project working fine, which I would like to run in B4X. In general the code creates a local proxy server running on port 8888 which connects to a remote host by sending a payload. I'm not sure how to start converting which libraries do you recommend? I leave the main code here for analysis.
Main.py:
import configparser
import subprocess
import multiprocessing
import time
import os
import json
bg=''
G = bg+'\033[32m'
O = bg+'\033[33m'
GR = bg+'\033[37m'
R = bg+'\033[31m'
def main():
os.system("echo -----------------logs--------------------------------- > logs.txt")
jsondata = {
"mode" : '',
"payload" : '',
"proxy" : '',
"sni" : "",
}
os.system('cls')
print('---------------------------------------------------------------')
jsondata["mode"] = confParse()['mode']['connection_mode']
jsondata["payload"] = confParse()['config']['payload']
jsondata["proxy"] = confParse()['config']['proxyip'] +':' +confParse()['config']['proxyport']
jsondata["sni"] = confParse()['sni']['server_name']
if jsondata["mode"] == '0':
print( f'{O}Direct SSH{GR}')
if jsondata["mode"] == '2':
print(f'{O}SNI : {GR} {jsondata["sni"]}')
if jsondata["mode"] in ['1','3']:
print(f'{O}payload :\n{GR} {jsondata["payload"]}\n')
#if len(jsondata["proxy"].split(':')[1]) > 1:
print(f'{O}proxy :{GR} ', jsondata["proxy"] if len(jsondata["proxy"].split(':')[1]) > 1 else None,end='\n\n')
print(f'{O}SSL/TLS :{GR}', jsondata["sni"] if jsondata["mode"] =='3' else None)
threadServ = multiprocessing.Process(target=ServRun)
threadServ.start()
sshStart = multiprocessing.Process(target=sshrun).start()
return readlogs()
def readlogs():
OneTimeOutput = []
while True:
try:
with open('logs.txt','r') as file:
time.sleep(1)
end = 0
logs = file.readlines()
for line in logs:
if line not in OneTimeOutput:
OneTimeOutput.append(line)
print(line)
if line.split(":")[-1].split("-")[0].strip()=='SSH':
os.system("echo -----------------logs--------------------------------- > logs.txt")
runProxifier()
end +=1
break
if end:break
except KeyboardInterrupt:
return serviceManage()
return serviceManage()
def killProcessid(target):
findProcess = subprocess.Popen(['tasklist','|','findstr', target],shell=True,stdout= subprocess.PIPE,stderr=subprocess.STDOUT)
for line in findProcess.stdout:
pid = line.decode('utf-8','ignore').split()[1]
killprocess = subprocess.Popen(['taskkill','/f','/pid',pid],shell=True,stdout= subprocess.PIPE,stderr=subprocess.STDOUT)
return "Done"
def ServRun():
#path = os.path.abspath(os.path.curdir)+'/lib'
Serv_Cmd = subprocess.Popen(['python','tunnel.py','8888'] , shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
def confParse():
config = configparser.ConfigParser()
try:
config.read_file(open('settings.ini'))
except Exception as e:
pass
return config
def sshrun():
#ssh load settings
ssh_server = confParse()['ssh']['host']
ssh_port = confParse()['ssh']['port']
username = confParse()['ssh']['username']
password = confParse()['ssh']['password']
#local proxy
proxy_ip = '127.0.0.1'
proxy_port = '8888'
#run ssh command
ssh_cmd = subprocess.Popen(( f'BvSsh.exe -host={ssh_server} -user={username} -pw={password} -port={ssh_port} -proxy=y -proxyType=HTTP -proxyServer=127.0.0.1 -proxyPort={proxy_port} -proxyFwding=y -proxyListIntf=127.0.0.1 -proxyListPort=1080 -loginOnStartup -reconnect=Always -reconnTimeout=2'),stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
def runProxifier():
proxify = subprocess.Popen(('"C:\\Program Files (x86)\\Proxifier\\Proxifier.exe" socks5profile.ppx '))
def serviceManage():
try:
index_input = int(input('1 - To Disconnect \n2 - To Reconnect \n3 - show logs\n choose op num: '))
services = ["Proxifier","BvSsh.exe",'python']
if index_input in [1,2] :
services = [services[0:2] if index_input == 2 else services[:]][0]
for ev in services:
killProcessid(ev)
if index_input == 2 :
return main()
if index_input == 3:
readlogs()
if index_input not in [1,2,3]:
print('Operation number not listed')
return serviceManage()
except Exception as e:
print(e)
print('A number required ')
return serviceManage()
if __name__=='__main__':
main()
tunnel.py:
import ssl,os,certifi,sys
import socket
import time
import select
import threading
from inject import injector
import configparser
bg=''
G = bg+'\033[32m'
O = bg+'\033[33m'
GR = bg+'\033[37m'
R = bg+'\033[31m'
Buffer_lenght = 4096 * 4
class Tun(injector):
def __init__(self):
self.localip = '127.0.0.1'
self.LISTEN_PORT = int(sys.argv[1])
def conf(self):
config = configparser.ConfigParser()
try:
config.read_file(open('settings.ini'))
except Exception as e:
self.logs(e)
return config
def extraxt_sni(self,config):
sni = config['sni']['server_name']
return sni
def gethost(self,config):
host=config['ssh']['host']
return host
def proxy(self,config):
proxyhost = config['config']['proxyip']
proxyport = int(config['config']['proxyport'])
return [proxyhost,proxyport]
def conn_mode(self,config):
mode = config['mode']['connection_mode']
return mode
def tunneling(self,client,sockt):
connected = True
while connected == True:
r, w, x = select.select([client,sockt], [], [client,sockt],3)
if x: connected = False; break
for i in r:
try:
data = i.recv(Buffer_lenght)
if not data: connected = False; break
if i is sockt:
client.send(data)
else:
sockt.send(data)
except Exception as e:
self.logs(f'{R} {e}{GR}')
connected = False;break
client.close()
sockt.close()
def destination(self,sock_server, address):
try:
request = sock_server.recv(9124).decode()
host = self.gethost(self.conf())
port = request.split(':')[-1].split()[0]
try:
proxy_ip=self.proxy(self.conf())[0]
proxy_port=self.proxy(self.conf())[1]
except ValueError:
proxy_ip = host
proxy_port = port
sock_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock_client.connect((proxy_ip,int(proxy_port)))
self.logs(f'{O}[TCP] {G}connected to {proxy_ip}:{proxy_port}{GR}')
if int(self.conn_mode(self.conf())) == 2:
SNI_HOST = self.extraxt_sni(self.conf())
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
sock_client = context.wrap_socket(sock_client,server_hostname=str(SNI_HOST))
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations(
cafile=os.path.relpath(certifi.where()),
capath=None,cadata=None)
self.logs(f'{O}[TCP] Handshaked successfully to {SNI_HOST}{GR}')
try:
self.logs(f'''{O}[TCP] Protocol :{G}{sock_client.version()}\n{O}Ciphersuite :{G} {sock_client.cipher()[0]}\n{O}Peerprincipal:{G} C={sock_client.getpeercert()["subject"][1][0][1]}, ST={sock_client.getpeercert()["subject"][1][0][1]} , L={sock_client.getpeercert()["subject"][2][0][1]} , O={sock_client.getpeercert()["subject"][3][0][1]} , CN={sock_client.getpeercert()["subject"][4][0][1]} {GR}''')
except:
self.logs(f'''{O}[TCP] Protocol :{G}{sock_client.version()}\n{O}Ciphersuite :{G} {sock_client.cipher()[0]}\n{O}Peerprincipal:{G} {sock_client.getpeercert()["subject"]}''')
sock_server.send(b"HTTP/1.1 200 Connection Established\r\n\r\n")
elif int(self.conn_mode(self.conf())) == 3:
SNI_HOST = self.extraxt_sni(self.conf())
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
sock_client = context.wrap_socket(sock_client,server_hostname=str(SNI_HOST))
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations(
cafile=os.path.relpath(certifi.where()),
capath=None,cadata=None)
self.logs(f'Handshaked successfully to {SNI_HOST}')
try:
self.logs(f'''{O}[TCP] Protocol :{G}{sock_client.version()}\n{O}Ciphersuite :{G} {sock_client.cipher()[0]}\n{O}Peerprincipal:{G} C={sock_client.getpeercert()["subject"][1][0][1]}, ST={sock_client.getpeercert()["subject"][1][0][1]} , L={sock_client.getpeercert()["subject"][2][0][1]} , O={sock_client.getpeercert()["subject"][3][0][1]} , CN={sock_client.getpeercert()["subject"][4][0][1]} {GR}''')
except:
self.logs(f'''{O}[TCP] Protocol :{G}{sock_client.version()}\n{O}Ciphersuite :{G} {sock_client.cipher()[0]}\n{O}Peerprincipal:{G} {sock_client.getpeercert()["subject"]}''')
injector.connection(self,sock_server,sock_client,kwargs={'SSH':f'{host}:{port}','PROXY':f'{proxy_ip}:{proxy_port}'})
else:
injector.connection(self,sock_server,sock_client,kwargs={'SSH':f'{host}:{port}','PROXY':f'{proxy_ip}:{proxy_port}'})
self.tunneling(sock_server,sock_client)
except Exception as e:
self.logs(f'{e}')
def create_connection(self):
for res in socket.getaddrinfo(self.localip, self.LISTEN_PORT, socket.AF_UNSPEC,socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
af, socktype, proto, canonname, sa = res
try:
sockt = socket.socket(af, socktype, proto)
except OSError as msg:
self.logs(str(msg))
continue
try:
localAddress = socket.gethostbyname("localhost")
sockt.bind((localAddress,self.LISTEN_PORT))
sockt.listen(1)
except OSError as msg:
self.logs(str(msg))
sockt.close()
if sockt:
pass
self.logs('Waiting for incoming connection to : {}:{}\n'.format(self.localip,self.LISTEN_PORT))
while True:
try:
client, address = sockt.accept()
thr = threading.Thread(target=self.destination, args=(client, address))
thr.start()
except :
sockt.close()
break
def logs(self,log):
logtime = str(time.ctime()).split()[3]
logfile = open('logs.txt','a')
logfile.write(f'[{logtime}] : {str(log)}\n')
if __name__=='__main__':
start = Tun()
start.create_connection()
inject.py:
import time
import socket
import configparser
import re
import sys
import user_agent
bg=''
G = bg+'\033[32m'
O = bg+'\033[33m'
GR = bg+'\033[37m'
R = bg+'\033[31m'
class injector():
def __init__(self):
pass
def conf(self):
config = configparser.ConfigParser()
try:
config.read_file(open('settings.ini'))
except Exception as e:
self.logs(e)
return config
def getpayload(self,config):
payload = config['config']['payload']
return payload
def proxy(self,config):
proxyhost = config['config']['proxyip']
proxyport = int(config['config']['proxyport'])
return [proxyhost,proxyport]
def conn_mode(self,config):
mode = config['mode']['connection_mode']
return mode
def auto_rep(self,config):
result = config['config']['auto_replace']
return result
def payloadformating(self,payload,**kwargs):
host, port = kwargs["kwargs"]["SSH"].split(':')[0],kwargs["kwargs"]["SSH"].split(':')[1]
proxy_ip,proxy_port = kwargs["kwargs"]["PROXY"].split(':')[0],kwargs["kwargs"]["PROXY"].split(':')[1]
User_Agent = user_agent.generate_user_agent()
payload = payload.replace('[crlf]','\r\n')
payload = payload.replace('[crlf*2]','\r\n\r\n')
payload = payload.replace('[cr]','\r')
payload = payload.replace('[lf]','\n')
payload = payload.replace('[protocol]','HTTP/1.0')
payload = payload.replace('[ua]',User_Agent)
payload = payload.replace('[raw]',f'CONNECT {kwargs["kwargs"]["SSH"]} HTTP/1.0\r\n\r\n')
payload = payload.replace('[real_raw]',f'CONNECT {kwargs["kwargs"]["SSH"]} HTTP/1.0\r\n\r\n')
payload = payload.replace('[netData]',f'CONNECT {kwargs["kwargs"]["SSH"]} HTTP/1.0')
payload = payload.replace('[realData]',f'CONNECT {kwargs["kwargs"]["SSH"]} HTTP/1.0')
payload = payload.replace('[split_delay]','[delay_split]')
payload = payload.replace('[split_instant]','[instant_split]')
payload = payload.replace('[method]','CONNECT')
payload = payload.replace('[lfcr]','\n\r')
payload = payload.replace('[host_port]',host+':'+port)
payload = payload.replace('[host]',host)
payload = payload.replace('[port]',port)
payload = payload.replace('[IP]',host)
payload = payload.replace('[PORT]',port)
payload = payload.replace('[proxy]',kwargs["kwargs"]["PROXY"])
payload = payload.replace('[ssh]',kwargs["kwargs"]["PROXY"])
payload = payload.replace('[auth]','')
payload = payload.replace('[split]' ,'=1.0=')
payload = payload.replace('[delay_split]' ,'=1.5=')
payload = payload.replace('[instant_split]','=0.0=')
return payload
def connection(self,client, server,**kwargs):
if int(self.conn_mode(self.conf())) == 0:
return self.get_resp(server=server,client=client)
else:
payloads = self.payloadformating(self.getpayload(self.conf()),**kwargs).split('=')
for payload in payloads:
if payload in ['1.0','1.5','0.0'] :
time.sleep(float(payload))
else:
self.logs(f'{O} sending payload : {payload.encode()}{GR}')
server.send(payload.encode())
return self.get_resp(server=server,client=client)
def get_resp(self,server,client) :
packet = server.recv(1024)
status = packet.decode('utf-8','ignore').split('\r\n')[0]
serverHandshakeResponse = status if status.split('-')[0]=='SSH' else False
if serverHandshakeResponse:
self.logs(f'response : {serverHandshakeResponse}')
client.send(packet)
return True
else:
if re.match(r'HTTP/\d(\.\d)? \d\d\d ',status):
self.logs(f'response : {status}')
client.send(b'HTTP/1.1 200 Connection established\r\n\r\n')
return self.get_resp(server,client)
def logs(self,log):
logtime = str(time.ctime()).split()[3]
logfile = open('logs.txt','a')
logfile.write(f'[{logtime}] : {str(log)}\n')