原文:https://gfw.report/blog/gfw_looking_glass/en/
一个神奇的脚本gfw-looking-glass.sh 会打印出GFW的部分内存
while true; do printf "\0\0\1\0\0\1\0\0\0\0\0\0\6wux.ru\300" | nc -uq1 $SOME_IP 53 | hd -s20; done
看过分析之后,发现真是大神,挑关键点讲为什么会出现这种情况:
首先是DNS查询包的格式如下:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| query name |
\ \
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| query type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| query class |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
关键点在于使用了DNS压缩指针进行查询,当进行正常的DNS查询www.google.com
时,它可以被以下格式所表示:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|3| www |6| google |3| com |0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
一个使用压缩指针的例子如下,www后面还跟着2字节的指针,这个指针的两个最高位为1,剩下的14位代表offset。当offset == n时,它指向整个DNS请求的n字节。
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|3| www|1|1| offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
但在如下DNS请求中,只构造了一字节指针。
\0\0\1\0\0\1\0\0\0\0\0\0\6wux.ru\300
因为GFW对压缩指针的处理不严,导致GFW将在内存中的下一个字节当作指针offset的一部分,而且他并不会检查offset是不是已经超出了DNS查询包,这样一来,就会将内存中的一部分当做你要查询的域名,所以当返回受污染的结果时,就会将该部分内存返回。