Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to use a custom (fake) DNS resolver #240

Merged
merged 3 commits into from
Feb 3, 2020

Conversation

codyprime
Copy link
Member

When performing HTTP scans with a domain name, we want to be able to scan that domain name with the specified IP address. Currently, if a domain is specified, the IP address is ignored and we scan whatever the name resolves to.

This adds a fake resolver, that can be attached to a Dialer and cause the http connection to always return the IP address we specify. In the scanner, this also checks that the intended domain name we are about to connect to in our dialContext matches the original target domain name; if it does not, we do not attach the custom/fake resolver.

How to Test

echo 172.217.9.78,google.com | ./zgrab2 http --port 443 --use-https

This should return valid results. Replace the IP address with something like 127.0.0.1:

echo 127.0.0.1,google.com | ./zgrab2 http --port 443 --use-https

Assuming no web server is running there, it will return a failure.

This adds a custom resolver, that will always resolve to the specified
ip address.  The intended usage is for when doing name-based scans,
but have a specified IP address as well.  This will provide a resolver
that can be added to a Dialer, that will cause all DNS lookups to match
the specified IP address.
@codyprime
Copy link
Member Author

Added do-no-merge tag because this can be done cleaner via PR #241. I would move it to draft, but that doesn't seem possible. We may want patch #1 for other functionality in the future, but patch #2 can be dropped.

Copy link
Member

@dadrian dadrian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing this to #241:

I think the behavior here is objectively better, although the PR is a bit scarier.

More fundamentally, I think this exposes that ZGrab2 output and perhaps the core scan model it uses doesn't handle HTTP nicely. We try to think of HTTP redirects as part of one scan, but since they can change hosts and ports, it doesn't fit into our current output model.

From a code standpoint, it also means that we have to do stuff like this, rather than just specifying at the module level "connect to this host with these parameters", like we would if we scanned 10 hosts in an input file, rather than 10 hosts as part of a redirect.

At any rate, I'd still merge this one rather than #241.

If both an IP address and a domain are specified for a scan, have the
HTTP scanner use a fake resolver in the DialContext, so that we always
scan the intended IP and Domain name pair.

However, make sure redirects still function as normal, so only use our
fake resolver if the domain name matches the original targeted domain
name.

In addition, the custom resolver is only used if the network specified
is one that supports domain names.
@codyprime codyprime force-pushed the jcody/http-custom-resolver branch from 6955920 to 82da88e Compare January 31, 2020 19:45
@codyprime
Copy link
Member Author

Some wireshark captures:

Command: echo 172.217.0.14,google.com | ./zgrab2-jcody http --port 80 --max-redirects=3
image

Command: echo 172.217.0.14,example.com | ./zgrab2-jcody http --port 80
image

}
}
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hunk (lines 164-181) addresses the concerns @justinbastress raised, and also adds an additional check against the specified network (similar to what internetAddrList does in the go net library)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I follow -- this dialContext gets called by the HTTP lib for all redirects, and it can decide to pass in the addr as a hostname(?!):port; if the redirect is to our "pinned" host, set a custom resolver for this connection only (a subsequent redirect leads to another dialContext, another Dialer, etc). If it's to another host, we use the default resolver (but if that host redirects back to our pinned host, we are again by another call to this).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep!

fake_resolver.go Outdated Show resolved Hide resolved
@dadrian
Copy link
Member

dadrian commented Jan 31, 2020

I like this, and I think it's better than #241

@codyprime codyprime force-pushed the jcody/http-custom-resolver branch from 3361415 to 0b6845e Compare February 1, 2020 04:09
@codyprime codyprime merged commit d9885ed into master Feb 3, 2020
@codyprime codyprime deleted the jcody/http-custom-resolver branch February 3, 2020 02:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants