I have written this script to test a single ip address for probing specific user names on smtp servers for a pentest. I am trying now to port this script to run the same tests, but to a range of ip addresses instead of a single one. Can anyone shed some light as to how that can be achieved?
#!/usr/bin/python
import socket
import sys
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()
fp.write('HELO test.example.com\r\n')
fp.flush()
fp.readline
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()
If you're using Python3.3+, this is mostly simple
import ipaddress # new in Python3.3
start_ip, end_ip = however_you_get_these_as_strings()
ip_networks = ipaddress.summarize_address_range(
ipaddress.IPv4Address(start_ip),
ipaddress.IPv4Address(end_ip))
# list of networks between those two IPs
for network in ip_networks:
for ip in network:
# ip is an ipaddress.IPv4Address object
probe(str(ip))
# which converts nicely to str
I would implement this by turning your code as it stands into a function to probe a single host, taking the host name/ip as an argument. Then, loop over your list of hosts (either from the command line, a file, interactive querying of a user, or wherever) and make a call to your single host probe for each host in the loop.
Ok, so here is what I have done to get this going.
The solution is not elegant at all but it does the trick, and also, I could not spend more time trying to find a solution on this purely in Python, so I have decided, after reading the answer from bmhkim above(thanks for the tips) to write a bash script to have it iterate over a range of ip addresses and for each one call my python script to do its magic.
#!/bin/bash
for ip in $(seq 1 254); do
python smtp-probe.py 192.168.1.$ip <users.txt
done
I have had some problems with the output since that was giving me the servers responses to my probing attempts but not the actual ip addresses which were sending those responses, so I have adapted the original script to this:
#!/usr/bin/python
import socket
import sys
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))
print sys.argv[1] #Notice the printing of the script arguments/ip addresses for my output
fp = s.makefile('rwb')
fp.readline()
fp.write('HELO test.example.com\r\n')
fp.flush()
fp.readline
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()
Like I said above, that is a tricky way out-I know, but I am not a programmer, so that is the way out I was able to find(if you have a way purely in Python to do it I would like very much to see it). I will definitely re-visit this issue once I have a bit more time and I will keep studying Python until I get this right.
Thanks all for the support to my question!!
Related
I need to interact directly with wpa_supplicant from Python. As I understand it one can connect to wpa_supplicant using Unix sockets and wpa_supplicant control interface (https://w1.fi/wpa_supplicant/devel/ctrl_iface_page.html).
I wrote a simple program that sends a PING command:
import socket
CTRL_SOCKETS = "/home/victor/Research/wpa_supplicant_python/supplicant_conf"
INTERFACE = "wlx84c9b281aa80"
SOCKETFILE = "{}/{}".format(CTRL_SOCKETS, INTERFACE)
s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
s.connect(SOCKETFILE)
s.send(b'PING')
while 1:
data = s.recv(1024)
if data:
print(repr(data))
But when I run it, wpa_supplicant reports an error:
wlx84c9b281aa80: ctrl_iface sendto failed: 107 - Transport endpoint is not connected
Could someone please provide an example, how you would do a 'scan' and then print 'scan_results'.
Apparently, the type of socket that wpa_supplicant uses (UNIX datagram) does not provide any way for the server to reply. There are a few ways to get around that. wpa_supplicant in particular seems to support replies through a separate socket (found at a path appended at the end of each message).
Weirdly enough, this seems to be a relatively common practice in Linux: /dev/log seems to work in the same way.
Here's a program that does what you asked for:
import socket, os
from time import sleep
def sendAndReceive(outmsg, csock, ssock_filename):
'''Sends outmsg to wpa_supplicant and returns the reply'''
# the return socket object can be used to send the data
# as long as the address is provided
csock.sendto(str.encode(outmsg), ssock_filename)
(bytes, address) = csock.recvfrom(4096)
inmsg = bytes.decode('utf-8')
return inmsg
wpasock_file = '/var/run/wpa_supplicant/wlp3s0'
retsock_file = '/tmp/return_socket'
if os.path.exists(retsock_file):
os.remove(retsock_file)
retsock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
retsock.bind(retsock_file)
replyToScan = sendAndReceive('SCAN', retsock, wpasock_file)
print(f'SCAN: {replyToScan}')
sleep(5)
replyToScanResults = sendAndReceive('SCAN_RESULTS', retsock, wpasock_file)
print(f'SCAN_RESULTS: {replyToScanResults}')
retsock.close()
os.remove(retsock_file)
I have two scripts I am actively using for a programming class. My code is commented nicely and my teacher prefers outside resources since there are many different solutions.
Getting to the actual problem though, I need to create a server with a socket (which works) and then allow another computer to connect to it using a separate script (which also works). The problem is after the connection is made. I want the two to be able to send messages back and forth. The way it sends has to be in byte form with how I have it set up but the byte returned is impossible to read. I can decode it but I want it to be conveniently located in the Command Prompt with everything else. I attempt to import the main script (Connection.py) into the secondary script (Client.py) but then it runs the main script. Is there any way I can prevent it from running?
Here is my main script (the one creating the server)
#Import socket and base64#
import socket
import base64
#Creating variable for continuous activity#
neverland = True
#Create socket object#
s = socket.socket()
print ("Socket created") #Just for debugging purposes#
#Choose port number for connection#
port = 29759 #Used a random number generator to get this port#
#Bind to the port#
s.bind((' ', port))
print ("Currently using port #%s" %(port)) #Just for debugging purposes#
#Make socket listen for connections#
s.listen(5)
print ("Currently waiting on a connection...") #Just for debugging purposes#
#Loop for establishing a connection and sending a message#
while neverland == True:
#Establish a connection#
c, addr = s.accept()
print ("Got a connection from ", addr) #Just for debugging purposes#
#Sending custom messages to the client (as a byte)#
usermessage = input("Enter your message here: ")
usermessage = base64.b64encode(bytes(usermessage, "utf-8"))
c.send(usermessage)
#End the connection#
c.close()
And here is my secondary script (the one that connects to the main one)
#Import socket module#
import socket
import Connection
#Create a socket object#
s = socket.socket()
#Define the port on which you want to connect#
port = 29759
#Connect to the server on local computer#
s.connect(('127.0.0.1', port))
#Receive data from the server#
print (s.recv(1024))
usermessage = base64.b64decode(str(usermessage, "utf-8"))
print (usermessage)
#Close the connection#
s.close()
Upon running them both in the command prompt, the following error occurs:
It attempts to run the main script again and gets the error, how can I prevent it?
The way you'd commonly achieve this is to not execute any actions when a script is read. I.e. you just define your functions, classes and variables and if this script is meant to be called directly, you if it was called as such and refer to appropriate entry point. E.g.:
myvar = "world"
def main():
print("Hello", myvar)
if __name__ == "__main__":
main()
This way you can call your script python example.py or import it from another one and use it content where needed: import example; print(example.myvar).
You can also, and this is not mutually exclusive with above, refactor your scripts and have one file with common/shared definitions which is imported into and used by both of your scripts.
As the title says, although this is also the first time I have used Python to really do anything big. I'm not all that used to the language yet, so this is probably my missing something. The code is fairly short and is as followed, with username and private pass removed:
import re
import socket
import sys
import time
import string
HOST = "irc.twitch.tv"
PORT = 6667
NICK = ""
PASS = ""
CHAN = ""
RATE = (20/30) # messages per second
CHAT_MSG=re.compile(r"^:\w+!\w+#\w+\.tmi\.twitch\.tv PRIVMSG #\w+ :")
def chat(sock, msg):
sock.send("PRIVMSG #{} :{}".format(cfg.CHAN, msg))
public = socket.socket()
public.connect((HOST, PORT))
public.send("PASS {}\r\n".format(PASS).encode("utf-8"))
public.send("NICK {}\r\n".format(NICK).encode("utf-8"))
public.send("JOIN {}\r\n".format(CHAN).encode("utf-8"))
private = socket.socket()
private.connect((HOST, PORT))
private.send("PASS {}\r\n".format(PASS).encode("utf-8"))
private.send("NICK {}\r\n".format(NICK).encode("utf-8"))
private.send("CAP REQ :twitch.tv/tags twitch.tv/commands {}\r\n".format(CHAN).encode("utf-8"))
while True:
channelResponse = public.recv(1024).decode("utf-8")
privateResponse = private.recv(1024).decode("utf-8")
if privateResponse == "PING :tmi.twitch.tv\r\n":
private.send("PONG :tmi.twitch.tv\r\n".encode("utf-8"))
else:
privateResponseUsername = re.search(r"\w+", privateResponse).group(0) # return the entire match
privateResponseMessage = CHAT_MSG.sub("", privateResponse)
print(privateResponseUsername + ": " + privateResponseMessage)
if channelResponse == "PING :tmi.twitch.tv\r\n":
public.send("PONG :tmi.twitch.tv\r\n".encode("utf-8"))
else:
username = re.search(r"\w+", channelResponse).group(0) # return the entire match
message = CHAT_MSG.sub("", channelResponse)
print(username + ": " + message)
time.sleep(1 / RATE)
One thing to mention is that I was following a basic template style, however it did not cover implementing whispers into the bot - so I'm having to guess by doing research on how to do that, and it seems to be that the most recommended way is two connections, one for public, one for private.
As you've structured your code, you can't get anything from the private socket until you've gotten something from the public socket. If IRC didn't send PING messages occasionally, this would work even worse.
The way to handle this is to use select, and give it your two sockets. Right as soon as one has stuff that can be read, select will return, and indicate which socket has bytes available for reading.
This answer has some general code. You might want to modify it to look something like:
while True:
# this will block until at least one socket is ready
ready_socks,_,_ = select.select([private, public], [], [])
if private in ready_socks:
privateResponse += private.recv()
if public in ready_socks:
channelResponse += public.recv()
# check privateResponse buffer, do stuff
# check channelResponse buffer, do stuff
There are a few other things you should keep in mind:
The network doesn't have to deliver entire IRC messages at the same time, nor does it have to deliver a single one at a time. You could get "PI", "NG :t", "mi.twitch.tv", "\r\n" as separate messages. So you should accumulate bytes in a buffer, and then when you've got at least one entire message, process it, and remove it from the buffer.
UTF-8 characters can span multiple bytes, and might be split up by the network. Don't decode UTF-8 until you're sure you've got an entire message to work with.
I'm totally confused as to why my script isn't working.
This script basically scans for servers with port 19 open (CHARGEN).
You enter a list of ips in the format:
1.1.1.1
2.2.2.2
3.3.3.3
4.4.4.4
5.5.5.5
and the script scans every ip in the list to check if port 19 is open, and if it is, it writes the ip to a file.
Here is my code:
#!/usr/bin/env python
#CHARGEN Scanner
#Written by Expedient
import sys
import Queue
import socket
import threading
queue = Queue.Queue()
def check_ip(host, output_file, timeout):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
result = sock.connect_ex((host, 19))
if result == 0:
print "Found: %s" % host
file = open(output_file, "a")
file.write(host+"\n")
file.close()
except:
pass
def add_to_queue(queue, host, output_file, timeout):
queue.put(check_ip(host, output_file, timeout))
if len(sys.argv) < 4:
print "Usage: %s <ip list> <output file> <timeout>" % sys.argv[0]
sys.exit()
try:
open(sys.argv[1])
except:
print "Unable to open ip list."
sys.exit()
print "Starting Expedient's CHARGEN Scanner..."
with open(sys.argv[1]) as ip_list:
for ip in ip_list:
thread = threading.Thread(target=add_to_queue, args=(queue, ip, sys.argv[2], float(sys.argv[3])))
thread.start()
Whenever I run the script on a list of CHARGEN enabled servers that I got from an nmap scan
(I double checked, every server has port 19 open), the script does not write any of the ips
to the output file, which is should, because every ip in the list has port 19 open.
I honestly have no idea why this isn't working and it would be wonderful if someone could
help me out/tell me what I'm doing wrong. Thank you.
Your example as posted is catching all exceptions in your check_ip function without telling you (except: pass). You could have any number of issues causing exceptions to be raised in this function, and if an exception is raising in every call of the function then you will get no results from your script while also not getting any feedback to log/console on the nature of the failure.
For the purposes of debugging, you should modify your exception handling to explicitly handle any exceptions that you want to pass over, and allow other exceptions to raise unhandled so that you can determine what your error conditions are.
I use python program to do traffic generator in Linux Ubuntu, and the code like below:
import socket, sys
host = sys.argv[1] #Server IP Address
textport = sys.argv[2] #Server Binding Port
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #socket
try:
port = int(textport)
except ValueError:
port = socket.getservbyname(textport, 'udp')
while 1:
try:
data = open('auth3.log')#read file
for each_line in data: #each rows
try:
(role,line_spoken) = each_line.split(': ',1)#split two parts
role = role.strip()
s.sendto(role, (host, port))
print('Send: ' + str(role) + "\n" )
except:
pass
except IOError as err:
print('file isn\'t exist!!~'+str(err))
finally:
if 'data' in locals(): #If data have no object, Don't use data to close!!~
data.close()
print "\n"
The size of auth3.log is about 1.8M.
When I send data to the destination server, I use snmp which OID is ''ifInOctets'' to get the traffic information.
But I the traffic recalculate to unit of ''Kbits'' is about 128.
How can I use this program to fill the bandwidth up to 1Gbits?(In other words, I want to fill out the bandwidth)
Thanks for your helping.
This version of your code implements the first two optimizations suggested by Chris Merck.
import socket, sys, itertools
host = sys.argv[1] #Server IP Address
textport = sys.argv[2] #Server Binding Port
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
port = int(textport)
except ValueError:
port = socket.getservbyname(textport, 'udp')
# preprocess file data
with open('auth3.log') as data:
roles = [role for (role, line_spoken) in line.split(': ', 1) for line in data]
# preprocess everything we can
hp = (host, port)
send = s.sendto
for role in itertools.cycle(roles):
try:
send(role, hp)
except:
pass
For further optimizations, you might want to process it using Cython, which might further speed up the loop. If the code still doesn't generate enough traffic, you'll probably need to launch several processes in parallel.
Your program is not running fast enough to generate 1Gbps on the wire.
To make it run faster, you can:
Remove the call to print after sendto. (Print is slow by nature.)
Preprocess your auth3.log file so that you do not need to process it within your inner loop. (Right now you are looping on .split and .strip, both of which are wasting CPU time.
Rewrite your program to send larger chunks.
But, I fear the result will still not reach 1Gbps. To really max out your line, try using a traffic generation program such as Colasoft Packet Builder (although I'm not sure even that program will do it. 1Gbps is a lot of traffic.)