I am trying to write a port scanner with python and there is an issue with UDP ports. Google says that I have to send some request and either recieve TimeoutError, meaning server got the message via the port and the port is opened, or recieve ICMP message "Destination unreacheable(Port unreachable)", meaning port is closed. I am able to see ICMP message in Wireshark but have no idea how to make python see it as well.
Now my code for UDP looks like this:
def udp_connection(ip, port, timeout):
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.settimeout(timeout)
try:
s.sendto(b'test', (ip, port))
data, addr = s.recvfrom(1024)
return "[+] UDP Port Open: " + str(port) + str(data) + '\n'
except TimeoutError:
return "[+] UDP Port Open: " + str(port) + 'kinda no response or something' + '\n'
except:
return "[+] UDP Port Closed: " + str(port) + '\n'
and this always returns TimeoutError.
Also tried a solution found on stackoverflow to add a raw socket with socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) as s1: and recieve data with data, addr = s1.recvfrom(1024) instead of data, addr = s.recvfrom(1024) but haven't succeeded
Python throws ConnectionResetError exception when trying to receive response from (ip,closedPort) because receiving the ICMP "Destination unreacheable(Port unreachable)" message but the ICMP packet may be blocked by windows firewall, python will not receive it and... that's it. I literally just had to turn it off to make my code work
Related
I know there are tons of questions like this but none of them helped me. I am trying to connect computer and vm that are on 2 different networks.
Server:
import socket
HOST = '0.0.0.0'
PORT = 1080
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(5)
print("\n Listening on port " +str(PORT)+ ", waiting for client to connect...")
client_socket, (client_ip, client_port) = server_socket.accept()
print("[+] Client " +client_ip+ " connected!\n")
while True:
try:
command = raw_input(client_ip+ ">")
if(len(command.split()) != 0):
client_socket.send(command)
else:
continue
except Exception,e:
print("[-]Something went wrong")
continue
if(command == "stop"):
break
data = client_socket.recv(1024)
print(data + "\n")
client_socket.close()
As you see,i opened a server that listens on port 1080 and accepts all connections.I turned off the windows firewall and the SPI Firewall. I also forwarded the port 1080( nmap scan finds it and says its open).
Client:
import socket
import platform
HOST = "output of whatismyipaddress.com when run on server computer"
PORT = 1080 # port(same as on server.py)
connection_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
connection_socket.connect((HOST, PORT))
print("\n[*] Connected to " +HOST+ " on port " +str(PORT)+ ".\n")
while True:
command = connection_socket.recv(1024)
split_command = command.split()
print("Received command : " +command)
if (command == "stop"):
break
elif (command == "info"):
connection_socket.send(("Info: " + str(tuple(platform.uname()))))
connection_socket.close()
So client is sending data to server and server is sending commands to client.
I assume client doesn't need to have any port forwarded.
The client(vm) was connected to Android HotSpot. The server was connected to router that had port forwarded. I've choose bridged connection for vm and connected my external wifi card for it.
Server started listening and client started. I get error that the server did not properly respond after period of time when trying to connect. I also tried connecting using default gateway but no success.
I am a little confused about it since Wikipedia says:
A default gateway in computer networking is the node that is assumed to know how to forward packets on to other networks. Typically, in a TCP/IP network, nodes such as servers, workstations and network devices each have a defined default route setting, (pointing to the default gateway), defining where to send packets for IP addresses for which they can determine no specific route.
Which I understand as it is used to communicate over 2 different networks?
Anyways, does anyone know how can I fix this issue and what am I doing wrong?
Consider the following code:
import socket, sys, time
HOST = '172.16.0.19'
PORT = 1000
#create a raw socket
try:
s = socket.socket(socket.AF_INET,socket.SOCK_RAW, socket.IPPROTO_TCP)
except socket.error , msg:
print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
s.bind((HOST,PORT))
while True:
print "Waiting for SYN..."
rec_packet, addr = s.recvfrom(100)
print "Incoming connection detected!"
print "".join(map("{0:08b}".format, map(ord, list(rec_packet[0:10]))))
print addr[0]
print ""
It is a simplified version of an automated SYN attack detector. When I use:
nmap 172.16.0.19 -sS -p 1001 **NOTE THE DIFFERENT PORT**
I still get a detection from the code. Does s.bind not listen only on given port?
SSH to the target also triggers the code.
A raw socket (see raw(7) for details) supports sending raw IP datagrams. Raw ip datagrams don't have ports. Ports are a construct of higher-level protocols layered on top of IP, like UDP and TCP.
You could inspect the received packet yourself to extract the udp/tcp port.
An alternative solution might utilize the netfilter framework to capture packets on specific tcp ports that have the SYN flag set, and then send these to your program via the nfqueue extension.
I'm trying to code a port scanner in python with banner grabbing.
Without the s.send('getBanner\n') line (which grabs the banner) my script works, and it prints the open ports.
But when I add the 'getBanner' line, a socket error says '[Errn 32] Broken Pipe'.
I know that this error probably happens because the clients don't wait till the connection get established and close the socket. How can I solve this?
The code:
import socket
host = '192.168.1.1'
for port in range(1,1024):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex((host, port))
s.send(('getBanner\n'))
banner = s.recv(1024)
if result == 0:
print "[+] Port %s tcp/open" % port
print "[+] Banner: %s" % banner
s.close()
Not all ports have a service listening on them and when they do, you need to follow whatever protocol is normal for that service. I assume you have some sort of service that responds to "getBanner", but most will not. You are connecting to things like FTP, SSH, DNS, NFS and mail servers and these things don't have "getBanner" commands. But you are also trying to connect to ports that don't have anything listening on them and this generates an error.
Looking at the docs:
connect_ex(...)
connect_ex(address) -> errno
This is like connect(address), but returns an error code (the errno value)
instead of raising an exception when an error occurs.
Your connection call is returning an error code and you need to check that before trying to send the request. So, as a minimum:
import socket
host = '192.168.1.1'
for port in range(1,1024):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex((host, port))
if result == 0:
s.send(('getBanner\n'))
banner = s.recv(1024)
if result == 0:
print "[+] Port %s tcp/open" % port
print "[+] Banner: %s" % banner
s.close()
But since most servers listening on ports don't respond to a "getBanner" command, its either going to hang or more likely raise connection reset errors.
I am writing a client/ server program in Python where, once the client and server have successfully connected via a socket, they may exchange messages. Below is my server and client code. When compiled, the connection is established correctly and the messages are sent successfully, but one cannot send a second message until it has received a response from the other party.
For example:
Client sends: "Hello, server!"
Server sends: "I have received your message, client!"
Client sends: "great, here's another one"
Client sends: "and a second one!"
At this point, the server terminal window has received the message saying "great, here's another one", but must first reply to this message before receiving "and a second one!".
I think my issue is that I need to use the select() method, but do not understand how to do so. How can I fix this?
#The server code
HOST = ''
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
print("Now listening...")
s.listen(1) #only needs to receive one connection (the client)
conn, addr = s.accept() #accepts the connection
print("Connected by: ", addr) #prints the connection
i = True
while i is True:
data = conn.recv(1024) #receives data
print('Received:' , repr(data)) #prints the message from client
reply = raw_input() #server types a response
conn.sendall(reply) #server now sends response back to client
close()
below is the client code (client.py)
The client code
from socket import*
HOST = '192.168.41.1'
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
while True:
message = raw_input() #client's message to the server
s.send(message) #sends message to the server
print("Waiting for response...")
reply = s.recv(1024) #receives message from server
print("New message: " + repr(reply)) #prints the message received
close()
Look at the following examples:
http://code.activestate.com/recipes/531824-chat-server-client-using-selectselect/
and
http://www.binarytides.com/code-chat-application-server-client-sockets-python/
also some similar answer here:
Python client side in chat
What you are missing is select on client side where its select if to handle input from server or from command line.
So in that case, you don't have to wait for server response and can send 2 calls one after another from the client.
Freely adapting the answers above to what you wished to accomplish.
(I didn't test it - so make sure to check it)
from socket import*
import sys
import select
HOST = '192.168.41.1'
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
while True:
socket_list = [sys.stdin, s]
# Get the list sockets which are readable
read_sockets, write_sockets, error_sockets = select.select(
socket_list, [], [])
for sock in read_sockets:
#incoming message from remote server
if sock == s:
data = sock.recv(1024)
if not data:
print('\nDisconnected from server')
break
else:
#print data
sys.stdout.write(data)
# prints the message received
print("New message: " + repr(data))
prompt()
#user entered a message
else:
msg = sys.stdin.readline()
s.send(msg)
prompt()
s.close()
I would strongly suggest reading and familiarizing with this document and especially the non-blocking sockets part.
Your code now blocks when waiting for the data to arrive from the user. You want to instruct your program to wait for the data from the socket and at the same time allow user to type input.
I am having some problems adding in a logging file for my python TCP server code.
I've looked at some examples, but as I don't have much experience in writing my own scripts/codes, I'm not very sure how to go about doing this. I would appreciate if someone could guide me in the right direction with explanation and some examples if possible.
I am using HERCULES SETUP UTILITY , which acts as my TCP client, while my visual studio python code acts as a SERVER. My SERVER can receive the data which is sent by the client by now , I just can't seem to add in a logging file which can save the sent data into text file.Can someone please show me some examples or referance please? Your help would mean alot. This is my code so far :
from socket import *
import thread
BUFF = 1024 # buffer size
HOST = '172.16.166.206'# IP address of host
PORT = 1234 # Port number for client & server to recieve data
def response(key):
return 'Sent by client'
def handler(clientsock,addr):
while 1:
data = clientsock.recv(BUFF) # receive data(buffer).
print 'data:' + repr(data) #Server to recieve data sent by client.
if not data: break #If connection is closed by client, server will break and stop recieving data.
print 'sent:' + repr(response('')) # respond by saying "Sent By Client".
if __name__=='__main__':
ADDR = (HOST, PORT) #Define Addr
serversock = socket(AF_INET, SOCK_STREAM)
serversock.bind(ADDR) #Binds the ServerSocket to a specific address (IP address and port number)
serversock.listen(0)
while 1:
print 'waiting for connection...'
clientsock, addr = serversock.accept()
print '...connected from:', addr #show its connected to which addr
thread.start_new_thread(handler, (clientsock, addr ))
In context, maybe something like this?
#!/usr/local/cpython-2.7/bin/python
import socket
import thread
BUFF = 1024 # buffer size
HOST = '127.0.0.1'
PORT = 1234 # Port number for client & server to recieve data
def response(key):
return 'Sent by client'
def logger(string, file_=open('logfile.txt', 'a'), lock=thread.allocate_lock()):
with lock:
file_.write(string)
file_.flush() # optional, makes data show up in the logfile more quickly, but is slower
def handler(clientsock, addr):
while 1:
data = clientsock.recv(BUFF) # receive data(buffer).
logger('data:' + repr(data) + '\n') #Server to recieve data sent by client.
if not data:
break #If connection is closed by client, server will break and stop recieving data.
logger('sent:' + repr(response('')) + '\n') # respond by saying "Sent By Client".
if __name__=='__main__':
ADDR = (HOST, PORT) #Define Addr
serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversock.bind(ADDR) #Binds the ServerSocket to a specific address (IP address and port number)
serversock.listen(0)
while 1:
logger('waiting for connection...\n')
clientsock, addr = serversock.accept()
logger('...connected from: ' + str(addr) + '\n') #show its connected to which addr
thread.start_new_thread(handler, (clientsock, addr))
HTH
It sounds to me like your question would be better rephrased as “How do I read and write files within Python?”.
This is something well documented at: http://docs.python.org/2.7/tutorial/inputoutput.html#reading-and-writing-files
Example:
f = open('/tmp/log.txt', 'a')
f.write('Doing something')
do_something()
f.write('Other stuff')
other_stuff()
f.write('All finished')
f.close()