here is a way to do this in kernel mode driver: (for WinXP/2003)
Hook undocumented API: ZwCreateProcessEx
then set the fouth parameter to SYSTEM handle info.
typedef NTSTATUS (*ZWCreatePROCESSEX)(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL,
IN HANDLE Unknown );
ZWCreatePROCESSEX OldZwCreateProcessEx;
NTSTATUS
NTAPI
ZwOpenProcess(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId
);
NTSTATUS NewZwCreateProcessEx(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL,
IN HANDLE Unknown OPTIONAL)
{
NTSTATUS ret;
HANDLE h;
CLIENT_ID id;
OBJECT_ATTRIBUTES oa;
id.UniqueProcess = (HANDLE)4; // run process as SYSTEM account
id.UniqueThread = 0;
InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL);
ZwOpenProcess(&h, PROCESS_ALL_ACCESS, &oa, &id);
ret= OldZwCreateProcessEx(ProcessHandle,DesiredAccess,ObjectAttributes,
h, InheritObjectTable,SectionHandle,DebugPort,ExceptionPort,Unknown);
ZwClose(h);
return ret;
}
SDT hook:
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;
extern PServiceDescriptorTableEntry KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
int ServiceIndex = 0x32; // for WinXP/2003
Hook SDT(Service Descriptor Table):
// save old system call locations
// OldNtCreateProcessEx=(NTCreatePROCESSEX)(SYSTEMSERVICE(0x32));
OldZwCreateProcessEx=(ZWCreatePROCESSEX)(*(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase + ServiceIndex));
_asm
{
CLI //dissable interrupt
MOV EAX, CR0 //move CR0 register into EAX
AND EAX, NOT 10000H //disable WP bit
MOV CR0, EAX //write register back
}
(ZWCreatePROCESSEX)(*(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase + ServiceIndex)) = NewZwCreateProcessEx;
_asm
{
MOV EAX, CR0 //move CR0 register into EAX
or EAX, 10000H //enable WP bit
MOV CR0, EAX //write register back
STI //enable interrupt
}
Unhook SDT:
_asm
{
CLI //dissable interrupt
MOV EAX, CR0 //move CR0 register into EAX
AND EAX, NOT 10000H //disable WP bit
MOV CR0, EAX //write register back
}
(ZWCreatePROCESSEX)(*(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase + ServiceIndex)) = OldZwCreateProcessEx;
_asm
{
MOV EAX, CR0 //move CR0 register into EAX
or EAX, 10000H //enable WP bit
MOV CR0, EAX //write register back
STI //enable interrupt
}
get SDI index by dynamic analyse NTDLL:
#define DWORD unsigned long
#define WORD unsigned short
#define BOOL unsigned long
#define BYTE unsigned char
#define SEC_IMAGE 0x01000000
NTSTATUS
NTAPI
ZwCreateSection(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN PLARGE_INTEGER MaximumSize OPTIONAL,
IN ULONG SectionPageProtection,
IN ULONG AllocationAttributes,
IN HANDLE FileHandle OPTIONAL
);
typedef struct _SECTION_IMAGE_INFORMATION {
PVOID EntryPoint;
ULONG StackZeroBits;
ULONG StackReserved;
ULONG StackCommit;
ULONG ImageSubsystem;
WORD SubsystemVersionLow;
WORD SubsystemVersionHigh;
ULONG Unknown1;
ULONG ImageCharacteristics;
ULONG ImageMachineType;
ULONG Unknown2[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
DWORD GetDllFunctionAddress(char* lpFunctionName, PUNICODE_STRING pDllName)
{
HANDLE hThread, hSection, hFile, hMod;
SECTION_IMAGE_INFORMATION sii;
IMAGE_DOS_HEADER* dosheader;
IMAGE_OPTIONAL_HEADER* opthdr;
IMAGE_EXPORT_DIRECTORY* pExportTable;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base, x, functionAddress;
char* functionName;
STRING ntFunctionName, ntFunctionNameSearch;
PVOID BaseAddress = NULL;
SIZE_T size=0;
IO_STATUS_BLOCK iosb;
OBJECT_ATTRIBUTES oa = {sizeof oa, 0, pDllName, OBJ_CASE_INSENSITIVE};
ZwOpenFile(&hFile, FILE_EXECUTE | SYNCHRONIZE, &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
oa.ObjectName = 0;
ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &oa, 0,PAGE_EXECUTE, SEC_IMAGE, hFile);
ZwMapViewOfSection(hSection, NtCurrentProcess(), &BaseAddress, 0, 1000, 0, &size, (SECTION_INHERIT)1, MEM_TOP_DOWN, PAGE_READWRITE);
ZwClose(hFile);
hMod = BaseAddress;
dosheader = (IMAGE_DOS_HEADER *)hMod;
opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24);
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*) hMod + opthdr->DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress);
// now we can get the exported functions, but note we convert from RVA to address
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfFunctions);
arrayOfFunctionNames = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfNames);
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)hMod + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
RtlInitString(&ntFunctionNameSearch, lpFunctionName);
for(x = 0; x < pExportTable->NumberOfFunctions; x++) {
functionName = (char*)( (BYTE*)hMod + arrayOfFunctionNames[x]);
RtlInitString(&ntFunctionName, functionName);
functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1; // always need to add base, -1 as array counts from 0
// this is the funny bit. you would expect the function pointer to simply be arrayOfFunctionAddresses[x]...
// oh no... thats too simple. it is actually arrayOfFunctionAddresses[functionOrdinal]!!
functionAddress = (DWORD)( (BYTE*)hMod + arrayOfFunctionAddresses[functionOrdinal]);
if (RtlCompareString(&ntFunctionName, &ntFunctionNameSearch, TRUE) == 0)
{
ZwClose(hSection);
return functionAddress;
}
}
ZwClose(hSection);
return 0;
}
use the above function like this:
RtlInitUnicodeString(&dllName, L"//Device//HarddiskVolume1//Windows//System32//ntdll.dll");
functionAddress = GetDllFunctionAddress("ZwCreateProcessEx", &dllName);
ServiceIndex = *((WORD*)(functionAddress+1)); // should = 0x32
相关推荐
MySQL用户与权限管理实战:从创建、授权到安全连接全解析
数据库用户与权限管理是数据安全的核心基础。其原理基于用户标识(用户名@主机)的精确匹配和分层级的权限验证体系,通过全局、数据库、表、列等多级权限控制实现最小权限原则。这一机制的技术价值在于构建了数据库访问的第一道安全防线,防止越权操作和数据泄露。在实际应用场景中,无论是Web应用后端连接、数据分析报表系统,还是运维管理平台,都需要精细化的用户权限配置来保障业务安全。本文聚焦MySQL用户创建、认证插件选择、GRANT/REVOKE授权实战及连接失败排查,深入解析如何通过**权限验证流程**和**主机名匹配*
MySQL用户权限四维模型:host+user+privilege+scope精细化管控
MySQL权限管理本质是基于host、user、privilege和scope四维坐标的精细化访问控制机制,其核心原理在于连接匹配时的最具体host优先策略、认证插件与密码哈希的绑定关系、权限类型与作用范围的强耦合性,以及内存缓存与磁盘权限数据的一致性保障。该模型支撑最小权限原则落地,显著提升数据库安全水位,广泛应用于Java微服务、PHP后台、Python数据分析等生产环境的账号隔离与敏感数据防护场景。本文深入解析créer un nouvel utilisateur与octroyer des autor
Windows凭证获取实战:5种方法原理、避坑与防御视角
在Windows系统安全与渗透测试领域,凭证获取是理解攻击链与构建有效防御的核心基础。其原理主要围绕从系统内存、注册表或文件中提取敏感认证数据,例如密码哈希、明文凭证或Kerberos票据。掌握这些技术对于安全评估、应急响应和权限提升至关重要,能够帮助管理员在合法授权范围内识别风险点。从技术价值看,它不仅是红队攻击的关键环节,也是蓝队构建检测规则、实施针对性防护的必备知识。常见的应用场景包括内网渗透测试、系统安全审计以及针对Credential Guard等安全机制的绕过研究。本文聚焦于Windows凭证获
VB创建SYSTEM用户进程(第一种方法)
Option Explicit Private Const PROCESS_CREATE_THREAD = &H2Private Const PROCESS_QUERY_INFORMATION = &H400Private Const PROCESS_VM_WRITE = &H20Private Const PROCESS_VM_OPERATION = &H8Private Const PROCE
Windows提权实战:利用SeImpersonatePrivilege从服务账户到SYSTEM权限
在Windows安全体系中,访问令牌是进程身份验证的核心机制,它决定了进程能够访问的系统资源范围。模拟机制允许服务进程临时扮演客户端的安全上下文执行操作,而SeImpersonatePrivilege特权正是实现这一功能的关键权限。这项技术价值在于,当攻击者获得低权限服务账户访问权时,可以通过滥用命名管道等系统组件,诱骗高权限进程连接并窃取其令牌,实现权限提升。在渗透测试和红队评估中,这种技术特别适用于IIS、SQL Server等常见服务场景,因为这些服务账户默认拥有SeImpersonatePrivil
session-process-connection
本文章为网络笔记,看了warehouse老师的视频受益匪浅,更是感觉自己技术太过初级,特写了本笔记,方便以后反复学习! 如有任何不妥,请发邮件至102448567@qq.com删除文章! 关于warehouse: http://blog.itpub.net/19602/viewspace-1059211/ 11gR2视频第四版 3_02_session_process_connsection SQL> create user a identified by a; 用户已创建。 SQL> co
AI 运行时革命:Managed Agents 与 Session-As-Event-Log 架构解析
AI 运行时(AI Runtime)是支撑大模型应用落地的核心基础设施,其本质是为 Agent 提供可管理、可审计、有状态的执行环境。它融合了操作系统级的资源隔离思想与云原生可观测性实践,通过将 session 状态从易失的 context window 迁移至持久化、不可变的事件日志(Event Log),从根本上解决状态失控、凭证泄露与故障不可追溯三大工程痛点。该架构不仅提升推理稳定性与安全水位,更推动 AI 应用从‘一次调用’迈向‘长期服务’范式。Anthropic Managed Agents 正是
042-7 Undo表空间,SESSION,PROCESS,Connect
--SESSION的概念 新窗口(不同SESSION)查询到1 a的原理,是由于存在undo表空间,oracle将修改前的数据放在undo表空间 /*SESSIO会话 --通过session信息查找对应的操作系统进程...
Windows下特权获取
Windows下特权获取Windows下部分操作需要特权才能执行,如下代码示例通过修改token获取SE_DEBUG_NAME特权,其他特权与此类似,只需要将SE_DEBUG_NAME换成其他特权即可,如下代码类似于MSDN的示例: https://msdn.microsoft.com/en-us/library/windows/desktop/aa446619(v=vs.85).aspx wi
择录自WINDOWS源码的提权函数
#define SE_MIN_WELL_KNOWN_PRIVILEGE (2L)#define SE_CREATE_TOKEN_PRIVILEGE (2L)#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE (3L)#define SE_LOCK_MEMORY_PRIVILEGE (4L)#define SE_INCRE
给进程提权的3个方法
第一个方法: bool EnableDebugPrivilege() { HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TO
Ansible 部署 Docker 的生产级确定性实践
Docker 是容器化运行时的核心基础,Ansible 则是实现基础设施即代码(IaC)的关键自动化工具。二者结合的本质,不是简化操作,而是通过声明式配置将环境部署转化为可验证、可审计、可复现的确定性过程。其技术价值在于消除手动安装中的发行版差异(如 Ubuntu 的 docker.io 与官方 docker-ce 版本鸿沟)、权限提升链路断裂(become 机制失效)、Daemon 配置失配(daemon.json 与 systemd 协同缺失)等典型工程风险。典型应用场景覆盖金融、电商等对稳定性与合规性
Windows 提权实战:NSudo 8.2 与 C++ 原生实现方案对比评测
本文深入对比了Windows系统权限管理中的NSudo 8.2工具与C++原生实现方案,详细解析了System和TrustedInstaller级别的权限提升技术。通过功能特性、性能表现和安全措施的全面评测,为开发者提供了针对不同场景的技术选型指南,帮助实现高效安全的系统提权操作。
VBA 64位API声明语句第009讲
跟我学VBA,我这里专注VBA, 授人以渔。我98年开始,从源码接触VBA已经20余年了,随着年龄的增长,越来越觉得有必要把这项技能传递给需要这项技术的职场人员。希望职场和数据打交道的朋友,都来学习VBA,利用VBA,起码可以提高自己的工作效率,可以有时间多陪陪父母,多陪陪家人,何乐而不为呢?我的教程一共九套,从入门开始一直讲到程序的分发,是学习利用VBA的实用教程。这讲我们继续学习VBA 64位API声明语句第009讲,这些内容是MS的权威资料,看似枯燥,但对于想学习API函数的朋友是非常有用的。
oracle 权限管理、角色管理详解
oracle权限分为两种: 系统权限:系统规定用户使用数据库的权限,允许用户执行特定的数据库动作,如创建表、创建索引、连接实例等。 对象权限:某种权限可以让用户对其它用户的的表或视图等对象进行特定操作。 (一)系统权限oracle有哪些系统权限呢?可以通过查找系统权限字典(SYSTEM_PRIVILEGE_MAP)得到:SELECT NAME FROM SYSTEM_PRIVILEGE_MAP在or
CVE-2023-40031漏洞复现:Notepad++本地提权原理与实战
本地提权(LPE)是Windows安全领域的关键概念,指攻击者利用系统或应用缺陷,从低权限账户提升至高权限账户(如SYSTEM)的能力。其核心原理通常围绕进程权限模型与资源访问控制展开,当高权限进程在未充分验证的情况下,操作了攻击者可控的路径或对象时,便可能引发权限跨越。这类漏洞的技术价值在于揭示了软件在权限边界设计上的缺陷,是评估系统纵深防御有效性的重要标尺。在应用场景上,本地提权常作为渗透测试链的关键一环,用于突破隔离、部署持久化后门或横向移动。本文以符号链接攻击为切入点,通过复现Notepad++插件
Windows句柄机制解析与资源管理实践
在操作系统资源管理中,句柄(Handle)是连接应用程序与系统资源的关键桥梁。作为一种抽象引用标识,句柄机制实现了资源访问的统一接口和安全隔离,其核心原理是通过整数值间接引用内核对象。Windows系统将文件、线程、事件等资源统一抽象为内核对象,通过句柄表进行管理。这种设计既保证了虚拟内存环境下的进程隔离性,又提供了高效的资源访问方式。在工程实践中,合理使用句柄能显著提升程序稳定性,常见的应用场景包括文件操作、进程间通信和系统监控等。通过RAII模式管理句柄生命周期、使用Process Explorer等工
with admin option选项和权限的关系测试
这篇文章衔接上文,当时问题查出来是用户登录一个普通账户对其他账户进行了授权 所以比较迷惑为什么这个用户可以赋权给其他人 查看uuser1 的系统权限 SQL> select * from dba_sys_privs where GRANTEE='UUSER1'; GRANTEE PRIVILEGE ...
329




被折叠的 条评论
为什么被折叠?



