我拿起三年前买的这本《python黑帽子:黑客与渗透测试编程之道》,翻开后发现只看了十页就放在书架上了,里面的代码可能都没有真正去敲过。没有使用python也有很长一段时间了,我决定要把这本书认真学习一遍,正好也复习和进一步学习一下python知识。
书的第一章只有8页,主要就是讲了配置python环境。作者讲了在虚拟机中安装Kali Linux系统,用WingIDE编辑代码。系统不用多说,我的虚拟机中装了各种系统。写代码的话我还是选择一直用的PyCharm。然后把我的Python版本升到3.7。
第2章讲网络基础。从这章开始就都有代码练习了。
TCP客户端
先贴代码:
# -*- coding:utf8 -*-
import socket
target_host = "www.bing.com" #目标主机地址
target_port = 80 #端口号
#建立一个socket对象
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#连接客户端
client.connect((target_host,target_port))
#发送一些数据
client.send("GET / HTTP/1.1\r\nHost: bing.com\r\n\r\n".encode("utf-8"))
#接收一些数据
response = client.recv(4096)
print(response)
代码很简单,就是按照创建socket对象→建立连接→发送数据→接收响应的顺序,最后把接收到的数据打印出来。也没有异常处理,这个有需要自己添加。
跑一下代码:
UDP客户端
# -*- code: utf-8 -*-
import socket
target_host = "192.168.31.177"
target_port = 1234
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.sendto("AAABBBCCC".encode("utf-8"),(target_host,target_port))
data,addr = client.recvfrom(4096)
print(data)
udp客户端也很简单,而且udp是一个无连接的协议,所以就不用connect()了。
我看了一下Windows安装netcat的教材,嫌麻烦,不如直接在VMware的系统里使用netcat打开udp服务。我打开虚拟机中的Kali系统,开启一个终端,用man netcat看了一下命令说明,开启udp服务:
l:开启监听模式 u:udp p:端口号
在代码中设置好地址和端口号:
target_host = "192.168.31.177"
target_port = 1234
运行代码:
服务端收到了客户端发送的消息,我们在服务器给客户端回复一些数据,我随便输入3个a:
再看PyCharm的客户端输出:
客户端收到了服务器发来的数据。
如果只是想得到服务器发来的数据,那用recv()函数不就行了?而且从代码来看时接收了data和addr。
没错,recvfrom()可以接收到回传的数据及远程主机的信息和端口好。我在上面代码print(data)下添加一行print(addr),把服务器所在的主机信息打印出来。重新运行一下代码,这次服务器发“bbb“:
这次把ip和port都打印出来了。
TCP服务器
import socket
import threading
bind_ip = "127.0.0.1"
bind_port = 9999
#建立socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#绑定ip地址和端口号
server.bind((bind_ip,bind_port))
#启动监听并设置最大连接数为5
server.listen(5)
print("[*] Listening on %s:%d" % (bind_ip,bind_port))
#客户处理线程
def handle_client(client_socket):
#打印客户端发送的内容
request = client_socket.recv(1024)
print("[*] Received: %s" % request)
#返还一个数据包
client_socket.send("ACK!".encode("utf-8"))
#关闭socket
client_socket.close()
while True:
client,addr = server.accept()
print("[*] Accepted connection from: %s:%d" % (addr[0],addr[1]))
#挂起客户端线程,处理传入的数据
client_handler = threading.Thread(target=handle_client,args=(client,))
client_handler.start()
运行代码:
把客户端的代码修改一下:
# -*- coding:utf8 -*-
import socket
target_host = "127.0.0.1" #目标主机地址
target_port = 9999 #端口号
#建立一个socket对象
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#连接客户端
client.connect((target_host,target_port))
#发送一些数据
#client.send("GET / HTTP/1.1\r\nHost: bing.com\r\n\r\n".encode("utf-8"))
client.send("123456".encode("utf-8"))
#接收一些数据
response = client.recv(4096)
print(response)
运行客户端:
接收到了服务器发送的“ACK"。在看看服务器接收到的:
这些可以说是最简单的Python网络编程了,需要知道一点计算机网络的基础知识和python语法及几个函数的作用。代码里面出现方法看注释基本上都能知道它的作用。要说一下的是线程那里,threading.Thread(target=handle_client,args=(client,))这个函数,第一个参数target是要执行的方法,第二个参数args 是传递给线程函数的参数,它必须是个tuple类型,如果需要多个参数,还得往后加,注意别忘了逗号,因为它是个元组。