怎么上网了.LookupIP是否适用于Base 8(八进制)



SSRF vul应禁止本地ip请求。怎么上网了。LookupIP是否适用于Base 8(八进制)

#go code
net.LookupIP("0177.0.0.01") // NOT_OK  0177.0.0.01
net.LookupIP("0266.075.0310.07") // OK 182.61.200.7
#shell
ping 0177.0.0.01 //OK 127.0.0.1
ping 0266.075.0310.07 // OK 182.61.200.7
input http:address to chrome is the same as ping ,but go not stablize

调试快照img net。LookupIP("0177.0.0.01")没有解码Base8

调试快照img ping 0177.0.0.01在shell中具有解码Base8

调试快照img net。LookupIP("0266.075.0310.07")具有解码Base8

问题

我认为你不能这样做,原因很简单:IPv4地址的CCD_;点小数";(或"点式十进制")是有原因的:表示地址八位字节的数字是十进制格式的;特殊修饰语"--如0x00o等,使其成为";非十进制";允许。

我倾向于认为ping可以用八进制中的一些八位字节来解析地址,这是其实现中的一些奇怪的假象;例如,它还解析十六进制:

$ ping 0xAB.0.0.0x01
PING 0xAB.0.0.0x01 (171.0.0.1) 56(84) bytes of data.
^C

还要注意,不存在";标准CCD_ 6工具":任何操作系统都可以有它的任何实现;例如,Windows上可用的ping与典型的基于GNU/Linux的操作系统上的ping肯定没有共享源代码,而且这可能与追溯到*BSD的系统上可用的ping实现不同。

为了进一步说明我的观点,请考虑A.B.C.D0:

$ host -t PTR 0177.0.0.01
Host 0177.0.0.01 not found: 3(NXDOMAIN)

正如你所看到的,这个工具无法应对领先的0s。

因此,我认为合理的假设是,net.LookupIP(以及net.ParseIP)肯定不能因为不支持";八进制";当它们解析IPv4地址的点小数表示时。

可能的解决方案

可能的解决方案取决于你真正想要的是什么。如果你必须接受IP地址作为字符串;虚线不那么十进制";格式,我建议编写一个简单的自定义解析器;预处理";在对字符串调用CCD_ 14之前。

这样的预处理器将拆分字符串,并尝试解析每个八位字节,然后将地址组装回来
Go在其标准库中有strconv.ParseInt,它接受"基本";参数,告诉它构成要解析的字符串表示的数字是哪个基数,如果你把0作为基数,函数会使用通常的启发式方法来猜测基数;特别是,前面的0向基站8发出信号——正如你所希望的那样。

所以,我们可以推出这样的东西:

package main
import (
"errors"
"fmt"
"net"
"strconv"
"strings"
)
func normalizeIPv4Addr(s string) (string, error) {
parts := strings.SplitN(s, ".", 4)
if len(parts) != 4 || strings.IndexByte(parts[3], '.') != -1 {
return "", errors.New("invalid IPv4 address: invalid number of octets")
}
var dst [4]byte
for i, p := range parts {
n, err := strconv.ParseInt(p, 0, 8)
if err != nil {
return "", fmt.Errorf("invalid IPv4 address: invalid octet %d: %s", i+1, err)
}
if n < 0 || 255 < n {
return "", fmt.Errorf("invalid IPv4 address: invalid octet %d: out of range", i+1)
}
dst[i] = byte(n)
}
return net.IP(dst[:]).String(), nil
}
func main() {
fmt.Println(normalizeIPv4Addr("0177.0.0.01"))
}

游乐场。

最新更新