Creating your first module

The basics

after cloning the project from Official GitHub repo , in scant3r -> scant3r -> modules folder you'll find all modules of scant3r

scant3r/modules/
├── firebase
│   └── __init__.py
├── __init__.py
├── req_callback
│   └── __init__.py
├── scan.py
├── ssti
│   └── __init__.py
└── xss
    ├── __init__.py
    └── payload_gen.py

to create your own module all you'v to do is create a init file inside folder with the name of module

# CURRENT PATH: scant3r/scant3r/modules
$ mkdir sqli_error
$ touch sqli_error/__init__.py

then open the init file and write your own functions inside Main class but don't forget to add Scan as a subclass to it, why?

because Scan provides a lot of easier things to do something like send http request or create OAST host, etc ..

after that you'll need to add the user options that your module need in the init function parameters

like the URL of the target, HTTP headers ,HTTP method

from typing import Dict, List
from scant3r.core.requester import httpSender
from scant3r.modules.scan import Scan


class Main(Scan):
    def __init__(
        self,
        http: httpSender,
        methods: List[str],
        url: str,
        convert_body: bool = False,
        **_,
    ):
        self.opts = {
            "url": url,
            "methods": methods,
        }
        # scanner tag = scan for every url
        # recon tag = scan only once for the root domain
        # convert_body = allow the http request to auto change the request body based on the method / content-type 
        super().__init__(http, "scanner", convert_body)
    def start(self):
        pass

now you've the point of the start all need to do is writing you're own scanning logic

for example in this artical we'll write a SQLI errors finder so first we need to add the matching data that our scanner will use

for non-executable files add them in scant3r -> db

for global data you can add it in scant3r -> code -> data.py file

I'm gonna to add matching patterns inside sqli_db.json file

[
"(SQLite\\/JDBCDriver|SQLite.Exception|System.Data.SQLite.SQLiteException|Warning.*sqlite_.*|Warning.*SQLite3::|\\[SQLITE_ERROR\\])",
"(SQL error.*POS([0-9]+).*|Warning.*maxdb.*)",
"(Dynamic SQL Error|Warning.*ibase_.*)"
]
db/
└── txt
    ├── sqli_db.json

data.py

import os.path
import json

from rich.console import Console

base_dir = Path(__file__).resolve().parent.parent


+ SQLI_ERRORS = json.load(f"{based_dir}/db/txt/sqli_db.json")

write logic

before writing code inside `scan` function we need first to planning for the scanning steps

1- send a http request to the url

2- match the response with the regex patterns

import re
from typing import Dict, List, Tuple
from scant3r.core.requester import httpSender
from scant3r.core.utils import dump_response
from scant3r.modules.scan import Scan
from scant3r.core.data import SQLI_ERRORS
from rich.syntax import Syntax


class Main(Scan):
    def __init__(
        self,
        http: httpSender,
        methods: List[str],
        url: str,
        convert_body: bool = False,
        **_,
    ):
        self.opts = {
            "url": url,
            "methods":methods
        }
        # scanner tag = scan for every url
        # recon tag = scan only once for the root domain
        # convert_body = allow the http request to auto change the request body based on the method / content-type 
        super().__init__(http, "scanner", convert_body)
        
    def start(self) -> Dict[str,Tuple[str,str]]:
        reports = {}
        for method in self.opts["methods"]:
            req = self.send_request(method,self.opts["url"])
            if req.__class__.__name__ == "Response": # there's no http request errors here
                for match_pattern in SQLI_ERRORS:
                    get_match = re.search(match_pattern,dump_response(req))
                    if get_match:
                        self.show_report(
                        *(
                        ":fire: SQLI ERROR on: %s" % self.opts["url"],
                        ":meg: Regex pattern: %s" % match_pattern,
                         Syntax(get_match,"html")
                        )
                        )
                        reports[self.opts["url"]] = (match_pattern,get_match)
        return reports

Run it

# CURRENT PATH: ~/scant3r
$ pip3 install .
$ echo "https://testphp.vulnweb.com/listproducts.php?cat=1%27" | scant3r -m sqli_error -o data.json
$ cat data.json
[
"https://testphp.vulnweb.com/listproducts.php?cat=1%27": ("(SQL error.*POS([0-9]+).*|Warning.*maxdb.*)","SQLi error")
]

Last updated