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
0 parents
commit 63a754d
Showing
5 changed files
with
174 additions
and
0 deletions.
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 |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules/ |
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,32 @@ | ||
# Bucket Hunter - Amazon AWS Open Files Scraper | ||
|
||
After few research, we discovered that by using passive DNS lookup on Amazon servers we can found hostname of customer hosted in the cloud. Many of them are not using any authentication systems and some of them are hosting sensitive files. | ||
|
||
We wrote a quick tool as proof of concept of automated exploitation as well as a white paper. | ||
|
||
### How to install | ||
* Clone the git (or click on the download button) | ||
* Install [Node.js](https://nodejs.org/) on your computer | ||
* Open your console and go in the repertory where `bucket-hunter.js` is located | ||
* Write `npm install` and wait until everything is finished | ||
* Write `node bucket-hunter.js` in the console | ||
|
||
### How does it work : | ||
|
||
To find the IP range of Amazon, use this [JSON document](https://ip-ranges.amazonaws.com/ip-ranges.json). The use of this JSON makes this security research unique by letting us use official Amazon IP ranges and not technics like bruteforcing. Yet, the previous bucket hunter were doing very well. | ||
|
||
Lets take the **ip** of one for example : | ||
``` | ||
"ip_prefix": "54.231.128.0/19" | ||
``` | ||
|
||
So the **IP** goes from `54.231.128.0` to `54.231.128.19`. | ||
|
||
Launch the script by writing | ||
`node bucket-hunter.js -i 54.231.128.0` in order to see the DNS passive lookup result concerning this URL. After a bit of times, you will see a list of results. | ||
|
||
If you see something like `example.s3.amazonaws.com is available` then you can copy the URL (`example.s3.amazonaws.com`) and launch the command :`node bucket-hunter.js -f example.s3.amazonaws.com` which will give you link for every files listed on the Amazon AWS bucket you selected. | ||
|
||
## authors : | ||
* [Samuel LESPES CARDILLO](http://samuelcardillo.com/) (Cyber_Owner) [@cyberwarfighte1](https://twitter.com/cyberwarfighte1) | ||
* [Amitay Dan](http://amitaydan.com) (popshark) [@popshark1](https://twitter.com/popshark1) |
Binary file not shown.
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,125 @@ | ||
var request = require('request') | ||
, program = require('commander'); | ||
|
||
program | ||
.version('0.0.1') | ||
.option('-i, --ip [value]', 'ipAddr') | ||
.option('-f, --getFile [value]', 'getFile') | ||
.parse(process.argv); | ||
|
||
console.log("/* __________________________________ */"); | ||
console.log("/* Bucket Hunter - Amazon AWS Open Bucket Scraper"); | ||
console.log("/* Samuel LESPES CARDILLO (Cyber_Owner) - @cyberwarfighte1"); | ||
console.log("/* Amitay Dan (popshark1)"); | ||
console.log("/* __________________________________ */"); | ||
|
||
/* _____________ CODE ___________ */ | ||
|
||
if(program.ip) { | ||
console.log('Passive DNS looking...'); | ||
passiveDNS(program.ip); | ||
} else if(program.getFile) { | ||
console.log('Checking availability...'); | ||
verifyAccess(program.getFile,function(availability) { | ||
console.log(availability); | ||
if(availability == program.getFile + " is available") { | ||
console.log('Getting the file list...'); | ||
getFiles(program.getFile,function(result){ | ||
console.log('________ FILE LIST ___________'); | ||
for(var k in result) { | ||
console.log(result[k]); | ||
} | ||
}); | ||
}; | ||
}); | ||
} else { | ||
return console.log("usage : node bucket-hunter.js -h"); | ||
} | ||
|
||
/* __________ FUNCTIONS ___________ */ | ||
|
||
// Deprecated | ||
function findHostname(ip,apiKey) { | ||
request({ | ||
headers: { | ||
'Authorization': apiKey, | ||
}, | ||
uri: "https://mxtoolbox.com/api/v1/lookup/ip/"+ip, | ||
method: 'GET', | ||
json: true | ||
}, function(err,res,body){ | ||
for(var k in body["Information"]) { | ||
passiveDNS(body["Information"][k]["Domain Name"]); | ||
} | ||
}); | ||
}; | ||
|
||
function passiveDNS(hostname) { | ||
request({ | ||
uri: 'https://1d4.us/'+hostname, | ||
method: 'GET', | ||
json: true | ||
}, function(err,res,body){ | ||
var hosted = parseResult(body,hostname); | ||
for(var k in hosted) { | ||
verifyAccess(hosted[k],function(availability){ | ||
console.log(availability); | ||
}); | ||
} | ||
}); | ||
}; | ||
|
||
function parseResult(data,hostname) { | ||
var result = []; | ||
var data = data.split('<tr class="odd">'); | ||
|
||
for(var k in data) { | ||
if(k == 0) continue; | ||
|
||
var lines = data[k].split("<td width='150px'><a href='/"); | ||
lines = lines[1].split(".\'>"); | ||
if(lines[0] != hostname) result.push(lines[0]); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
function verifyAccess(host,callback) { | ||
request({ | ||
headers: { | ||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', | ||
}, | ||
uri: 'http://'+host, | ||
method: 'GET', | ||
}, function(err,res,body){ | ||
if(err) return err; | ||
|
||
var availability = (body.indexOf("<Error>") != -1) ? "blocked" : "available"; | ||
return callback(host + " is " + availability); | ||
}); | ||
} | ||
|
||
function getFiles(host,callback) { | ||
request({ | ||
headers: { | ||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', | ||
}, | ||
uri: 'http://'+host, | ||
method: 'GET', | ||
}, function(err,res,body){ | ||
if(err) return err; | ||
var result = []; | ||
var body = body.split('<Contents>'); | ||
|
||
for(var k in body) { | ||
if(k == 0) continue; | ||
|
||
var content = body[k].split('</Contents>'); | ||
var fileName = content[0].split('<Key>'); | ||
fileName = fileName[1].split('</Key>'); | ||
result.push(host + '/' + fileName[0]); | ||
} | ||
|
||
return callback(result); | ||
}); | ||
} |
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,16 @@ | ||
{ | ||
"name": "bucket-hunter", | ||
"version": "1.0.0", | ||
"description": "Amazon AWS Open Bucket Scraper", | ||
"main": "bucket-hunter.js", | ||
"dependencies": { | ||
"commander": "^2.8.1", | ||
"request": "^2.60.0" | ||
}, | ||
"devDependencies": {}, | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"author": "Amitay Dan & Samuel LESPES CARDILLO", | ||
"license": "ISC" | ||
} |