SSRF应禁止本地ip请求。net.LookupIP如何与基础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
发布于 2022-07-13 19:13:46
问题所在
我认为您不能这样做是因为一个简单的原因:A.B.C.D格式的IPv4地址被称为“小数点” (或“虚线-小数点”)是有原因的:表示地址八进制的数字是十进制格式,并且不允许使用“特殊修饰符”-such作为0x、0、0o等,以使其“不小数”。
我倾向于认为,ping可以用八进制来解析地址,这是它实现的一些奇怪的假象;例如,它还解析了十六进制:
$ ping 0xAB.0.0.0x01
PING 0xAB.0.0.0x01 (171.0.0.1) 56(84) bytes of data.
^C还要注意的是,没有所谓的“标准ping工具”:任何操作系统都可以有它的任何实现;例如,在ping上可用的ping绝对没有与一个典型的基于GNU/Linux的操作系统上可用的ping共享源代码,而且它可能与追踪其传统到*BSD的系统上的ping实现不同。
为了进一步说明我的观点,请考虑host
$ host -t PTR 0177.0.0.01
Host 0177.0.0.01 not found: 3(NXDOMAIN)正如您所看到的,这个工具无法处理领先的0。
因此,我认为,假设net.LookupIP (以及net.ParseIP )在解析IPv4地址的小数点表示时不支持“八进制”这一事实是明智的。
可能的解决办法
可能的解决办法取决于你到底想要什么。如果您必须将IP地址接受为这样一种“点对点-不那么十进制”格式的字符串,我建议编写一个简单的自定义解析器,在调用字符串之前对字符串进行“预处理”。
这样的预处理器将拆分字符串并尝试解析每个八进制,然后重新组装地址。
Go的标准库中有strconv.ParseInt,它接受" base“参数,告诉它形成要解析的字符串表示的数字是哪一个,如果传递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"))
}游乐场。
https://stackoverflow.com/questions/72966895
复制相似问题