Created ServiceScan Plugin (markdown)

Tib3rius 2021-08-29 23:27:01 -04:00
parent 0790a723c6
commit 9992bd2f99
1 changed files with 86 additions and 0 deletions

86
ServiceScan-Plugin.md Normal file

@ -0,0 +1,86 @@
# ServiceScan Plugin
The following is an example ServiceScan plugin which performs a simple Curl request to a website:
```python
from autorecon import ServiceScan
class Curl(ServiceScan):
def __init__(self):
super().__init__()
self.name = "Curl"
self.tags = ['default', 'safe', 'http']
def configure(self):
self.add_option("path", default="/", help="The path on the web server to curl. Default: %(default)s")
self.match_service_name('^http')
self.match_service_name('^nacn_http$', negative_match=True)
self.add_pattern('(?i)Powered by [^\n]+')
async def run(self, service):
if service.protocol == 'tcp':
await service.execute('curl -sSik {http_scheme}://{addressv6}:{port}' + self.get_option('path'), outfile='{protocol}_{port}_{http_scheme}_curl.html')
```
Here is a breakdown:
```python
from autorecon import ServiceScan
```
This simply imports the ServiceScan class from AutoRecon, something that is required to write a valid ServiceScan plugin.
```python
class Curl(ServiceScan):
def __init__(self):
super().__init__()
self.name = "Curl"
self.tags = ['default', 'safe', 'http']
```
Each plugin is defined as a class. If you are familiar with object-oriented programming, you'll understand this. If not, just know that a class name ("Curl" in this case) has to be unique. The parentheses after the class name tell AutoRecon that this is a ServiceScan plugin.
Every plugin has a number of methods / functions that it must define. The first is the __init__ method, which must call `super().__init__()` before anything else.
The last two lines define attributes of the plugin. Technically, only `self.name` is required. This is the name which AutoRecon will use when referring to the plugin in its output, and so should ideally be kept short. It should also be unique, but does not have to be the same as the class name.
`self.tags` defines a list of tags that the plugin belongs to. By default, all plugins are tagged as "default" only, meaning the plugin will run if no tags are specified on the command line. If you override the tags list, you should include the "default" tag if you want the plugin to run by default.
```python
def configure(self):
self.add_option("path", default="/", help="The path on the web server to curl. Default: %(default)s")
self.match_service_name('^http')
self.match_service_name('^nacn_http$', negative_match=True)
self.add_pattern('(?i)Powered by [^\n]+')
```
Plugins can have a `configure(self)` method if they need to configure something with AutoRecon. In the case of ServiceScan plugins, the configure method is mandatory, as plugins must at the very least add a service name to match against.
The `self.add_option` line configures a user option called "path" which defaults to "/" (the webroot). Users can change this at runtime using the command-line option --curl.path or by setting the following in their config file:
```toml
[curl]
path = "/newpath"
```
Many different types of options can be set. Check out the API documentation for more details.
The next two lines tell AutoRecon to run this plugin if it matches the regular expression '^http', and to not run it if it matches the regular expression '^nacn_http$'.
The final line adds a pattern which AutoRecon will attempt to match against output from this plugin only. It attempts to match HTTP response headers that disclose the language the website is using.
```python
async def run(self, service):
if service.protocol == 'tcp':
await service.execute('curl -sSik {http_scheme}://{addressv6}:{port}' + self.get_option('path'), outfile='{protocol}_{port}_{http_scheme}_curl.html')
```
The "run" method is actually a coroutine, identified by the "async" keyword before the definition. This means it will run asynchronously (i.e. concurrently) with other methods. This method is passed a Service object via the "service" argument in the definition.
Since the `curl` command (which this plugin runs) does not work against UDP, there is a quick check to confirm the protocol of the service is TCP.
Service objects have an "execute" method which can be used to execute commands on the underlying OS. As this method is asynchronous, it must be awaited using the "await" keyword. This method returns three things: a Process object, a custom CommandStreamReader which reads standard output, and a custom CommandStreamReader which reads standard error.
For this example, and for most ServiceScan plugins, you do not need to worry about any of these returned values.