In this post, we are looking at what the packets look like when unencrypted HTTP basic authentication is targeted.
First up, let's see what types of packets are in the PCAP
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -q -z io,phs =================================================================== Protocol Hierarchy Statistics Filter: sll frames:3162 bytes:1168718 ip frames:3162 bytes:1168718 tcp frames:3162 bytes:1168718 vssmonitoring frames:870 bytes:53940 http frames:570 bytes:207928 data-text-lines frames:285 bytes:121331 tcp.segments frames:285 bytes:121331 ===================================================================
From above, we see about 570 frames are HTTP.
First let's identify the HTTP version:
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -T fields -e http.request.version -E header=y | sort | uniq --count | sort --numeric --reverse 2877 285 HTTP/1.1 1 http.request.version
Now that we know the version is HTTP/1.1, let's see the types of HTTP methods being used in this PCAP. The idea is since, we know we are analyzing HTTP, then there is more than likely going to be a method of GET, POST, etc.
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -T fields -e http.request.method | sort | uniq --count | sort --numeric --reverse 2877 285 POST
Now that we know above the method is PUT, let's now see the host and URI which was accessed.
To see the host being accessed and the source, we execute:
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -T fields -e ip.src -e http.host -E header=y | sort | uniq --count | sort --numeric --reverse 1452 192.168.0.4 1425 10.0.2.15 285 10.0.2.15 lab.securitynik.local 1 ip.src http.host
Let's learn a little bit more about the source. Maybe we look at the User-Agent:
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -T fields -e ip.src -e http.user_agent | sort | uniq --count | sort --numeric --reverse 1452 192.168.0.4 1425 10.0.2.15 285 10.0.2.15 Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html) 1 ip.src http.user_agent
Looks like the device at 10.0.2.15 is using NMAP to target our host at lab.securitynik.local.
So at this point, we know the HTTP version, the source IP, the destination being targeted and the user agent of the device attacking us. Let's now identify the URI which is being targeted.
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -T fields -e http.request.uri -E header=y | sort | uniq --count | sort --numeric --reverse 2877 285 /lab/webapp/basicauth 1 http.request.uri
We now know that "POST" method was used against the URI above. Let's take a glance at the server responses. While the request being made is good to know, we are more interested in the server response.
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -T fields -e http.response.code | sort | uniq --count | sort --numeric --reverse 2877 284 401 1 200
Above we see 284, "401" errors status codes and 1 "200" status code. Seems strange.
Researching error status code 401, RFC 2616 identifies this status code as "Unauthorized". The RFC further states this "request requires user authentication". It also states that "the response MUST include a WWW-Authenticate header field"
Let's verify this WWW-Authenticates header exist.
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -T fields -e http.www_authenticate | sort | uniq --count | sort --numeric --reverse 2878 284 Basic realm="SecurityNik Realm!"
Looks like it does. Would it be safe now to conclude that the user failed authentication 284 times and then ultimately was successful with that 1 "200" status code.
Taking a look at the Authorization requests being made:
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -T fields -e http.authorization | sort | uniq --count | sort --numeric --reverse | more 2878 1 Basic YWRtaW46YXNzYXM= 1 Basic YWRtaW46YXNzYWQ= 1 Basic YWRtaW46YXNzYWE= 1 Basic YWRtaW46YXNhZHM= 1 Basic YWRtaW46YXNhZGQ= 1 Basic YWRtaW46YXNhZGE= 1 Basic YWRtaW46YXNhYXM= 1 Basic YWRtaW46YXNhYWQ= 1 Basic YWRtaW46YXNhYWE= ....
Looks like lots of Basic Authorization. Since the above looks like base 64 encoded content, let's continue to use TShark to find the actual credentials being used.
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -T fields -e http.authbasic | sort | uniq --count | sort --numeric --reverse | more 2878 1 nick:sssss 1 nick:ssssd 1 nick:ssssa 1 nick:sssds 1 nick:sssdd 1 nick:sssda 1 nick:sssas 1 nick:sssad 1 nick:sssaa ....
Looks like a password based attack with the username being "nick" and the password changing as show above.
Let's now take a look at the one entry which has status code "200" to see what we get. Because there are a number of packets in this PCAP and the fact that the packet with "200 OK" implies success, let's extract the source IP, source port, destination IP, destination port and the stream number. The stream number we will later use.
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -Y "(http.response.code == 200)" -T fields -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport -e tcp.stream -E header=y ip.src tcp.srcport ip.dst tcp.dstport tcp.stream 192.168.0.4 80 10.0.2.15 35028 60
With above, we can now follow the TCP stream. This allows us to see the full session. Most importantly, it allows us to see the full client request.
=================================================================== kali@securitynik:~$ tshark -r nmap-http-brute.pcap -Y "(http.response.code == 200)" -T fields -e ip.src -e tcp.srcport -z follow,tcp,ascii,192.168.0.4:80,10.0.2.15:35028 | more 192.168.0.4 80 =================================================================== Follow: tcp,ascii Filter: ((ip.src eq 192.168.0.4 and tcp.srcport eq 80) and (ip.dst eq 10.0.2.15 and tcp.dstport eq 35028)) or ((ip.src eq 10.0.2.15 and tcp.srcport eq 35028) and ( ip.dst eq 192.168.0.4 and tcp.dstport eq 80)) Node 0: 10.0.2.15:35028 Node 1: 192.168.0.4:80 248 POST /lab/webapp/basicauth HTTP/1.1 User-Agent: Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/n se.html) Host: lab.securitynik.local Content-Length: 0 Authorization: Basic YWRtaW46YWFkZGQ= Connection: close 2840 HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Cache-Control: no-cache X-Cloud-Trace-Context: 96b68704d4489f3c80ee15e704876ce5 Date: Sun, 31 May 2020 01:24:00 GMT Server: Google Frontend Accept-Ranges: none Content-Length: 3827 Via: HTTP/1.1 forward.http.proxy:3128 Connection: close ..................
Awesome! At this point, we see "Authorization: Basic YWRtaW46YWFkZGQ=". We can now use TShark to find this packet. Alternatively, we can easily plug this value into an online base64 decoder to find the result.
Let's take a bit of Python for this.
kali@securitynik:~$ python -c "import base64;print(base64.decodestring('YWRtaW46YWFkZGQ='))" admin:aaddd
Let's now wrap this up by looking at the time this activity started.
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -Y '((http) && (ip.src == 10.0.2.15) && (http.request.method == POST) && (http.request.uri == http.request.uri == "/lab/webapp/basicauth"))' -t ad | more 28 2020-05-30 21:23:57.541751 10.0.2.15 → 192.168.0.4 HTTP 265 POST /lab/w ebapp/basicauth HTTP/1.1 50 2020-05-30 21:23:57.715894 10.0.2.15 → 192.168.0.4 HTTP 300 POST /lab/w ebapp/basicauth HTTP/1.1 52 2020-05-30 21:23:57.716791 10.0.2.15 → 192.168.0.4 HTTP 304 POST /lab/w ebapp/basicauth HTTP/1.1 54 2020-05-30 21:23:57.717297 10.0.2.15 → 192.168.0.4 HTTP 304 POST /lab/w ebapp/basicauth HTTP/1.1 56 2020-05-30 21:23:57.717872 10.0.2.15 → 192.168.0.4 HTTP 304 POST /lab/w ebapp/basicauth HTTP/1.1 58 2020-05-30 21:23:57.719344 10.0.2.15 → 192.168.0.4 HTTP 304 POST /lab/w ebapp/basicauth HTTP/1.1 .... 3097 2020-05-30 21:24:02.422018 10.0.2.15 → 192.168.0.4 HTTP 304 POST /lab/w ebapp/basicauth HTTP/1.1 3098 2020-05-30 21:24:02.422234 10.0.2.15 → 192.168.0.4 HTTP 304 POST /lab/w ebapp/basicauth HTTP/1.1 3099 2020-05-30 21:24:02.422609 10.0.2.15 → 192.168.0.4 HTTP 304 POST /lab/w ebapp/basicauth HTTP/1.1 3100 2020-05-30 21:24:02.422823 10.0.2.15 → 192.168.0.4 HTTP 304 POST /lab/w ebapp/basicauth HTTP/1.1 3101 2020-05-30 21:24:02.423343 10.0.2.15 → 192.168.0.4 HTTP 304 POST /lab/w ebapp/basicauth HTTP/1.1 3102 2020-05-30 21:24:02.423554 10.0.2.15 → 192.168.0.4 HTTP 304 POST /lab/w ebapp/basicauth HTTP/1.1
From above we can conclude this activity started on May 30, 2020 at 21:23:57 local time.
Looking at the time the time the login was successful from the server perspective, we see:
kali@securitynik:~$ tshark -r nmap-http-brute.pcap -Y '((http) && (ip.dst == 10.0.2.15) && (http.response.code == 200))' -t ad 741 2020-05-30 21:23:58.779688 192.168.0.4 → 10.0.2.15 HTTP 1347 HTTP/1.1 200 OK (text/html)
At this point we can say the successful login occurred within a second of of the initial attempt.
Ok At this point I believe we are good to go with detecting the issue.
References: