0x011.Python learning-network programming, PortScan

Python3 network programming

 

Python provides network services with two levels of access. :

  • Low-level network services support basic Socket, which provides a standard BSD Sockets API, which can access all methods of the underlying operating system Socket interface.
  • The high-level network service module SocketServer, which provides server center classes, can simplify the development of network servers.

What is Socket?

Socket is also known as "socket". Applications usually send requests to the network or respond to network requests through "sockets", so that the hosts or processes on a computer can communicate.


socket() function

In Python, we use the socket() function to create a socket. The syntax format is as follows:

socket.socket([family[, type[, proto]]])

parameter

  • family: The socket family can be AF_UNIX or AF_INET
  • type: The socket type can be divided into SOCK_STREAMorSOCK_DGRAM
  • protocol: Generally, if you don't fill in, the default is 0.

Socket object (built-in) methods

function description
Server-side socket
s.bind() Bind the address (host, port) to the socket. Under AF_INET, the address is expressed in the form of a tuple (host, port).
s.listen() Start TCP monitoring. The backlog specifies the maximum number of connections that the operating system can hang before the connection is refused. The value is at least 1, most applications set it to 5.
s.accept() Passively accept TCP client connections, (blocking) waiting for the connection to arrive
Client socket
s.connect() Actively initiate the TCP server connection. Generally, the format of address is a tuple (hostname, port). If there is a connection error, socket.error will be returned.
s.connect_ex() An extended version of the connect() function, which returns an error code when an error occurs, instead of throwing an exception
Public-use socket functions
s.recv() Receive TCP data, the data is returned in the form of a string, bufsize specifies the maximum amount of data to be received. The flag provides other information about the message and can usually be ignored.
s.send() Send TCP data, and send the data in string to the connected socket. The return value is the number of bytes to be sent, which may be less than the byte size of string.
s.sendall() Completely send TCP data, and complete TCP data. Send the data in the string to the connected socket, but will try to send all the data before returning. Return None on success, throw an exception on failure.
s.recvfrom() Receive UDP data, similar to recv(), but the return value is (data, address). Where data is a string containing the received data, and address is the address of the socket that sends the data.
s.sendto() Send UDP data, send the data to the socket, address is a tuple of the form (ipaddr, port), specifying the remote address. The return value is the number of bytes sent.
s.close() Close socket
s.getpeername() Returns the remote address of the connected socket. The return value is usually a tuple (ipaddr, port).
s.getsockname() Returns the address of the socket itself. Usually a tuple (ipaddr, port)
s.setsockopt(level,optname,value) Set the value of the given socket option.
s.getsockopt(level,optname[.buflen]) Returns the value of the socket option.
s.settimeout(timeout) Set the timeout period of the socket operation. Timeout is a floating point number in seconds. A value of None means that there is no timeout period. Generally, the timeout period should be set when the socket is just created, because they may be used for connection operations (such as connect())
s.gettimeout() Returns the value of the current time-out period in seconds. If the time-out period is not set, it returns None.
s.fileno() Returns the file descriptor of the socket.
s.setblocking(flag) If the flag is 0, the socket is set to non-blocking mode, otherwise the socket is set to blocking mode (default value). In non-blocking mode, if the call to recv() does not find any data, or the send() call cannot send data immediately, it will cause a socket.error exception.
s.makefile() Create a file associated with the socket

Simple example

Server

我们使用 socket 模块的 socket 函数来创建一个 socket 对象。socket 对象可以通过调用其他函数来设置一个 socket 服务。

现在我们可以通过调用 bind(hostname, port) 函数来指定服务的 port(端口)

接着,我们调用 socket 对象的 accept 方法。该方法等待客户端的连接,并返回 connection 对象,表示已连接到客户端。

完整代码如下:

#!/usr/bin/python3
# 文件名:server.py

# 导入 socket、sys 模块
import socket
import sys

# 创建 socket 对象
serversocket = socket.socket(
            socket.AF_INET, socket.SOCK_STREAM) 

# 获取本地主机名
host = socket.gethostname()

port = 9999

# 绑定端口号
serversocket.bind((host, port))

# 设置最大连接数,超过后排队
serversocket.listen(5)

while True:
    # 建立客户端连接
    clientsocket,addr = serversocket.accept()      

    print("连接地址: %s" % str(addr))
    
    msg='欢迎访问菜鸟教程!'+ "\r\n"
    clientsocket.send(msg.encode('utf-8'))
    clientsocket.close()

客户端

接下来我们写一个简单的客户端实例连接到以上创建的服务。端口号为 9999。

socket.connect(hosname, port ) 方法打开一个 TCP 连接到主机为 hostname 端口为 port 的服务商。连接后我们就可以从服务端获取数据,记住,操作完成后需要关闭连接。

完整代码如下:

#!/usr/bin/python3
# 文件名:client.py

# 导入 socket、sys 模块
import socket
import sys

# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# 获取本地主机名
host = socket.gethostname() 

# 设置端口号
port = 9999

# 连接服务,指定主机和端口
s.connect((host, port))

# 接收小于 1024 字节的数据
msg = s.recv(1024)

s.close()

print (msg.decode('utf-8'))
现在我们打开两个终端,第一个终端执行 server.py 文件:
$ python3 server.py
第二个终端执行 client.py 文件:
$ python3 client.py 
欢迎访问菜鸟教程!
这时我们再打开第一个终端,就会看到有以下信息输出:
连接地址: ('192.168.0.118', 33397)

Python Internet 模块

以下列出了 Python 网络编程的一些重要模块:

协议 功能用处 端口号 Python 模块
HTTP 网页访问 80 httplib, urllib, xmlrpclib
NNTP 阅读和张贴新闻文章,俗称为”帖子” 119 nntplib
FTP 文件传输 20 ftplib, urllib
SMTP 发送邮件 25 smtplib
POP3 接收邮件 110 poplib
IMAP4 获取邮件 143 imaplib
Telnet 命令行 23 telnetlib
Gopher 信息查找 70 gopherlib, urllib

更多内容可以参阅官网的 Python Socket Library and Modules

TCP 服务端
服务端结构:
tcps = socket() #创建服务器套接字
tcps.bind()      #把地址绑定到套接字
tcps.listen()      #监听链接
while True:      #服务器无限循环
    tcpc = tcps.accept() #接受客户端链接
    while True:         #通讯循环
        tcpc.recv()/tcpc.send() #对话(接收与发送)
    tcpc.close()    #关闭客户端套接字
tcps.close()        #关闭服务器套接字(可选)
时间戳服务端实例:
#!/usr/bin/python3
# -*-coding:utf-8 -*-
from socket import *
import time
COD = 'utf-8'
HOST = '192.168.164.141' # 主机ip
PORT = 21566 # 软件端口号
BUFSIZ = 1024
ADDR = (HOST, PORT)
SIZE = 10 
tcpS = socket(AF_INET, SOCK_STREAM) # 创建socket对象
tcpS.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #加入socket配置,重用ip和端口
tcpS.bind(ADDR) # 绑定ip端口号
tcpS.listen(SIZE)  # 设置最大链接数
while True:
    print("服务器启动,监听客户端链接")
    conn, addr = tcpS.accept() 
    print("链接的客户端", addr)
    while True:
        try:
            data = conn.recv(BUFSIZ) # 读取已链接客户的发送的消息
        except Exception:
            print("断开的客户端", addr)
            break
        print("客户端发送的内容:",data.decode(COD))
        if not data:
            break
        msg = time.strftime("%Y-%m-%d %X") #获取结构化事件戳
        msg1 = '[%s]:%s' % (msg, data.decode(COD))
        conn.send(msg1.encode(COD)) #发送消息给已链接客户端
    conn.close() #关闭客户端链接
tcpS.closel()

TCP 客户端

客户端结构:

tcpc = socket()    # 创建客户端套接字
tcpc.connect()    # 尝试连接服务器
while True:        # 通讯循环
    tcpc.send()/tcpc.recv()    # 对话(发送/接收)
tcpc.close()      # 关闭客户套接字

时间戳客户端实例:

#!/usr/bin/python3
# -*-coding:utf-8 -*-
from socket import *
from time import ctime
HOST = '192.168.164.141' #服务端ip
PORT = 21566 #服务端端口号
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM) #创建socket对象
tcpCliSock.connect(ADDR) #连接服务器
while True:
    data = input('>>').strip()
    if not data:
        break
    tcpCliSock.send(data.encode('utf-8')) #发送消息
    data = tcpCliSock.recv(BUFSIZ) #读取消息
    if not data:
        break
    print(data.decode('utf-8'))
tcpCliSock.close() #关闭客户端

Lession11-Client.py

#! /usr/bin/python
#! -*- coding:UTF-8 -*-
#lession11-client.py
import socket,sys,os
c =socket.socket()
host =socket.gethostname()
port =9999
c.connect((host,port))
while True:
    print c.recv(1024)
    while 1:
        b =raw_input("Say to Server:")
        c.send(b)
        print "Send to server success!"
        print c.recv(1024)

Lession11-Server.py

#! /usr/bin/python
#! -*- coding:UTF-8 -*-
import socket,sys,os
s =socket.socket()
host =socket.gethostname()
port =9999
s.bind((host,port))
s.listen(5)
while True:
    c,addr =s.accept()
    print("Client address is:",str(addr))
    c.send("Link success!")
    while 1:
        if c.recv(1024) == 'cmd':
            while 1:
                c.send("It's cmd!")
                y =os.popen(c.recv(1024)).read()
                c.send(y)
                print "Send to client CMD success!"
        else:
            print c.recv(1024)


scanPort.py(sample_version)

#! /usr/bin/python
# ! -*- coding:UTF-8 -*-
import socket,time
port =[80,21,1433,3389,8000,6666,135,445]
def isOpen(ip,port):
    s = socket.socket()
    try:
        s.connect(ip,port)
        return True
    except:
        return False
def scan(ip):
    for x in port:
        if isOpen(ip,x):
            print "%s host %s is open"%(ip,x)
            time.sleep(1)
        else:
            print "%s host %s is close"%(ip,x)
            time.sleep(1)
scan('127.0.0.1')

扫描器完善后(未引入多线程和单接口):

#! /usr/bin/python
# ! -*- coding:UTF-8 -*-
import socket,sys,os
port =[21,80,43,135,445,1433,3306,3389]
def open(ip,port):
    s =socket.socket()
    try:
        s.connect((ip,port))
        return True
    except:
        return False
def scanIp(ip):
    for x in port:
        if open(ip,x):
            print("%s host %s is open!")%(ip,x)
        else:
            print("%s host %s is close!")%(ip,x)
def rscan(ip):
    for x in range(s,e):
        if open(ip,x):
            print("%s host %s is open!") % (ip, x)
        else:
            print("%s host %s is close!") % (ip, x)

if len(sys.argv)<2:
    print '''
    This program prints files to the standard output.
       Any number of files can be specified.
       Options include:
       --version : Prints the version number
       --help    : Display this help
    '''
    sys.exit()
if sys.argv[1].startswith('--'):
    option =sys.argv[1][2:]
    if option == 'version':
        print 'version 1.0'
    elif option == 'help':
        print ''' python.py scanport.py host port
            python.py scanport.py host
            python.py scanport.py 127.0.0.1 21,80,135
            python.py scanport.py 127.0.0.1 80-90
            python py scanport.py 127.0.0.1 all
        '''
    else:
        print "Unknown option!"
    sys.exit()
if len(sys.argv) == 2:
    scanIp(sys.argv[1])
elif len(sys.argv) == 3:
    try:
        if ',' in sys.argv[2]:
            p =sys.argv[2]
            p =p.split(',') #以逗号为分隔符,将此分开,成为列表
            for x in p:
                a =[]
                a.append(int(x))
                port = a
                scanIp(sys.argv[1])
        elif '-' in sys.argv[2]:
            a =sys.argv[2]
            a =a.split('-')
            s =int(a[0])
            e =int(a[1])+1
            rscan(sys.argv[1])
        elif sys.argv[2] == 'all':
            s = 1
            e = 65536
            rscan(sys.argv[1])
        elif sys.argv[2] is
    except KeyboardInterrupt:
        print "Program End!"




转载请注明:Adminxe's Blog » 0x011.Python学习-网络编程、PortScan

Guess you like

Origin blog.csdn.net/Adminxe/article/details/106679045