wmap v2.0


wmap started as a proof-of-concept program written in Java. Recently, it was rewritten in C++ (using STL, cURL and getopt), allowing it to reach a more broad audience. At present, it is only available in source-code form, but is very easy to compile.


The current version of wmap is 2.0, and it can be found at:

The older (Java) version is still available at:


See INSTALL.txt for details.


In order to explain wmap, we must first look at another computer security tool, nmap. Security professionals: please excuse the over-simplification. I will be explaining it just enough to draw parallels between nmap and wmap without confusing less experienced readers.

As we all know, servers on the internet provide services to user. Those services come in the form of web site, FTP sites, databases, email, and countless others. Those services also come running on pretty standard port numbers so that people wanting to use those services know where to find them. Ftp is on port 21, email is on port 25, simple logins are on port 23, web servers are on port 80, etc. If another system needs to deliver email, it connects on port 25 and sends it, without having to guess what port the program is running on.

Nmap takes advantage of this piece of knowledge. Since there are dozens of pretty standard services running on pretty standard port numbers, you can easily tell what kinds of software a machine is running by what ports are listening for connections. If you can successfully connect to port 80, you know there is bound to be a website. If you can successfully connect on port 25, you know that it accepts inbound email.

In the web world, web servers send you the files you request. Your browser requests a page because you happen to know the URL–either it was linked from another page, a search engine, an email, etc. or you guessed the name. That page then likely contains references out to other pages as well as media files–images, sounds, applets, etc.

You can request files because you know they are there. Of course, there could be files and directories that exist, but are not explicitly linked from anywhere. A good number of websites have a “/logs” directory that is web-accessable (often with a password, but sometimes without), but not actually linked from anywhere–you just have to know it is there. Many personal sites have a folder called “/stuff” or “/junk” where they put random stuff to share amongst their friends, but are not generally for public consumption. Most sites have an “/images” folder to hold graphical assets–but a good amount of the time, that folder has no default page and allows “directory browsing” so you can see a list of every image the site employs.


This is where wmap comes in. Wmap has a list of common folder names. When you point it at a base URL, it appends each of the folder names, requests the page (actually just a “HEAD” request for the techies that want to know), and takes note of the response. If the response is a 200-series code, there might be something there worth paying attention to. If the response is a “403 Forbidden,” you know something is there, but you will be unable to get a listing–you might have to chalk it up as not available unless you want to guess filenames. If the response is a different 400-series code, there is probably nothing of interest (i.e. it doesn’t exist).

I am one of those people who learns best by example, so let us cut to an example:

% ./wmap --auto --delay=3 https://netninja.com
404 https://netninja.com/default.asp
404 https://netninja.com/default.htm
404 https://netninja.com/thumbnails/
404 https://netninja.com/gallery/
404 https://netninja.com/_img/
404 https://netninja.com/pics/
404 https://netninja.com/img/
404 https://netninja.com/image/
200 https://netninja.com/images/ <<<<<<<<<<
404 https://netninja.com/log/
404 https://netninja.com/journal/
404 https://netninja.com/blog/
404 https://netninja.com/weblog/
404 https://netninja.com/MP3S/
404 https://netninja.com/MP3/
404 https://netninja.com/mp3s/
404 https://netninja.com/mp3/
404 https://netninja.com/music/
404 https://netninja.com/flash/
404 https://netninja.com/MP3s/
404 https://netninja.com/media/
404 https://netninja.com/assets/
404 https://netninja.com/classes/
404 https://netninja.com/logs/
200 https://netninja.com/files/ <<<<<<<<<<
404 https://netninja.com/db/
404 https://netninja.com/default.html
404 https://netninja.com/sql/
404 https://netninja.com/index.jsp
404 https://netninja.com/data/
404 https://netninja.com/index.asp
404 https://netninja.com/index.pl
404 https://netninja.com/archives/
404 https://netninja.com/index.phps
404 https://netninja.com/documents/
404 https://netninja.com/index.php3
404 https://netninja.com/support/
200 https://netninja.com/index.php <<<<<<<<<<
404 https://netninja.com/index.htm
404 https://netninja.com/index.html
404 https://netninja.com/backup/

EXISTS, LOADS         https://netninja.com/images
EXISTS, LOADS         https://netninja.com/files
EXISTS, LOADS         https://netninja.com/index.php

You can see that a number of files and directories were tried. Three (the ones with “<<<<<” arrows) returned results we might be interested in. After everything has been tried, those three results are presented in summary form.

Keep in mind that sending repeated requests can pound a server and use a lot of resources (bandwith, CPU, etc). It can also get you banned from their network for a while if they have a good firewall running. Take advantage of the “–delay” parameter. This will wait a number of seconds between requests.


Sometimes, you might want a little more control over what pages are being requested, based on a site’s content. You might want to run an automatic scan, but follow it with a few manual requests because you think something is there. This is where the manual scan comes in.

In manual mode, you give wmap a base URL, then it interactively asks you for words. It will then attempt to locate interesting files/folders on the web server based on the word you give. For example, if you give it the word “swordfish,” it will attempt to locate a “/swordfish/” folder, then a “swordfish.html” web page, then a “swordfish.htm” (three-letter Windows extension) web page, then a “swordfish.php” script, etc.

Once again, I think a little example is in order:

% ./wmap --manual https://netninja.com
Enter directory/file name to search for at base URL (enter to quit)
> ninja
404 https://netninja.com/ninja/
404 https://netninja.com/ninja.html
404 https://netninja.com/ninja.htm
404 https://netninja.com/ninja.php
404 https://netninja.com/ninja.php3
404 https://netninja.com/ninja.phps
404 https://netninja.com/ninja.asp
404 https://netninja.com/ninja.pl
404 https://netninja.com/ninja.jsp
404 https://netninja.com/ninja.txt
404 https://netninja.com/ninja.jpg
404 https://netninja.com/ninja.gif
404 https://netninja.com/ninja.png
Enter directory/file name to search for at base URL (enter to quit)
> netninja
404 https://netninja.com/netninja/
404 https://netninja.com/netninja.html
404 https://netninja.com/netninja.htm
200 https://netninja.com/netninja.php <<<<<<<<<<
404 https://netninja.com/netninja.php3
404 https://netninja.com/netninja.phps
404 https://netninja.com/netninja.asp
404 https://netninja.com/netninja.pl
404 https://netninja.com/netninja.jsp
404 https://netninja.com/netninja.txt
404 https://netninja.com/netninja.jpg
404 https://netninja.com/netninja.gif
404 https://netninja.com/netninja.png
Enter directory/file name to search for at base URL (enter to quit)
> projects
404 https://netninja.com/projects/
404 https://netninja.com/projects.html
404 https://netninja.com/projects.htm
200 https://netninja.com/projects.php <<<<<<<<<<
404 https://netninja.com/projects.php3
404 https://netninja.com/projects.phps
404 https://netninja.com/projects.asp
404 https://netninja.com/projects.pl
404 https://netninja.com/projects.jsp
404 https://netninja.com/projects.txt
404 https://netninja.com/projects.jpg
404 https://netninja.com/projects.gif
404 https://netninja.com/projects.png
Enter directory/file name to search for at base URL (enter to quit)

As you can see, “ninja” did not turn up anything, but “netninja” and “projects” turned up some interesting pages. Of course, on the netninja web site, these are explicitly linked from the front page, so nothing “secret” was discovered–but you should get the point.


Wmap is started with the Java command “java -jar wmap.jar,” but wrapper scripts for Windows (wmap.bat) and Unix (wmap.sh) have been provided. The wrapper scripts just need the jar file to be in the current directory. Feel free to modify them if you want to use them system-wide on your computer. Unix users might have to “chmod +x wmap.sh” since the zip file this is distributed in does not store permission bits.

There are two main flags available: –auto (or -a) starts automatic mode –manual (or -m) starts manual mode

If you are using automatic mode, the you are advised to use: –delay={seconds} (or -d{seconds}) to set a delay

All modes require a base URL to be supplied on the command line. It should be a standard “http://” formatted URL.


At present, wmap looks for about 44 different “standard” folders. These are all things I have personally run across in the past, as either standard convention, folders auto-generated by web tools, or lazy people using simple folder names. My personal experience is nothing compared to the entire internet. Take a look at the file auto.properties (it can be found in the “src” folder or within the JAR file). If you know of something that should be there, drop me a note at the email address listed at the top of this file.

6 thoughts on “wmap”

  1. I get this when compiling

    wmap-2.0$ make
    cd src; g++ -Wall -c autolist.cc
    autolist.cc: In member function ‘int AutoList::parseLine(std::string, AutoTouple*)’:
    autolist.cc:70:75: error: ‘strlen’ was not declared in this scope
    make: *** [src/autolist.o] Error 1

  2. Add #include to autolist.cc (for strlen)
    Add #include to main.c (for atoi)

    and after that curl library link missing

    $ make
    g++ -Wall `curl-config –libs` -o wmap src/*.o
    src/tryurl.o: In function `TryUrl::TryUrl()’:
    tryurl.cc:(.text+0x12): undefined reference to `curl_global_init’
    tryurl.cc:(.text+0x17): undefined reference to `curl_easy_init’
    tryurl.cc:(.text+0x3f): undefined reference to `curl_easy_setopt’
    tryurl.cc:(.text+0x5d): undefined reference to `curl_easy_setopt’
    tryurl.cc:(.text+0x7b): undefined reference to `curl_easy_setopt’
    src/tryurl.o: In function `TryUrl::~TryUrl()’:
    tryurl.cc:(.text+0x8f): undefined reference to `curl_global_cleanup’
    tryurl.cc:(.text+0x9e): undefined reference to `curl_easy_cleanup’
    src/tryurl.o: In function `TryUrl::tryUrl(std::basic_string<char, std::char_traits, std::allocator >, std::basic_string<char, std::char_traits, std::allocator >*)’:
    tryurl.cc:(.text+0x512): undefined reference to `curl_easy_setopt’
    tryurl.cc:(.text+0x540): undefined reference to `curl_easy_setopt’
    tryurl.cc:(.text+0x552): undefined reference to `curl_easy_perform’
    tryurl.cc:(.text+0x5b6): undefined reference to `curl_easy_getinfo’
    collect2: ld returned 1 exit status
    make: *** [all] Error 1

Leave a Reply

Your email address will not be published. Required fields are marked *