Tuesday, December 12, 2023

Beginning Nikto - Scanning for interesting files seen in the logs

The idea of this series, is to use Nikto to learn about common vulnerabilities in web services. Once those vulnerabilities are identified, we will then attempt to exploit them where possible. As I work in a SOC, we have to be prepared to detect. As a result, we will analyze logs, packets (Tshark), IDS (Suricata) and Zeek data. This is all in the spirit of hack and detect.

We will attempt to learn some of the different evasion techniques used by Nikto throughout this series, as we go through the 10 different "Tuning" strategies.

The web server I will be targeting is Dam Vulnerable Web App (DVWA).

In this first post within this series, we will leverage Nikto to find "interesting files" on the web server. 


Hack "Interesting File / Seen in logs"

Let's assume we did reconnaissance on the host and identified that port 80 is opened and offering web service. With that knowledge, lets' see if what we can learn about interesting files on the system.

First run Nikto without any type of evasions.

┌──(kali㉿securitynik)-[~/nikto_stuff]
└─$ nikto -host http://10.0.0.106 -ipv4 -Display 1 --ask no -Format json \
-o /tmp/nikto.json -nossl -no404 -Tuning 1
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP:          10.0.0.106
+ Target Hostname:    10.0.0.106
+ Target Port:        80
+ Start Time:         2023-05-11 16:08:10 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28
...
+ /: HTTP TRACE method is active which suggests the host is vulnerable to XST. See: https://owasp.org/www-community/attacks/Cross_Site_Tracing
+ /img/: Directory indexing found.
+ /img/: This might be interesting.
...
+ 2596 requests: 0 error(s) and 8 item(s) reported on remote host
+ End Time:           2023-05-11 16:08:16 (GMT-4) (6 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

Above, the host at 10.0.0.106 was targeted via IPv4. We will also write the content out to a file and disable SSL. At the same time, don't show the 404 messages and most importantly, use option "Tuning 1".

Based on the response above, it seems only one "interesting" file, in this case a directory was found.

Detect - Log Analysis

How many times was the "threat actor's IP" seen in the logs?

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat access.log | cut --fields 1 --delimiter=' ' | uniq --count                                                                                                                   
   2596 10.0.0.107

Above shows 2596 occurrences of this IP in the Apache access.log file.

Interestingly, we know Nikto is the tool used to target our environment, is there any evidence of Nikto in our logs? Let's find out.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat access.log | grep nikto                                                                                                                                                      
10.0.0.107 - - [11/May/2023:16:07:39 -0400] "PUT /nikto-test-Bqe4RxLj.html HTTP/1.1" 405 321 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"

We see one above, "PUT /nikto-test-Bqe4RxLj.html HTTP/1.1", at this point, this is the only evidence of Nikto being used. Not sure if you noticed it but the user agent says nothing about Nikto by default.

Talking about user agents, I believe this is a great source of threat intelligence (even though it can be easily spoofed). Let's see what is in our logs.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat access.log | grep "10.0.0.107" | cut --field 6 --delimiter='"' | \
sort | uniq --count | sort --numeric-sort --reverse 
   2408 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
    123 () { :; }; echo 93e4r0-CVE-2014-6271: true;echo;echo;

We saw earlier that there was a PUT method. Taking a closer look at what other methods are there and how was the access being attempted.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat access.log | grep "10.0.0.107" | cut --field 2 --delimiter=']' | \
cut --fields 1 --delimiter='/' | sort | uniq --count | sort --numeric-sort --reverse 
   2586  "GET 
      2  "TRACK 
      1  "UVMGSHXG 
      1  "TRACE 
      1  "PUT 
      1  "PROPFIND 
      1  "OPTIONS * HTTP
      1  "OPTIONS 
      1  "GET . HTTP
      1  "DEBUG 

Not much surprise that the GET method is most seen. Interesting, looking at RFC 2616 "Hypertext Transfer Protocol -- HTTP/1.1", I see GET, PUT, TRACE and OPTIONS. I don't see anything for TRACK, UVMGSHXG, PROPFIND or DEBUG. Where did these comes from?!

PROPFIND is part of RFC4918 "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)" and can be used to retrieve directory information. TRACK is Microsoft's implementation similar to TRACE.

Rather than going through all these methods, let's instead look at the status codes returned by the server for possible clues on how to further our investigation.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat access.log | grep "10.0.0.107" | cut --field 2 --delimiter=']'| \
cut --fields=3 --delimiter='"' | cut --fields=2 --delimiter=' ' | sort | \
uniq --count | sort --numeric-sort --reverse 
   2496 404
     51 
     21 302
     13 ./.\\\
      5 400
      4 403
      4 200
      1 417
      1 405

Nice to see the majority of requests returned 404 - Not Found. There is a lot to poke through but I will not waste time on any of the 400 series errors as these are all "Client Error"

Let's instead focus on status code 200 "Successful"

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat access.log | grep "10.0.0.107" | grep --perl-regexp '\s+200?\s+' | \
awk --field-separator='Mozilla' '{ print $1 }'
10.0.0.107 - - [11/May/2023:16:07:40 -0400] "GET /favicon.ico HTTP/1.1" 200 30894 "-" "
10.0.0.107 - - [11/May/2023:16:07:41 -0400] "OPTIONS * HTTP/1.1" 200 - "-" "
10.0.0.107 - - [11/May/2023:16:07:41 -0400] "TRACE / HTTP/1.0" 200 192 "-" "
10.0.0.107 - - [11/May/2023:16:07:42 -0400] "GET /img/ HTTP/1.1" 200 1214 "-" "

The last line shows the '"GET /img/ HTTP/1.1" 200', this suggest the response "+ /img/: This might be interesting." which was returned in Nikto's output above, is more likely associated with this.

At this point, no need for additional log analysis. There is nothing "threatening" in the logs.


Detect - Packet Analysis 

Setup for packet analysis. Capture packets on ports 80 or 443

┌──(kali㉿securitynik)-[~/nikto_stuff]
└─$ tshark -n -w tuning_1.pcap -f 'tcp port(80 or 443)' --interface eth0
Capturing on 'eth0'
 ** (tshark:395047) 16:07:08.756192 [Main MESSAGE] -- Capture started.
 ** (tshark:395047) 16:07:08.756254 [Main MESSAGE] -- File: "tuning_1.pcap"
5808 ^C

With the capture in place, let's do some analysis.

What are the protocols seen in the PCAP.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -q -z io,phs

===================================================================
Protocol Hierarchy Statistics
Filter: 

eth                                      frames:5808 bytes:2283533
  ip                                     frames:5808 bytes:2283533
    tcp                                  frames:5808 bytes:2283533
      http                               frames:5189 bytes:2214997
        data-text-lines                  frames:2574 bytes:1523618
        urlencoded-form                  frames:1 bytes:358
        media                            frames:1 bytes:603
          tcp.segments                   frames:1 bytes:603
      tcp.segments                       frames:1 bytes:60
        http                             frames:1 bytes:60
          message-http                   frames:1 bytes:60
===================================================================

Looking at IP conversations, we see communications between two hosts and for a total of 5808 frames or 2,283 kB

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -q -z conv,ip
================================================================================
IPv4 Conversations
Filter:<No Filter>
                                               |       <-      | |       ->      | |     Total     |    Relative    |   Duration   |
                                               | Frames  Bytes | | Frames  Bytes | | Frames  Bytes |      Start     |              |
10.0.0.107           <-> 10.0.0.106              2869 1,578 kB     2939 704 kB       5808 2,283 kB      0.000000000         6.6385
================================================================================

How did the two hosts communicate? Let's figure that out by looking at the TCP conversations. I choose TCP because there is no UDP data in the protocol hierarchy show above. Looking at the conversations with a focus on the duration, frames and the bytes suggest this is more reconnaissance activity as the bytes and frame are similar.

Some may even see this as possible beaconing activity because of the consistency of frame and bytes to this particular destination (10.0.0.106) on the particular port (80). We know it is now because we are doing this scenario ;-). 

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -q -z conv,tcp | more
================================================================================
TCP Conversations
Filter:<No Filter>
                                                           |       <-      | |       ->      | |     Total     |    Relative    |   Duration   |
                                                           | Frames  Bytes | | Frames  Bytes | | Frames  Bytes |      Start     |              |
10.0.0.107:37652           <-> 10.0.0.106:80                  104 59 kB         106 27 kB         210 86 kB         1.456681410         0.2623
10.0.0.107:38216           <-> 10.0.0.106:80                  104 59 kB         106 26 kB         210 86 kB         4.558459670         0.4762
10.0.0.107:37538           <-> 10.0.0.106:80                  104 59 kB         105 25 kB         209 85 kB         0.000000000         0.2090
10.0.0.107:37550           <-> 10.0.0.106:80                  104 59 kB         105 25 kB         209 85 kB         0.209464854         0.2453
10.0.0.107:37554           <-> 10.0.0.106:80                  104 59 kB         105 25 kB         209 85 kB         0.454103547         0.163
....

Overall, how many TCP conversations are there?

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -q -z conv,tcp | sed '1,5d;$d;/^$/d' | \
wc --lines                                                                                                     
84

How many unique streams do I have in this PCAP? Well you just got the answer above. This is just another way to confirm.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -T fields -e tcp.stream | sort | \
uniq --count | sort --numeric-sort --reverse | wc --lines
84

With 84 streams, where do we start? Taking a look at the packets TCP payload lengths, while returning the matching stream number.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -T fields -e tcp.len -e tcp.stream | \
sort --numeric-sort --key=1 --reverse  | more                                                                    
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1460    4
1443    13
742     6
660     81
607     0
...

Stream 4 looks to be the biggest at 1460 bytes long. Peaking into stream 4. This returned a number of entries with 404 errors.

There was however, one response with 200 OK and a 302 Found

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -q -z follow,tcp,ascii,4 | grep --perl-regexp '^HTTP/1.1' | sort | uniq --count | sort --numeric-sort --reverse
     80 HTTP/1.1 404 Not Found
      4 HTTP/1.1 302 Found
      1 HTTP/1.1 400 Bad Request
      1 HTTP/1.1 200 OK

Finding records where the HTTP response code is 200.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -Y 'http.response.code == 200'
  967 0.944983715   10.0.0.106 → 10.0.0.107   HTTP 603 HTTP/1.1 200 OK  (image/x-icon)
 1363 1.441673139   10.0.0.106 → 10.0.0.107   HTTP 241 HTTP/1.1 200 OK 
 1381 1.450651187   10.0.0.106 → 10.0.0.107   HTTP 60 HTTP/1.1 200 OK  (message/http)
 1951 2.310611664   10.0.0.106 → 10.0.0.107   HTTP 1497 HTTP/1.1 200 OK  (text/html)

Looking a bit deeper

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -Y 'http.response.code == 200' -T fields -e ip.src -e ip.dst -e tcp.srcport -e tcp.stream -E header=y
ip.src  ip.dst  tcp.srcport     tcp.stream
10.0.0.106      10.0.0.107      80      4
10.0.0.106      10.0.0.107      80      8
10.0.0.106      10.0.0.107      80      9
10.0.0.106      10.0.0.107      80      13

Following the stream 8 to see what's going on inside. We see this was an OPTIONS request 

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -q -z follow,tcp,ascii,8 | grep --perl-regexp '200 OK' --after-context=5 --before-context=7                                                          
OPTIONS * HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Connection: Keep-Alive
Host: 10.0.0.106


        187
HTTP/1.1 200 OK
Date: Thu, 11 May 2023 20:07:41 GMT
Server: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28
Content-Length: 0
Keep-Alive: timeout=5, max=77
Connection: Keep-Alive

Above, just seem to be looking for the HTTP communication options available on the server.

Let's see what stream 13 has.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ tshark -n -r tuning_1.pcap -q -z follow,tcp,ascii,13 | \
grep --perl-regexp '200 OK' --after-context=5 --before-context=7 
GET /img/ HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Connection: Keep-Alive
Host: 10.0.0.106


        1443
HTTP/1.1 200 OK
Date: Thu, 11 May 2023 20:07:42 GMT
Server: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28
Content-Length: 1214
Keep-Alive: timeout=5, max=35
Connection: Keep-Alive

Looks like we found one entry, where the response was successful. This in turns ties into what we found via our log analysis.

Closing out the packet analysis.

Detect - Zeek Analysis

Setup Zeek

┌──(kali㉿securitynik)-[~/nikto_stuff/zeek_stuff]
└─$ sudo zeek --iface any --no-checksums

What logs were created for this activity?

┌──(kali㉿securitynik)-[~/nikto_stuff/zeek_stuff]
└─$ ls
conn.log  dhcp.log  dns.log  files.log  http.log  packet_filter.log  reporter.log  weird.log

Looking at the conn.log file to see what communication is there for response code 200.

┌──(kali㉿securitynik)-[~/nikto_stuff/zeek_stuff]
└─$ cat http.log | grep --perl-regexp '\s+200\s+' | awk --field-separator=' ' '{ print $1"   " $3":"$4 "    "  $5":"$6 "  " $8 "   " $9 "   " $10  }'                            
1683835691.086935   10.0.0.107:37570    10.0.0.106:80  GET   10.0.0.106   /favicon.ico
1683835691.585128   10.0.0.107:37616    10.0.0.106:80  OPTIONS   10.0.0.106   *
1683835691.592865   10.0.0.107:37630    10.0.0.106:80  TRACE   -   /
1683835692.447548   10.0.0.107:37658    10.0.0.106:80  GET   10.0.0.106   /img/

The last one, matters the most as we can see the "/img/"

In the other logs, there are nothing meaningful.

P.S. It would have been a lot easier to use zeek-cut to answer above but zeek-cut is not available on Kali and I'm only interested in solving my problem. Not about a particular tool.


Detect - Suricata (IDS) Analysis

Setup Suricata to operate in IDS mode

┌──(kali㉿securitynik)-[/var/log/suricata]
└─$ sudo suricata -c /etc/suricata/suricata.yaml -s /var/lib/suricata/rules/suricata.rules -i eth0 -l /var/log/suricata/ --simulate-ips -k all

How many alerts triggered for this activity?

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat fast.log.1 | grep --perl-regexp '\[\*\*\].*?\[\**\]' --only-matching | wc --lines                                                                                            
65

What about unique alerts.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat fast.log.1 | grep --perl-regexp '\[\*\*\].*?\[\**\]' --only-matching | \
sort --unique | wc --lines
18

Looking at those 18 alerts and their frequency.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat fast.log.1 | grep --perl-regexp '\[\*\*\].*?\[\**\]' --only-matching | sort | uniq --count | sort --numeric-sort --reverse                                                   
     38 [**] [1:2022028:2] ET WEB_SERVER Possible CVE-2014-6271 Attempt [**]
      5 [**] [1:2101201:11] GPL WEB_SERVER 403 Forbidden [**]
      3 [**] [1:2101877:11] GPL WEB_SERVER printenv access [**]
      3 [**] [1:2100977:15] GPL EXPLOIT .cnf access [**]
      2 [**] [1:2019904:5] ET EXPLOIT QNAP Shellshock CVE-2014-6271 [**]
      2 [**] [1:2009485:7] ET WEB_SERVER /etc/shadow Detected in URI [**]
      1 [**] [1:2260002:1] SURICATA Applayer Detect protocol only one direction [**]
      1 [**] [1:2221028:1] SURICATA HTTP Host header invalid [**]
      1 [**] [1:2102073:7] GPL WEB_SERVER globals.pl access [**]
      1 [**] [1:2101402:9] GPL EXPLOIT iissamples access [**]
      1 [**] [1:2101401:11] GPL EXPLOIT /msadc/samples/ access [**]
      1 [**] [1:2101013:12] GPL EXPLOIT fpcount access [**]
      1 [**] [1:2100952:10] GPL WEB_SERVER author.exe access [**]
      1 [**] [1:2044504:1] ET INFO Request for Visual Studio Code sftp.json - Possible Information Leak [**]
      1 [**] [1:2034253:2] ET SCAN FTPSync Settings Disclosure Attempt [**]
      1 [**] [1:2015940:4] ET SCAN SFTP/FTP Password Exposure via sftp-config.json [**]
      1 [**] [1:2010766:12] ET POLICY Proxy TRACE Request - inbound [**]
      1 [**] [1:2006445:14] ET WEB_SERVER Possible SQL Injection Attempt SELECT FROM [**]

What are the priorities of the these alerts?

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat fast.log.1 | grep --perl-regexp '\[Priority.*?\]' --only-matching | \
sort | uniq --count                                                                                      
     43 [Priority: 1]
     20 [Priority: 2]
      2 [Priority: 3]

The majority of alerts are priority 1. Hmmm!

Looking at the classifications.

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat fast.log.1 | grep --perl-regexp '\[Classification.*?\]' --only-matching | \
sort | uniq --count | sort --numeric-sort --reverse                                                
     40 [Classification: Attempted Administrator Privilege Gain]
      9 [Classification: Attempted Information Leak]
      9 [Classification: access to a potentially vulnerable web application]
      3 [Classification: Web Application Attack]
      2 [Classification: Potentially Bad Traffic]
      2 [Classification: Generic Protocol Command Decode]

What alerts are associated with "Attempted Administrator Privilege Gain"

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat fast.log.1 | grep --perl-regexp 'Attempted Administrator Privilege Gain' | cut --fields=3- --delimiter=' ' |sort | uniq --count | sort --numeric-sort --reverse              
     26 [**] [1:2022028:2] ET WEB_SERVER Possible CVE-2014-6271 Attempt [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 10.0.0.107:37600 -> 10.0.0.106:80
     12 [**] [1:2022028:2] ET WEB_SERVER Possible CVE-2014-6271 Attempt [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 10.0.0.107:37616 -> 10.0.0.106:80
      2 [**] [1:2019904:5] ET EXPLOIT QNAP Shellshock CVE-2014-6271 [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 10.0.0.107:37600 -> 10.0.0.106:80

Looking at the rule for "ET WEB_SERVER Possible CVE-2014-6271 Attempt".

┌──(kali㉿securitynik)-[~/nikto_stuff]
└─$ cat /var/lib/suricata/rules/suricata.rules  | grep "2022028"
alert tcp any any -> $HTTP_SERVERS $HTTP_PORTS (msg:"ET WEB_SERVER Possible CVE-2014-6271 Attempt"; flow:established,to_server; content:" HTTP/1."; pcre:"/^[^\r\n]*?HTTP\/1(?:(?!\r?\n\r?\n)[\x20-\x7e\s]){1,500}\n[\x20-\x7e]{1,100}\x3a[\x20-\x7e]{0,500}\x28\x29\x20\x7b/s"; content:"|28 29 20 7b|"; fast_pattern; reference:url,blogs.akamai.com/2014/09/environment-bashing.html; classtype:attempted-admin; sid:2022028; rev:2; metadata:created_at 2015_11_04, updated_at 2019_10_08;)

These all seems to be associated with Shellock and since the device this web server is running on is a Windows based system. I will conclude these are all false positives.

Do we have anything relating to "/img" as we saw in the log and packet analysis?

┌──(kali㉿securitynik)-[~/nikto_stuff/tuning_1]
└─$ cat /var/log/suricata/alert-debug.log.1 | grep --ignore-case "img"

Hmm nothing returned.

Moving on from the IDS analysis.


Reference:

No comments:

Post a Comment