I'm trying to check using Python 3.6 if a remote DNS server is listening on port 53 UDP.
This is what I tried:
def check_port(host, port):
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(1)
try:
result = s.connect_ex((host, port))
except socket.gaierror:
s.close()
return 1
s.close()
return result # 0 == Port is open
But I get 0 all the time even if the port is close. Trying TCP using SOCK_STREAM works like a charm.
I also tried:
def check_port_udp(host, port):
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(1)
try:
s.sendto('ping'.encode(), (host, port))
s.recvfrom(1024)
except socket.timeout:
s.close()
print(1)
return 1
s.close()
print(0)
return 0 # 0 == Port is open
But I get 1 all then time even if the port it's open
Basic idea: send a DNS query to that port.If there is a response, the port is open.
import random
import socket
import struct
class SendDNSPkt:
def __init__(self,url,serverIP,port=53):
self.url=url
self.serverIP = serverIP
self.port=port
def sendPkt(self):
pkt=self._build_packet()
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(1)
sock.sendto(bytes(pkt), (self.serverIP, self.port))
data, addr = sock.recvfrom(1024)
sock.close()
return data
def _build_packet(self):
randint = random.randint(0, 65535)
packet = struct.pack(">H", randint) # Query Ids (Just 1 for now)
packet += struct.pack(">H", 0x0100) # Flags
packet += struct.pack(">H", 1) # Questions
packet += struct.pack(">H", 0) # Answers
packet += struct.pack(">H", 0) # Authorities
packet += struct.pack(">H", 0) # Additional
split_url = self.url.split(".")
for part in split_url:
packet += struct.pack("B", len(part))
for s in part:
packet += struct.pack('c',s.encode())
packet += struct.pack("B", 0) # End of String
packet += struct.pack(">H", 1) # Query Type
packet += struct.pack(">H", 1) # Query Class
return packet
def checkDNSPortOpen():
# replace 8.8.8.8 with your server IP!
s = SendDNSPkt('www.google.com', '8.8.8.8')
portOpen = False
for _ in range(5): # udp is unreliable.Packet loss may occur
try:
s.sendPkt()
portOpen = True
break
except socket.timeout:
pass
if portOpen:
print('port open!')
else:
print('port closed!')
if __name__ == '__main__':
checkDNSPortOpen()
Inspired by this post
I have had no luck using sockets for this purpose. The port response is based on the target application and is not standard like TCP. I always use netcat for this:
import os
ip = "127.0.0.1"
port = "<some_udp_port>"
''' send to /dev/null 2>&1 to suppress terminal output '''
res = os.system("nc -vnzu "+ip+" "+port+" > /dev/null 2>&1")
if res == 0:
print("port alive")
else:
print("port dead")
This, obviously, requires running on a Linux system. However if you have nmap installed on your Windows system you can try the following:
import os
ip = "127.0.0.1"
port = "<some_udp_port>"
res = os.system("ncat -vnzu "+ip+" "+port)
if res == 0:
print("port alive")
else:
print("port dead")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With