Modules
Oblivion's power comes from its modular design. Each module is a focused tool designed to perform specific web hacking and security tasks. Modules can be easily loaded, configured, and executed from the interactive REPL.
dns brute
Brute-force subdomains using a wordlist and DNS resolution, optionally appending numeric suffixes to found hosts
Usage: use dnsbrute
port scanner
Simple port scanner with UDP support
Usage: use portscanner
subdomains search
Simple subdomains search
Usage: use subdomains_search
subdomain takeover
Detects subdomain takeover via CNAME and HTTP response analysis
Usage: use subdomain_takeover
web spider
Web spider with JavaScript support via headless browser
Usage: use webspider
Custom Modules
You can extend Oblivion by creating your own modules in Go. Write your code in the /modules
directory, then register your module in main.go
to make it available in the REPL.
Example file location: modules/custom/my_module.go
Below is a generic, fully‑commented Go “boilerplate” template you can adapt for any Oblivion module that uses a cancellable context, worker goroutines and channels. Replace the {{…}} placeholders with your own module’s names, options, and logic:
package {{ .PackageName }}
import (
"context"
"fmt"
"os"
"sort"
"sync"
"github.com/czz/oblivion/utils/option"
"github.com/czz/oblivion/utils/help"
)
// {{ .StructName }} is the main struct for the {{ .ModuleTitle }} module.
type {{ .StructName }} struct {
optionManager *option.OptionManager
help *help.HelpManager
results []string
running bool
name string
author string
desc string
prompt string
}
// New{{ .StructName }} constructs a new {{ .ModuleTitle }} instance.
func New{{ .StructName }}() *{{ .StructName }} {
om := option.NewOptionManager()
// Register your options here. Example:
om.Register(option.NewOption("TARGET", "", true, "The target to process"))
om.Register(option.NewOption("THREADS", "10", false, "Number of concurrent workers"))
// … add more options as needed …
hm := help.NewHelpManager()
hm.Register("{{ .Prompt }}", "{{ .ModuleTitle }}", [][]string{
{"TARGET", "example.com", "The domain to enumerate"},
{"THREADS", "10", "Concurrency level"},
// … help for other options …
})
return &{{ .StructName }}{
optionManager: om,
help: hm,
name: "{{ .ModuleTitle }}",
author: "{{ .Author }}",
desc: "{{ .Description }}",
prompt: "{{ .Prompt }}",
}
}
// Run executes the module, honoring context cancellation.
func (m *{{ .StructName }}) Run(ctx context.Context) [][]string {
// Clear previous results
m.results = nil
// 1. Extract and validate options
targetOpt, _ := m.optionManager.Get("TARGET")
threadsOpt, _ := m.optionManager.Get("THREADS")
target := targetOpt.Value.(string)
threads := 10
if t, err := strconv.Atoi(threadsOpt.Value.(string)); err == nil && t > 0 {
threads = t
}
if target == "" {
return [][]string{{"Error: TARGET not set"}}
}
// 2. Prepare your input slice (e.g. wordlist, prefixes, IPs…)
inputs := []string{/* fill from file or option */}
// 3. Create channels
tasks := make(chan string, len(inputs))
results := make(chan string, len(inputs))
// 4. Enqueue all tasks and close
for _, item := range inputs {
tasks <- item
}
close(tasks)
// 5. Launch worker goroutines
var wg sync.WaitGroup
for i := 0; i < threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for {
select {
case <-ctx.Done():
// context cancelled: exit immediately
return
case item, ok := <-tasks:
if !ok {
return
}
// --- YOUR PROCESSING LOGIC HERE ---
if someCheck(item) {
select {
case <-ctx.Done():
return
case results <- item:
}
}
}
}
}()
}
// 6. Close results channel when all workers finish
go func() {
wg.Wait()
close(results)
}()
// 7. Collect unique results, respecting cancellation
unique := make(map[string]struct{})
for {
select {
case <-ctx.Done():
// stop collecting on cancel
goto DONE
case r, ok := <-results:
if !ok {
goto DONE
}
unique[r] = struct{}{}
}
}
DONE:
// 8. Build sorted output table
sorted := make([]string, 0, len(unique))
for k := range unique {
sorted = append(sorted, k)
}
sort.Strings(sorted)
table := make([][]string, len(sorted))
for i, v := range sorted {
table[i] = []string{v}
}
m.results = sorted
return table
}
// Save writes the results to a file.
func (m *{{ .StructName }}) Save(path string) error {
if len(m.results) == 0 {
return fmt.Errorf("no results to save")
}
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
for _, line := range m.results {
if _, err := f.WriteString(line + "\n"); err != nil {
return err
}
}
return nil
}
// Help returns the help text for the module.
func (m *{{ .StructName }}) Help() [][]string {
h, _ := m.help.Get(m.prompt)
return h
}
// Options lists the module’s configurable options.
func (m *{{ .StructName }}) Options() []map[string]string {
opts := m.optionManager.List()
out := make([]map[string]string, len(opts))
for i, o := range opts {
out[i] = o.Format()
}
return out
}
// Results returns the raw string results.
func (m *{{ .StructName }}) Results() [][]string {
table := make([][]string, len(m.results))
for i, v := range m.results {
table[i] = []string{v}
}
return table
}
// Set allows runtime modification of an option.
func (m *{{ .StructName }}) Set(name, val string) []string {
om := *m.optionManager
if o, ok := om.Get(name); ok {
o.Set(val)
return []string{o.Name, fmt.Sprintf("%v", o.Value)}
}
return []string{"Error", "Option not found"}
}
// Metadata methods:
func (m *{{ .StructName }}) Name() string { return m.name }
func (m *{{ .StructName }}) Author() string { return m.author }
func (m *{{ .StructName }}) Description() string { return m.desc }
func (m *{{ .StructName }}) Prompt() string { return m.prompt }
func (m *{{ .StructName }}) Running() bool { return m.running }
func (m *{{ .StructName }}) Start() error { m.running = true; return nil }
func (m *{{ .StructName }}) Stop() error { m.running = false; return nil }
// Helper: your per‑item check or processing function.
func someCheck(item string) bool {
// implement your domain lookup / HTTP request / whatever…
return true
}
Module Architecture Diagram
│ REPL UI │
└──────┬──────┘
│
┌───────▼───────┐
│ Module Loader │
└───────┬───────┘
│
┌─────────▼────────┐
│ Selected Module │
│ (e.g. spider) │
└─────────┬────────┘
│
┌─────────▼────────┐
│ Module Interface │
│ (Run, Config) │
└─────────┬────────┘
│
┌─────────▼────────┐
│ Requests & │
│ Response Parsing │
└──────────────────┘
Using Modules
Typical workflow from the REPL:
use webspider
show options
set TARGETS https://example.com
set ALLOWED_DOMAINS example.com
run
Modules accept parameters via set
commands and expose options with options
.