转载文章,原文来源:https://juejin.cn/post/695413...
目录
- 链接的构成
- 浏览器如何对 URL 进行解析
- 测试的例子
- 链接只能固定格式吗?
- 链接真的只是你看到的那样吗
1. 链接的构成
- 第一部分:协议名(以单个冒号结束) ,如http、https、ftp(少见)等等
- 第二部分:用户信息 也就是账号密码!(登陆ftp时常用)
- 第三部分:主机名(也就是域名)
- 第四部分:端口
- 第五部分:查询,?号后的内容是查询!
- 第六部分:片段ID(是不会发送到服务器的!)
ftp链接:我最常用的一个,ftp://ftp.ncbi.nlm.nih.gov/genomes/refseq/ 打开访达
片段ID:倘若有个名为 example.html 的文档中包含一个 id 属性值为 myelement 的元素,那么使用 example.html#myelement 这个 URL 即可直接导航至该元素,该 URL 中的 #myelement 即称为 URL 片段标志符。简单来说就是锚点。
2. 浏览器对 URL 的解析
1. 提取协议名称
查找第一个: ,:在哪里,那 :前面的就是协议名,如果在协议中获取了不该获取的字符,那么将认为这是一个相对的 URL ,并不是一个协议名。
2. 去除层级url标记符
字符串//应该算跟在协议名后面的,如果发现有该字符 则会跳过该字符 如果没有找到便不管了!所以 http:baidu.com 也是可以访问的! 浏览器中还可以用反斜杠 \ 来代替正斜杆,firefox除外!
3. 获取授权信息部分
依次扫描url,如果这三个符号中 哪个先出现便以哪个为准来截取
/(正斜杠)、?(问号)、#(井号)
从url里提取出来的信息,就算授权部分信息!
除了IE跟safari其他浏览器还接受 ;(分号)也算授权信息部分中可接受的分隔符!
- 定位登陆信息,如果有的话:授权部分信息提取出来后,在截取出来的信息里再来查找 @ 如果找到了 那么他前面的部分便是登陆信息!登陆信息再查找 : (冒号) 冒号前面的便是账号 后面便是密码!
- 提取目标地址,授权信息部分剩下的便是目标地址了 第一个冒号分开的就算主机名跟端口!用方括号括起来的就是ipv6地址,这也是个特例!
结合以上信息 我们分析下以下链接:
ftp://admin:admin@192.168.1.100:21
这样的链接我经常用来登陆ftp!这样便会以admin的身份 密码为:admin
ftp协议去登陆主机192.168.1.100,端口号是21端口!
4. 确定路径
如果授权部分的结尾跟着一个正斜杆,某些场景里,跟着一个反斜杠或者分号,就像之前提到的,依次扫描下一个? #或字符串结尾符,那个先出现便以哪个为准!截取出来的部分就是路径信息!最后根据unix路径语义进行规范化整理!
5. 提取查询字符串
如果在上一条解析里,后面跟着的是一个问号,便继续扫描下一个 # 或到字符串结尾,哪个先出现便以哪个为准!中间的部分便是查询字符串。
6. 提取片段ID
如果成功解析完上一条信息,它最后还跟着#号 那么从这个符号到字符串的结尾便算片段ID了,片段ID是不会发送到服务器的!一般用来跳到A标签的锚链接 或者用来js的 location.hash 取值 等等!
3. 测试的例子
例子1
http://xss1.com&action=test@w...
这个链接会跳转到哪里了,我们按照上面的思路来模拟一下浏览器的解析过程。
- 解析:,解析到的前面就是协议
- 解析//,跳过
- 解析授权信息,找/,?,#,;发现都没有,那直到结尾都是授权信息
- 授权新信息查找@,前面是登录信息,xss1.com&action=test为登录信息
- 后面的就被当做主机名解析,所以跳转到了www.baidu.com
例子2
http://xss1.com\@www.baidu.com
按照 URL 的解析思路,大胆想一想这个 URL 会去哪里了?
- 解析:,解析到的前面就是协议
- 解析//,跳过
- 解析授权信息,找/,?,#,;这里就有点不一样了,一般浏览器会把 \ 转换成 / ,http://xss1.com\@www.baidu.com 也就是 http://xss1.com/@www.baidu.com 这个正常的解析也就访问搭配http://xss1.com了。但是在fire...
- 在firefox 下,找/,?,#,;发现都没有,那直到结尾都是授权信息
- 授权新信息查找@,前面是登录信息,http://xss1.com\为登录信息。
例子3
http://xss1.com;.baidu.com/
在不同的浏览器对;的处理不太一样。
一些浏览器会自动的把url纠正成http://xss1.com/;.baidu.com/
,谷歌浏览器认为这不是一个url,唤起查询引擎,safari会认为这是一个错误。
4. 链接真的只能是这样固定的格式么?
通过对浏览器对URL 解析的一个分析,我想大家都知道了,答案是:不是。
这样的
- \/www.baidu.com
- \@www.baidu.com
- \/@www.baidu.com
- \\\\www.baidu.com
///////www.baidu.com
这些链接都能正常的访问到百度。这样的
ⅅʳºℙˢ.ʷººʸⓊⁿ.ºʳℊ
再看看这个链接也是能正常解析的(虽然这个网站不存在的,但是解析是没有问题的),但是你会发现如果把上面这个链接插入到语雀、掘金、有道云笔记插入链接会出现不一样的情况。有兴趣可以尝试一下还是这样的
http://ⅅʳºℙˢ.ʷººʸⓊⁿ.ºʳℊ
上面这些奇奇怪怪的链接都能正常访问,为什么了?为什么?
这里需要提到的是针对域名的编码:Punycode。经过Punycode编码后的域名是会被DNS服务器所识别的!
举个🌰拿中文域名来说,因为操作系统的核心都是英文组成,DNS服务器的解析也是由英文代码交换,所以DNS服务器上并不支持直接的中文域名解析。 所有中文域名的解析都需要转成punycode码,然后由DNS解析punycode码。最后我们成功的访问到了我们要去网站!只不过今天我们这里 punycode编码的解析过程并不是由dns服务器来解析的 而是在浏览器访问时就给解码回来!
5. 链接真的是你看到的那样么?
先看一个例子:http://www.baidu.com@qq.com, 大家认为这个链接为跳转到哪里去,安装第二小节的解析规则很简单,跳转到qq.com。因为@前面的信息被解析成了授权信息。 所以我们这段链接为什么去qq.com 而不是去baidu.com 算因为一个@符 让浏览器认为www.baidu.com 算一段用户信息 而后面的才算主机名 他要去访问的地址。所以我们有时候如果你想伪装找不到跳转漏洞也可以如此实现!并且在谷歌、firefox你还可以这样写http:www.baidu.com@qq.com。
url地址是可以用进制来代替
在《web之困》中讲了其实url地址是可以用进制来代替的!只不过算把ip地址给转换成进制来访问!
十进制 —||||||> 十六进制 —||||||> 八进制 然后在访问时 指定协议然后加个0
http://0[八进制] 比如 115.239.210.26, 首先用.分割数字 115 239 210 26 ,然后选择10进制转换16进制!(要用0来表示前缀,可以是一个0也可以是多个0 跟XSS中多加几个0来绕过过滤一样!)。首先把这四段数字给 转成 16 进制!结果:73 ef d2 1a 然后把 73efd21a 这十六进制一起转换成8进制!,结果就是16373751032,然后指定协议 http:// 用0表示前缀 加上结果 链接:http://0016373751032。
以百度为例
百度首页 IP 14.215.177.38
- 先用 . 分割 14 215 177 38
- 将数字转换为16进制,结果是e d7 b1 26
- 将四个转换后的进制数()链接起来,转换为8进制,结果是1665730446
- 然后指定协议 http:// 用0表示前缀 加上结果,http://01665730446
- 是不是成功了?
结束语
如果文章中什么不对或者写的不好的地方,请大家多多指正,谢谢!码字不易,点个赞加个关注吧!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。