浅谈 URL 协议
By 香草
1、 URL 的构成
Scheme://login:password@address:port/path/to/resource?query_string#frag
ment
https://user:123456@www.xcao.vip/xx/x/text.php?url=www.baidu.com#mm
2、 常见验证子域名的正则表达式
/.*.xcao.vip/
我们有 100 种方法绕过它 httt://xxx.baidu.com
/^(http|https)://.*.baidu.com/
http://www.xcao.vip/?baidu.com
/^(http|https)://[0-1a-zA-Z-]*.baidu.com/
http://xxxxbaidu.com
/^(http|https)://[^.]+.baidu.com/
http://2067398186/?baidu.com
/^((http|https)://[a-zA-Zd-_*@]+.)+baidu.com/
http://[email protected]@xcao.vip
/^(http|https)://([^/?#]+.)*(baidu.com)(/|?|#|$)/
http://www.xcao.vip.baidu.com
3、 解析差异
1) 浏览器解析
http://xcao.vip/test/testhost.php
http://[email protected]@www.qq.com
chrome 和 firefox 识别为 www.qq.com,但是如果用 iframe 加载,chrome 会失
败
http://www.xcao.vipwww.baidu.com
无论是 host 还是 path 部分都转换为/
2) PHP parse_url 库解析 URL
http://123.57.254.42:80www.baidu.com/sss
会解析失败,但是不加端口,可成功
可见和浏览器解析是存在差异的,可能导致 xss 或者 jsonp 劫持问题
进一步 http://[email protected]/index.php
Pase_url 会认为 host 是 www.baidu.com 并且可以成功访问,但是浏览器认为访问的是 www.xcao.vip,这里可能造成 XSS 漏洞。
和浏览器保持一致,但是 curl 会访问失败
但是在 path 部分可以出现,并且不会被转换为/
路径中出现特殊字符,如n、空格、%00 等会被转义为_,但是 curl 不会识别,并
且在端口后面可以最最多 5 个字符,包括特殊字符,会被丢弃,如:
http://www.baidu.com:80xxx/,但是 curl 访问会失败
127.0.0.1://www.baidu.com
对于这种特殊的协议格式,就比较有意思
parse_url 识别的 host 为 www.baidu.com 但是 curl 请求会认为是 127.0.0.1,这就
可能导致问题,比如利用 parse_url 验证 host 是否为 127.0.0.1 这种内网 IP,然
后 用 curl 发 起 请 求 , 就 可 能 等 导 致 ssrf 攻 击 。 比 如 :
127.0.0.1://www.baidu.com/../index.php
这里得到的 host 是 www.baidu.com,但是 curl 实际访问的确是 127.0.0.1
3) PHP curl 请求
只接受一个@,多个@会请求失败
不能在 host 中,否则会请求失败
无法识别 IP10 进制等 IP 编码
访问 127.0.0.1://www.baidu.com/../index.php 会请求 127.0.0.1/index.php
4) C# HttpWebRequest、HttpClient 和 Uri 解析库(没有找到 URL 解析
库)
http://[email protected]@www.qq.com
无效的 URI: 未能分析主机名
在 host 部分不能出现,但是在 path 部分可以出现,并且会被转换为/
会自动把 IP10 进制转换成正常格式的 IP
这种 xcao.vip://www.baidu.com/../index.php,不带协议的写法,host 会识别为
www. baidu.com 但是 webrequest 和 httpclient 访问会失败
PS:和 parse_url 存在差异
5) Java URL、HttpURLConnection 和 URI
www.baidu.com://www.qq.com:8080/sss,URL 会报错,无法识别
protocol,但是 URI可以识别,原因是 URI是比 URL更广义的一种协议,
https://www.cnblogs.com/throwable/p/9740425.html
http://[email protected]:[email protected]
host 解析为 null,并且无法请求成功
http://[email protected]/file/flag.php
设想一种场景,java网站后台利用URL类处理获取到的url参数,解析出来url是否合法,这里得到的是www.qq.com,但是浏览器实际上识别为www.xcao.vip,这就可能导致xss问题
6) Java HttpClient
http://www.xcao.vipwww.baidu.com 和 http://[email protected]
都会解析失败
http://[email protected]@www.qq.com
httpclient4 会识别为 www.xcao.vip 和浏览器、URL 类以及 pase_url 都不同
httpclient3 会报错,端口转化错误
http://127.0.0.1:80.xcao.vip/file/flag.php
httpclient4 将会访问 127.0.0.1:80/file/flag.php 原因是为了容错,80 后面的非数
字会被丢弃,并且 host 会做一次解码,意思是
http://127.0.0.1%3a80.xcao.vip/file/flag.php 这种连接也是合法的
http://127.0.0.1%253a80%253f.xcao.vip/file/flag.php
httclient3 和 4 都会认为访问的是 127.0.0.1:80/file/flag.php,原因是 httpclient3
会对截取的 host 部分 url 解码,然后再做一次 urlpase,得到 host。这样就可以绕
过诸如/^(http|https)://([^/?#]+.)*(baidu.com)(/|?|#|$)/这样的正则,
某些场景下造成 SSRF 漏洞
再比如,程序员如果使用 URL 类来解析 URL 连接,然后判断是否合法,然后发送 httpclient
请求
这显示会存在绕过的风险顺便给出之前挑战的答案:http://xcao.vip:8080/httpclient4/Test?url=http://127.0.0.1:80xx.xcao.vip/file
/flag.php
http://xcao.vip:8080/httpclient3/Test?url=http://127.0.0.1%253a80%253f.xc
ao.vip/file/flag.php
7) 网上常见的获取 URL 中 host 部分的正则表达式
(?<=://)[a-zA-Z\.0-9]+(?=\/)
(?<=//|)((\w)+\.)+\w+
^(?:([A-Za-z]+):)?(/{0,3})([0-9.-A-Za-
z]+)(?::(d+))?(?:/([^?#]*))?(?:?([^#]*))?(?:#(.*))?$
事实证明,任何企图用正则去正确匹配 url 中的 host 都是徒劳的,因为 url 协议实际上还
是比较复杂的,大家去看一下 java 的 URL 类就知道了,总共有 1500 多行代码
8) Javascript
document.createElement('a'); 采用浏览器自带的函数解析,情况和浏览器一样
new URL(“”); 浏览器自带的函数,情况和浏览器响应一致
9) NodeJS、python、go 解析,未完待续!
4、 应用场景
1) Xss 正则绕过
http://wooyun.2xss.cc/whitehat_detail.php?whitehat=%E9%A6%99%E8%8D%
89
2) jsonp referer 限制绕过
3) SSRF 绕过
5、 总结
1)http://[email protected]@www.qq.com
这种链接 java 和 c#解析函数识别 host 为 null,php 和浏览器识别为 www.qq.com
2) http://[email protected]/index.php
这种链接 c#解析报错,java 和 PHP host 识别为 www.baidu.com,其中 php 的
curl 还可以访问成功,但是浏览器识别为 www.xcao.vip 存在 xss,jsonp 风险
3)www.qq.com://www.baidu.com/../index.php
这种链接,java 解析报错,c#和 php pase_url 识别为 www.baidu.com,但是
curl 访问又识别为 www.qq.com,存在 ssrf 风险
(127.0.0.1://www.baidu.com/../index.php)
4)http://127.0.0.1:80xx/file/flag.php
只有 java 的 httpclient4 和 php 的 curl 可以正确访问,其他的都报端口错误,
但是 curl 只需要 port 部分最多 5 个字符
5)host 编码,http://127.0.0.1%253a80%253f.xcao.vip/file/flag.php
只 有 java 的 httpclient3 和 httpclient4 可 以 正 常 访 问 , 识 别 为
127.0.0.1:80/file/flag.php
由于和香草讨论过,得到了香草的分享,感谢香草,互联网精神:人人为我,我为人人!
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论