[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r11302: added more documentation, bugfixes, process detection (in topf/trunk: doc examples lib/fuzz lib/fuzz-struct)
Author: benedikt
Date: 2007-08-29 15:19:35 -0400 (Wed, 29 Aug 2007)
New Revision: 11302
Added:
topf/trunk/examples/tutorial-example.rb
Modified:
topf/trunk/doc/tutorial.tex
topf/trunk/lib/fuzz-struct/fuzz-struct.rb
topf/trunk/lib/fuzz/connection.rb
topf/trunk/lib/fuzz/observer.rb
Log:
added more documentation, bugfixes, process detection
Modified: topf/trunk/doc/tutorial.tex
===================================================================
--- topf/trunk/doc/tutorial.tex 2007-08-29 19:02:43 UTC (rev 11301)
+++ topf/trunk/doc/tutorial.tex 2007-08-29 19:19:35 UTC (rev 11302)
@@ -14,85 +14,103 @@
\section{Introduction}
\label{working}
T.O.P.F is a fuzzing Framework written in Ruby and developed to test the
-Tor protocol-suite. It uses a block-based approch like the famous SPIKE
-fuzzer written by Dave-Aitel. Block-based means that data is divided into
-so-called blocks that are then processed in a predefined fashion. Compared
+Tor protocol-suite. It uses a block-based approch like the famous SPIKE
+fuzzer written by Dave-Aitel. Block-based means that data is divided into
+so-called blocks who are then processed in a predefined fashion. Compared
to the random byte-flipping that many other fuzzers do, this allows a more
focused approach on specific vulnerbilities like buffer, format-string
-or integer overflows. If fuzzing and/or ruby sound strange to you,
-you should read into the links listed in Appendix \ref{links}.
+or integer overflows. If fuzzing and/or ruby sound strange to you,
+you should read the links listed in Appendix \ref{links}.
\section{Working with T.O.P.F}
To use T.O.P.F a few basic steps described in this section are necessary.
\subsection{Setting up a working Environment}
+\label{config}
T.O.P.F needs Ruby and the Ruby-SSL library which is on some systems supplied
-as standart-library and not on others. On Debian you need to run
-"apt-get install ruby libruby-openssl" beside the normal Ruby library.
+as standart-library and not on others.
+On Debian you need to run "apt-get install ruby libruby-openssl" to get it running.
+On Fedora "yum install ruby" should to the trick :)
+
\subsubsection{Checking out the current T.O.P.F trunk}
-Checking out T.O.P.F is as simple as starting a
+Next you need the T.O.P.F source which you are able to get from the
+Tor Subversion on https://tor-svn.freehaven.net/svn/. The Sources are
+on https://tor-svn.freehaven.net/svn/topf/trunk so
\begin{verbatim}
svn co https://tor-svn.freehaven.net/svn/topf/trunk topf
\end{verbatim}
-on your command-shell of choice.
+should copy them to the directory topf.
\subsection{Running the fuzz tests}
+To run the tests you first need to setup a config-file which must
+be in the YAML file-format (see: \ref{yaml}).
+The config-file contains information for the Framework on which
+Port each Service is running, if the Framework should output debug-message,
+where corefiles are being created and where it can find the tor-binary.
+
\subsubsection{Adjusting the config File}
-To let the Framework work properly the right setup of the
-config-file is nessesary. Just alter the given options
-to your environment.
+To give you a better insight on how the config-file must look, next
+you see an example config.
\begin{verbatim}
-DIRPORT: "2324"
-CONTROLPORT: "2323"
-HOST: "127.0.0.1"
-KEYFILE: "stuff/fuzz-private.pem"
-DEBUG: false
-COREDIR: "/home/your_user/topf/core"
-BINDIR: "/home/your_user/topf/binary"
-CONFDIR: "/home/your_user/topf/config"
+DIRPORT: "2324" # where is the dirport ?
+CONTROLPORT: "2323" # where is the control-port ?
+HOST: "127.0.0.1" # on which ip is tor running
+KEYFILE: "stuff/fuzz-private.pem" # this is to sign dir-descriptors
+ # (password is fuzz)
+DEBUG: false # should the framework output
+ # debug-messages?
+COREDIR: "/home/your_user/topf/core" # where are corefiles created ? see next
+ # sections on howto setup a path for
+ # corefiles
+BINDIR: "/home/your_user/topf/binary" # path to the tor binary
+CONFDIR: "/home/your_user/topf/config" # patch to the directory containing the
+ # tor-config-file
\end{verbatim}
\subsubsection{Setting the u-limit}
-To let your system create core-dumps you normaly have
-to adjust your ulimit. You can do this on the
-shell with the command: "ulimit -c unlimited"
+Now we need to tell the system that it should create core-files
+when tor gets killed by the framework. This can be done through the
+command: "ulimit -c unlimited"
+
\subsubsection{Setting a core-pattern}
-T.O.P.F checks if a process has been crashed by diffing the
-coredump-directory that was setup in the config-file.
-To let your system create core-files in this directory you
-have to supply a core-pattern. If you work with Linux you
-can set the core-pattern with echoing a path+filepattern
-into the file in proc named core\_pattern.
-When using Fedora this can be done with the following command
- executed as root:
- \begin{verbatim}
+To tell the System where to create core-files, on Linux, one can
+alter the proc-file "/proc/sys/kernel/core\_pattern" to point
+to the core-directory in the T.O.P.F root-directory.
+You can do this manually when running the following command as root:
+\begin{verbatim}
echo "/home/youruser/path_to_topf/core/core" > /proc/sys/kernel/core_pattern
\end{verbatim}
+or you can run the bash-script "set\_core\_pattern" in the utils directory as root.
+\subsection{Running the Tests}
+Now after completing all of the steps from \ref{config} we are finally able to
+run the standart-tests supplied with T.O.P.F.
\subsubsection{Running the Dir-Port tests}
-To run the tests against the Dir-Port make sure you have setup
-the right host and dir-port in the configuration file.
-If everything is setup right you can just execute the dir-fuzzing
-with the command "ruby tor-dir-fuzz.rb".
-If something goes wrong a corefile should be dumped and the
-test-script should give you a backtrace and register information
-out of that corefile. Also it should print out the data that triggered
-the bug.
+To run the Dir-Port tests simply execute "ruby tor-dir-fuzz.rb"
+which looks first if tor is allready running on the system and if not
+tries to execute it using the information in the config-file on where
+the binary and the config-file are.
+If the test succeeds and tor crashes a corefile should be dumped and the
+Script should print a backtrace and register informations on the standart output.
+Also it should print out the data that triggered the crash.
+
\subsubsection{Running the Control-Port tests}
Running tests against the Control-Port should be the same as running
the tests against the Dir-Port. If you're sure you did all config options
-right you can execute "ruby tor-control-fuzz.rb" and the rest is done
+right you execute "ruby tor-control-fuzz.rb" and the rest is done
automatically.
+
\subsection{Writing tests for TOR}
-To give you a more tor-specific example of how such a test might look i give you
-an example out of control.rb that helds the structures to fuzz the Tor
-control-port. From the control-spec we take the "SIGNAL" keyword and check out
-the syntax of the command: \begin{varbatim}"SIGNAL" SP Signal CRLF\end{verbatim}
-If we now want to check if the parsing of the given signal has a bug we also
-want to set the initial "SIGNAL" keyword and the appended crlf field to non-fuzzable.
-Implementing this as a FuzzStruct could look like this:\\
+Next it is shown how you can alter the Framework to write your own test-cases
+our implement future tor-protocols.
+To do this a bit tor-related we will write a test against the Control-Port
+ keyword "SIGNAL" (see \ref{control-spec} ).\\
+We start including topf and build a fuzz-struct containing the blocks that are describing the
+right Syntax to config SIGNAL.
\begin{verbatim}
+require "lib/topf"
+
class SignalItem < FuzzStruct
text :item, 6, :fuzzable => false
text :signal, 13
@@ -103,52 +121,84 @@
end
\end{verbatim}
The signal-field is chosen to be 13 bytes long as the longest signal-string
-("CLEARDNSCACHE") is 13 bytes long.\\
-Now we want to test the signal "RELOAD" so we create a SignalItem object and set
-signal to "RELOAD".
+("CLEARDNSCACHE") is 13 bytes long. Also the field item and crlf is set
+non-fuzzable so the fuzzing-algorithm doesnt alter these.\\
+Next we create a SignalItem object and set signal to "RELOAD" as a start.
\begin{verbatim}
si = SignalItem.new
si.signal = "RELOAD"
\end{verbatim}
-Next we want to apply two tests for the signal-field, a very long string and
-a format-string.
+Now we write two tests for the signal-field.
+One just returns the given argument, one returns an empty string, one
+creates a large string and one tries to test for a format-string bug
+using the format-string "\%n" which says the function using this string
+to write something on the stack.
\begin{verbatim}
t = Fuzz::Tests.new
t.register Fuzz::Test.new("char") {|arg, size| arg }
-t.register Fuzz::Test.new("char") {|arg, size| "A"*1000 } # long-string
-t.register Fuzz::Test.new("char") {|arg, size| "%n"*1000 } # format-string
-
+t.register Fuzz::Test.new("char") {|arg, size| "" } # empty-string
+t.register Fuzz::Test.new("char") {|arg, size| "A"*1000 } # long-string
+t.register Fuzz::Test.new("char") {|arg, size| "%n"*1000 } # format-string
si.prepare! t
\end{verbatim}
-Now we need a connection to the control-port through which we can send our data.
+As you can see we also applied the tests to our SignalItem using the "prepare!"
+method.\\
+Of course we also need a socket connecting to the control-port so we load our
+configuration-file and setup a options hash that we use to create a new Connection object.
\begin{verbatim}
+config = YAML::load_file "config/config.yml"
+
+observer = Fuzz::BinaryObserver.new "#{config["BINDIR"]}/tor", config["COREDIR"], "-f #{config["CONFDIR"]}/torrc", "&> /dev/null"
+observer.observe!
+
options = {
- :host => "127.0.0.1", # ip where our tor process is running
- :port => "2323", # number of the control-port
- :debug => true, # much output but shows the permutations
+ :host => config["HOST"], # ip where our tor process is running
+ :port => config["CONTROLPORT"], # number of the control-port
+ :debug => true, # more output but to show you how it works
+ # its okay :)
:type => :tcp, # tcp-connection
:timeout => 0.5 # timeout between each sending
}
c = Fuzz::Connection.new(options)
-c.fuzz!( si, " " )
\end{verbatim}
-This is allready enough to fuzz the Signal Item but it doesnt give us any
-information when the tor-process has been crashed by the fuzzer. Cause
-this is very important when running a larg amount of tests automatically
-one can use the Observer and Coremanager classes.\\
-To start a binary as a child of the observer class
-\subsection{Do the Fuzz!}
+Also included in the options hash is an observer item. This Object starts a new
+tor process if none is allready running. It also can check if new corefiles
+have appeared in the core-directory and prints information out of these files if
+it found a new core-file.
+Now everything is complete and we can start the test using the method "fuzz!"
+from the Connection class. This Method takes the Item thats going to be fuzzed
+and a join-character to join the data properly.
+\begin{verbatim}
+c.fuzz!(si, " ")
+\end{verbatim}
+Everything together can be found in the file tutorial-example.rb included in the
+example directory of the T.O.P.F Source-directory.\\
+Running all this should result in an output similar to this:\\
+\begin{verbatim}
+D, [2007-08-29T17:53:29.481354 #32593] DEBUG -- : [x] calculated 4 permutations of struct SignalItem /tor/
+I, [2007-08-29T17:53:29.492493 #32593] INFO -- : [x] /home/Benedikt/topf/binary/tor allready running
+I, [2007-08-29T17:53:29.492963 #32593] INFO -- : [x] fuzzing struct 1 of 1 with 4 permutations
+D, [2007-08-29T17:53:29.493126 #32593] DEBUG -- : sending data: SIGNAL
+D, [2007-08-29T17:53:29.493388 #32593] DEBUG -- : sending data: SIGNAL AAAAAAA...A
+D, [2007-08-29T17:53:29.493561 #32593] DEBUG -- : sending data: SIGNAL %n%n%n%...%n
+D, [2007-08-29T17:53:29.493561 #32593] DEBUG -- : sending data: SIGNAL %n%n%n%...%n
+D, [2007-08-29T18:03:20.273310 #32649] DEBUG -- : sending data: SIGNAL RELOAD
+I, [2007-08-29T17:53:29.494169 #32593] INFO -- : [?] no new corefile found
+\end{verbatim}
\section{T.O.P.F Reference}
\subsection{Fuzz}
\subsubsection{Test-Cases}
+Is implemented and documented under "lib/fuzz/test.rb"
\subsubsection{Tests}
+Is implemented and documented under "lib/fuzz/tests.rb"
\subsubsection{Connection}
+Is implemented and documented under "lib/fuzz/connection.rb"
\subsubsection{Observer}
+Is implemented and documented under "lib/fuzz/observer.rb"
\subsection{Dir}
\subsection{Control}
\subsection{Cell}
-\subsection{Logger}
\subsection{Backtrace}
\subsection{Proxy}
\subsubsection{Http-Proxy}
@@ -175,12 +225,14 @@
\section{Appendix}
\section{Links}
\label{links}
+\label{control-spec}
\begin{verbatim}
http://en.wikipedia.org/wiki/Fuzzing
http://events.ccc.de/congress/2005/fahrplan/attachments/582-paper_fuzzing.pdf
http://immunitysec.com/downloads/usingspike3.ppt
http://en.wikipedia.org/wiki/Ruby_%28programming_language%29
http://www.ruby-lang.org
+http://tor.eff.org/doc/control-spec.txt
\end{verbatim}
\end{document}
Added: topf/trunk/examples/tutorial-example.rb
===================================================================
--- topf/trunk/examples/tutorial-example.rb (rev 0)
+++ topf/trunk/examples/tutorial-example.rb 2007-08-29 19:19:35 UTC (rev 11302)
@@ -0,0 +1,39 @@
+require "../lib/topf"
+
+class SignalItem < FuzzStruct
+ text :item, 6, :fuzzable => false
+ text :signal, 13
+ char :crlf, 2*8, :fuzzable => false
+
+ initial_value.item = "SIGNAL"
+ initial_value.crlf = "\r\n"
+end
+
+begin
+ si = SignalItem.new
+ si.signal = "RELOAD"
+
+ t = Fuzz::Tests.new
+ t.register Fuzz::Test.new("char") {|arg, size| arg }
+ t.register Fuzz::Test.new("char") {|arg, size| "" } # empty-string
+ t.register Fuzz::Test.new("char") {|arg, size| "A"*1000 } # long-string
+ t.register Fuzz::Test.new("char") {|arg, size| "%n"*1000 } # format-string
+ si.prepare! t
+
+ config = YAML::load_file "../config/config.yml"
+
+ observer = Fuzz::BinaryObserver.new "#{config["BINDIR"]}/tor", config["COREDIR"], "-f #{config["CONFDIR"]}/torrc", "&> /dev/null"
+ observer.observe!
+
+ options = {
+ :host => config["HOST"], # ip where our tor process is running
+ :port => config["CONTROLPORT"], # number of the control-port
+ :debug => true, # more output but to show you how it works
+ # its okay :)
+ :type => :tcp, # tcp-connection
+ :timeout => 0.5, # timeout between each sending
+ :observer => observer
+ }
+ c = Fuzz::Connection.new(options)
+ c.fuzz!( si, " " )
+end
Modified: topf/trunk/lib/fuzz/connection.rb
===================================================================
--- topf/trunk/lib/fuzz/connection.rb 2007-08-29 19:02:43 UTC (rev 11301)
+++ topf/trunk/lib/fuzz/connection.rb 2007-08-29 19:19:35 UTC (rev 11302)
@@ -41,7 +41,7 @@
def fuzz!(structs, join_character="", args={})
structs = [structs] if !structs.is_a? Array
structs.each_with_index do |struct, index|
- Fuzz::LOGGER.info "[x] fuzzing struct %d of %d with %d permutations" % [index+1, structs.size, 0]
+ Fuzz::LOGGER.info "[x] fuzzing struct %d of %d with %d permutations" % [index+1, structs.size, struct.permutations]
Fuzz.fuzz(@observer, struct){|struct|
data = struct.join( join_character )
Modified: topf/trunk/lib/fuzz/observer.rb
===================================================================
--- topf/trunk/lib/fuzz/observer.rb 2007-08-29 19:02:43 UTC (rev 11301)
+++ topf/trunk/lib/fuzz/observer.rb 2007-08-29 19:19:35 UTC (rev 11302)
@@ -35,8 +35,11 @@
def is_running?
reg = Regexp.new( @programname.split("/").last )
- result = IO.popen("ps faux").readlines.find_all{|x| x=~ reg }
+ pp reg
+ result = IO.popen("ps -eo \"%p %c\"").readlines.find_all{|x| x =~ reg }
if result.size > 0
+ @pid = result.to_s.slice(/\d+/)
+ @running = true
true
else
false
Modified: topf/trunk/lib/fuzz-struct/fuzz-struct.rb
===================================================================
--- topf/trunk/lib/fuzz-struct/fuzz-struct.rb 2007-08-29 19:02:43 UTC (rev 11301)
+++ topf/trunk/lib/fuzz-struct/fuzz-struct.rb 2007-08-29 19:19:35 UTC (rev 11302)
@@ -556,7 +556,7 @@
end
def permutations
- @permutations.first.size
+ @permutations.collect{|x| x.size}.max
end
def fuzz!(opts = DEFAULT_INSPECT_OPTS)