Cleans up TODOs and includes more results to collect from scans.
This commit is contained in:
parent
e46f988d28
commit
ffaeeab0f1
@ -42,6 +42,7 @@ func attributeByteString(syntaxTag byte, name string, value string) []byte {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Dynamically create nothing except uri?
|
||||||
//Construct a minimal request that an IPP server will respond to
|
//Construct a minimal request that an IPP server will respond to
|
||||||
func getPrinterAttributesRequest(uri string) bytes.Buffer {
|
func getPrinterAttributesRequest(uri string) bytes.Buffer {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
|
@ -7,9 +7,11 @@ import (
|
|||||||
//"bytes"
|
//"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
//"errors"
|
//"errors"
|
||||||
"io"
|
//"fmt"
|
||||||
|
//"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
//"net"
|
//"net"
|
||||||
//"net/url"
|
//"net/url"
|
||||||
//"time"
|
//"time"
|
||||||
@ -18,15 +20,20 @@ import (
|
|||||||
"github.com/zmap/zgrab2"
|
"github.com/zmap/zgrab2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CONTENT_TYPE string = "application/ipp"
|
||||||
|
)
|
||||||
|
|
||||||
//TODO: Tag relevant results and exlain in comments
|
//TODO: Tag relevant results and exlain in comments
|
||||||
// ScanResults instances are returned by the module's Scan function.
|
// ScanResults instances are returned by the module's Scan function.
|
||||||
type ScanResults struct {
|
type ScanResults struct {
|
||||||
Response *http.Response `json:"response,omitempty"`
|
//TODO: Include a full response or at least a blob in the data
|
||||||
|
//Response *http.Response `json:"response,omitempty"`
|
||||||
|
|
||||||
MajorVersion int8 `json:"major_version"`
|
MajorVersion int8 `json:"version_major"`
|
||||||
MinorVersion int8 `json:"minor_version"`
|
MinorVersion int8 `json:"version_minor"`
|
||||||
|
|
||||||
Version string `json:"version_string,omitempty"`
|
VersionString string `json:"version_string,omitempty"`
|
||||||
CUPSVersion string `json:"cups_version,omitempty"`
|
CUPSVersion string `json:"cups_version,omitempty"`
|
||||||
|
|
||||||
//TODO: Uncomment this when implementing the TLS version of things
|
//TODO: Uncomment this when implementing the TLS version of things
|
||||||
@ -34,35 +41,30 @@ type ScanResults struct {
|
|||||||
// TLSLog *zgrab2.TLSLog `json:"tls,omitempty"`
|
// TLSLog *zgrab2.TLSLog `json:"tls,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: We don't need this.
|
// TODO: Annotate every flag thoroughly
|
||||||
func readResultsFromResponseBody(body *io.ReadCloser) *ScanResults {
|
// TODO: Add more protocol-specific flags as needed
|
||||||
return &ScanResults{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add more protocol-specific flags
|
|
||||||
// Flags holds the command-line configuration for the ipp scan module.
|
// Flags holds the command-line configuration for the ipp scan module.
|
||||||
// Populated by the framework.
|
// Populated by the framework.
|
||||||
type Flags struct {
|
type Flags struct {
|
||||||
zgrab2.BaseFlags
|
zgrab2.BaseFlags
|
||||||
//FIXME: Borrowed from http module
|
//FIXME: Borrowed from http module
|
||||||
MaxSize int `long:"max-size" default:"256" description:"Max kilobytes to read in response to an HTTP request"`
|
MaxRead int `long:"max-size" default:"256" description:"Max kilobytes to read in response to an HTTP request"`
|
||||||
//TODO: Include once TLS is implemented
|
// TODO: Protocols that support TLS should include zgrab2.TLSFlags (do once implemented)
|
||||||
// Protocols that support TLS should include zgrab2.TLSFlags
|
// TODO: Maybe implement both an ipps connection and upgrade to https
|
||||||
|
IPPSecure bool `long:"ipps" description:"Perform a TLS handshake immediately upon connecting."`
|
||||||
|
|
||||||
Verbose bool `long:"verbose" description:"More verbose logging, include debug fields in the scan results"`
|
Verbose bool `long:"verbose" description:"More verbose logging, include debug fields in the scan results"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Figure out what moduel-global state may be necessary
|
|
||||||
// Module implements the zgrab2.Module interface.
|
// Module implements the zgrab2.Module interface.
|
||||||
type Module struct {
|
type Module struct {
|
||||||
// TODO: Add any module-global state
|
// TODO: Add any module-global state if necessary
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Figure out what scan state may be necessary
|
|
||||||
// Scanner implements the zgrab2.Scanner interface.
|
// Scanner implements the zgrab2.Scanner interface.
|
||||||
type Scanner struct {
|
type Scanner struct {
|
||||||
config *Flags
|
config *Flags
|
||||||
// TODO: Add scan state
|
// TODO: Add scan state if any is necessary
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterModule registers the zgrab2 module.
|
// RegisterModule registers the zgrab2 module.
|
||||||
@ -97,7 +99,6 @@ func (flags *Flags) Help() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Implement
|
|
||||||
// Init initializes the Scanner.
|
// Init initializes the Scanner.
|
||||||
func (scanner *Scanner) Init(flags zgrab2.ScanFlags) error {
|
func (scanner *Scanner) Init(flags zgrab2.ScanFlags) error {
|
||||||
f, _ := flags.(*Flags)
|
f, _ := flags.(*Flags)
|
||||||
@ -127,7 +128,6 @@ func (scanner *Scanner) GetPort() uint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: Maybe switch to ipp/ipps schemes, at least optionally
|
//FIXME: Maybe switch to ipp/ipps schemes, at least optionally
|
||||||
//FIXME: Stolen from http module, which isn't a good practice
|
|
||||||
func getIPPURL(https bool, host string, port uint16, endpoint string) string {
|
func getIPPURL(https bool, host string, port uint16, endpoint string) string {
|
||||||
var proto string
|
var proto string
|
||||||
if https {
|
if https {
|
||||||
@ -138,6 +138,15 @@ func getIPPURL(https bool, host string, port uint16, endpoint string) string {
|
|||||||
return proto + "://" + host + ":" + strconv.FormatUint(uint64(port), 10) + endpoint
|
return proto + "://" + host + ":" + strconv.FormatUint(uint64(port), 10) + endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ippInContentType(resp http.Response) bool {
|
||||||
|
for _, t := range resp.Header["Content-Type"] {
|
||||||
|
if strings.Contains(t, CONTENT_TYPE) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Doesn't support TLS at all right now
|
//TODO: Doesn't support TLS at all right now
|
||||||
func (scanner *Scanner) grab(target zgrab2.ScanTarget) (int8, int8, *zgrab2.ScanError) {
|
func (scanner *Scanner) grab(target zgrab2.ScanTarget) (int8, int8, *zgrab2.ScanError) {
|
||||||
//FIXME: This is not where this hostname assignment logic should live
|
//FIXME: This is not where this hostname assignment logic should live
|
||||||
@ -145,25 +154,31 @@ func (scanner *Scanner) grab(target zgrab2.ScanTarget) (int8, int8, *zgrab2.Scan
|
|||||||
if host == "" {
|
if host == "" {
|
||||||
host = target.IP.String()
|
host = target.IP.String()
|
||||||
}
|
}
|
||||||
//TODO: Make https bool depend on scanner's config
|
//FIXME: ?Should just use endpoint "/", since we get the same response as "/ipp" on CUPS??
|
||||||
//TODO: ?Shouldn't put any endpoint, since we get the same response w/o on CUPS??
|
uri := getIPPURL(scanner.config.IPPSecure, host, uint16(scanner.config.BaseFlags.Port), "/ipp")
|
||||||
uri := getIPPURL(false, host, uint16(scanner.config.BaseFlags.Port), "/ipp")
|
|
||||||
b := getPrinterAttributesRequest(uri)
|
b := getPrinterAttributesRequest(uri)
|
||||||
resp, err := http.Post(uri, "application/ipp", &b)
|
resp, err := http.Post(uri, CONTENT_TYPE, &b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//FIXME: Create a descriptive error
|
//TODO: Create a descriptive error
|
||||||
return 0, 0, zgrab2.NewScanError(zgrab2.SCAN_UNKNOWN_ERROR, err)
|
return 0, 0, zgrab2.NewScanError(zgrab2.SCAN_UNKNOWN_ERROR, err)
|
||||||
}
|
}
|
||||||
if resp != nil && resp.Body != nil {
|
if resp != nil && resp.Body != nil {
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
} else {
|
} else {
|
||||||
//FIXME: Determine whether we need this error to avoid reading from Body
|
//TODO: Determine whether we need this error to avoid reading from Body
|
||||||
return 0, 0, zgrab2.NewScanError(zgrab2.SCAN_UNKNOWN_ERROR, err)
|
return 0, 0, zgrab2.NewScanError(zgrab2.SCAN_UNKNOWN_ERROR, err)
|
||||||
}
|
}
|
||||||
//FIXME: Maybe add something to handle redirects
|
//FIXME: Maybe add something to handle redirects
|
||||||
//FIXME: Probably return the whole response for further inspection, rather
|
//FIXME: Probably return the whole response for further inspection by ztag, rather
|
||||||
// than grabbing first 2 bytes. In that case, probs instate maxRead like http
|
// than grabbing first 2 bytes. In that case, implement maxRead like http module
|
||||||
//FIXME: Check to make sure that the response is actually IPP
|
|
||||||
|
//Check to make sure that the repsonse received is actually IPP
|
||||||
|
//Content-Type header matches is sufficient
|
||||||
|
//HTTP on port 631 is sufficient
|
||||||
|
//Still record data in the case of protocol error to see what that data looks like
|
||||||
|
|
||||||
|
//TODO: Record server-header version numbers
|
||||||
|
//protocols := resp.Header["Server"])
|
||||||
var version int16
|
var version int16
|
||||||
if err := binary.Read(resp.Body, binary.BigEndian, &version); err != nil {
|
if err := binary.Read(resp.Body, binary.BigEndian, &version); err != nil {
|
||||||
return 0, 0, zgrab2.NewScanError(zgrab2.SCAN_UNKNOWN_ERROR, err)
|
return 0, 0, zgrab2.NewScanError(zgrab2.SCAN_UNKNOWN_ERROR, err)
|
||||||
@ -172,17 +187,16 @@ func (scanner *Scanner) grab(target zgrab2.ScanTarget) (int8, int8, *zgrab2.Scan
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Scan TODO: describe how scan operates
|
// Scan TODO: describe how scan operates
|
||||||
//1. FIXME: Don't open connection, because we don't need it?
|
//1. Send a request (currently get-printer-attributes)
|
||||||
//2. Send something (currently get-printer-attributes)
|
//2. Take in that response & read out version numbers
|
||||||
//3. Take in that response & read out version numbers
|
|
||||||
func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error) {
|
func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error) {
|
||||||
// TODO: implement
|
// TODO: use Connection again, at least when implementing TLS
|
||||||
major, minor, err := scanner.grab(target)
|
major, minor, err := scanner.grab(target)
|
||||||
//FIXME: Triggering even though error IS nil
|
//FIXME: Triggering even though error IS nil
|
||||||
//FIXME: This is a sloppy bodge to handle the issue, since you must know implementation details below you
|
//FIXME: This is a sloppy bodge to handle the issue
|
||||||
if major == 0 && minor == 0 && err != nil {
|
if major == 0 && minor == 0 && err != nil {
|
||||||
//TODO: Consider mimicking HTTP Scan's retryHTTPS functionality
|
//TODO: Consider mimicking HTTP Scan's retryHTTPS functionality
|
||||||
//TODO: Create relevant error, or send something more descriptive?
|
//TODO: Create more detailed error message?
|
||||||
return zgrab2.TryGetScanStatus(err), nil, err
|
return zgrab2.TryGetScanStatus(err), nil, err
|
||||||
}
|
}
|
||||||
results := &ScanResults{}
|
results := &ScanResults{}
|
||||||
|
@ -9,7 +9,11 @@ import zgrab2
|
|||||||
|
|
||||||
ipp_scan_response = SubRecord({
|
ipp_scan_response = SubRecord({
|
||||||
"result": SubRecord({
|
"result": SubRecord({
|
||||||
"test_key": String(doc="FIXME: Remove this")
|
"version_major": Signed8BitInteger(),
|
||||||
|
"version_minor": Signed8BitInteger(),
|
||||||
|
"version_string": String(),
|
||||||
|
"cups_version": String(),
|
||||||
|
#"tls": zgrab2.tls_log,
|
||||||
})
|
})
|
||||||
}, extends=zgrab2.base_scan_response)
|
}, extends=zgrab2.base_scan_response)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user