0x00
网络一直是黑客们最喜欢的竞技场。通过简单的网络访问,攻击者可以做任何想做的事情。例如主机扫描,数据包注入,远程攻击等。但是当我们通过某种方法进入某企业内网,假设在次内网中无任何工具可以利用,但是你惊讶的发现目标环境中安装了Python环境,那么我们可以利用这个环境,将编写你所可能要用到的工具,实现我们的渗透。
我们的目标不是成为网络编程高手,我们只需要迅速,简单,可靠的处理日常的任务工具。
0x01
在学习客户端/服务器网络编程之前,我们有必要先熟悉socket()模块的函数。其语法如下:
socket( socket_family , socket_type , protocol=0) ,socket_family 可以是AF_VNIX,也可以是AFI_NET , socket_type 可以是 SOCK_STREAM(TCP客户端) 也可以是 SOCK_DGRAM(UDP客户端)
套字节对象的常用函数:
服务端套字节函数:
s.bind() 绑定地址到(主机名,端口)套字节
s.listen() 开始TCP监听
s.accept() 被动接受客户端的连接,(阻塞式)等待连接的到来
客户端套字节函数:
s.connect() 主动初始化TCP服务连接
s.connect_ex() connect()函数的扩展,出错时返回错误码,而不是抛出异常
公共用处套字节函数:
s.recv() 接受TCP数据
s.send() 发送TCP数据
s.sendall() 完整发送TCP数据
s.recvfrom() 接受UDP数据
s.sendto() 发送UDP数据
0x02
在渗透测试过程中,我们经常会遇到需要创建一个TCP客户端来连接服务,下面是一个TCP客户端简单编写
1 #!usr/bin/python 2 #coding:utf-8 3 4 import socket 5 target_host = "www.xiyounet.org" 6 target_port = 80 7 8 #建立一个包含AF_INET和SOCK_STREAM参数的socket对象 9 client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 10 11 #连接客户端 12 13 client.connect((target_host,target_port)) 14 15 #发送数据 16 17 client.send("GET / HTTP/1.1\t\nHOST:xiyounet.org\r\n\r\n") 18 #接受一些数据 19 20 response = client.recv(4096) 21 22 print response
AF_INET参数是说明我们使用的是标准Ipv4地址或者主机名,SOCK_STREAM说明这将是一个TCP 客户端。
作为一名渗透者,我们总是期盼好的事情,例如上面的代码总是假设成功,不会出现异常,这时可以简单的体会到我们与开发者的一点点区别!!!
0x03
UDP客户端的一般代码:
1 #!usr/bin/python 2 #coding:utf-8 3 4 import socket 5 6 target_host = "127.0.0.1" 7 target_port = 80 8 9 #建立一个socket对象 10 client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 11 12 #发送一些数据 13 client.sendto("AABBCC",(target_host,target_port)) 14 15 #接受一些数据 16 data,addr = client.recvfrom(4096) 17 18 print data
这里,与TCP客户端的差别不是很大,只是连接时用的是 AF_INET参数和 SOCK_DGRAM 直接将数据发送到服务器上,因为UDP是无状态协议,所以不用像tcp一样去使用connects()函数。最后一步是调用recvfrom()函数接受返回的udp包。
0x04
TCP服务器,我们首先来创建一个标准的TCP服务器
1 #!usr/bin/python 2 #coding:utf-8 3 import socket 4 import threading 5 6 bind_ip = "0.0.0.0" 7 bind_port = 9999 8 9 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 10 server.bind((bind_ip,bind_port)) 11 12 server.listen(5) 13 14 print " [*] Listening on %s:%d"%(bind_ip,bind_port) 15 #这是客户端处理线程 16 def handle_client(client_socket): 17 #打印出客户端发送得到的内容 18 request = client_sockent.recv(1024) 19 print "[*]Received: %s " % request 20 #返还一个数据包 21 client_socket.send("ACK!") 22 client_socket.close() 23 while True: 24 client,addr = server.accept() 25 print "[*] Accepted connection from : %s:%d"%(addr[0],addr[1]) 26 #挂起客户端线程,输入传入的数据 27 client_handle = threading.Thread(target = handle_client,args = (client,)) 28 client_handle.start()
首先我们先确定服务器要监听的地址和端口,然后启动监听,并设置最大监听数为5,下一步,我们让服务器进入主循环,被动接受TCP客户连接,等待客户端的数据。当与客户端成功的建立连接时,我们将接收到的客户端套字节对象保存至client变量中,将远程细节保存至addr变量中,接着我们以handle_client()函数为回调函数创建一个新的线程对象,将客户端套字节对象作为一个句柄传递给它,然后我们启动线程开始处理客户端连接,handle_client()函数执行recv()函数之后将一段信息发送给客户端。
0x05
利用TCPL连接实现一个简单的扫描器
#!usr/bin/python import socket s = socket.socket() hosts = ['127.0.0.1','222.24.62.76'] ports = [22,445,80,443,3389,3306] for host in hosts: for port in ports: try: print"[+] Connecting to "+host+":"+str(port) s.connect((host,port)) s.send('Primal Security \n') banner = s.recv(1024) if banner: print "[+] Port "+str(port)+" open :"+banner s.close() except:pass