就屏幕截图所描述的而言,我可以说您走在正确的轨道上。您已经正确地覆盖了指向 NextSEH和SE Handler的指针。
一些解释:
异常注册记录结构
typedef struct _EXCEPTION_REGISTRATION_RECORD
{
struct _EXCEPTION_REGISTRATION_RECORD *Next;
PEXCEPTION_ROUTINE Handler;
} EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;
每当调用具有异常处理机制的新函数时,都会将EXCEPTION_REGISTRATION_RECORD添加到堆栈中。其中*Next是指向Previous EXCEPTION_REGISTRATION_RECORD的指针,Handler是指向Exception handler的函数指针。
该FS:0寄存器总是指向第一个EXCEPTION_REGISTRATION_RECORD。一旦EXCEPTION_REGISTRATION_RECORD被压入堆栈,FS:0寄存器将被设置为指向新的EXCEPTION_REGISTRATION_RECORD,下一条记录将被设置为指向FS:0寄存器的先前值。这将维护 SEH 链的链接列表。
异常处理器结构
typedef EXCEPTION_DISPOSITION (*ExceptionHandler) (
IN PEXCEPTION_RECORD ExceptionRecord,
IN ULONG64 EstablisherFrame,
IN OUT PCONTEXT ContextRecord,
IN OUT PDISPATCHER_CONTEXT DispatcherContext
);
当异常发生时,系统异常调度器例程启动并设置它自己的堆栈框架。ExceptionHandler的结构被压入堆栈。
在 SEH 覆盖场景中,攻击者是幸运的,因为系统异常调度程序例程在调用此ExceptionHandler函数之前将创建者帧值放在[ESP+8]的堆栈中。
建立者帧是指向NextSEH记录的指针。攻击者可以通过用任意内存地址覆盖NextSEH记录来控制它。
注意: Attacker 还没有覆盖ResponderFrame。然而,攻击者已经覆盖了栈上的NextSEH指针。
一次,您传递异常System Exception Dispatcher将控制权传递给SE 处理程序并执行异常处理代码。
剥削策略:
- 攻击者将使用后向跳转覆盖NextSEH,并使用POP/POP/RET序列的地址覆盖SE Handler。
- 一旦异常发生,由于异常调度例程序言,NextSEH的地址将被放置在[ESP+8]的堆栈中。
- 一旦异常被传递,异常调度程序例程会将控制权传递给SE Handler。
- SE处理器将执行POP / POP / RET序列,将POP的地址NextSEH在EIP。因此,获得代码执行。
如果答案中有错误,请接受我的歉意,并请帮助改进答案,以便对社区成员有用。
谢谢。