/*  Copyright (c) 2005, Applied Security, Inc.
    Jared DeMott, jdemott@appliedsec.com, www.appliedsec.com

    This file is part of GPF.

    GPF is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    CmdLine is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with GPF; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

General Purpose Fuzzer (GPF)

Table of Contents
 1. GPF Description
 2. Requirements
 3. Make Instructions
 4. Directory Structure
 5. Using GPF
	5.1. PureFuzz Mode
	5.2. Convert Mode
	5.3. Main GPF Mode
		5.3.1. Buffer Overflow Attack
		5.3.2. Format String Attack
		5.3.3. Logic Error Attack
	5.4. PatternFuzz Mode
 6. Monitoring GPF
 7. SuperGPF
 8. User Defined Functions
 9. FAQ
10. Version Notes
11. Future Work


1. DESCRIPTION
Fuzzing is an active attempt to discovery bugs in software. GPF is designed to
facilitate this against IP networked code. GPF is a program that can replay
captured IP sessions against arbitrary targets (client mode) or against
arbitrary clients (server mode) with faults (fuzzy data) injected in the recorded stream.
To minimize development efforts we leverage existing code; ethereal.  GPF is as smart
and as protocol aware as one likes.  Manually updating the capture file is made 
simple by the conversion from libpcap to a easy to read text format.  Additionally,
user defined fuctions can be added to deal with sessions that perform dynamic 
calculations on data (hashes, etc.)


2. REQUIREMENTS TO RUN GPF (against any networked device)
*NIX, Ethereal, a sniffable network configuration, libpcap, gcc, make, etc.
The jabber component requires loudmouth.  If you don't care about jabber,
take jabber.h out of GPF.c and the "-lloudmouth-1" from
../GPF/Make_Templates/Make.bin


3. DIRECTORY STRUCTURE
/bin = the executable to run
/lib = the .a goes here
/Make_Templates = the actual make files that do the work are here
/src = Makefile to call makefiles
/src/lib = the .c for the socketlib
/src/bin = the .c for the GPF


4. MAKE INSTRUCTIONS
'make' or 'make install' to make the socketlib.o, libsocketlib.a, and GPF.
Don't be alarmed by the warnings during the compilation.

'make clean' to clean up, and than 'make install' to recompile.

Code has been tested on RH9 and fedora core 5, but any Linux should work.
To compile on Solaris uncomment the COMMONLIB in the Make.bin.


5. USING GPF
GPF has multiple modes: PureFuzz, Convert, GPF, Pattern fuzz, and SuperGPF.


5.1. PUREFUZZ MODE (Random):
Point it any IP aware code, and let it rip.  PureFuzz Mode sends totally
random sized packets with totally random data. The search space may be infinite,
but it's found a few bugs in the past.  The seed option allows the user to
choose the pseudorandom stream, and then replay that stream - if there was some
success. PureFuzz has a range (x-y) option to help narrow down the possible 
"bad" pkts if one of the many packets sent out did manage to crash the target.
Try purefuzz with different seeds.

Examples:
./GPF Target 21 TCP 68716299 100 -R +

To narrow it down
./GPF Target 23 TCP 68716299 100 -R 53-86


5.2. CONVERT MODE
In this mode, GPF converts a libpcap (ethereal capture) file to GPF's text
format. This allows the vulnerability researcher to easily make manual changes
to a capture file for replay. NOTE: Conversion is not required for replay.

Example:
./GPF cap cap.gpf -C


5.3. Main GPF MODE
Use ethereal to capture whatever conversation you like (TCP or UDP -- raw IP
not yet developed).  Save just one stream, such as an ftp client talking to an 
ftp server. (NOTE: Be sure to check the "Save only Packets currently being 
displayed" if a display filter was used. "Follow TCP stream" is a display
filter).  Start GPF with that file, and choose all the other fuzzing args to
fit your needs.  (NOTE: The machine running GPF need not be the host that
the stream was originally sent from or to.)  You will need to specify all the
args from the command line.  Execute './GPF' or './GPF ... -h' to bring up the
usage statement. In brackets [] behind each arg is a value that tends to be
popular.  Within the GPF mode there are three attack modes: 'b' will insert
incrementally increasing arbitrary buffers in search of buffer overflows.  
'f' will insert '%AChar' in search of format bugs.  
'l' will rotate each original data byte either progressively or send totally 
random data that is equal to the size of the original payload.  It's typically 
good to try all the various modes against your target.

For the logic attack AStart, Inc, Stop, and Char have special meanings.  
The AStart indicates a byte value at which to start.  Inc is how much to add 
to that value, and stop is the value at which we stop fuzzing.  0x00-0xff (0-255)
is the whole range. After that it begins changing other bytes as well.  Char has
meaning when set to 43; in that case it will randomize all the bytes for each leg
x times determined by the AStart, Inc, and Stop.


5.3.1. Buffer overflow attack:
	This will (in every position of the original data) send 1-17000 A's incrementing by 1 (then cycle after attack is sent)
./GPF ftpcapture 1 0 Target 21 TCP 123abc 1000 0 + 0 + 1 1 17000 41 2 none 0 3 0 -G b
	This will do the same thing but will finish sending each leg of the capture file after the attack has been sent
./GPF ftpcapture 1 0 Target 21 TCP 123abc 1000 0 + 0 + 1 1 17000 41 2 none 1 3 0 -G b
	This will do the same thing but with start@leg2, stop@leg4, start@position 6, and stop@position 9
./GPF ftpcapture 1 0 Target 21 TCP 123abc 1000 4 6 6 9 1 1 17000 41 2 none 1 3 0 -G b
	This will do the same thing but will wait 9 seconds if there's no data on each read and sends 2 extra attacks
./GPF ftpcapture 1 0 Target 21 TCP 123abc 1000 4 6 6 9 1 1 17000 41 2 none 1 9 2 -G b
	This will do the same thing but use a converted file
./GPF ftpcapture.gpf 0 0 Target 21 TCP 123abc 1000 4 6 6 9 1 1 17000 41 2 none 1 9 0 -G b
	those may take a while, so maybe try this first...
./GPF telnetcapture 1 0 Target 23 TCP 123abc 1000 0 + 0 + 1 1000 17000 41 2 none 1 3 0 -G b
	To start in the 5th position of the 2nd leg of a protocol (that would be 'PASS_' for FTP) and continue to end	
./GPF ftpcapture 1 0 Target 21 TCP 123abc 1000 2 + 5 +  1 1000 17000 41 2 none 1 3 0 -G b
	or to randomize do...
./GPF HTTPcapture 1 0 Target 80 TCP 123abc 1000 0 + 0 + 1 100 17000 43 2 none 1 3 0 -G b
	or...
./GPF dns 1 0 Target 53 UDP 456efg 1000 0 + 0 +  1 1 1500 43 2 none 1 3 0 -G b
	Here's server mode.  GPF will fuzz the client in this mode
./GPF ftpcapture 1 localhost 21 TCP 123abc 1000 2 + 5 + 1 1000 17000 41 2 none 1 3 0 -G b

Sample Output:

[root@server general]# ../GPF ftp.gpf 0 0 localhost 21 TCP 8973987234 100000 0 + 6 6 100 100 5000 43 2 none 1 3 0 -G b
7 total legs

Beginning replay attack:
  [<-DIFF-][0] "220 (vsFTPd 2.0.4)\x0d\x0a"
[1][-100->] "USER j"[b-6]"ared\x0d\x0a"
  [<--][2] "331 Please specify the password.\x0d\x0a"
[3][-->]  "PASS jared\x0d\x0a"
  [<-DIFF-][4] "530 Login incorrect.\x0d\x0a"
[5][-->]  "QUIT\x0d\x0a"
  [<--][6] "221 Goodbye.\x0d\x0a"
=================================Total Loops: 0====================================

  [<-DIFF-][0] "220 (vsFTPd 2.0.4)\x0d\x0a"
[1][-200->] "USER j"[b-6]"ared\x0d\x0a"
  [<-DIFF-][2] "331 Please specify the password.\x0d
530 Please login with USER and PASS.\x0d\x0a"
[3][-->]  "PASS jared\x0d\x0a"
  [<-DIFF-][4] "530 Login incorrect.\x0d\x0a"
[5][-->]  "QUIT\x0d\x0a"
  [<--][6] "221 Goodbye.\x0d\x0a"
=================================Total Loops: 1====================================

  [<-DIFF-][0] "220 (vsFTPd 2.0.4)\x0d\x0a"
[1][-300->] "USER j"[b-6]"ared\x0d\x0a"
  [<-DIFF-][2] "331 Please specify the password.\x0d
530 Please login with USER and PASS.\x0d\x0a"
[3][-->]  "PASS jared\x0d\x0a"
  [<-DIFF-][4] "530 Login incorrect.\x0d\x0a"
[5][-->]  "QUIT\x0d\x0a"
  [<--][6] "221 Goodbye.\x0d\x0a"
=================================Total Loops: 2====================================

  [<-DIFF-][0] "220 (vsFTPd 2.0.4)\x0d\x0a"
PAUSED
Use ctrl-\ to QUIT
Press Enter to continue.
...

The first line '7 total legs' indicates how my legs are in the capture file.  A leg is defined as one phase sent or recieved in an arbitrary protocol. The '[<--]' or '[<-DIFF-]' indicates data coming from the target, the later of the two flags data that's different from that in the capture file. The number '[0]' indecates that this is the first leg in the protocol.  The '[1][-100->]' indicates second leg and an attack size of 100 bytes going to the target. The "USER j"[b-6]"ared\x0d\x0a" shows the actual data that was sent out. '[b-6]' lets us know that a buffer attack in the 6th position of the original data was inserted. The CR and LF are explicitly printed for clearity.


5.3.2. Format string attack:
	This will insert 1-15 (by 1) %n's in the original data and send to target
./GPF SMTP 1 0 Target 25 TCP 123abc 1000 0 + 0 + 1 1 15 6e 2 none 1 3 0 -G f
	or to randomize...
./GPF ftpcapture 1 0 Target 21 TCP 2345678 1000 0 + 0 + 1 1 15 43 2 none 1 3 0 -G f


5.3.3. Logic error attack:
	This will cycle each data byte from 0x00 to 0xff by 1.
./GPF binary 1 0 Target 10260 UDP 994783 1000 0 + 0 + 00 1 255 41 1 none 1 3 0 -G l
	This will cycle each data byte from 0xa0 to 0xf0 by 0x0a
./GPF binary 1 0 Target 10260 UDP 123abc 1000 0 + 0 + 10 10 240 41 1 none 1 3 0 -G l
	This will randomize the value of all the data bytes for each leg 10 times
./GPF binary 1 0 Target 10260 UDP kj3874jff 1000 0 + 0 + 00 01 09 43 1 none 1 3 0 -G l

Sample Output:
[root@server general]# ../GPF ftp.gpf 0 0 localhost 21 TCP 8973987234 100000 0 + 6 6 255 1 256 41 2 none 1 1 1 -G l
7 total legs

Beginning replay attack:
  [<-DIFF-][0] "220 (vsFTPd 2.0.4)\x0d\x0a"
[1][-l_ff->] "USER �ared\x0d~"
~~waiting to read data~~
~~~~moving on without that data~~~~
{{Couldn't Read Socket (R -2)}}: Resource temporarily unavailable
[3][-l_ff->] "PASS �ared\x0d
~~waiting to read data~~
~~~~moving on without that data~~~~
{{Couldn't Read Socket (R -2)}}: Resource temporarily unavailable
[5][-->]  "QUIT\x0d\x0a"
  [<-DIFF-][6] "331 Please specify the password.\x0d\x0a"
=================================Total Loops: 0====================================

The '[-l_ff->]' indicates a logic attack with byte '0xff' currently being used as the replacement byte. Notice also that the attack happened both in the USER and PASS becuase the extra attacks options was set.

[root@server general]# ../GPF ftp.gpf 0 0 localhost 21 TCP 6561212 100000 0 + 6 6 255 1 256 43 2 none 1 1 0 -G l
7 total legs

Beginning replay attack:
  [<-DIFF-][0] "220 (vsFTPd 2.0.4)\x0d\x0a"
[1][-l_ff->] "=\�\"b�%:)F."
~~waiting to read data~~
~~~~moving on without that data~~~~
{{Couldn't Read Socket (R -2)}}: Resource temporarily unavailable
[3][-->]  "PASS jared\x0d\x0a"
  [<-DIFF-][4] "530 Please login with USER and PASS.\x0d\x0a"
[5][-->]  "QUIT\x0d\x0a"
  [<--][6] "221 Goodbye.\x0d\x0a"
=================================Total Loops: 0====================================

  [<-DIFF-][0] "220 (vsFTPd 2.0.4)\x0d\x0a"
[1][-->]  "USER jared\x0d\x0a"
  [<--][2] "331 Please specify the password.\x0d\x0a"
[3][-l_ff->] ".0.'g�f!j�a�"
~~waiting to read data~~
~~~~moving on without that data~~~~
{{Couldn't Read Socket (R -2)}}: Resource temporarily unavailable
[5][-->]  "QUIT\x0d\x0a"
  [<-DIFF-][6] "530 Please login with USER and PASS.\x0d\x0a"
=================================Total Loops: 1====================================

  [<-DIFF-][0] "220 (vsFTPd 2.0.4)\x0d\x0a"
[1][-->]  "USER jared\x0d\x0a"
  [<--][2] "331 Please specify the password.\x0d\x0a"
[3][-->]  "PASS jared\x0d\x0a"
~~waiting to read data~~
~~~~moving on without that data~~~~
{{Couldn't Read Socket (R -2)}}: Resource temporarily unavailable
[5][-l_ff->] "a1 72 6c d7 98 7c "
~~waiting to read data~~
  [<-DIFF-][6] "530 Login incorrect.\x0d\x0a"
=================================Total Loops: 2====================================

In this case the 'ff' doesn't mean anything. That's because the byte '43' was 
entered. Each leg was only fuzzed once because 255+1=266. If it had been
'1 1 10' each leg would have been fuzzed 10 times.


5.4. PATTERNFUZZ MODE (PF)
PF is a bit different than the main GPF mode.  It looks for patterns
(e.g. ascii, delimeter, ascii, delimeter, ending) and fuzzes according to 
internal rules.  This is nice for a user that may not be sure which values 
to choose in main mode, or a user that wants to fuzz all the different 
ways (buffer, logic, format, and more). PF also messes with cmd order and 
various other attributes. PF is currently tuned to work with ascii based 
protocols only, i.e 1 space for delimeter and CF LF for ending.

Sample Output:
[root@server general]# ../GPF ftp.gpf 0 0 localhost 21 TCP 92323232 100000 2 none 1 " " 1 -P
7 total legs

Beginning replay attack:
  [<-DIFF-][0] "220 (vsFTPd 2.0.4)\x0d\x0a"
[1][-p:12->] ".SER jared\x0d\x0a"
  [<-DIFF-][2] "530 Please login with USER and PASS.\x0d\x0a"
[3][-p:11->] "PASS jared\x0d"
~~waiting to read data~~
~~~~moving on without that data~~~~
{{Couldn't Read Socket (R -2)}}: Resource temporarily unavailable
[5][-p:6->] "Q.IT\x0d\x0a"
  [<-DIFF-][6] "503 Login with USER first.\x0d\x0a"
=================================Total Loops: 0====================================

  [<-DIFF-][0] "220 (vsFTPd 2.0.4)\x0d\x0a"
[1][-p:34->] "USER ja.e%d%d%d%d%d%d%d%d%d%d%dd\x0d\x0a"
  [<--][2] "331 Please specify the password.\x0d\x0a"
[3][-p:11->] "PASS jared\x0d"
~~waiting to read data~~
~~~~moving on without that data~~~~
{{Couldn't Read Socket (R -2)}}: Resource temporarily unavailable
[5][-p:6->] "QUIT\x0d\x0a"
  [<-DIFF-][6] "530 Login incorrect.\x0d\x0a"
=================================Total Loops: 1====================================

[0][-p:5->] "PASS "
[1][-p:5->] "USER "
  [<-DIFF-][2] "220 (vsFTPd 2.0.4)\x0d\x0a"
[3][-p:17->] "USER jared\x0d
PASS "
[4][-p:12->] "PASS jared\x0d\x0a"
[5][-p:6->] "QUIT\x0d\x0a"
[6][-p:2193->] ".Sp`.u*_.i,+m~{$..H.....
.1M)m%.\x0d.c"...'w.Sd-N        6SQGWVIv`f'-..R.!huDt.F.{uo_"=iX.:.h.i^pP..`.qr<Zh.NlGkh<ZH_.17)lW.}Aqn.w.q.}dMWMN&:.."Skj2..j-.A@..1s."...TRUNCATED...
=================================Total Loops: 2====================================

Notice the '[-p:num->]' shows the total size of the attack sent out.  Also, the printing of large attacks is truncated.


6. MONITORING GPF
Carefully watch the responses from the server while running GPF.  If you get 
a lot of premature RST's or if the target stops responding, try slowing GPF 
down.  If that doesn't work check your cmdline args and capture file to be 
sure they are valid.

If GPF just hangs there's probably a good reason.  It could be it sent a 
value to the target and the target choked, but GPF isn't done with a 
sequence so it keeps going and doesn't notice the deviation in traffic.
For example, with the Jabber protocol an ID is sent by the server to the 
client in the first leg.  When the client talks back in subsequent legs (to 
authenticate) that ID needs to have been correctly processed (sha1(ID+user)) 
and sent back, or jabber will kill the connection prematurely.  
In a case such as this, a user function needs to be defined.


7. SUPERGPF
SuperGPF is an extenion that takes a .gpf protocol capture and a .txt (cmds 
valid for that protocol), and creates 100's or 1000's of new capture files.
Using those files, superGPF starts many main mode or pattern mode GPF's.

The .txt that superGPF reads in has three sections, each user more frequently
than the next.  There are some examples in the bin directory.

All the config params are in superGPF.pl and should be tuned for your 
particular application. The one downside to this approach is that it's often 
difficult to determine that exact cause of a server crash as it may be caused 
by some combination of the multiple fuzzers running in tandem. To mitigate 
this problem, copies of each session are stored in the GPF subdir, which
needs to be there. 

When fuzzing it is best to start easy (pure or main mode) and than ramp up
to superGPF.


8. USER DEFINED FUNCTIONS
User functions are additional code that can be compiled with GPF to 
perform an "intelligent replay." (Calulating a hash, etc.)

To add a user function:
- In the ../GPF/include directory add your .h file, such as jabber.h.
- In the ../GPF/src/bin/GPF.c file, add the .h to the userFunc section. 
  Also, update the USERFUNC() if-then statement
- In the ../GPF/Make_Templates directory add any libs needed, 
  such as -lloudmouth-1 for jabber
- Do the normal 'make clean', and 'make install' to rebuild GPF.

When you envoke GPF the exact function name ('jabber' in this case) should be 
used such as this:

./GPF jabber 1 0 Target 5222 TCP 8973987234 1000 0 + 0 + 00 01 9999 43 2 jabber 1 3 -G b


9. FAQ

Q:  What will the program do with mixed pkt streams? 
A:  It will attempt to send that data as if it were part of the current stream. 
I could filter that, but why? The user creating the capture should get just
one stream.

Q:  What are some recommended attacks?
A:
  A. Try purefuzz -R 

  B. Looking for buffer overflows
     0 + 0 + 100 77 17000 6e 2 none 1 3 x -G b

  C. Looking for format bugs
     0 + 0 + 1 1 20 6e 2 none 1 3 x -G f

  D. Looking for logic flaws
     0 + 0 + 1 1 255 6e 2 none 1 3 x -G l

  E. Looking for logic with random data on each line
     0 + 0 + 1 1 255 43 2 none 1 3 x -G l

  F. Looking for buffer overflows, with random insert data
     0 + 0 + 100 100 12000 43 2 none 1 3 x -G b

  G. Looking for bugs with pattern matching
     0 + 0 + 100 100 12000 43 2 none 1 3 x -G b

  H. Looking for everything: try -P

  I. Really looking for everything: USE superGPF.pl  to do them all. Don't forget to change
     the files, IP, PORT, PROTO, timing, etc. for your particular protocol.


10. VERSION NOTES
Beta version 0.0, 03/28/05
  Introducing the General Purpose Fuzzer...lets find some bugs!! :)

Beta version 0.1, 04/01/05
  Added userFuncs, added server capability, fixed read/write seq, 
  increased speed, updated README, etc.

Version 0.11, 04/05/05
  More data included in prints, enhanced plugin capability, etc.

Version 0.12, 04/06/05
  Minor display changes to enhance user experience.

Version 0.14, 04/18/05
  Added a verification mode (replay with no attack) and a cycle mode (to 
  control if GPF will continue replaying after attack or not).

Version 0.2, 04/20/05
  Changed the way reading is done to allow GPF to ignore bad reads from the 
  server and move on.  Added stopLeg, stopPosition, and readWait.

Version 0.3, 04/21/05
  Added a method for libpcap files to be converted to a .gpf format, for easy 
  manual changes, and than replay through GFP.  This also allows for creation 
  of new txt.gpf files to have GPF fuzz protocols that weren't a capture.  
  Changed usage statements around a bit.

Version 0.31, 05/25/05
  Minor changes made while using GPF to fuzz isakmpd.  Also added a 
  -I 'Internal UserFunc'.  Added this so I could write a userfunc that was out 
  of the ordinary.  (it adds multiple VendorIDs to pkt1 in an iskmpd exchange).

Version 0.4, 05/27/05
  GPF now has the ability to be a UDP server.  The problem, UDP doesn't do 
  any SYNC (like TCP does at the beginning of a stream).  Therefore, it's 
  very easy to get out of sequence.  Thus, I've added a 
  'return value/goto hook' in USERFUNC location==1 (after the read) such that 
  a userFunc() can now be written to SYNC UDP transfers.  Actively working on 
  the isakmp userFuncs.

Version 0.41, 06/01/05
  Fixed a stupid little bug in the -R option, and added a bit more to the 
  -I test.

Version 1.0, 01/11/06
  Added superGPF.pl perl extension. SuperGPF could also be used to do file
  fuzzing.  Fixed minor startPosition, bug so it won't generate core 
  if SP > max.

Version 1.1, 01/31/06
  Fixed a few bugs in superGPF and made some enhancements to it.

Version 1.2, 02/06/06
  Changed the way time delays and error printing works in GPF.

Version 1.3, 02/12/06
  Made superGPF's file fuzzing a bit smarter.

Version 1.4, 02/15/06
  Minor updates to GPF: Print '\x0d' for '\r'. Randomize -l changes after 255.

Version 2.0, 03/08/06
  Made wholesale changes.  The way the attack functions are called is more 
  modular.  This allowed for the extraAttacks extension.  The biggest change 
  is the new Pattern Matching type - it's a different approach to fuzzing, and 
  it rocks. :)

Version 2.1, 03/14/06
  Updated superGPF: fixed .gpf readin (to use embedded size) and added Pattern Matching support.

Version 2.2, 06/14/06
  Updated/cleaned up a few files like this README.


11. FUTURE WORK
- Reorganize code in GPF.c
- Fix the way superGPF.pl reads in \r\n.
- Handle IP/ICMP in GPF.c (change read/writes for ICMP?)

