domingo, 5 de mayo de 2013

w3af on raspberry pi

w3af on raspbian (debian 7.0)

Si necesitas versión en español, pídela y la haré.

Dreaming about plugging in a tiny box in a free port, wait a few minutes and walk away with a network scan and a vulnerability assessment in your pocket? Perhaps running an automated exploit too? So are you ready for load average: 2.85, 2.40, 1.72? You are not alone.

Step 0

Install raspbian[1] on your raspberry pi B[2]

$> sudo apt-get update
$> sudo apt-get upgrade

First attempt

Install w3af[3] from the repos

$> sudo apt-get install w3af

$> w3af_console

/usr/bin/w3af_console: 3: /usr/bin/w3af_console: /usr/bin/python2.5: not found

$> whereis w3af_console

w3af_console: /usr/bin/w3af_console

$> cat /usr/bin/w3af_console

Rename python2.5 to python, bad start.

$> w3af_console

28 seconds later...

w3af>>> profiles
w3af/profiles>>> use fast_scan
The plugins configured by the scan profile have been enabled, and their options configured.
Please set the target URL(s) and start the scan.

w3af/profiles>>> back
w3af>>> target
w3af/config:target>>> set target
w3af/config:target>>> back
w3af>>> start
Auto-enabling plugin: grep.error500
The thread: <WorkerThread(Thread-9, started daemon -1319824272)> raised an exception while running the request: <bound method fingerprint_404._send_404 of <core.controllers.coreHelpers.fingerprint_404.fingerprint_404 instance at 0x1a8d3c8>>
Exception: w3afMustStopException found by _send_404, someone else will handle it.
The thread: <WorkerThread(Thread-14, started daemon -1361767312)> raised an exception while running the request: <bound method fingerprint_404._send_404 of <core.controllers.coreHelpers.fingerprint_404.fingerprint_404 instance at 0x1a8d3c8>>

try again...
w3af>>> version
w3af - Web Application Attack and Audit Framework
Version: 1.1 (from Debian Package 1.0-rc3svn3489-1)
Author: Andres Riancho and the w3af team.

oops! it's too old! but its new! I've just installed it from the repos! I can not ask for help: "Please upgrade to the latest version". We have to clean up the mess.


# parses an apt log searching for a package
# and prints all the packages that were 
# installed to fullfill it's dependencies.

my $found = 0;
my $stop=0;
my $result='';
while (( $line = <> ) && !$stop) {
  if ($found==1) {
    foreach my $val (split(' ', $line)) {
      if (! ( $val =~ m/[()]/ ) and ! ($val =~ /Install/ )) {
        my ($name,$arch) = split(':',$val);
          $result .= "$name ";
   } elsif ($line =~ m/Commandline: apt-get install w3af/) {
print $result . "\n";

Run this script to remove w3af and it's dependencies.

$> sudo apt-get remove $( cat /var/log/apt/history.log | perl

Second attempt

Install w3af from github.

$> git clone

$> ./w3af_console

It will start crying for dependencies, be kind with it and resolve them:

$> sudo apt-get install python-setuptools git libxslt-dev python2.7-dev libsqlite3-dev libxml2-dev python-pip

$> sudo pip install PyGithub GitPython pybloomfiltermmap esmre nltk pdfminer futures pyOpenSSL lxml scapy-real guess-language cluster msgpack-python python-ntlm

$> sudo pip install -e git+git://

Run it again and again

$> ./w3af_console
$> sudo pip install chardet
$> sudo pip install -e git+git://

$> ./w3af_console

Do you accept the terms and conditions? [N|y] y

I'd only tried the console because I don't have an hdmi monitor and did not want to burn my eyes with the tv output, so I used ssh from a "real" computer.

Later, I connected with ssh -X and tried the gui:

$> ssh pi@ -X

$> ./w3af_gui

Resolve until it runs

$> sudo apt-get install graphviz python-gtk2 python-gtksourceview2

$> sudo pip install xdot

If you are using a 2GB card like me,

rootfs           1838936 1488260    257636  86% /

keep an eye on df. If you are running out of space, remember to purge /var/cache/apt/archives. pip does not keep temporary files, but apt-get installs the packages in the root partition. Remember that 4GB is the recommended size.

I am using an extra pendrive with ext4 to host w3af with no problems.

Some people would say "why didn't you use[4]"

Well, it's more fun this way and learn about it later and I don't have another sd card.

(update: there is a pretty list at )

One way or another, the nerd thing:

Step two

Be careful, don't fry your computer


Thanks to Andrés Riancho from w3af for the advice on monitoring w3af.

There is a single file [5] to modify.

First you have to import gpio and add some setup code

import RPi.GPIO as GPIO
GPIO.setup(channel, GPIO.OUT) // for each channel

Then you turn on the leds

GPIO.output(channel, True/False) // for each channel

Event based blinking effect without PWM

GPIO.output(channel, not GPIO.input(channel))

I left this out in order to keep the leds on when the script is over


update: Andrés asked me for the code, here it is:

diff --git a/core/controllers/core_helpers/ b/core/controllers/core_
index 8aa19bf..353f154 100644
--- a/core/controllers/core_
+++ b/core/controllers/core_
@@ -19,6 +19,7 @@ along with w3af; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

+import RPi.GPIO as GPIO
 import time

 import core.controllers.output_
manager as om
@@ -33,6 +34,12 @@ class w3af_core_status(object):
     the different methods to (get) the information required.
     def __init__(self, w3af_core):
+        GPIO.setmode(GPIO.BCM)
+        GPIO.setup(25, GPIO.OUT, initial=GPIO.LOW)
+        GPIO.setup(24, GPIO.OUT, initial=GPIO.LOW)
+        GPIO.setup(23, GPIO.OUT, initial=GPIO.LOW)
+        GPIO.setup(4, GPIO.OUT, initial=GPIO.LOW)
         # Store the core to be able to access the queues to get status
         self._w3af_core = w3af_core
@@ -49,6 +56,8 @@ class w3af_core_status(object):
         # The current fuzzable request that the core is analyzing at each phase
         # where a phase means crawl/audit
         self._current_fuzzable_request = {}
+        print "#### INIT ####\n"
+        GPIO.output(25, True)

     def pause(self, pause_yes_no):
         self._paused = pause_yes_no
@@ -81,6 +90,8 @@ class w3af_core_status(object):
             audit_fr = self.get_current_fuzzable_
             if crawl_plugin == audit_plugin == crawl_fr == audit_fr == None:
+                print "#### STARTING SCAN ####\n"
+                GPIO.output(24, True)
                 return 'Starting scan.'

             status_str = ''
@@ -110,6 +121,8 @@ class w3af_core_status(object):
type] = plugin_name
         self._latest_ptype, self._latest_pname = plugin_type, plugin_name
+        print "#### SET RUNNING PLUGIN: %s ####\n" % plugin_name
+        GPIO.output(23, not GPIO.input(23))

     def get_running_plugin(self, plugin_type):
@@ -129,6 +142,9 @@ class w3af_core_status(object):
         :return: If the user has called start, and then wants to know if the
         core is still working, it should call is_running() to know that.
+        print "### RUNNING ###\n"
+        GPIO.output(23, not GPIO.input(23))
         return self._is_running
     def is_paused(self):
@@ -170,6 +186,10 @@ class w3af_core_status(object):
         self._is_running = False
         self._running_plugin = {}
         self._current_fuzzable_request = {}
+        print "### SCAN FINISHED ###\n"
+        GPIO.output(23, True)
+        GPIO.output(4, True)

     def get_current_fuzzable_request(
self, plugin_type):
@@ -282,11 +302,10 @@ class w3af_core_status(object):
                       ' ETA (%(aeta)s)\n'
         status_str += 'Requests per minute: %(rpm)s'
         return status_str % data

 def round_or_None(float_or_none):
     if float_or_none is None:
         return None
-        return round(float_or_none, 2)
\ No newline at end of file
+        return round(float_or_none, 2)




No hay comentarios:

Publicar un comentario en la entrada