-
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
383 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,147 @@ | ||
# s3reverse | ||
## Install | ||
```cassandraql | ||
$ go get -u github/hahwul/s3reverse | ||
``` | ||
## Usage | ||
j | ||
### Input options | ||
Basic Usage | ||
```cassandraql | ||
8""""8 eeee 8"""8 8"""" 88 8 8"""" 8"""8 8""""8 8"""" | ||
8 8 8 8 8 88 8 8 8 8 8 8 | ||
8eeeee 8 8eee8e 8eeee 88 e8 8eeee 8eee8e 8eeeee 8eeee | ||
88 eee8 eeee 88 8 88 "8 8 88 88 8 88 88 | ||
e 88 88 88 8 88 8 8 88 88 8 e 88 88 | ||
8eee88 eee88 88 8 88eee 8ee8 88eee 88 8 8eee88 88eee | ||
by @hahwul | ||
Usage of ./s3reverse: | ||
-iL string | ||
input List | ||
-oA string | ||
Write output in Array format (optional) | ||
-oN string | ||
Write output in Normal format (optional) | ||
-tN | ||
to name | ||
-tP | ||
to path-style | ||
-tS | ||
to s3 url | ||
-tV | ||
to virtual-hosted-style | ||
-verify | ||
testing bucket(acl,takeover) | ||
``` | ||
Using from file | ||
```cassandraql | ||
$ s3reverse -iL sample -tN | ||
udemy-web-upload-transitional | ||
github-cloud | ||
github-production-repository-file-5c1aeb | ||
github-production-upload-manifest-file-7fdce7 | ||
github-production-user-asset-6210df | ||
github-education-web | ||
github-jobs | ||
s3-us-west-2.amazonaws.com | ||
optimizely | ||
app-usa-modeast-prod-a01239f | ||
doc | ||
swipely-merchant-assets | ||
adslfjasldfkjasldkfjalsdfkajsljasldf | ||
cbphotovideo | ||
cbphotovideo-eu | ||
public.chaturbate.com | ||
wowdvr | ||
cbvideoupload | ||
testbuckettesttest | ||
``` | ||
Using from pipeline | ||
```cassandraql | ||
$ cat sample | s3reverse -tN | ||
udemy-web-upload-transitional | ||
github-cloud | ||
github-production-repository-file-5c1aeb | ||
github-production-upload-manifest-file-7fdce7 | ||
github-production-user-asset-6210df | ||
github-education-web | ||
github-jobs | ||
s3-us-west-2.amazonaws.com | ||
optimizely | ||
app-usa-modeast-prod-a01239f | ||
doc | ||
swipely-merchant-assets | ||
adslfjasldfkjasldkfjalsdfkajsljasldf | ||
cbphotovideo | ||
cbphotovideo-eu | ||
public.chaturbate.com | ||
wowdvr | ||
cbvideoupload | ||
testbuckettesttest | ||
``` | ||
|
||
### Output options | ||
to Name | ||
```cassandraql | ||
$ s3reverse -iL sample -tN | ||
udemy-web-upload-transitional | ||
github-cloud | ||
github-production-repository-file-5c1aeb | ||
github-production-upload-manifest-file-7fdce7 | ||
... snip ... | ||
``` | ||
to Path Style | ||
```cassandraql | ||
$ s3reverse -iL sample -tP | ||
https://s3.amazonaws.com/udemy-web-upload-transitional | ||
https://s3.amazonaws.com/github-cloud | ||
https://s3.amazonaws.com/github-production-repository-file-5c1aeb | ||
... snip ... | ||
``` | ||
to Virtual Hosted Style | ||
```cassandraql | ||
$ s3reverse -iL sample -tV | ||
udemy-web-upload-transitional.s3.amazonaws.com | ||
github-cloud.s3.amazonaws.com | ||
github-production-repository-file-5c1aeb.s3.amazonaws.com | ||
github-production-upload-manifest-file-7fdce7.s3.amazonaws.com | ||
github-production-user-asset-6210df.s3.amazonaws.com | ||
... snip ... | ||
``` | ||
|
||
### Verify mode | ||
```cassandraql | ||
$ s3reverse -iL sample -verify | ||
[NoSuchBucket] adslfjasldfkjasldkfjalsdfkajsljasldf | ||
[PublicAccessDenied] github-production-user-asset-6210df | ||
[PublicAccessDenied] github-jobs | ||
[PublicAccessDenied] public.chaturbate.com | ||
[PublicAccessDenied] github-education-web | ||
[PublicAccessDenied] github-production-repository-file-5c1aeb | ||
[PublicAccessDenied] testbuckettesttest | ||
[PublicAccessDenied] app-usa-modeast-prod-a01239f | ||
[PublicAccessGranted] cbphotovideo-eu | ||
[PublicAccessDenied] swipely-merchant-assets | ||
[PublicAccessDenied] optimizely | ||
[PublicAccessDenied] wowdvr | ||
[PublicAccessGranted] s3-us-west-2.amazonaws.com | ||
[PublicAccessDenied] cbphotovideo | ||
[PublicAccessDenied] cbvideoupload | ||
[PublicAccessDenied] github-production-upload-manifest-file-7fdce7 | ||
[PublicAccessDenied] doc | ||
[PublicAccessDenied] udemy-web-upload-transitional | ||
[PublicAccessDenied] github-cloud | ||
``` | ||
|
||
## Case study | ||
Pipelining `meg`, `s3reverse`, `gf` , `s3scanner` for Find S3 Misconfiguration. | ||
```cassandraql | ||
$ meg -d 1000 -v / ; cd out ; gf s3-buckets | s3reverse -tN > buckets ; s3scanner buckets | ||
``` | ||
|
||
Find S3 bucket takeover | ||
```cassandraql | ||
$ meg -d 1000 -v / ; cd out ; gf s3-buckets | s3reverse -verify | grep NoSuchBucket > takeovers | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"flag" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"os" | ||
"regexp" | ||
"strings" | ||
"sync" | ||
) | ||
|
||
const ( | ||
s3path = "^(s3-|s3\\.)?(s3.*)\\.amazonaws\\.com" | ||
s3url = "^s3://*" | ||
s3vh = "(s3.*)\\.amazonaws\\.com$" | ||
) | ||
|
||
func banner() { | ||
fmt.Println(` | ||
8""""8 eeee 8"""8 8"""" 88 8 8"""" 8"""8 8""""8 8"""" | ||
8 8 8 8 8 88 8 8 8 8 8 8 | ||
8eeeee 8 8eee8e 8eeee 88 e8 8eeee 8eee8e 8eeeee 8eeee | ||
88 eee8 eeee 88 8 88 "8 8 88 88 8 88 88 | ||
e 88 88 88 8 88 8 8 88 88 8 e 88 88 | ||
8eee88 eee88 88 8 88eee 8ee8 88eee 88 8 8eee88 88eee | ||
`) | ||
fmt.Println("by @hahwul") | ||
fmt.Println("") | ||
} | ||
|
||
func main() { | ||
// input options | ||
iL := flag.String("iL", "", "input List") | ||
// to options | ||
tN := flag.Bool("tN", false, "to name") | ||
tS := flag.Bool("tS", false, "to s3 url") | ||
tP := flag.Bool("tP", false, "to path-style") | ||
tV := flag.Bool("tV", false, "to virtual-hosted-style") | ||
verify := flag.Bool("verify", false, "testing bucket(acl,takeover)") | ||
// output options | ||
oN := flag.String("oN", "", "Write output in Normal format (optional)") | ||
oA := flag.String("oA", "", "Write output in Array format (optional)") | ||
var s3Buckets []string | ||
flag.Parse() | ||
if flag.NFlag() == 0 { | ||
banner() | ||
flag.Usage() | ||
return | ||
} | ||
|
||
// accept domains on stdin | ||
if *iL == "" { | ||
sc := bufio.NewScanner(os.Stdin) | ||
for sc.Scan() { | ||
target := strings.ToLower(sc.Text()) | ||
var s3 = identifys3(target) | ||
if s3 != "" { | ||
s3Buckets = append(s3Buckets, s3) | ||
} | ||
} | ||
} else { | ||
target, err := readLinesOrLiteral(*iL) | ||
_ = err | ||
for i, s := range target { | ||
_ = i | ||
var s3 = identifys3(s) | ||
if s3 != "" { | ||
s3Buckets = append(s3Buckets, s3) | ||
} | ||
} | ||
|
||
} | ||
// Remove Deplicated value | ||
s3Buckets = unique(s3Buckets) | ||
// Printing | ||
if *verify { | ||
var wg sync.WaitGroup | ||
for _, s := range s3Buckets { | ||
wg.Add(1) | ||
go func(s string) { | ||
defer wg.Done() | ||
var DefaultTransport http.RoundTripper = &http.Transport{} | ||
req, _ := http.NewRequest("GET", "https://s3.amazonaws.com/"+s, nil) | ||
resp, _ := DefaultTransport.RoundTrip(req) | ||
defer resp.Body.Close() | ||
contents, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
fmt.Printf("%s", err) | ||
} | ||
if strings.Contains(string(contents), "<Code>NoSuchBucket</Code>") { | ||
fmt.Println("[NoSuchBucket] " + s) | ||
} else if strings.Contains(string(contents), "<Code>AccessDenied</Code>") { | ||
fmt.Println("[PublicAccessDenied] " + s) | ||
} else { | ||
fmt.Println("[PublicAccessGranted] " + s) | ||
} | ||
}(s) | ||
} | ||
wg.Wait() | ||
} else { | ||
for _, s := range s3Buckets { | ||
if *tN { | ||
fmt.Println(s) | ||
} | ||
if *tS { | ||
fmt.Println("s3://" + s) | ||
} | ||
if *tP { | ||
fmt.Println("https://s3.amazonaws.com/" + s) | ||
} | ||
if *tV { | ||
fmt.Println(s + ".s3.amazonaws.com") | ||
} | ||
} | ||
} | ||
_ = oN | ||
_ = oA | ||
} | ||
|
||
func unique(intSlice []string) []string { | ||
keys := make(map[string]bool) | ||
list := []string{} | ||
for _, entry := range intSlice { | ||
if _, value := keys[entry]; !value { | ||
keys[entry] = true | ||
list = append(list, entry) | ||
} | ||
} | ||
return list | ||
} | ||
|
||
func identifys3(t string) string { | ||
// images.skypicker.com-dev.s3-website-eu => images.skypicker.com-dev1 | ||
target := strings.Replace(t, "http://", "", 1) | ||
target = strings.Replace(target, "https://", "", 1) | ||
target = strings.Replace(target, "s3://", "s3:////", 1) | ||
target = strings.Replace(target, "//", "", 1) | ||
|
||
path, _ := regexp.MatchString(s3path, target) | ||
vh, _ := regexp.MatchString(s3vh, target) | ||
url, _ := regexp.MatchString(s3url, target) | ||
|
||
if path { | ||
target = strings.Replace(target, "s3.amazonaws.com/", "", 1) | ||
target = strings.Split(target, "/")[0] | ||
return target | ||
} else if vh { | ||
target = strings.Replace(target, ".s3.amazonaws.com", "", 1) | ||
target = strings.Split(target, "/")[0] | ||
return target | ||
} else if url { | ||
target = strings.Replace(target, "s3://", "", 1) | ||
target = strings.Split(target, "/")[0] | ||
return target | ||
} | ||
return "" | ||
} | ||
|
||
// readLines reads all of the lines from a text file in to | ||
// a slice of strings, returning the slice and any error | ||
func readLines(filename string) ([]string, error) { | ||
f, err := os.Open(filename) | ||
if err != nil { | ||
return []string{}, err | ||
} | ||
defer f.Close() | ||
|
||
lines := make([]string, 0) | ||
sc := bufio.NewScanner(f) | ||
for sc.Scan() { | ||
lines = append(lines, sc.Text()) | ||
} | ||
|
||
return lines, sc.Err() | ||
} | ||
|
||
// readLinesOrLiteral tries to read lines from a file, returning | ||
// the arg in a string slice if the file doesn't exist, unless | ||
// the arg matches its default value | ||
func readLinesOrLiteral(arg string) ([]string, error) { | ||
if isFile(arg) { | ||
return readLines(arg) | ||
} | ||
|
||
// if the argument isn't a file, but it is the default, don't | ||
// treat it as a literal value | ||
|
||
return []string{arg}, nil | ||
} | ||
|
||
// isFile returns true if its argument is a regular file | ||
func isFile(path string) bool { | ||
f, err := os.Stat(path) | ||
return err == nil && f.Mode().IsRegular() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
udemy-web-upload-transitional.s3.amazonaws.com | ||
github-cloud.s3.amazonaws.com | ||
github-production-repository-file-5c1aeb.s3.amazonaws.com | ||
github-production-upload-manifest-file-7fdce7.s3.amazonaws.com | ||
github-production-user-asset-6210df.s3.amazonaws.com | ||
github-cloud.s3.amazonaws.com | ||
github-cloud.s3.amazonaws.com | ||
github-education-web.s3.amazonaws.com | ||
github-education-web.s3.amazonaws.com | ||
github-cloud.s3.amazonaws.com | ||
github-production-repository-file-5c1aeb.s3.amazonaws.com | ||
github-production-upload-manifest-file-7fdce7.s3.amazonaws.com | ||
github-production-user-asset-6210df.s3.amazonaws.com | ||
github-cloud.s3.amazonaws.com | ||
github-jobs.s3.amazonaws.com | ||
//s3-us-west-2.amazonaws.com/rubygems-dumps | ||
optimizely.s3.amazonaws.com | ||
app-usa-modeast-prod-a01239f.s3.amazonaws.com | ||
app-usa-modeast-prod-a01239f.s3.amazonaws.com | ||
//s3.amazonaws.com/doc | ||
swipely-merchant-assets.s3.amazonaws.com | ||
s3://adslfjasldfkjasldkfjalsdfkajsljasldf | ||
swipely-merchant-assets.s3.amazonaws.com | ||
swipely-merchant-assets.s3.amazonaws.com | ||
swipely-merchant-assets.s3.amazonaws.com | ||
//s3-us-west-2.amazonaws.com/public.lob.com | ||
//s3-us-west-2.amazonaws.com/public.lob.com | ||
cbphotovideo.s3.amazonaws.com | ||
cbphotovideo-eu.s3.amazonaws.com | ||
public.chaturbate.com.s3.amazonaws.com | ||
wowdvr.s3.amazonaws.com | ||
cbvideoupload.s3.amazonaws.com | ||
cbphotovideo.s3.amazonaws.com | ||
s3://testbuckettesttest | ||
cbphotovideo-eu.s3.amazonaws.com | ||
public.chaturbate.com.s3.amazonaws.com | ||
wowdvr.s3.amazonaws.com | ||
cbvideoupload.s3.amazonaws.com | ||
cbphotovideo.s3.amazonaws.com | ||
cbphotovideo-eu.s3.amazonaws.com |