Skip to content
This repository has been archived by the owner on Jan 7, 2024. It is now read-only.

Update Subjack to use Embed #96

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module github.com/haccer/subjack

go 1.19

require (
github.com/haccer/available v0.0.0-20200921032034-0d552efb6cd4
github.com/miekg/dns v1.1.50
github.com/valyala/fasthttp v1.41.0
)

require (
github.com/PuerkitoBio/goquery v1.8.0 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/andybalholm/cascadia v1.3.1 // indirect
github.com/domainr/whois v0.1.0 // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/zonedb/zonedb v1.0.3544 // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c // indirect
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
)
71 changes: 71 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
github.com/domainr/whois v0.1.0 h1:36I1Hu+5pfvJzSXjnxN3lmIXeNNlZJmM5fkk9zlRF2o=
github.com/domainr/whois v0.1.0/go.mod h1:/6Ej6qU9Xcl/8we/QKFWhJlvUlqmEDGXgHzOwbazVpo=
github.com/domainr/whoistest v0.0.0-20180714175718-26cad4b7c941 h1:E7ehdIemEeScp8nVs0JXNXEbzb2IsHCk13ijvwKqRWI=
github.com/domainr/whoistest v0.0.0-20180714175718-26cad4b7c941/go.mod h1:iuCHv1qZDoHJNQs56ZzzoKRSKttGgTr2yByGpSlKsII=
github.com/haccer/available v0.0.0-20200921032034-0d552efb6cd4 h1:MxQoqqy0scTAXWDH36lXAbRWbr3t8+e/aCmxvzTxlpQ=
github.com/haccer/available v0.0.0-20200921032034-0d552efb6cd4/go.mod h1:CvVDzx8GCt0H9avR2A0NnFViM9QhXQghxKnZaosoaSU=
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/miekg/dns v1.1.46/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.41.0 h1:zeR0Z1my1wDHTRiamBCXVglQdbUwgb9uWG3k1HQz6jY=
github.com/valyala/fasthttp v1.41.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zonedb/zonedb v1.0.3544 h1:u5a3xOaI338FclecJ/H6J7fiImVEZ/qZomJnVYIlTeM=
github.com/zonedb/zonedb v1.0.3544/go.mod h1:h9mfHV/S6lboOkltULrbNY52cd7JZo6MbxIiqKMWPLg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo=
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
18 changes: 11 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package main

import (
_ "embed"
"flag"
"fmt"
"os"

"github.com/haccer/subjack/subjack"
)

func main() {
GOPATH := os.Getenv("GOPATH")
Project := "/src/github.com/haccer/subjack/"
configFile := "fingerprints.json"
defaultConfig := GOPATH + Project + configFile
//go:embed fingerprints.json
var defaultConfig string

func main() {
o := subjack.Options{}

flag.StringVar(&o.Domain, "d", "", "Domain.")
Expand All @@ -24,7 +23,7 @@ func main() {
flag.BoolVar(&o.All, "a", false, "Find those hidden gems by sending requests to every URL. (Default: Requests are only sent to URLs with identified CNAMEs).")
flag.BoolVar(&o.Verbose, "v", false, "Display more information per each request.")
flag.StringVar(&o.Output, "o", "", "Output results to file (Subjack will write JSON if file ends with '.json').")
flag.StringVar(&o.Config, "c", defaultConfig, "Path to configuration file.")
flag.StringVar(&o.ConfigFile, "c", "", "Path to configuration file.")
flag.BoolVar(&o.Manual, "m", false, "Flag the presence of a dead record, but valid CNAME entry.")

flag.Parse()
Expand All @@ -39,5 +38,10 @@ func main() {
os.Exit(1)
}

subjack.Process(&o)
o.Config = defaultConfig
err := subjack.Process(&o)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
47 changes: 21 additions & 26 deletions subjack/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package subjack
import (
"bufio"
"encoding/json"
"io/ioutil"
"io"
"log"
"os"
"strings"
Expand All @@ -16,23 +16,6 @@ type Results struct {
Domain string `json:"nonexist_domain,omitempty"`
}

func open(path string) (lines []string, Error error) {
file, err := os.Open(path)
if err != nil {
log.Fatalln(err)
}

defer file.Close()

scanner := bufio.NewScanner(file)

for scanner.Scan() {
lines = append(lines, scanner.Text())
}

return lines, scanner.Err()
}

func chkJSON(output string) (json bool) {
json = false

Expand Down Expand Up @@ -90,7 +73,7 @@ func writeJSON(service, url, output string) {

defer f.Close()

file, err := ioutil.ReadAll(f)
file, err := io.ReadAll(f)
if err != nil {
log.Fatalln(err)
}
Expand All @@ -111,16 +94,28 @@ func writeJSON(service, url, output string) {
wf.Write(results)
}

func fingerprints(file string) (data []Fingerprints) {
config, err := ioutil.ReadFile(file)
func readFile(filename string) (content []byte, Error error) {
return os.ReadFile(filename)
}

func readFileLines(filename string) (lines []string, Error error) {
file, err := os.Open(filename)
if err != nil {
log.Fatalln(err)
return nil, err
}

err = json.Unmarshal(config, &data)
if err != nil {
log.Fatalln(err)
defer file.Close()

scanner := bufio.NewScanner(file)

for scanner.Scan() {
lines = append(lines, scanner.Text())
}

return data
return lines, scanner.Err()
}

func fingerprints(config []byte) (data []Fingerprints, Error error) {
err := json.Unmarshal(config, &data)
return data, err
}
104 changes: 104 additions & 0 deletions subjack/file_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package subjack

import (
"log"
"os"
"testing"
)

func TestReadFileLines(t *testing.T) {
// Read a file that does not exist.
_, err := readFileLines("does_not_exist.txt")
if err == nil {
t.Errorf("Expected error, got nil")
}

// Read a file that does exist.
tmpfile, err := os.CreateTemp("", "subjack_test")
if err != nil {
log.Fatal(err)
}
defer os.Remove(tmpfile.Name())

if _, err := tmpfile.Write([]byte("test\nFoobar")); err != nil {
log.Fatal(err)
}
if err := tmpfile.Close(); err != nil {
log.Fatal(err)
}

lines, err := readFileLines(tmpfile.Name())
if err != nil {
t.Errorf("Expected nil, got %v", err)
}
if len(lines) != 2 {
t.Errorf("Expected 2 lines, got %d", len(lines))
}
}

func TestReadFile(t *testing.T) {
// Read a file that does not exist.
_, err := readFile("does_not_exist.txt")
if err == nil {
t.Errorf("Expected error, got nil")
}

// Read a file that does exist.
tmpfile, err := os.CreateTemp("", "subjack_test")
if err != nil {
log.Fatal(err)
}
defer os.Remove(tmpfile.Name())

if _, err := tmpfile.Write([]byte("test\nFoobar")); err != nil {
log.Fatal(err)
}
if err := tmpfile.Close(); err != nil {
log.Fatal(err)
}

lines, err := readFile(tmpfile.Name())
if err != nil {
t.Errorf("Expected nil, got %v", err)
}
if string(lines) != "test\nFoobar" {
t.Errorf("Expected 'test\nFoobar', got %v", lines)
}
}

func TestFingerprints(t *testing.T) {
invalid_fingerprints := []byte(`[
{
"service": ",
"cname": [,
"fingerprint": [,
"nxdomain": [,
}
]`)

_, err := fingerprints(invalid_fingerprints)
if err == nil {
t.Errorf("Expected error, got nil")
}

valid_fingerprints := []byte(`[
{
"service": "fastly",
"cname": [
"fastly"
],
"fingerprint": [
"Fastly error: unknown domain"
],
"nxdomain": false
}
]`)
fs, err := fingerprints(valid_fingerprints)
if err != nil {
t.Errorf("Expected nil, got %v", err)
}
if len(fs) != 1 {
t.Errorf("Expected 1 fingerprint, got %d", len(fs))
}

}
35 changes: 25 additions & 10 deletions subjack/subjack.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package subjack

import (
"log"
"sync"
)

Expand All @@ -15,6 +14,7 @@ type Options struct {
All bool
Verbose bool
Config string
ConfigFile string
Manual bool
Fingerprints []Fingerprints
}
Expand All @@ -24,23 +24,37 @@ type Subdomain struct {
}

/* Start processing subjack from the defined options. */
func Process(o *Options) {
func Process(o *Options) (err error) {
var list []string
var err error

urls := make(chan *Subdomain, o.Threads*10)

if(len(o.Domain) > 0){

// Load fingerprints
if o.ConfigFile != "" {
custom_fingerprints, err := readFile(o.ConfigFile)
if err != nil {
return err
}
o.Fingerprints, err = fingerprints(custom_fingerprints)
if err != nil {
return err
}
} else {
// No error checking here because the default fingerprints are
// hard-coded into the binary.
o.Fingerprints, _ = fingerprints([]byte(o.Config))
}

// Load domain list
if len(o.Domain) > 0 {
list = append(list, o.Domain)
} else {
list, err = open(o.Wordlist)
list, err = readFileLines(o.Wordlist)
}

if err != nil {
log.Fatalln(err)
return err
}

o.Fingerprints = fingerprints(o.Config)

wg := new(sync.WaitGroup)

Expand All @@ -61,4 +75,5 @@ func Process(o *Options) {

close(urls)
wg.Wait()
return nil
}