- home
- info. for developers
- server plugins
- import plugins
Import Plugins
An import plugin is a special type of server plugin.
Import plugins let you search in remote sources of information and import back the results to the dradis repository.
You can access the Import plugins through the Import note...
tab in dradis web interface:
How to create an import plugin
We are going to go through the steps to create a new import plugin to search for vulnerabilities in the Open Source Vulnerability Database (OSVDB).
- Define Plugin Goals
- Generate the Plugin
- Create the Test Cases
- Plugin Configuration
- Implement the Functionality
- Add Rake tasks
- More Information
Define Plugin Goals
We are going to use OSVDB's API to query the database, so we will need an API key that we can get from: https://osvdb.org/account/signup.
Our plugin will have two filters (i.e ways of querying the OSVDB database):
- OSVDBIDLookup: used to lookup a specific OSVDB ID.
- GeneralSearch: tu run a query with a custom search string.
In this tutorial we will cover the first one. The full code of the plugin is available in the project's subversion repository under
/dradis/server/trunk/vendor/plugins/osvdb_import/
Generate the Plugin
The framework comes with a few handy plugin generators that will help you getting your plugin kickstarted. Go to the server folder and run:
$ ./script/generate import_plugin osvdb
That will generate all the files we are going to need for the plugin.
All the generated code have been put in: ./vendor/plugins/osvdb_import/.
Create the Test Cases
To know where we are going, we start the plugin development by figuring out what test cases we are going to need to verify that our code does what it is meant to do.
We will create two unit tests:
- One to verify that we have a valid API key.
- Another to verify we are pulling the right information from the server.
Edit ./test/osvdb_import_test.rb:
def test_no_API_key
OSVDBImport::CONF['API_key'] = OSVDBImport::BAD_API_KEY
assert_raise RuntimeError do
OSVDBImport::Filters::validate_API_key()
end
end
So we will implement a validate_API_key() method that would
ensure that the configured API key is valid.
As we will see in the next section, the test case code makes use of the
OSVDBImport::CONF constant. This constant is generated by the
import_plugin generator and will hold all the configuration
settings of your plugin.
The test case can be extended to ensure that the different filters are making use of such function.
We are not providing the full code for the test cases in this tutorial for the sake of clarity, but the bottom line is: write your test cases before your code.
Plugin Configuration
If you check the ./lib/osvdb_import.rb you will see the
following constants:
CONF_FILE = File.join(RAILS_ROOT, 'config', 'osvdb_import.yml')
CONF = YAML::load( File.read CONF_FILE )
The plugin generator created a plugin config file for you
(./conf/osvdb_import.yml) and included this code to load the
configuration data from the file into the CONF constant. The config file
is in YAML format.
It also did a couple of other things:
- Create install hooks to copy the plugin's config file
(
./vendor/plugins/osvdb_import/conf/osvdb_import.yml) to the framework's config directory (./conf/) when the plugin is installed into an existing dradis folder. - Create uninstall hooks to remove the config file from the application if the plugin is uninstalled.
In our case, the config file will only contain one key/value pair: API_key, to store your OSVDB's API key:
# Please register an account in the OSVDB site to get your API key. Steps:
# 1. Create the account: http://osvdb.org/account/signup
# 2. Find your key in http://osvdb.org/api
API_key: <your_API_key>
<your_API_key> is the default value and needs to be
changed by the user (the Filters::validate_API_key() will
verify that the user has set their API key - see below).
A final note on configuration: when installed the plugin will copy the config file to its final location, however since you are creating the plugin for the first time, you need to copy the file manually:
$ cp ./vendor/plugins/osvdb_import/config/osvdb_import.yml config/
Implement the Functionality
Lets first have a look at the implementation of the OSVDBIDLookup filter:
module OSVDBImport
module Filters
module OSVDBIDLookup
NAME = 'OSVDB ID Lookup'
def self.run(params={})
# Ensure that we have a valid OSVDB API key
begin
Filters::validate_API_key()
rescue Exception => e
return [
{
:title => 'Error in OSVDB API key',
:description => e.message
}
]
end
logger = params.fetch( :logger, RAILS_DEFAULT_LOGGER )
query = CGI::escape( params.fetch( :query, '1234') )
logger.info{"Running a OSVDB ID lookup on: #{query}"}
results = OSVDB::IDLookup(
:API_key => CONF['API_key'],
:osvdb_id => query
)
return Filters::from_OSVDB_to_dradis( results)
end
end
# [...] other filters
end
end
When creating Import Plugin filters, a few rules apply:
- Each filter is defined as a new module inside the Filters module.
- Each filter module needs to define a
NAMEconstant. - The filter needs to return an array of
Hashobjects. Each hash needs to have a:titleand a:descriptionfield.
In our example the first thing we do is to ensure that we have a valid
API key with a call to Filters::validate_API_key().
If we do, then we make a call to the OSVDB::IDLookup
(more on this library later) to fetch the results.
Finally we use the Filters::from_OSVDB_to_dradis() helper
method to convert from the OSVDB format to the format expected by the
framework (see rule #3 above).
In order to avoid cluttering in the filter definition I placed all the
OSVDB fetching code in a separate file, the OSVDB module. It
handles the HTTP connection and XML parsing of the response. You can
checkout the source code here: /dradis/server/trunk/vendor/plugins/osvdb_import/lib/osvdb.rb.
Add Rake Tasks
The last step in the process is to make your plugin's functionality available through the command line.
This is done by virtue of Rake (simple ruby build program with capabilities similar to make).
This is a good idea also for debugging purposes. Rails plugins do not get reloaded unless you restart the server. So in order for a change in your code to become used by the framework, you need to restart dradis (which is a slow process). Running your plugin through rake will make debugging easier.
The plugin generator defined a dummy rake task in:
./tasks/osvdb_import_tasks.rake, we will replace it a
slightly more complex (and useful) one:
desc "Run a OSVDB ID Lookup"
task :osvdb_id_lookup, :id, :needs => :environment do |task, args|
logger = Logger.new(STDOUT)
logger.level = Logger::DEBUG
results = OSVDBImport::Filters::OSVDBIDLookup.run(
:query => args[:id],
:logger => logger )
logger.info{ "Total number of records: #{results.size}\n" }
results.each do |record|
puts "#{record[:title]}\n\t#{record[:description]}"
end
end
In a nutshell this task invokes the
OSVDBImport::Filters::OSVDBIDLookup filter with a
:query that the user passes as a command line parameter.
Afterwards, it prints the results.
Note that the final version of the plugin makes use of Rake's namespaces. The art of Rake tasks is complex and we can't cover much depth here.
More Information
So that is about it. You are good to go, all the components are in place and the new plugin should be integrated with your dradis server.
Import plugins as any dradis server plugin are just standard Ruby on Rails plugins with a specific structure and purpose.
You can learn more about Rails plugins at the Plugins page of the Rails wiki.
using dradis:
developing dradis:
communications channels:
#dradis at freenode.orgsupport from:
If you're part of the community, have used the tool, like the project or want to tell everybody you support the project and it's goals, do not hesitate in contacting us so we can add your link.
