Making HTTP requests to identify vulnerable Trendnet webcams

The Nmap Scripting Engine offers a library to handle requests and other common functions of an HTTP client. With this library, NSE developers can accomplish many tasks, from information gathering to vulnerability exploitation.

This recipe will show you how to use the HTTP library to send an HTTP request to identify vulnerable Trendnet TV-IP110W webcams.

How to do it...

Trendnet TV-IP110W webcams allow unauthenticated access to their video feed by simply requesting the URI /anony/mjpg.cgi. Let's write an NSE script to detect these devices. For now, let's ignore the documentation tags:

  1. Create the file http-trendnet-tvip110w.nse and start by filling up the NSE script basic information fields:
    description = [[
    Attempts to detect webcams Trendnet TV-IP110W vulnerable to unauthenticated access to the video stream by querying the URI "/anony/mjpg.cgi".
    
    Original advisory: http://console-cowboys.blogspot.com/2012/01/trendnet-cameras-i-always-feel-like.html
    ]]
    
    categories = {"exploit","vuln"}
  2. We load the libraries that we are going to need. Note that this format corresponds to Nmap 6.x:
    local http = require "http"
    local shortport = require "shortport"
    local stdnse = require "stdnse"
  3. We define our execution rule. We use the alias shortport.http to tell Nmap to execute the script when a web server is found:
    portrule = shortport.http
  4. Our main function will identify the type of 404 responses and determine if the webcam is vulnerable to unauthorized access by sending the HTTP request to /anony/mjpg.cgi and checking for status code 200:
    action = function(host, port)
      local uri = "/anony/mjpg.cgi"
    
      local _, status_404, resp_404 = http.identify_404(host, port)
      if status_404 == 200 then
        stdnse.print_debug(1, "%s: Web server returns ambiguous response. Trendnet webcams return standard 404 status responses. Exiting.", SCRIPT_NAME)
        return
      end
    
      stdnse.print_debug(1, "%s: HTTP HEAD %s", SCRIPT_NAME, uri)
      local resp = http.head(host, port, uri)
      if resp.status and resp.status == 200 then
        return string.format("Trendnet TV-IP110W video feed is unprotected:http://%s/anony/mjpg.cgi", host.ip)
      end
    end
  5. Now just run the NSE script against your target:
    $ nmap -p80 -n -Pn --script http-trendnet-tvip110w.nse <target>
    
  6. If you find a vulnerable webcam you will see the following output:
    PORT   STATE SERVICE REASON
    80/tcp open  http    syn-ack
    |_http-trendnet-tvip110w: Trendnet TV-IP110W video feed is unprotected:http://192.168.4.20/anony/mjpg.cgi

The complete script with documentation tags can be downloaded from https://github.com/cldrn/nmap-nse-scripts/blob/master/scripts/6.x/http-trendnet-tvip110w.nse.

How it works...

In the script http-trendnet-tvip110w.nse, we defined the execution rule with the alias http from the shortport library:

portrule = shortport.http

The alias shortport.http is defined in the file /nselib/shortport.lua as follows:

LIKELY_HTTP_PORTS = {
        80, 443, 631, 7080, 8080, 8088, 5800, 3872, 8180, 8000
}

LIKELY_HTTP_SERVICES = {
        "http", "https", "ipp", "http-alt", "vnc-http", "oem-agent", "soap",
        "http-proxy",
}

http = port_or_service(LIKELY_HTTP_PORTS, LIKELY_HTTP_SERVICES)

The http library has methods such as http.head(), http.get(), and http.post() corresponding to the common HTTP methods HEAD, GET, and POST respectively, but it also has a generic method named http.generic_request() to allow more flexibility to developers who may want to try more obscure HTTP verbs.

In the script http-trendnet-tvip110w, we used the function http.head() to retrieve the URI /anony/mjpg.cgi:

local resp = http.head(host, port, uri)

The function http.head() returns a table containing the following response information:

  • status-line: Contains the returned status line. For example, HTTP/1.1 404 Not Found.
  • status: Contains the status code returned by the web server.
  • body: Contains the response body.
  • cookies: Table of cookies set by the web server.
  • header: Associative table where the returned headers are stored. The name of the header is used as an index. For example, header["server"] contains the Server field returned by the web server.
  • rawheader: Numbered array of headers in the same order as they were sent by the web server.

The library stdnse is also used in the script http-trendnet-tvip110w.nse. This library is a collection of miscellaneous functions that come in handy when writing NSE scripts. The script used the function stdnse.print_debug(), a function to print debugging messages:

stdnse.print_debug(<debug level required>, <format string>, arg1, arg2...)  

The complete documentation for these libraries can be found at http://nmap.org/nsedoc/lib/http.html and http://nmap.org/nsedoc/lib/stdnse.html.

There's more...

Some web servers do not return regular status 404 code responses when a page does not exist, and instead return status code 200 all the time. This is an aspect that is often overlooked and even I have made the mistake before of assuming that a status of 200 meant that the URI exists. We need to be careful with this to avoid false positives in our scripts. The functions http.identify_404() and http.page_exists() were created to identify if a server returns regular 404 responses and if a given page exists.

local status_404, req_404, page_404 = http.identify_404(host, port)

If the function http.identify_404(host, port) was successful, we can use http.page_exists():

if http.page_exists(data, req_404, page_404, uri, true) then
  stdnse.print_debug(1, "Page exists! → %s", uri)
end

Debugging Nmap scripts

If something unexpected happens, turn on debugging to get additional information. Nmap uses the flag -d for debugging and you can set any integer between 0 and 9:

$ nmap -p80 --script http-google-email -d4 <target>

Setting the user agent pragmatically

There are some packet filtering products that block requests using Nmap's default HTTP user agent. You can use a different user agent value by setting the argument http.useragent:

$ nmap -p80 --script http-sqli-finder --script-args http.useragent="Mozilla 42" <target>

To set the user agent in your NSE script, you can pass the header field:

options = {header={}}
options['header']['User-Agent'] = "Mozilla/9.1 (compatible; Windows NT 5.0 build 1420;)"
local req = http.get(host, port, uri, options)

HTTP pipelining

Some web server's configuration supports encapsulation of more than one HTTP request in a single packet. This may speed up the execution of an NSE HTTP script and it is recommended that you use it if the web server supports it. The http library, by default, tries to pipeline 40 requests and automatically adjusts that number according to the network conditions and the Keep-Alive header.

Users will need to set the script argument http.pipeline to adjust this value:

$ nmap -p80 --script http-methods --script-args http.pipeline=25 <target>

To implement HTTP pipelining in your NSE scripts, use the functions http.pipeline_add() and http.pipeline(). First, initiate a variable that will hold the requests:

local reqs = nil

Add requests to the pipeline with http.pipeline_add():

reqs = http.pipeline_add('/Trace.axd', nil, reqs)
reqs = http.pipeline_add('/trace.axd', nil, reqs)
reqs = http.pipeline_add('/Web.config.old', nil, reqs)

When you are done adding requests, execute the pipe with http.pipeline():

local results = http.pipeline(target, 80, reqs)

The variable results will contain the number of response objects added to the HTTP request queue. To access them, you can simply iterate through the object:

for i, req in pairs(results) do
  stdnse.print_debug(1, "Request #%d returned status %d", I, req.status)
end

See also

  • The Sending UDP payloads by using NSE sockets recipe
  • The Exploiting a path traversal vulnerability with NSE recipe
  • The Writing a brute force script recipe
  • The Working with the web crawling library recipe
  • The Reporting vulnerabilities correctly in NSE scripts recipe
  • The Writing your own NSE library recipe
  • The Listing supported HTTP methods recipe in Chapter 4, Auditing Web Servers
  • The Checking if an HTTP proxy is open recipe in Chapter 4, Auditing Web Servers
  • The Detecting web application firewalls recipe in Chapter 4, Auditing Web Servers
  • The Detecting possible XST vulnerabilities recipe in Chapter 4, Auditing Web Servers
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.79.88