Plugins

Since v0.6.0, you can write your own external plugins. For now, authentication, acl and audit plugins are supported.

Authentication

You will find here a fully working example of an external authentication plugin. Please refer to the Auth API page for more details.

 1from burpui.misc.auth import interface
 2
 3__type__ = 'auth'
 4
 5class UserHandler(interface.BUIhandler):
 6    name = 'CUSTOM:AUTH'
 7    priority = 1000
 8
 9    def __init__(self, app):
10        self.users = {
11            'toto': CustomUser('toto', 'toto'),
12            'tata': CustomUser('tata', 'tata'),
13            'titi': CustomUser('titi', 'titi'),
14            'tutu': CustomUser('tutu', 'tutu'),
15        }
16
17    def user(self, name):
18        return self.users.get(name, None)
19
20    @property
21    def loader(self):
22        return self
23
24class CustomUser(interface.BUIuser):
25    def __init__(self, name, password):
26        self.name = self.id = name
27        self.password = password
28
29    def login(self, passwd):
30        self.authenticated = passwd == self.password
31        return self.authenticated

Line 1 is mandatory since you must implement the auth interface in order for your plugin to work.

Line 3 __type__ = 'auth' defines a auth plugin.

Line 6 defines your auth backend name.

The rest of the code is just a minimal implementation of the auth interface.

This plugin defines four hardcoded users: toto, tata, titi, tutu with respectively the same passwords as their username.

You can put this code in a file called custom.py, save this file in /etc/burp/plugins for instance, and set plugins = /etc/burp/plugins. The plugin will be automatically loaded.

Note

This is just an example, do not run this particular plugin in production!

ACL

You will find here a fully working example of an external acl plugin. Please refer to the ACL API page for more details.

 1    from burpui.misc.acl import interface
 2
 3    __type__ = 'acl'
 4
 5    class ACLloader(interface.BUIaclLoader):
 6        name = 'CUSTOM:ACL'
 7        priority = 1000
 8
 9        def __init__(self, app):
10            self.app = app
11            self.admin = 'toto'
12            self._acl = CustomACL(self)
13
14        @property
15        def acl(self):
16            return self._acl
17
18        @property
19        def grants(self):
20            return None
21
22        @property
23        def groups(self):
24            return None
25
26        def reload(self):
27            """This method is used to reload the rules in case of config
28            change for instance"""
29            pass
30
31
32    class CustomACL(interface.BUIacl):
33
34        def __init__(self, loader):
35            self.loader = loader
36
37        def is_admin(self, username=None):
38            if not username:
39                return False
40            return username == self.loader.admin
41
42        def is_moderator(self, username=None):
43            if not username:
44                return False
45            return username == self.loader.admin
46
47        def is_client_rw(self, username=None, client=None, server=None):
48            if not username:
49                return False
50            return username == self.loader.admin
51
52        def is_client_allowed(self, username=None, client=None, server=None):
53            if not username:
54                return False
55            return username == self.loader.admin
56
57        def is_server_rw(self, username=None, server=None):
58            if not username:
59                return False
60            return username == self.loader.admin
61
62        def is_server_allowed(self, username=None, server=None):
63            if not username:
64                return False
65            return username == self.loader.admin

Line 1 is mandatory since you must implement the acl interface in order for your plugin to work.

Line 3 __type__ = 'acl' defines a acl plugin.

Line 6 defines your acl backend name.

The rest of the code is just a minimal implementation of the acl interface.

This plugin defines a hardcoded admin user: toto which will be granted admin rights through the whole application.

You can put this code in a file called custom_acl.py, save this file in /etc/burp/plugins for instance, and set plugins = /etc/burp/plugins. The plugin will be automatically loaded.

Note

This is just an example, do not run this particular plugin in production!

ACL engine has built-in Groups support, to take full advantage of this feature, it is recommended to use the meta_grants object as shown bellow:

Note

The grant syntax is explained in the ACL documentation

 1    from burpui.misc.acl.meta import meta_grants
 2    from burpui.misc.acl import interface
 3
 4    from six import iteritems
 5
 6    __type__ = 'acl'
 7
 8    class ACLloader(interface.BUIaclLoader):
 9        name = 'CUSTOM2:ACL'
10        priority = 1001
11
12        _groups = {
13            'gp1': {
14                'grants': '["server1", "server2"]',  # this needs to be a string
15                'members': ['user1'],
16            },
17        }
18
19        def __init__(self, app):
20            self.app = app
21            self.admin = 'toto'
22            self.init_rules()
23            self._acl = meta_grants
24            # We need to register our backend in order to be notified of
25            # configuration changes in other registered backends.
26            # This will then call our 'reload' function in order to re-apply
27            # our grants.
28            meta_grants.register_backend(self.name, self)
29
30        def init_rules(self):
31            for gname, content in iteritems(self._groups):
32                meta_grants.set_group(gname, content['members'])
33                meta_grants.set_grant(gname, content['grants'])
34
35        @property
36        def acl(self):
37            return self._acl
38
39        @property
40        def grants(self):
41            return self.acl.grants
42
43        @property
44        def groups(self):
45            return self._groups
46
47        def reload(self):
48            """This method is used to reload the rules in case of config
49            change for instance"""
50            self.init_rules()

You can omit either the meta_grants.set_grant or the meta_grants.set_group part if you like. For instance to define the grants of a given group using another ACL backend, and using your plugin to manage groups membership only.

Audit

# BUIaudit, BUIauditLogger as BUIauditLoggerInterface You will find here a fully working example of an external audit plugin. Please refer to the Audit API page for more details.

 1from burpui.misc.audit import interface
 2
 3import logging
 4
 5__type__ = 'audit'
 6
 7class BUIauditLoader(interface.BUIhandler):
 8    name = 'CUSTOM:AUDIT'
 9    priority = 1000
10
11    def __init__(self, app):
12        self.app = app
13        self.conf = app.conf
14        self.level = default = logging.getLevelName(self.app.logger.getEffectiveLevel())
15
16        if self.section in self.conf.options:
17            self.level = self.conf.safe_get(
18                'level',
19                section=self.section,
20                defaults=default
21            )
22
23        if self.level != default:
24            self.level = logging.getLevelName(f'{self.level}'.upper())
25            if not isinstance(self.level, int):
26                self.level = default
27
28        self._logger = BUIauditLogger(self)
29
30
31class BUIauditLogger(interface.BUIauditLogger):
32
33    def __init__(self, loader):
34        self.loader = loader
35        self._level = self.loader.level
36
37        self.LOG_FORMAT = 'CUSTOM AUDIT LOG %(levelname)s in %(from)s: %(message)s'
38
39    def log(self, level, message, *args, **kwargs):
40        kwargs['levelname'] = level
41        kwargs['message'] = message % args if args else message
42        print(self.LOG_FORMAT % kwargs)

Line 1 is mandatory since you must implement the audit interface in order for your plugin to work.

Line 5 __type__ = 'audit' defines a auth plugin.

Line 8 defines your auth backend name.

The rest of the code is just a minimal implementation of the audit interface.

You must define a self._logger object that implements the BUIauditLogger interface (see line 28).

In our example, the BUIauditLogger object is defined line 31.

This object must implement the log method. This is the method that will be called when the loglevel matches your minimal log level.