Chris Truncer's EyeWitness is a great tool that allows easy visual reconnaissance of HTTP, VNC and RDP servers. It's an essential recommended by sources such as Jason Haddix's "bug hunter methodology" or Peter Kim's "the hacker playbook".
Unfortunately, it is pretty troublesome to setup on MacOS. Fortunately, the
repo does provide a Dockerfile. But when following the docker instructions
given in the README on a Mac, capture modes that require a display (
web) fail with the following error :
cannot connect to X server
First, MacOS doesn't ship with an X server. One must be installed before running anything. So install XQuartz
Second, XQuartz uses a named socket as
$DISPLAY and mounting those in Docker
is troublesome (I'm actually not sure if it's supported at the moment). It is
way easier to have the display server listen on the network and use that
In order to do that, open the XQuartz preferences, navigate to
Allow connections from network clients checkbox. Then run the
following command to disable X ACLs:
(there is probably a safer way to do this, but that's how I got it to work)
Third, the example command provided in the
EyeWitness README is the
docker run \ --rm \ -it \ -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -v ~/EyeWitness:/tmp/EyeWitness \ eyewitness \ -f /tmp/EyeWitness/urls.txt --vnc
It has to be changed to :
docker run \ --rm \ -it \ -e DISPLAY=$IPADDRESS:0 \ -v ~/EyeWitness:/tmp/EyeWitness \ -f /tmp/EyeWitness/urls.txt --vnc
$IPADDRESS is your host's local IP address.
won't work here, even when using the
--net=host Docker option.
Bonus : use a bind mount instead of a volume mount
-v option mounts a host directory as a volume. This has some (arguably
negligible) overhead as it uses the union filesystem, tends to clog up the
filesystem by leaving dangling volumes and can create some sync issues where
the state of the directory differs on the host and on the container.
In EyeWitness' case (the mounted directory is only used to write the tool's output) it's better to use a bind mount. The syntax for that is :
docker run --mount type=bind,source=$HOST_DIRECTORY_PATH,target=$CONTAINER_DIRECTORY_PATH
$HOST_DIRECTORY_PATH is the absolute path to the host directory and
$CONTAINER_DIRECTORY_PATH the absolute path to the mount point on the container.
Using a bind mount, the example command becomes :
docker run \ --rm \ -it \ -e DISPLAY=$IPADDRESS:0 \ --mount type=bind,source=$HOST_DIRECTORY_PATH,target=/tmp/EyeWitness \ -f /tmp/EyeWitness/urls.txt --vnc
$HOST_DIRECTORY_PATH would be
/Users/$USER/EyeWitness on MacOS or
/home/$USER/EyeWitness on Linux.