0515-Browser Security-超文本标记语言(HTML)

# Browser Security-超文本标记语言(HTML)

#### 重要的4个规则:

“`
1 &符号不应该出现在HTML的大部分节点中。
2 尖括号<>是不应该出现在标签内的,除非为引号引用。
3 在text节点里面,<左尖括号有很大的危害。 4 引号在标签内可能有危害,具体危害取决于存在的位置,但是在text节点是没有危害的。 ``` #### 文件解析模式 在任何HTML文档中,最开始的``用来指示浏览器需要解析的方式,同样也可使用`Content-Type`头来告诉浏览器。

一般情况下,浏览器中的解析器会尝试恢复大多数类型的语法错误,包括开始和结束标记。

在XML中,是非常严格的,所有标签必须有对应的开始关闭,也可以有自动关闭如也是允许的。

#### 了解HTML解析

[![](http://static.wooyun.org/20140918/2014091812393789842.jpeg)](http://static.wooyun.org/20141017/2014101716205670084.jpeg)

在IE浏览器中允许在1中插入NUL字符(0x00),可以绕过非常多的xss过滤器。

如下php代码可把NUL字符插入标签内做测试:

2和4中的空格也可以由tab(0x0B)与换页键(0x0C),2处也可以用/来代替。

5中的”在IE中也可替换成`。

IE当中还有一个特性是当遇到=后面紧跟一个引号的时候会有奇怪的解析。

“`
图片[1]-0515-Browser Security-超文本标记语言(HTML)-棉花糖会员站Yes, we are still inside a tag!”>

“`

#### Entity编码

HTML解析器在建立文档树的时候会针对节点内的Entity编码解码后传输。

以下两个表示相同:

“`
图片[2]-0515-Browser Security-超文本标记语言(HTML)-棉花糖会员站

“`

下面两个例子代码不会执行,因为,编码的是标签本身的结构而非节点内的内容:

“`
图片[3]-0515-Browser Security-超文本标记语言(HTML)-棉花糖会员站

“`

#### Fuzzing

对一个普通的HTML进行Fuzzing测试:

“`
Click me

“`

看一下可以Fuzzing的位置

| 位置 | 代码 | 可能插入或替代的代码 |
| — | — | — |
| <的右边 | `<[here]a href="...` | 控制符,空白符,非打印字符 | | a标签的后门 | `` | 其他引号 |
| >之前 | `` | 任意字符 |
| /之前 | `
…<[here]/a>` | 空白符,控制符 |
| /之后 | `
` | 空白符,控制符 |
| >闭合之前 | `
…` | 所有字符 |

可以使用php代码进行快速测试,例如我们对第一个位置(<的右边)进行Fuzzing: ``` <'.$character.'a href="http://www.google.com/">‘.$i.’

‘; }
?>

“`

上面的代码只测试了256个字符,如果想要测试Unicode的所有字符,则需要创建65536个链接。

php默认字符是ISO-8859-1作为默认的字符编码,而这种编码只有256个字符,所以单纯的循环65536遍是没用的。

所以采用Entity编码方式循环,解码后输出:

“`
<'.$character.'a href="http://www.google.com/">‘.$i.’

‘;
}?>

“`

有一个有趣的现象是几乎所有浏览器对`$#33;`即`!`,浏览器会`33

“`

##### 针对标签名的Fuzzing:

“`
click me

“`

上面的代码,在Chrom、Firefox和Safari中点击,可以顺利弹出1。

讨论一下空字符的问题,IE浏览器会自动忽略空字符,并解析剩下的代码,这样会绕过很多采用正则匹配黑名单字符串的过滤器。

并且,很多函数和库并没有意识到这个问题:

“`
‘;
?>

“`

用IE8打开上述代码的网页,查看源代码只能看到”\r\n”;
} ?>

“`

代码很简单,设置返回响应字符集为Shift_JIS,然后把utf-8转换为Shift_JIS字符集。

可以看到在IE中129-159和224-252中,123456中的1消失了,与前面的字符合并成一个字符了。

标签后面也可加入/符号做间隔:

“`

“`

尝试在标签与/之间再插入其他字符来测试,由于空字符无法直观显示,所以用\0来表示null,同样主流浏览器都可以执行:

“`

“`

再尝试ASCII码之外的字符,这种字符在正则表达式中\w是无法匹配到的,主流浏览器都可以执行:

“`

“`

测试发现,标签名与属性名直接只要是以/开头以/或”结尾,中间几乎可以插入任意字符。

在Fuzzing属性方面,考虑两方面,一个是可以使用什么分隔符,一个是属性值可以采用什么编码。

分隔符有很多种,单引号,双引号,无任何引号,反撇号(IE中)。

“`
‘.$i.’

‘;
} ?>

“`

上面代码可以直观的看出当前浏览器支持的分隔符有哪些字符。

上面代码size属性如果输入的是字符的话,会顺利执行,所以当$character中循环到数字的时候也会顺利解析,但这并非是把数字当成了分割符:

“`

‘;
} ?>

“`

以上代码可以看出,属性为字符串的时候,可以作为分隔符的字符。

为了表示那些不可打印的字符,就用`\x十六进制`来表示:

“`
图片[4]-0515-Browser Security-超文本标记语言(HTML)-棉花糖会员站

“`

以上代码\x17即表示不可打印字符chr(23),浏览器提交的时候可以输入%3Cimg%20src%3D%17%17%20onerror%3Dalert%281%29%2f%2f%3E。

在src中可以正常工作的分隔字符,在处理事件的属性里不一定会工作,例如onerror。

但是仍然有一些字符可以达到我们的目的,ASCII表中的133和160已经IE中的空字符,甚至是分号。

“`

“`

以上代码urldecode之后在chrome中可以顺利执行。

下面讨论多个标签的问题,比如用户可控的数据插入到了``标签中,同时过滤了`<>`只能插入标签内数据:

“`

“`

绿色部分是我们插入的数据,又插入了一个type属性,但是浏览器执行了alert(),浏览器实际上会执行第一个属性,后面的会忽略掉。

在IE中还有一个lowsrc的属性,跟src类似,原本是为了方便调用一个缩略图的,但是在IE6和IE7中,同时也支持伪协议javascript:,还有一个dynsrc属性也类似:

“`
图片[5]-0515-Browser Security-超文本标记语言(HTML)-棉花糖会员站 // 所有IE都支持
图片[6]-0515-Browser Security-超文本标记语言(HTML)-棉花糖会员站 //IE6和IE7支持
图片[7]-0515-Browser Security-超文本标记语言(HTML)-棉花糖会员站 // 只有IE6支持

“`

sytle属性中还可以定义非常多的参数:

“`
foobar

“`

上面代码可以看到,浏览器显示的字体为红色,背景为黄色,除了定义颜色之外也可以用expression()执行js,后面会讨论。

还有一个属性是专门用来在一个标签中插入多个的:xmlns,XML的命名空间属性,这个后面会在XML中讨论。

还有一处可Fuzzing的点即为标签的关闭,一个有趣的现象是浏览器把`
`与`
`,`

`与`

`成完全一样。

“`
foobar // 不会执行alert
foo bar // IE执行了alert

```

也有利用标签中的属性来执行js,例如:onclick,onload,onerror等等。

在iframe标签中,不需要src属性就可以顺利执行onload属性,而img标签不可以。

这是因为在iframe中没有src属性的时候,浏览器会自动加载about:blank页面,即空白页。

附件tag.php可以方便的看到当前浏览器针对各标签在不需要用户交互的情况下,可以自动执行的所有属性。

[tag-event.php](http://static.wooyun.org/20141017/2014101716205735611.zip)

从输出结果可以看到body标签支持非常多的属性可以在与用户没有交互的情况下执行js。

例如load,error事件,所有的mouse和keyboard事件,以及在用户离开时的blur事件,还有unload和beforeunload,以及大家很少知道的pageshow属性。

同样标签中也有很少遇到的marquee标签:

```

```

在Chrome中,html标签也可以执行非常多的属性,,同源frameset标签也接受focus和blur事件。

一个很有趣的例子是,让scroll事件可以无交互触发,我们可以引入一个锚点,例如:

``或者通过id属性`

`

那我们可以访问http://test.com/test.html#bottom来访问,浏览器自动滚到该锚点,触发scroll属性。

```

some text


```

1.html为以上代码,访问1.html#bottom会自动触发onscroll事件。

IE中hr标签中的onresize属性,在当前窗口大小变化时,会触发resize事件,执行alert(1)。

```


```

还有非常多的组合可以在IE中使用,很难全部列出来,只列举出几个很少见的例子:

```







X

```

从IE5.5到IE8中,除了expression可以用来执行JavaScript之外,也可以通过HTML+TIME的形式。

这种方式唯一的缺点就是也需要一个事件来执行JavaScript,即onbegin或者onend:

```
1

```

还有一种方式利用set标签:

```
1

```

测试一下style属性中在哪些浏览器中,可以插入哪些字符:

```
'.dechex($i).'['.$chr.']';
} ?>

```

从测试结果可以得出,下面的代码可以在IE中执行:

```

```

在一些老版本的IE中,如IE6和IE7,还可以通过背景相关属性调用javascript的URL来执行javascript代码:

```
xxx
xxx
xxx
xxx

```

通过link标签(在IE6下适用,同时javascript可以换成vbscript):

```

```

style标签中可以通过导入url的方式执行javascript:

```

```

HTML5中增加了很多标签跟属性,列举一些可执行JavaScript的方法:

```

//Opera支持

```

onfocus与autofocus的配合:

```