Wiki

Imprimir Propiedades
Developers Guide

In this section is described how to extend the functionality of Wapiti. The character strings used in some attacks can be configured and also new attacks can be developed.

For configuring the character strings is not necessary have programming skills only knowledge in web application security, but for developing a new attack is necessary knowledge in python language and object-oriented programming skills.

 

 

Adding more character strings to use into the attacks

Wapiti acts like a fuzzer, injecting payloads to see if a script is vulnerable. A fuzz testing or fuzzing is a software testing technique that provides random data ("fuzz") to the inputs of a program. If the program fails (for example, by crashing, or by failing built-in code assertions), the defects can be noted.

 

This payloads or data which are used into the attacks can be extended easily. Each attack has a configuration fail where are stored the character string that are going to be used in the attack.

 

This files are into "config/attacks" directory:

  • execPayloads.txt: The payloads for execution commands attack.
  • fileHandlingPayloads.txt: The payloads for file handling attack.
  • xssPayloads.txt: The payloads for cross site scripting attack.

 

Adding a new attack to Wapiti

You have to follow the next steps:

 

1. Create a class that extends Attack class

Create a class in "attack" package ("attack" folder inside wapiti hierarchy directories) which extends Attack class. The name of the class should have this format: <NameOfAttack>Attack. The class should be stored in a file with the same name that the class but without use capital letters and with the suffix ".py" of python files: <nameofattack>attack.py.

 

 

Example: For SQL injection attack, the name of the class should be "SQLInjectionAttack" and should be into "sqlinjectionattack.py" file

[file: sqlinjectionattack.py]
class SQLInjectionAttack(Attack):  	
  """SQLInjectionAttack"""

 

2. Implement the methods attackGET and/or attackPOST

  • attackGET(self,page,dict,attackedGET): This method must make an attack by GET if proceed
    • page: the URL of the page
    • dict: a dictionary that contains as keys the parameters and as values the values of the parameters.
    • attacketGET: array that contains all the URLs that have been previously proved.
  • attackPOST(self,form,attackedPOST): This method must make an attack by POST if proceed
    • form: an array with the information about the form.
      • the first element (form[0]) is the URL where the form go when is submitted.
      • the second element (form[1]) is a dictionary that contains as keys the parameters and as values the values of the parameters.
      • the third element (form[2]) is the URL of the page where is the form.
    • attacketPOST: array that contains all the URLs that have been previously proved.

3. Use the objects inherited from Attack class

You can use the following objects that can help you to implement your class:

  • reportGenerator: this object is responsible for generating the report.
  • HTTP: this object manages all the things related with connections and request to Internet.

For more information see the code of the attacks already implemented (SQLInjectionAttack, ExecAttack, etc).

 

4. Integrate with Wapiti class in order to execute the attack developed

You have to do changes in some Wapiti class methods this class is in wapity.py file and it is situated in wapiti root folder. In the next chapters are described the changes for each method and with a example. In the example we add a example attack implemented in ExampleAttack class.

 

Import the class which implements the attack

Import the attack class for using in Wapity class.

Example: Importing ExampleAttack. At the top of the file you have to add the import of ExampleAttack class:

from attack.exampleattack import ExampleAttack

 

Method __initAttacks(self)

In this methods you should instantiate the Attack and append to the attacks array.

Example: Adding ExampleAttack

This is the current status of the method:

def __initAttacks(self):   
  self.__initReport()   
  self.sqlInjectionAttack = SQLInjectionAttack(self.HTTP,self.reportGen)   
  self.fileHandlingAttack = FileHandlingAttack(self.HTTP,self.reportGen)   
  self.execAttack         = ExecAttack        (self.HTTP,self.reportGen)   
  self.crlfAttack         = CRLFAttack        (self.HTTP,self.reportGen)   
  self.xssAttack          = XSSAttack         (self.HTTP,self.reportGen)   
  self.attacks = [self.sqlInjectionAttack, self.fileHandlingAttack,                   
                  self.execAttack, self.crlfAttack, self.xssAttack]   
  for attack in self.attacks:     
    attack.setVerbose(self.verbose)     
    if self.color == 1:       
      attack.setColor()

After adding ExampleAttack:

def __initAttacks(self):   
  self.__initReport()   
  self.sqlInjectionAttack = SQLInjectionAttack(self.HTTP,self.reportGen)   
  self.fileHandlingAttack = FileHandlingAttack(self.HTTP,self.reportGen)   
  self.execAttack         = ExecAttack        (self.HTTP,self.reportGen)   
  self.crlfAttack         = CRLFAttack        (self.HTTP,self.reportGen)   
  self.xssAttack          = XSSAttack         (self.HTTP,self.reportGen)   
  self.exampleAttack      = ExampleAttack     (self.HTTP,self.reportGen)
  self.attacks = [self.sqlInjectionAttack, self.fileHandlingAttack,                   
	          self.execAttack, self.crlfAttack, self.xssAttack, self.exampleAttack]   
  for attack in self.attacks:     
    attack.setVerbose(self.verbose)     
    if self.color == 1:       
      attack.setColor()

 

Add a variable called do<name_of_attack> and its setter method

You have to define a variable and a method with the next signature:

  • Variable: If the value is 1 the attack will be performed and if it is 0 will not
    do<name_of_attack> = 1
    
  • Method: It sets the value of a control variable that indicates if the attack will be performed when all the attacks are launched.
    def set<name_of_attack>(self,<name_of_attack>=1):   
      self.do<name_of_attack>=<name_of_attack>     

 

Example: Adding ExampleAttack

You can define the variable when you want inside Wapiti class but defining at the top of the class is correct according with code conventions. If the value is 1 the attack will be performed and if it is 0 will not.

doExample=1

The method also can be declared in any part of Wapiti class:

def setExampleAttack(self,example=1):   
  self.doExample=example

 

Method attackGET

This method performs all the GET attacks available with the URLs caught previously. It invokes the method attackGET() of the instances of the attack classes created in the method __initAttacks().

 

Example: Adding ExampleAttack

This is the current status of the method:

def attackGET(self,url):
  page=url.split('?')[0]
  query=url.split('?')[1]
  params=query.split('&')
  dict={}
  if self.verbose==1:
    print "+ attackGET "+url
    print "  ",params
  if query.find("=")>=0:
    for param in params:
      dict[param.split('=')[0]]=param.split('=')[1]
  if self.doFileHandling==1: self.fileHandlingAttack.attackGET(page,dict,self.attackedGET)
  if self.doExec==1:         self.execAttack        .attackGET(page,dict,self.attackedGET)
  if self.doInjection==1:    self.sqlInjectionAttack.attackGET(page,dict,self.attackedGET)
  if self.doXSS==1:          self.xssAttack         .attackGET(page,dict,self.attackedGET)
  if self.doCRLF==1:         self.crlfAttack        .attackGET(page,dict,self.attackedGET)

After adding ExampleAttack:

def attackGET(self,url):
  page=url.split('?')[0]
  query=url.split('?')[1]
  params=query.split('&')
  dict={}
  if self.verbose==1:
    print "+ attackGET "+url
    print "  ",params
  if query.find("=")>=0:
    for param in params:
      dict[param.split('=')[0]]=param.split('=')[1]
  if self.doFileHandling==1: self.fileHandlingAttack.attackGET(page,dict,self.attackedGET)
  if self.doExec==1:         self.execAttack        .attackGET(page,dict,self.attackedGET)
  if self.doInjection==1:    self.sqlInjectionAttack.attackGET(page,dict,self.attackedGET)
  if self.doXSS==1:          self.xssAttack         .attackGET(page,dict,self.attackedGET)
  if self.doCRLF==1:         self.crlfAttack        .attackGET(page,dict,self.attackedGET)
  if self.doExample==1:      self.exampleAttack     .attackGET(page,dict,self.attackedGET)

 

Method attackPOST

This method performs all the POST attacks available with the forms found previously. It invokes the method attackPOST() of the instances of the attack classes created in the method __initAttacks().

 

Example: Adding ExampleAttack

This is the current status of the method:

def attackPOST(self,form):
  if self.verbose==1:
    print "+ attackPOST "+form[0]
    print "  ",form[1]
  if self.doFileHandling==1: self.fileHandlingAttack.attackPOST(form,self.attackedPOST)
  if self.doExec==1:         self.execAttack        .attackPOST(form,self.attackedPOST)
  if self.doInjection==1:    self.sqlInjectionAttack.attackPOST(form,self.attackedPOST)
  if self.doXSS==1:          self.xssAttack         .attackPOST(form,self.attackedPOST)

After adding ExampleAttack:

def attackPOST(self,form):
  if self.verbose==1:
    print "+ attackPOST "+form[0]
    print "  ",form[1]
  if self.doFileHandling==1: self.fileHandlingAttack.attackPOST(form,self.attackedPOST)
  if self.doExec==1:         self.execAttack        .attackPOST(form,self.attackedPOST)
  if self.doInjection==1:    self.sqlInjectionAttack.attackPOST(form,self.attackedPOST)
  if self.doXSS==1:          self.xssAttack         .attackPOST(form,self.attackedPOST)
  if self.doExample==1:      self.exampleAttack     .attackPOST(form,self.attackedPOST)

 

 

4160 Accesos, 2 Ficheros adjuntos 2 Ficheros adjuntos

  • Comentarios