科普 asp.net ValidateRequest filter rule

提取了.net4.0 检验源代码如下:

 

 

 

/// 这里伪入口

/// </summary>

/// <param name=”s”></param>

/// <returns></returns>

private static bool IsDangerousString(string s)

{

//先去除 \0

s = RemoveNullCharacters(s);

int macount = 0;

return IsDangerousString(s, out macount);

}

 

/// <summary>

/// 去除字符截断

/// </summary>

/// <param name=”s”></param>

/// <returns></returns>

private static string RemoveNullCharacters(string s)

{

if (s == null)

{

return null;

}

if (s.IndexOf(‘\0’) > -1)

{

return s.Replace(“\0″, string.Empty);

}

return s;

}

 

 

 

static char[]startingChars = new char[] { ‘<‘, ‘&’ };

 

private static bool IsAtoZ(char c)

{

return (((c >=’a’) && (c <=’z’)) || ((c >=’A’) && (c <= ‘Z’)));

}

 

/// <summary>

/// 1.没有 < 和 & 一定可以

/// 2. < 后面是字母 或 ! / ? 都不可以

/// 3. & 后面 # 不可以

/// </summary>

/// <param name=”s”></param>

/// <param name=”matchIndex”></param>

/// <returns></returns>

internal static bool IsDangerousString(string s, out int matchIndex)

{

matchIndex = 0;

int startIndex = 0;

while (true)

{

int num2 = s.IndexOfAny(startingChars, startIndex);

if (num2 < 0)

{

return false;

}

if (num2 == (s.Length – 1))

{

return false;

}

matchIndex = num2;

char ch = s[num2];

if (ch !=’&’)

{

if ((ch == ‘<‘) && ((IsAtoZ(s[num2 + 1]) || (s[num2 + 1] == ‘!’)) || ((s[num2 + 1] == ‘/’) || (s[num2 + 1] == ‘?’))))

{

return true;

}

}

else if (s[num2 + 1] == ‘#’)

{

return true;

}

startIndex = num2 + 1;

}

}

 

总结

1. 不出现 < 和 & 一定是安全的

2. 只出现 < 或 & 单字符 是安全的

3. < 后出现a-Z , / , ! ,?  是不安全的

4. & 后出现# 是不安全的

5. 上述未匹配的全部是安全的

 

结合过滤规则和ie特性,就能找出一些bypass的方法,如 ie6 下

 

<~/XSS/*-*/STYLE=xss:e/**/xpression(alert(‘XSS’))>

 

参考

http://www.procheckup.com/vulnerability_manager/documents/document_1258758664/bypassing-dot-NET-ValidateRequest.pdf

评论关闭。