This is a short write up of a old flaw I reported to Cisco years ago to which they replied it’s that they see no issue there.
When doing a security audit at a client I stumbled upon a Cisco-WSA/11.5.2-020 appliance filtering HTTP traffic. As it’s the first encounter for me with sucha device, the first thing that came to my mind when seeing that header in HTTP responses was, how can I abuse this. As it turns out I actually could abuse it.
It is a small corporate network with a few different segments separated by a firewall with a really strict access policy. Client computers don’t have access to the management network only access to specific internal applications and the internet.
All internet bound HTTP requests are sent by the firewall to the Cisco WSA by using “policy based routing”. that client computers network from which all internet HTTP traffic gets redirected to the Cisco WSA by the firewall.
The clients firewall was blocking access to their management network from the users segment as it should. But I was able to bypass the firewall rules by adding a extra header to HTTP requests and effectively map all the hosts in their management network. As it turned out they had too much trust in their Cisco appliance and firewall rule set and thought you don’t need to create “deny to internal” rules on the WSA. But that provided them with a false sense of security.
In the case of this setup, when you add a extra “Host: x.x.x.x” header the firewall wont know the true connection destination thus won’t be able to actually do it’s job. As it will see your computer connecting to the IP address of the original query destination. At the same time the Cisco WSA device ignores the connection that your firewall thinks you are opening actually establishes a connection to the secondary host header. That effectively bypasses your firewall policy giving and purely relies on what policies you have set in the WSA. An example from the notes I have from that time:
C:\>curl -kv http://google.com --header host:"192.168.90.1"
* Rebuilt URL to: http://google.com/
* Trying 126.96.36.199...
* TCP_NODELAY set
* Connected to google.com (188.8.131.52) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.55.1
> Accept: */*
< HTTP/1.1 301 Moved Permanently
< Location: https://192.168.90.1/
< Transfer-Encoding: chunked
< Date: Mon, 23 Aug 2021 12:16:19 GMT
< Via: 1.1 wsa.ent.int:80 (Cisco-WSA/11.5.2-020)
< Connection: close
* Closing connection 0
As you can see, I originally queried google.com, but WSA actually returned to me the HTTP response from an internal host. In that case it was the management network where the WSA management interface resides. Using that “Host” header, I could map their whole network. When the IP address I chose didn’t have a listening tcp port 80, then the connection was closed, when it existed it returned the HTTP page/response from the hidden server or when the host didn’t exist it timed out.
Although this looks bad, then it gets worse.. At least for that client. In their case they actually had a switch that had it’s web management over HTTP open and with default credentials. It turned out it was the same switch I was connected to, so I was able to reconfigure the port where I was connected to be directly in the management network.
Although most of the things that I reported to the client probably could have been avoided by having changed their switch admin password and having also a strict “deny all inbound HTTP” traffic from that specific user segment rule on the WSA (not sure, if it would have triggered). Then still in my honest opinion the fact that the WSA device actually connects to the added host header, while all other devices in the connection chain see that the client is going to some innocent place is just wrong. Probably a lot of implementations can fall victim to this oversight in the policy as normal policy testing will never find such a loop hole.. When directly trying hidden/internal hosts you get time outs, when you add them to the header “voila it works..”.