Skip to content

Instantly share code, notes, and snippets.

@t94j0
Last active August 4, 2017 14:17
Show Gist options
  • Save t94j0/2d1dfd506282dede217c8f8917f93d1c to your computer and use it in GitHub Desktop.
Save t94j0/2d1dfd506282dede217c8f8917f93d1c to your computer and use it in GitHub Desktop.
Transform the Nikto DB into a folder of `.scan` files
package main
import (
"encoding/csv"
"fmt"
"io"
"io/ioutil"
"os"
"strconv"
"strings"
)
type NiktoField struct {
FieldId string
Type string
URI string
Method string
Match string
MatchOr string
MatchAnd string
Fail1 string
Fail2 string
Summary string
HTTPData string
Headers string
}
func main() {
if len(os.Args) < 3 {
fmt.Println("usage [input file name] [directory]")
os.Exit(1)
}
inputFileName := os.Args[1]
outputDirectory := os.Args[2]
inputFileReader, err := os.Open(inputFileName)
if err != nil {
fmt.Println("Failed to open input file:", err)
os.Exit(1)
}
niktoFields := make([]NiktoField, 0)
inputCSV := csv.NewReader(inputFileReader)
inputCSV.Comment = '#'
for {
entry, err := inputCSV.Read()
if err == io.EOF {
break
}
if err != nil {
fmt.Println("Error reading CSV:", err)
continue
}
if len(entry) != 13 {
fmt.Println(entry)
continue
}
field := NiktoField{
entry[0],
entry[2],
entry[3],
entry[4],
entry[5],
entry[6],
entry[7],
entry[8],
entry[9],
entry[10],
entry[11],
entry[12],
}
niktoFields = append(niktoFields, field)
}
tuningOptions := []string{"file-upload", "interesting-file", "misconfiguration", "information-disclosure", "injection", "file-disclosure", "dos", "command-execution", "sql-injection", "authentication-bypass", "software-identification", "remote-source-inclusion", "webservice", "administrative-console", "multiple"}
// Create appropriate directories
for _, folder := range tuningOptions {
if err := os.Mkdir(outputDirectory+"/"+folder, 0700); err != nil {
fmt.Println("Could not create directory:", err)
}
}
count := 0
for _, field := range niktoFields {
count += 1
var tuningType string
switch field.Type {
case "0":
tuningType = tuningOptions[0]
case "1":
tuningType = tuningOptions[1]
case "2":
tuningType = tuningOptions[2]
case "3":
tuningType = tuningOptions[3]
case "4":
tuningType = tuningOptions[4]
case "5":
tuningType = tuningOptions[5]
case "6":
tuningType = tuningOptions[6]
case "7":
tuningType = tuningOptions[5]
case "8":
tuningType = tuningOptions[7]
case "9":
tuningType = tuningOptions[8]
case "a":
tuningType = tuningOptions[9]
case "b":
tuningType = tuningOptions[10]
case "c":
tuningType = tuningOptions[11]
case "d":
tuningType = tuningOptions[12]
case "e":
tuningType = tuningOptions[13]
default:
tuningType = "multiple"
}
fieldFileName := outputDirectory + "/" + tuningType + "/" + field.FieldId + ".scan"
// Create file as string
file := ""
// URI=/robots.txt
file += "URI=" + field.URI + "\n"
// METHOD=GET
file += "METHOD=" + field.Method + "\n"
if field.Match != "" {
// MATCH=root_shell
// Not 100% sure why things are weirdly escaped
field.Match = strings.Replace(field.Match, "\\\\", "\\", -1)
field.Match = strings.Replace(field.Match, "\\\\/", "\\/", -1)
file += "MATCH=" + field.Match + "\n"
}
if field.MatchOr != "" {
// MATCHOR=a_root_shell
file += "MATCHOR=" + field.MatchOr + "\n"
}
// Remove the AND part
if field.MatchAnd != "" {
// MATCH=admin user
file += "MATCH=" + field.MatchAnd + "\n"
}
if field.Fail1 != "" {
file += "FAIL=" + field.Fail1 + "\n"
}
if field.Fail2 != "" {
file += "FAIL=" + field.Fail2 + "\n"
}
file += "SUMMARY=" + field.Summary + "\n"
if field.HTTPData != "" {
file += "HTTP_DATA=" + field.HTTPData + "\n"
}
if field.Headers != "" {
file += "HEADER=" + field.Headers
}
if err := ioutil.WriteFile(fieldFileName, []byte(file), 0600); err != nil {
fmt.Println("Failed to write file:", err)
}
fmt.Print(strconv.Itoa(count) + "\r")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment