运行程序输入进程pid
import winreg
import psutil # pip install psutil
import logging
logging.basicConfig(format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',
level=logging.DEBUG)
"""
要分析一个应用程序是否存在劫持系统DLL的漏洞,需要这么几个步骤:
1.启动应用程序
2.使用Process Explorer等类似软件查看该应用程序启动后加载的动态链接库。
3.从该应用程序已经加载的DLL列表中,查找在上述“KnownDLLs注册表项”中不存在的DLL。
4.编写第三步中获取到的DLL的劫持DLL。
5.将编写好的劫持DLL放到该应用程序目录下,重新启动该应用程序,检测是否劫持成功。
https://www.dyxmq.cn/program/code/python/python-regedit-winreg.html
https://www.nhooo.com/note/qa0qxl.html
https://www.freebuf.com/articles/78807.html
winreg使用文档:https://docs.python.org/zh-cn/3.6/library/winreg.html#functions
"""
# Windows系统中默认情况下的KnownDLLs注册表
def get_knownDLLs_list():
"""
微软为了更进一步的防御系统的DLL被劫持,将一些容易被劫持的系统DLL写进了一个注册表项中,那么凡是此项下的DLL文件就会被禁止从EXE自身所在的目录下调用,而只能从系统目录即SYSTEM32目录下调用。注册表路径如下:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
:return: knownDLLs_list
"""
knownDLLs_list = []
# handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) # 连接到注册表
access_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
r"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs") # 访问注册表
try:
print("-----get process dll-----")
i = 0
while True:
key_name, value_name, key_type = winreg.EnumValue(access_key, i) # 枚举所有的value,有三个返回值:键值名,键值,键类型
i += 1
# print(f"key_name:{key_name} value_name:{value_name} key_type:{key_type}")
knownDLLs_list.append(value_name)
except Exception as e:
pass
return knownDLLs_list
# https://pypi.org/project/psutil/
# 根据pid获取进程名和加载的dll库
def get_process_dll(pid):
process_dll_dict = {}
try:
p = psutil.Process(
pid=pid) # psutil.Process(pid=17364, name='QQMusic.exe', status='running', started='11:54:41')
logging.info(p)
for dll in p.memory_maps():
path = dll.path
if path.endswith('.exe'): # 进程名
process_name = path.split("\\")[-1]
process_dll_dict["process_name"] = process_name
print("process_name:", process_name, "||", "process_pid:", pid)
if path.endswith('.dll'): # 进程加载的所有dll库
process_dll_dict[path.split("\\")[-1]] = path
except psutil.NoSuchProcess:
logging.warning(f"no process found with pid {pid}")
return process_dll_dict
# 从该应用程序已经加载的DLL列表中,查找在上述“KnownDLLs注册表项”中不存在的DLL
def attack_dll():
"""
找到存在预加载漏洞的dll列表
:return: dll_all
"""
dll_all = {}
knownDLLs_list = get_knownDLLs_list()
process_dll_dict = get_process_dll(int(input("请输入程序pid:"))) #
if not process_dll_dict: return
for k, v in process_dll_dict.items():
# 判断程序加载的dll 不在KnownDLLs注册表项中
if k.upper() not in [knownDLL.upper() for knownDLL in knownDLLs_list]:
dll_all[k] = v
print(v)
return dll_all
attack_dll()
"""
taskkill /F /IM notepad.exe 终止进程
"""