Skip to content

Commit 2ba744f

Browse files
bitquarkthezakman
andcommitted
Added support for reading a list of URLs to scan from a file by using @-syntax (see docs)
Co-authored-by: TheZakMan <[email protected]>
1 parent 19f0dda commit 2ba744f

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ Shortscan is easy to use with minimal configuration. Basic usage looks like:
3737
$ shortscan http://example.org/
3838
```
3939

40+
You can also specify a file containing a list of URLs to be scanned:
41+
42+
```
43+
$ shortscan @urls.txt
44+
```
45+
4046
### Examples
4147

4248
This example sets multiple custom headers by using `--header`/`-H` multiple times:
@@ -54,11 +60,11 @@ shortscan --isvuln
5460
The following options allow further tweaks:
5561

5662
```
57-
Shortscan v0.7 · an IIS short filename enumeration tool by bitquark
58-
Usage: shortscan [--wordlist FILE] [--header HEADER] [--concurrency CONCURRENCY] [--timeout SECONDS] [--output type] [--verbosity VERBOSITY] [--fullurl] [--stabilise] [--patience LEVEL] [--characters CHARACTERS] [--autocomplete mode] [--isvuln] URL
63+
🌀 Shortscan v0.9.2 · an IIS short filename enumeration tool by bitquark
64+
Usage: main [--wordlist FILE] [--header HEADER] [--concurrency CONCURRENCY] [--timeout SECONDS] [--output format] [--verbosity VERBOSITY] [--fullurl] [--norecurse] [--stabilise] [--patience LEVEL] [--characters CHARACTERS] [--autocomplete mode] [--isvuln] URL [URL ...]
5965
6066
Positional arguments:
61-
URL url to scan
67+
URL url to scan (multiple URLs can be provided; a file containing URLs can be specified with an «at» prefix, for example: @urls.txt)
6268
6369
Options:
6470
--wordlist FILE, -w FILE
@@ -69,11 +75,12 @@ Options:
6975
number of requests to make at once [default: 20]
7076
--timeout SECONDS, -t SECONDS
7177
per-request timeout in seconds [default: 10]
72-
--output type, -o type
78+
--output format, -o format
7379
output format (human = human readable; json = JSON) [default: human]
7480
--verbosity VERBOSITY, -v VERBOSITY
7581
how much noise to make (0 = quiet; 1 = debug; 2 = trace) [default: 0]
7682
--fullurl, -F display the full URL for confirmed files rather than just the filename [default: false]
83+
--norecurse, -n don't detect and recurse into subdirectories (disabled when autocomplete is disabled) [default: false]
7784
--stabilise, -s attempt to get coherent autocomplete results from an unstable server (generates more requests) [default: false]
7885
--patience LEVEL, -p LEVEL
7986
patience level when determining vulnerability (0 = patient; 1 = very patient) [default: 0]

pkg/shortscan/shortscan.go

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ type statsOutput struct {
109109
}
110110

111111
// Version, rainbow table magic, default character set
112-
const version = "0.9.1"
112+
const version = "0.9.2"
113113
const rainbowMagic = "#SHORTSCAN#"
114114
const alphanum = "JFKGOTMYVHSPCANDXLRWEBQUIZ8549176320"
115115

@@ -138,7 +138,7 @@ var checksumRegex *regexp.Regexp
138138

139139
// Command-line arguments and help
140140
type arguments struct {
141-
Urls []string `arg:"positional,required" help:"url to scan (multiple URLs can be specified)" placeholder:"URL"`
141+
Urls []string `arg:"positional,required" help:"url to scan (multiple URLs can be provided; a file containing URLs can be specified with an «at» prefix, for example: @urls.txt)" placeholder:"URL"`
142142
Wordlist string `arg:"-w" help:"combined wordlist + rainbow table generated with shortutil" placeholder:"FILE"`
143143
Headers []string `arg:"--header,-H,separate" help:"header to send with each request (use multiple times for multiple headers)"`
144144
Concurrency int `arg:"-c" help:"number of requests to make at once" default:"20"`
@@ -1047,6 +1047,41 @@ func Run() {
10471047
p.Fail("output must be one of: human, json")
10481048
}
10491049

1050+
// Build the list of URLs to scan
1051+
var urls []string
1052+
for _, url := range args.Urls {
1053+
1054+
// If this is a filename rather than a URL
1055+
if strings.HasPrefix(url, "@") {
1056+
1057+
// Open the file
1058+
path := strings.TrimPrefix(url, "@")
1059+
fh, err := os.Open(path)
1060+
if err != nil {
1061+
log.WithFields(log.Fields{"path": path, "err": err}).Fatal("Unable to open URL list file")
1062+
}
1063+
defer fh.Close()
1064+
1065+
// Add each line to the URL list
1066+
sc := bufio.NewScanner(fh)
1067+
for sc.Scan() {
1068+
urls = append(urls, sc.Text())
1069+
}
1070+
1071+
// Check for file read errors
1072+
if err := sc.Err(); err != nil {
1073+
log.WithFields(log.Fields{"path": path, "err": err}).Fatal("Error reading URL list file")
1074+
}
1075+
1076+
} else {
1077+
1078+
// This is a plain URL, add it to the list
1079+
urls = append(urls, url)
1080+
1081+
}
1082+
1083+
}
1084+
10501085
// Say hello
10511086
printHuman(getBanner())
10521087

@@ -1160,6 +1195,6 @@ func Run() {
11601195
}
11611196

11621197
// Let's go!
1163-
Scan(args.Urls, hc, st, wc, mk)
1198+
Scan(urls, hc, st, wc, mk)
11641199

11651200
}

0 commit comments

Comments
 (0)