0b6d1d994d
fox read with io.EOF ,but the data has been returned https://github.com/zmap/zgrab2/pull/207
123 lines
5.1 KiB
Go
123 lines
5.1 KiB
Go
package fox
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"errors"
|
|
"net"
|
|
"strconv"
|
|
"strings"
|
|
"io"
|
|
|
|
"github.com/zmap/zgrab2"
|
|
)
|
|
|
|
const (
|
|
// ORIGINAL_QUERY is the hex encoding of the query that will be sent to each server.
|
|
ORIGINAL_QUERY = "666f7820612031202d3120666f782068656c6c6f0a7b0a" +
|
|
"666f782e76657273696f6e3d733a312e300a69643d693a310a686f73744e" +
|
|
"616d653d733a7870766d2d306f6d64633031786d790a686f737441646472" +
|
|
"6573733d733a3139322e3136382e312e3132350a6170702e6e616d653d73" +
|
|
"3a576f726b62656e63680a6170702e76657273696f6e3d733a332e372e34" +
|
|
"340a766d2e6e616d653d733a4a61766120486f7453706f7428544d292053" +
|
|
"657276657220564d0a766d2e76657273696f6e3d733a32302e342d623032" +
|
|
"0a6f732e6e616d653d733a57696e646f77732058500a6f732e7665727369" +
|
|
"6f6e3d733a352e310a6c616e673d733a656e0a74696d655a6f6e653d733a" +
|
|
"416d65726963612f4c6f735f416e67656c65733b2d32383830303030303b" +
|
|
"333630303030303b30323a30303a30302e3030302c77616c6c2c6d617263" +
|
|
"682c382c6f6e206f722061667465722c73756e6461792c756e646566696e" +
|
|
"65643b30323a30303a30302e3030302c77616c6c2c6e6f76656d6265722c" +
|
|
"312c6f6e206f722061667465722c73756e6461792c756e646566696e6564" +
|
|
"0a686f737449643d733a57696e2d393943422d443439442d353434322d30" +
|
|
"3742420a766d557569643d733a38623533306263382d373663352d343133" +
|
|
"392d613265612d3066616264333934643330350a6272616e6449643d733a" +
|
|
"76796b6f6e0a7d3b3b0a"
|
|
// RESPONSE_PREFIX is the prefix that will identify a Fox service.
|
|
RESPONSE_PREFIX = "fox a 0 -1 fox hello"
|
|
)
|
|
|
|
var queryBytes []byte
|
|
|
|
func init() {
|
|
var err error
|
|
queryBytes, err = hex.DecodeString(ORIGINAL_QUERY)
|
|
if err != nil {
|
|
panic("Could not decode Fox query")
|
|
}
|
|
}
|
|
|
|
// GetFoxBanner sends the static query and reads the response, filling out the logStruct with any fields that are
|
|
// present. The IsFox field will identify whether a Fox service was detected, regardless of whether an error was
|
|
// returned.
|
|
func GetFoxBanner(logStruct *FoxLog, connection net.Conn) error {
|
|
bytesWritten, err := connection.Write(queryBytes)
|
|
if bytesWritten != len(queryBytes) {
|
|
return errors.New("Unable to write all Fox query bytes...")
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
data, err := zgrab2.ReadAvailable(connection)
|
|
if err != nil && err != io.EOF {
|
|
return err
|
|
}
|
|
|
|
responseString := string(data)
|
|
output := strings.Split(responseString, string(0x0a))
|
|
|
|
if strings.HasPrefix(responseString, RESPONSE_PREFIX) {
|
|
logStruct.IsFox = true
|
|
|
|
for _, value := range output {
|
|
if strings.HasPrefix(value, "fox.version") && strings.Contains(value, ":") {
|
|
logStruct.Version = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "id") && strings.Contains(value, ":") {
|
|
id, err := strconv.ParseUint(strings.Split(value, ":")[1], 10, 32)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logStruct.Id = uint32(id)
|
|
} else if strings.HasPrefix(value, "hostAddress") && strings.Contains(value, ":") {
|
|
// TODO: What if this is IPv6? Or, more generally, what if any of these contain a colon?
|
|
logStruct.HostAddress = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "hostName") && strings.Contains(value, ":") {
|
|
logStruct.Hostname = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "app.name") && strings.Contains(value, ":") {
|
|
logStruct.AppName = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "app.version") && strings.Contains(value, ":") {
|
|
logStruct.AppVersion = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "vm.name") && strings.Contains(value, ":") {
|
|
logStruct.VMName = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "vm.version") && strings.Contains(value, ":") {
|
|
logStruct.VMVersion = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "os.name") && strings.Contains(value, ":") {
|
|
logStruct.OSName = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "os.version") && strings.Contains(value, ":") {
|
|
logStruct.OSVersion = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "station.name") && strings.Contains(value, ":") {
|
|
logStruct.StationName = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "lang") && strings.Contains(value, ":") {
|
|
logStruct.Language = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "timeZone") && strings.Contains(value, ":") {
|
|
timeZone := strings.Split(value, ":")[1]
|
|
if strings.Contains(timeZone, ";") {
|
|
timeZone = strings.Split(timeZone, ";")[0]
|
|
}
|
|
logStruct.TimeZone = timeZone
|
|
} else if strings.HasPrefix(value, "hostId") && strings.Contains(value, ":") {
|
|
logStruct.HostId = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "vmUuid") && strings.Contains(value, ":") {
|
|
logStruct.VMUuid = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "brandId") && strings.Contains(value, ":") {
|
|
logStruct.BrandId = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "sysInfo") && strings.Contains(value, ":") {
|
|
logStruct.SysInfo = strings.Split(value, ":")[1]
|
|
} else if strings.HasPrefix(value, "authAgentTypeSpecs") && strings.Contains(value, ":") {
|
|
logStruct.AuthAgentType = strings.Split(value, ":")[1]
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|