堆栈溢出在我们exploit时常用到,利用其一般方式是:JMP ESP 与 JMP EBX;
昨天有一“同学”问我关于JMP EBX详细的问题,所以在此介绍一下:
1 JMP ESP
函数调用后的堆栈结构:
L
L -> child program of Local variable
L -> 一般情况下此处保存的ebp
R -> EIP for return parent funcion
P -> pass to child prgram variable
P
P
exploit后的堆栈结构:
N
N
N -> NOP把原来的Local variable空间覆盖掉,导致它overflow
R -> 系统dll中的Jmp esp的地址
N -> NOP把原来pass过来的参数给覆盖掉
N
N
S -> Shellcode
S
S
解释:
1) 函数返回时执行ret XXX指令; 要做的事: pop eip; add esp,XXX;
2) 此时栈中的R已不是原来的返回地址了,而改成了系统dll中的Jmp esp的地址(eg:0x7FFA4512)
3) ret指令执行完毕后,此时的EIP->Jmp esp的addr(eg:0x7FFA4512);ESP->我们的shellcode
4) 程序继续执行,此时EIP里的内容是Jmp esp,系统执行Jmp esp,就跳到我们的ShellCode了
注: 子过程是stdcall/pascal调用,才要用NOP把原来pass过来的参数给覆盖掉
因为堆栈平衡在子过程中完成,通过ret XXX; 如果是cdecl或无参数就不要R下面的NOP了
2 JMP EBX
函数调用后的堆栈结构:
L
L -> child program of Local variable
L -> 一般情况下此处保存的ebp
R -> EIP for return parent funcion
P -> pass to child prgram variable
P
P
PL -> parent program of Local variable
PL
PL
...
SEH.prev ->前一个EXCEPTION_REGISTRATION结构
SEH.handler ->异常处理例程入口
exploit后的堆栈结构:
N
N ->
N ->
N ->
N ->
N
N
N -> NOP把原来的栈上异常处理前的东西全覆盖掉,导致它overflow和Trap
N
N
...
J -> 现在内容是0xeb 0x04 0x90 0x90(Jmp $+8);原来是前一个EXCEPTION_REGISTRATION结构
E -> 系统dll中的Jmp ebx的地址
S -> Shellcode
S
S
解释:
1) 子过程返回,此时的返回地址已经改成Nop了,EIP->0x90909090;
2) EIP所指向的地址不可访问,GP
3) SEH被激活,但此时的处理地址是系统dll的Jmp ebx的地址
4) SEH激活后EBX指向的是J的地址,就是前一个EXCEPTION结构的地址
5) 程序继续执行Jmp ebx后,现在EIP指向J的地址
6) 程序再继续执行Jmp$+8,到我们的shellcode了
注: 关于SEH激活后EBX指向的是J的地址,我debug到ntdll中的KiRaiseUserExceptionDispatcher
它会调用一个过程(0x77FACBB2),在这个过程中它主要处理了:
a)它会调用一个过程(0x77FBB3BC)把SEH的最后一个EXCEPTION_REGISTRATION结构放到EBX中
b)它会调用一个过程(0x77FBB23C)通过指针调用我们的SEH处理函数
a)处对应代码解释
77FACBC8 E8 EFE70000 CALL ntdll.77FBB3BC
77FACBCD 8365 FC 00 AND DWORD PTR SS:[EBP-4],0
77FACBD1 8BD8 MOV EBX,EAX
77FBB3BC 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
77FBB3C2 C3 RETN
b)处对应代码解释
77FACC06 6A 10 PUSH 10
77FACC08 53 PUSH EBX
77FACC09 6A 00 PUSH 0
77FACC0B FF75 0C PUSH DWORD PTR SS:[EBP+C]
77FACC0E 56 PUSH ESI
77FACC0F E8 2C7E0000 CALL ntdll.77FB4A40
77FACC14 8945 08 MOV DWORD PTR SS:[EBP+8],EAX
77FACC17 FF73 04 PUSH DWORD PTR DS:[EBX+4]; exploit.__except_handler3
77FACC1A 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10]
77FACC1D 50 PUSH EAX
77FACC1E FF75 0C PUSH DWORD PTR SS:[EBP+C]
77FACC21 53 PUSH EBX
77FACC22 56 PUSH ESI
77FACC23 E8 14E60000 CALL ntdll.77FBB23C
77FBB23C BA 86B2FB77 MOV EDX,ntdll.77FBB286
77FBB241 EB 09 JMP SHORT ntdll.77FBB24C
77FBB243 90 NOP
77FBB244 BA ADB2FB77 MOV EDX,ntdll.77FBB2AD
77FBB249 8D49 00 LEA ECX,DWORD PTR DS:[ECX]
77FBB24C 55 PUSH EBP
77FBB24D 8BEC MOV EBP,ESP
77FBB24F FF75 0C PUSH DWORD PTR SS:[EBP+C]
77FBB252 52 PUSH EDX
77FBB253 64:FF35 0000000>PUSH DWORD PTR FS:[0]
77FBB25A 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
77FBB261 FF75 14 PUSH DWORD PTR SS:[EBP+14]
77FBB264 FF75 10 PUSH DWORD PTR SS:[EBP+10]
77FBB267 FF75 0C PUSH DWORD PTR SS:[EBP+C]
77FBB26A FF75 08 PUSH DWORD PTR SS:[EBP+8]
77FBB26D 8B4D 18 MOV ECX,DWORD PTR SS:[EBP+18]
77FBB270 FFD1 CALL ECX ; exploit.__except_handler3
77FBB272 64:8B25 0000000>MOV ESP,DWORD PTR FS:[0]
77FBB279 64:8F05 0000000>POP DWORD PTR FS:[0]
77FBB280 8BE5 MOV ESP,EBP
77FBB282 5D POP EBP
77FBB283 C2 1400 RETN 14
Windows SEH的整个处理并不是想象的那么简单,涉及到KiTrap/KiUserTrapHandler
发表评论 取消回复