Skip to content

Commit

Permalink
Add Censys Port Scanning (#34)
Browse files Browse the repository at this point in the history
* chore: update gitignore

* docs: update README

* feat: Censys port scanning

* docs: update usage

* Update README.md

Added an acknowledgement.

* Update asm.py

* Update asm.py

Co-authored-by: Andreas Georgiou <4098865+superhedgy@users.noreply.github.com>
  • Loading branch information
thehappydinoa and superhedgy committed Nov 25, 2020
1 parent ded9b34 commit 97a2827
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 37 deletions.
95 changes: 91 additions & 4 deletions .gitignore
@@ -1,7 +1,94 @@
.DS_Store
*.pyc
*.egg-info
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Environments
.env
.venv
env/
venv/
.idea/
ENV/
env.bak/
venv.bak/

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# IDE
.vscode/
.idea/

# macOS
.DS_Store

# Run Outputs
asm_run_*/
69 changes: 40 additions & 29 deletions README.md
Expand Up @@ -6,49 +6,58 @@
![Attack Surface Mapper Logo](https://npercoco.typepad.com/.a/6a0133f264aa62970b0240a49c6ba4200d-800wi "Attack Surface Mapper Logo")

# AttackSurfaceMapper
AttackSurfaceMapper (ASM) is a reconnaissance tool that uses a mixture of open source intellgence and active techniques to expand the attack surface of your target. You feed in a mixture of one or more domains, subdomains and IP addresses and it uses numerous techniques to find more targets. It enumerates subdomains with bruteforcing and passive lookups, Other IPs of the same network block owner, IPs that have multiple domain names pointing to them and so on.

Once the target list is fully expanded it performs passive reconnaissance on them, taking screenshots of websites, generating visual maps, looking up credentials in public breaches, passive port scanning with Shodan and scraping employees from LinkedIn.
AttackSurfaceMapper (ASM) is a reconnaissance tool that uses a mixture of open source intelligence and active techniques to expand the attack surface of your target. You feed in a mixture of one or more domains, subdomains and IP addresses and it uses numerous techniques to find more targets. It enumerates subdomains with bruteforcing and passive lookups, Other IPs of the same network block owner, IPs that have multiple domain names pointing to them and so on.

Once the target list is fully expanded it performs passive reconnaissance on them, taking screenshots of websites, generating visual maps, looking up credentials in public breaches, passive port scanning with Shodan/Censys and scraping employees from LinkedIn.

## Demo

[![Demo](https://img.youtube.com/vi/buIQSf_gmdE/0.jpg)](https://www.youtube.com/watch?v=buIQSf_gmdE)

## Setup

As this is a Python based tool, it should theoretically run on Linux, ChromeOS ([Developer Mode](https://www.chromium.org/chromium-os/developer-information-for-chrome-os-devices/generic)), macOS and Windows.

[1] Download AttackSurfaceMapper
```
$ git clone https://github.com/superhedgy/AttackSurfaceMapper
```
1. Download AttackSurfaceMapper

[2] Install Python dependencies
```sh
git clone https://github.com/superhedgy/AttackSurfaceMapper
cd AttackSurfaceMapper
```
$ cd AttackSurfaceMapper
$ python3 -m pip install --no-cache-dir -r requirements.txt

2. Install Python dependencies

```sh
python3 -m pip install --no-cache-dir -r requirements.txt
```

[3] Add optional API keys to enhance data gathering & analysis
3. Add optional API keys to enhance data gathering & analysis

Register and obtain an API key from:
* [VirusTotal](https://www.virustotal.com/gui/join-us)
* [ShodanIO](https://account.shodan.io/register)
* [HunterIO](https://hunter.io/users/sign_up)
* ~~[WeLeakInfo](https://weleakinfo.com/register)~~
* [LinkedIn](https://www.linkedin.com/start/join)
* [GrayHatWarfare](https://buckets.grayhatwarfare.com/register)
Register and obtain an API key from:

- [VirusTotal](https://www.virustotal.com/gui/join-us)
- [Shodan.io](https://account.shodan.io/register)
- [Hunter.io](https://hunter.io/users/sign_up)
- ~~[WeLeakInfo](https://weleakinfo.com/register)~~
- [LinkedIn](https://www.linkedin.com/start/join)
- [GrayHatWarfare](https://buckets.grayhatwarfare.com/register)
- [Censys.io](https://censys.io/account)

Edit and enter the keys in keylist file
```
$ nano keylist.asm
```

### Example run command
```sh
nano keylist.asm
```
$ python3 asm.py -t your.site.com -ln -w resources/top100_sublist.txt -o demo_run

## Usage

```sh
python asm.py -t your_site.com -ln -w resources/top100_sublist.txt -o demo_run
```

### Optional Parameters

Additional optional parameters can also be set to choose to include active reconnaissance modules in addition to the default passive modules.

```
Expand All @@ -65,7 +74,7 @@ optional arguments:
Sets the path of the output file.
-sc, --screen-capture
Capture a screen shot of any associated Web Applications.
-sth, --stealth Passive mode allows reconaissaince using OSINT techniques only.
-sth, --stealth Passive mode allows reconnaissance using OSINT techniques only.
-t TARGET, --target TARGET
Set a single target IP.
-V, --version Displays the current version.
Expand All @@ -74,18 +83,20 @@ optional arguments:
-sw SUBWORDLIST, --subwordlist SUBWORDLIST
Specify a list of child subdomains.
-e, --expand Expand the target list recursively.
-ln, --linkedinner Extracts emails and employees details from linkedin.
-ln, --linkedinner Extracts emails and employees details from LinkedIn.
-d, --debug Enables debugging information.
-v, --verbose Verbose ouput in the terminal window.
-v, --verbose Verbose output in the terminal window.
Authors: Andreas Georgiou (@superhedgy)
Jacob Wilkin (@greenwolf)
Jacob Wilkin (@greenwolf)
Aidan Holland (@thehappydinoa)
```

## Authors
* [Andreas Georgiou](https://twitter.com/superhedgy)
* [Jacob Wilkin](https://github.com/Greenwolf)

- [Andreas Georgiou](https://twitter.com/superhedgy)
- [Jacob Wilkin](https://github.com/Greenwolf)

## Acknowledgments
* Thanks to `[Your Name Could Be Here, Come Help Out!]` for contributions to the project.
- Thanks to [Aidan Holland](https://github.com/thehappydinoa) for adding the Censys module.

18 changes: 14 additions & 4 deletions asm.py
Expand Up @@ -47,6 +47,7 @@
from modules import subhunter
from modules import urlscanio
from modules import whois_collector
from modules import censys

# Constants
__author__ = " Andreas Georgiou (@superhedgy)\n\t Jacob Wilkin (@greenwolf)"
Expand Down Expand Up @@ -124,6 +125,7 @@ def __init__(self):
self.screencapture = True
self.webscraper = True
self.linkedinner = False
self.censys = False
self.expand = False
self.stealth = False
self.verbose = False
Expand Down Expand Up @@ -156,7 +158,7 @@ def init_checks(master_switch, outpath):
parser.add_argument("-o", "--output", help="Sets the path of the output file.", type=str, default=outpath)
parser.add_argument("-sc", "--screen-capture", help="Capture a screen shot of any associated Web Applications.",
action="store_true", default=False)
parser.add_argument("-sth", "--stealth", help="Passive mode allows reconaissaince using OSINT techniques only.",
parser.add_argument("-sth", "--stealth", help="Passive mode allows reconnaissance using OSINT techniques only.",
action="store_true", default=False)
parser.add_argument("-t", "--target", help="Set a single target IP.")
parser.add_argument("targets", nargs='?', help="Sets the path of the target IPs file.", type=str, default="")
Expand All @@ -167,10 +169,10 @@ def init_checks(master_switch, outpath):
default="resources/top1000_sublist.txt")
parser.add_argument("-e", "--expand", help="Expand the target list recursively.", action="store_true",
default=False)
parser.add_argument("-ln", "--linkedinner", help="Extracts emails and employees details from linkedin.",
parser.add_argument("-ln", "--linkedinner", help="Extracts emails and employees details from LinkedIn.",
action="store_true", default=False)
parser.add_argument("-d", "--debug", help="Enables debugging information.",action="store_true",default=False)
parser.add_argument("-v", "--verbose", help="Verbose ouput in the terminal window.", action="store_true",
parser.add_argument("-v", "--verbose", help="Verbose output in the terminal window.", action="store_true",
default=False)
args = parser.parse_args()

Expand Down Expand Up @@ -478,6 +480,12 @@ def keyloader(keychain, master_switch):
"{0} VirusTotal Module : [{1}Disabled{2}]{3}".format(Fore.WHITE + Style.BRIGHT, Fore.RED, Fore.WHITE, Style.RESET_ALL))
master_switch.virustotal = False

if len(keychain["censys_id"]) > 0 and len(keychain["censys_secret"]) > 0:
print("{0} Censys Module : [{1}Enabled{2}]{3}".format(Fore.WHITE + Style.BRIGHT, Fore.GREEN, Fore.WHITE, Style.RESET_ALL))
master_switch.censys = True
else:
print("{0} Censys Module : [{1}Disabled{2}]{3}".format(Fore.WHITE + Style.BRIGHT, Fore.RED, Fore.WHITE, Style.RESET_ALL))
master_switch.censys = False

if args.expand:
print("{0} SubHunter Module : [{1}Recursive{2}]{3}".format(Fore.WHITE + Style.BRIGHT, Fore.YELLOW, Fore.WHITE, Style.RESET_ALL))
Expand Down Expand Up @@ -699,6 +707,9 @@ def main(keychain, switch, output_path, count):
if switch.whois_collector is True and switch.stealth is False:
whois_collector.wlookup(target_list[key]) # Active

if switch.censys is True:
censys.port_scan(target_list[key], keychain["censys_id"], keychain["censys_secret"], count) # Passive

# hosthunter.query_api(target_list[key]) # Passive
hosthunter.org_finder(target_list[key]) # Passive

Expand Down Expand Up @@ -920,7 +931,6 @@ def sig_handler(signal, frame):
sys.exit(0)

if __name__ == "__main__":

signal.signal(signal.SIGINT, sig_handler) # Signal Listener
now = datetime.now()
output_path = 'asm_run_' + str(datetime.now().strftime("%d.%m.%y_%H-%M-%S"))
Expand Down
2 changes: 2 additions & 0 deletions keylist.asm
Expand Up @@ -4,3 +4,5 @@ shodan = ""
linkedin_username = ""
linkedin_password = ""
grayhatwarfare = ""
censys_id = ""
censys_secret = ""
25 changes: 25 additions & 0 deletions modules/censys.py
@@ -0,0 +1,25 @@
#!/usr/bin/python3
# Filename: censys.py
# Module: Censys
# Authors: Censys Team (support@censys.io)
# Aidan Holland (@thehappydinoa)

# Standard Libraries
import time

# External Libraries
from censys.ipv4 import CensysIPv4

__version__ = "v1.0"

def port_scan(hostx, censys_id, censys_secret, counter):
c = CensysIPv4(censys_id, censys_secret)

for ip in hostx.resolved_ips:
try:
response = c.view(ip.address)
ip.ports = response["ports"]
counter.ports = counter.ports + len(hostx.ports)
except:
time.sleep(1)
continue
1 change: 1 addition & 0 deletions requirements.txt
Expand Up @@ -13,3 +13,4 @@ tld>=0.9.3
trans>=2.1.0
validator_collection
selenium>=3.141.0
censys>=1.1.0

0 comments on commit 97a2827

Please sign in to comment.