I have written a code in Python, and I want to change it.
I use it when I am performing a penetration tests in my organization and I want to make my script better.
The script gets a username that I entering and it connect to the SMTP server over port 25 and check if the user exists or not.
Here is the script:
#!/usr/bin/python
import socket
import sys
if len(sys.argv) != 2:
print "Usage: vrfy.py <username>"
sys.exit(0)
# Create a Socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to the Server
connect=s.connect(('192.168.0.10',25))
# Recieve the banner
banner=s.recv(1024)
print banner
# VRFY a user
s.send('VRFY ' + sys.argv[1] + '\r\n')
result=s.recv(1024)
print result
# Close the socket
s.close()
The changes that I want to perform are the following:
Instead of entering only one username to check, I want to mention a location of a txt file and the script will read all the usernames it contains.
Also, I what that the IP address at the script wont be hard coded and I will need to insert it every time I am using the script.
Many thanks in advance,
Bar Aviv
You're not really supposed to use the low-level socket send() and recv() directly like that. They're not guaranteed to send/receive any particular amount of data. It might just happen to work the way you want talking to one particular mail server, but as soon as commands/responses don't fit one-to-one into IP packets, you're going to get weird results.
If you want a simple blocking conversational stream, try the file interface you get from socket.makefile.
You should probably implement a little more of SMTP as well... at least say helo!
The below reads usernames from standard input, so you can direct a file of usernames to it by saying:
python vrfy.py 127.0.0.1 < usernames.txt
though you could change it to read sys.argv[2] for another filename parameter if you wanted.
users= []
for line in sys.stdin:
line= line.strip()
if line!='':
users.append(line)
s= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 25))
fp= s.makefile('rwb')
fp.readline() # ignore banner
fp.write('HELO test.example.com\r\n')
fp.flush()
fp.readline() # ignore response
for user in users:
fp.write('VRFY %s\r\n' % user)
fp.flush()
print '%s: %s' % (user, fp.readline().strip())
fp.write('QUIT\r\n')
fp.flush()
s.close()
Use something like the following:
with open(sys.argv[1]) as f:
for line in f:
username = line.replace('\n', '')
print 'Testing with user: %s' % user
For the IP address, you can pass it as a second argument -- verify.py username-list-file server-ip-address -- and reference as sys.argv[2].
You can also do something like:
try:
userlist = sys.argv[1]
server_address = sys.argv[2]
except IndexError:
print 'Usage: verify.py username-list-file server-ip-address'
sys.exit(-1)
Related
Wizards of stackoverflow. I'm trying to read in commands from a .txt file to SSH using paramiko. Currently it will read in the first line from the file and execute it. When I get to the second line though, it will throw an EOFError and quit. I put a check in to see if the second command makes it to print and it does, however, it does not execute. I was hoping someone would be able to help and solve this issue with me. Here is my code:
from paramiko import client
import logging
import os
#Clear the screen before starting the script
os.system('cls')
# Prompting for the user input config file
filename = input('Input configuration filename, the file extension must be attached: ')
# Creating the LOG file for the execution of the config file
logFileName = "LOG" + filename[0:]
try:
logging.basicConfig(filename= logFileName ,format='%(asctime)s %(message)s', level= logging.DEBUG)
print ("The file was created!")
except IOError:
print ("File failed to create")
logging.info("---------------------------------------------------------------------------")
logging.info("NEW CONFIGURATION LOG ENTRY")
logging.info("---------------------------------------------------------------------------")
# Class for creating an SSH client, logging in, letting us write out commands, and close the client.
class ssh:
client = None
def __init__(self, address, username, password):
print ("Connecting to server...")
logging.info('Connecting to server...')
self.client = client.SSHClient()
self.client.set_missing_host_key_policy(client.AutoAddPolicy())
self.client.connect(address, username= username, password= password, look_for_keys= False)
logging.info("Address: " + address)
logging.info("Username: " + username)
print ("Connection successful!")
logging.info('Connection successful!')
def sendCommand(self, command):
if (self.client):
stdin, stdout, stderr = self.client.exec_command(command)
receiveData = b""
while not stdout.channel.exit_status_ready():
receiveData += stdout.channel.recv(1024)
if stdout.channel.recv_ready():
received = stdout.channel.recv(1024)
while received:
receiveData += received
received = stdout.channel.recv(1024)
if receiveData:
print (str(receiveData, "utf8"))
else:
print ("stdout is empty")
else:
print ("Connection failed, check credentials and try again..")
logging.warning('Connection failed, check credentials and try again..')
connection = ssh('0.0.0.0', 'test', 'test')
with open(filename) as f:
for line in f:
print(line)
connection.sendCommand(line)
The .txt file would read something like this:
configure terminal
Interface Gi0/9
description Test_Interface
Any help is much appreciated, thank you.
Possible bug. Current implementation of sendCommand may not receive output (or full output).
Reason
exit_status_ready is a non blocking way to find that exit status is received. It is possible that lastpart of output still not readed by script. You need to call recv after while if recv_ready is True.
Also, I don't think that checking recv_ready in while loop is good idea. It's non-blocking method. Because of it while loop will uselessly run multiple times, just wasting your CPU power.
This version work for me:
receiveData = b""
while not stdout.channel.exit_status_ready():
receiveData += stdout.channel.recv( 2048 )
if stdout.channel.recv_ready():
received = stdout.channel.recv( 2048 )
while received: #received will be empty only when all data received
receiveData += received
received = stdout.channel.recv( 2048 )
if receiveData:
print( str( receiveData, "utf8" ) )
else:
print( "stdout is empty" )
Also I should mention that there is easer way to build string from output. You can use the fact that stdin, stdout, and stderr are file like objects.
Here simpler example for stderr (it may be good idea to read it too):
data = ""
for line in stderr:
#line in string already (probably will work only if locale is utf8)
data += line
if data:
print( data )
else:
print( "stderr is empty" )
Update:
if you don't have multiple commands on one line then
filename = input('Input configuration filename, the file extension must be attached: ')
# define ssh class here (i'll skip it to make it shorter)
connection = ssh('0.0.0.0', 'test', 'test')
with open(filename) as f:
for line in f:
connection.sendCommand( line )
If you have several commands per line just split them to array of different commands.
This is the client and server program where a client sends a file to server to save in the server. There is a issuse in that same file name is not getting copied on the server with same file size
Please help me in this
Client program
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost",9999))
path=raw_input("Please enter the complete PATH of your file : ")
f=open (path, "rb")
l = f.read(256)
while (l):
s.sendall(l)
l = f.read(10000)
s.close()
Server Program
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost",9999))
s.listen(10)
while True:
s, address = s.accept()
print address
i=1
f = open( str(i),'wb') #open in binary
#i=i+1
while (True):
l=s.recv(256)
#while (l):
f.write(l)
l=s.recv(256)
print 'File recieve succesfully'
f.close()
#sc.close()
s.close()
Thanks in advance
Start by walking through the code and thinking about what the client knows about the data it is sending and what the server knows about the data it is receiving. You will have to send 2 types of messages: the data and the filename. How you do that is up to you.
Without over-thinking it, maybe try writing the filename first (followed by a newline or special character) then send the file data. On the server side accept the connection, read in data until you find a newline character (that's the filename), then receive the rest of the data and write it to the file.
Also, the server code you've provided doesn't work, at least I don't think, since you never break out of your while True loops.
I am trying to make a TCP port server in python. Here is my code so far:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('',4000))
sock.listen(1)
while 1:
client, address = sock.accept()
fileexists = client.RUNCOMMAND(does the file exist?)
if fileexists = 0:
client.close()
else if:
filedata = client.RUNCOMMAND(get the contents of the file)
if filedata = "abcdefgh":
client.send('Transfer file accepted.')
else:
client.send('Whoops, seems like you have a corrupted file!')
client.close()
I just have no idea how to run a command (RUNCOMMMAND) that would check if a file exists on the client.
Also, is there a way to check what operating system the client is on to run different commands (eg. linux will have a file finder different command than windows). And I totally understand if this isn't possible, but I am really hoping that there is a way to do this.
Thank you very much.
XMLRPC may help you.
XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a transport.
http://docs.python.org/2/library/xmlrpclib.html
You might want to look at the very handy bottle.py micro server. its great for small server tasks like this and you get the Http protocol on top of this. You just include one file with your code. http://bottlepy.org
here is code that will work from http://blah:8090/get/file or http://blah:8090/exists/file so to see the contents of /etc/hosts would be http://blah:8090/get/etc/hosts
#!/usr/bin/python
import bottle
import os.path
#bottle.route("/get/<filepath:path>")
def index(filepath):
filepath = "/" + filepath
print "getting", filepath
if not os.path.exists(filepath):
return "file not found"
print open(filepath).read() # prints file
return '<br>'.join(open(filepath).read().split("\n")) # prints file with <br> for browser readability
#bottle.route("/exists/<filepath:path>")
def test(filepath):
filepath = "/" + filepath
return str(os.path.exists(filepath))
bottle.run(host='0.0.0.0', port=8090, reloader=True)
the reloader option on the run method allows you to edit the code without manually restarting the server. Its quite handy.
I'm new to Python programming and I'm trying to create a server and a client. I still want to be able to type something from the keyboard so i can close the server from the server by typing 'exit'. I've taken samples codes from various sites to get to where I'm at in socket programming and this code.
However, whenever I run the code I get the following error message:
The host name of this machine is 127.0.0.1
The IP address of the host is 127.0.0.1
Server now awaiting client connection on port 2836
im right before the select
Traceback (most recent call last):
File "/root/Server_2.py", line 42, in <module>
inputready, outputready, exceptready = select.select(input, [], [])
TypeError: argument must be an int, or have a fileno() method.
>>>
I was reading around that to get passed this (in Windows) is to remove the sys.stdin because Windows only accepts sockets. I'm trying to write this code in Linux. I've tried all sorts of things to try to get it to work and I'm all out of resources and ideas to try. Below is the server code:
import socket #import socket module
import select
import sys
host = "127.0.0.1"
print ("The host name of this machine is " + host)
hostIP = socket.gethostbyname(host) # get host IP address
print ("The IP address of the host is %s" % (hostIP))
port = 2836 # Reserve the port for the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((hostIP, port)) # This server to a port
s.listen(4) # Now wait for client connection
print("Server now awaiting client connection on port %s" % (port))
#WINDOWS ONLY ACCEPTS SOCKETS FOR SELECT(), no standard in
input = [s, sys.stdin]
running = 1
while running:
print("im right before the select")
# when there's something in input, then we move forward
# ignore what's in output and except because there's nothing
# when it comes to sockets
inputready, outputready, exceptready = select.select(input, [], [])
print("i'm here na")
# check who made a response
for x in inputready:
if x == s:
print(s)
#handle the server socket
client, address = s.accept()
print("connection comming in")
input.append(client)
elif x == sys.stdin:
# handle standard input
stuff = sys.stdin.readline()
if stuff == "exit":
running = 0
else:
print("you typed %s" % (stuff))
else:
#handle all other sockets
data = x.recv(1024)
print("i received " + data)
if data:
if data == "exit":
x.close()
input.remove(x)
running = 0
else:
x.send(data)
print("I am sending %s" % (data))
else:
x.close()
input.remove(x)
s.close()
Any help or ideas would be greatly appreciated. Thanks!!
Well I know you asked this 7 years ago, but I had similar questions so I would figure I answer you. I'm still working and bugfixing a program that has the same functionality, but one thing I do know is that the lists that are the arguments in select.select() need to be file descriptors (ints).
So if you have this block
input = [s, sys.stdin]
running = 1
while running:
print("im right before the select")
# when there's something in input, then we move forward
# ignore what's in output and except because there's nothing
# when it comes to sockets
inputready, outputready, exceptready = select.select(input, [], [])
The first thing I'd say is change your read list to not be input. You'll likely get some clashing with the input() function, which may cause confusing bugs. After that, you want the values to be file descriptors. So that first line should be
inputSockets = [s.fileno(), sys.stdin.fileno()]
Then when checking which socket is ready to ready, you would want to do it like this
for x in inputready:
if x == s.fileno():
# Read from your s socket
elif x == sys.stdin().fileno():
# Read from stdin
else:
'''
Here you would want to read from any other sockets you have.
The only problem is your inputSockets array has ints, not socket
objects. What I did was store an array of actual socket objects
alongside the array of file descriptors. Then I looped through the
list of sockets and found which socket's .fileno() matched x. You could
probably be clever and use a dict() with the filenos as key and socket as
value
'''
I just came across this while writing a unix domain socket (UDS) interface. The server socket id is used to accept incoming client connections. That is pretty much all it does. Once the client is accepted, reading uses its own file descriptor. Something like this works:
conn = None
inputReady, Null, Null = select.select(inputSockets, [], [])
for x in inputReady:
if x == s.fileno():
# accept incoming connect and add to poll list
conn, addr = s.accept()
inputReady.append(conn.fileno())
elif x = sys.stdin.fileno():
# read whole line and remove newline
cmd = sys.stdin.readline()[:-1]
...
elif conn and x == conn.fileno():
data = conn.recv(msglen)
if data:
....
else:
# connection has ended, remove from poll list and close
if conn.fileno() in inputReady:
inputReady.remove(conn.fileno())
conn.close()
I'm not able to connect to the server it will print out
"Connecting to port..." then it will just say "Sockets timed out."
My program is due tomorrow and it'd be nice to have this actually work.
EDITED CODE: Now it will only use Connecting to Port....
nothing else printed.
import socket, string, time, random, re, urllib2, cookielib, smtplib, os
class Pibot: #main class
def __init__(self): #basic information to allow for the rest of the program to work.
self.server= 'irc.evilzone.org'
self.port = 6667
self.botname= 'pibot'
self.chan= 'test'
self.owner = 'Josh.H'
self.nick = "bawt"
self.irc = None
self.data = ''
def iConnect(self): #trys to connect to the server and allows the user to see if it failed to connect.
print ("Connecting to ports...")
print self.data
time.sleep(3)
try:
self.irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.irc.connect((self.server, self.port))
except (socket.error, socket.herror, socket.gaierror):
print "Failed to connect to Ports"
def iStart(self):
#Not guaranteed to send all your data, iisn't checking the return values
#however this function iStart is used to send the NICK of the bot and the USER to the server through particle data
#it then auto joins the channel
#in future development I'd like to get accuainted with Twisted or IRCutils as they allow it to be quiet powerful and less buggy
self.irc.send('NICK %s\r\n' % self.nick)
self.irc.send("USER %s %s bla :%s\r\n" % ("Ohlook", 'itsnotmy', 'Realname'))
time.sleep(4)
self.irc.send("JOIN #%s\r\n" % self.chan)
self.data = self.irc.recv( 4096 )
def MainLoop(self,iParse = 0): #MainLoop is used to make the commands executable ie !google !say etc;
try:
while True:
# This method sends a ping to the server and if it pings it will send a pong back
#in other clients they keep receiving till they have a complete line however mine does not as of right now
#The PING command is used to test the presence of an active client or
#server at the other end of the connection. Servers send a PING
#message at regular intervals if no other activity detected coming
#from a connection. If a connection fails to respond to a PING
#message within a set amount of time, that connection is closed. A
#PING message MAY be sent even if the connection is active.
#PONG message is a reply to PING message. If parameter <server2> is
#given, this message will be forwarded to given target. The <server>
#parameter is the name of the entity who has responded to PING message
#and generated this message.
self.data = self.irc.recv( 4096 )
if self.data.find ( 'PING' ) != -1:
self.irc.send(( "PONG %s \r\n" ) % (self.recv.split() [ 1 ])) #Possible overflow problem
if self.data.find( "!google" ) != -1:
#googles the search term and displays the first 5 results
#format = !google: <Search Term>
#One thing that I noticed is that it will print on a seperate line without the header
#In the next Update I would have fixed this.
fin = data.split(':')
if not fin:
irc.send("PRIVMSG #%s :syntax'^google :search term\r\n'" % chan)
else:
#In the next version to avoid overflow I will create another if statement and edit the search code
#However I am using what xgoogle has reccomended.
fin = fin[3].strip()
gs = GoogleSearch(fin)
gs.results_per_page = 5
results = gs.get_results()
for result in results:
irc.send("PRIVMSG #%s :%s\r\n" % (chan, result.url.encode("utf8")))
###############################################################################################################################
# No excpetion checking here, these functions can and will fail in time and in later versions will need to be edited.
# If hellboundhackers changes this code may break
# This function takes a quote from the header of hellboundhackers
# it first looks at the header of the USer agent then the header of the website (HBH) and reads it then prints
# the quote when QUOTEM is recognized in the irc closes the connection to the wbesite and deletes the cookie
###############################################################################################################################
if "QUOTEM" in self.data:
#Pulls a quote from HBH
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
opener.addheaders.append(('User-agent', 'Mozilla/4.0'))
opener.addheaders.append( ('Referer', 'http://www.hellboundhackers.org/index.php') )
resp = opener.open('http://www.hellboundhackers.org/index.php')
r = resp.read()
resp.close()
del cj, opener
da = re.findall("Enter; width:70%;'>(.*)",r)
self.irc.send("PRIVMSG #%s :%s\r\n" % (chan, da[0])) # Note Possible overflow
if "!whoareyou" in self.data:
#bot info allows users on IRC to see which commands are currently working
self.irc.send("PRIVMSG #%s :I am %s, I was created By:%s \r\n" % (self.chan, self.nick,self.owner))
self.irc.send("PRIVMSG #%s :I was written in Python 27, and edited with IDLE\r\n" % self.chan)
self.irc.send("PRIVMSG #%s :The Classes used are socket, string, time, re, urllib2, cookielib\r\n" % self.chan)
self.irc.send("PRIVMSG #%s :As well as some functions from various other sources(supybot,twisted,xgoogle)\r\n" % self.chan)
self.irc.send("PRIVMSG #%s :type ^commands for a list of things I can do\r\n" % self.chan)
except (socket.error, socket.timeout):
print "Sockets timed out."
bot = Pibot()
bot.iConnect()
bot.MainLoop()
Side Note: No errors present.
Greatly Appreciated. Also I am just learning so don't flame me. :(
EDIT2: I have fixed most of the problems and am now getting error:
Traceback (most recent call last):
File "L:\txtbot.py", line 119, in <module>
bot.MainLoop()
File "L:\txtbot.py", line 64, in MainLoop
self.irc.send(( "PONG %s \r\n" ) % (self.recv.split() [ 1 ])) #Possible overflow problem
AttributeError: Pibot instance has no attribute 'recv'
It seems you're never passing the connection information to the socket:
self.irc = socket.socket()
I think it should be something like this:
self.irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.irc.connect((self.server, self.port))
In iConnect you're just creating a socket, not connecting it to the server. You need to use socket.create_connection.
Also, lumping together socket.error and socket.timeout is not a good idea as it might be misleading when debugging. Also, you should print the error, not just a generic message. It will help you figure out what's wrong.
You don't call iStart anywhere. If I remember my IRC correctly, you need to send your nick information before it will send you any data back.