/* * Author: Saeed Ghiassy * Date: Mon Sep 21 03:27:34 BST 2009 * Version: 0.1 * * Description: This java class tries to stop SSH Brute Force Attacks * by look into log file created by SSH daemon. * it checks number of failure login attempts,and if it is more than * 10 times failure attempt, the IP will be categorised as an Attacker IP. * Then the IP address will be added to /etc/hosts.deny to be blocked for * Any further attempts.Also the list file creates for user information. * * * ##### Example Log file can be downloaded from here ######### */ import java.io.*; import java.util.*; import java.util.regex.*; public class jssh_bruteforce_blocker { //Regular expression to find IP address private final static String IP_REGEX = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"; private final static String failure_msg_REGEX = "Failed password"; private static HashMap<String, Integer > ipaddresses = new HashMap<String, Integer>(); private static ArrayList<String> blacklist = new ArrayList<String>(); public static void main(String[]args) throws IOException { if(args.length != 1) { System.err.println("Usage: java jssh_bruteforce_blocker <log file>"); System.exit(-1); } String m_filename = args[0]; File m_logfile = new File(m_filename); if(m_logfile.exists()) { System.out.println("[+]Log file located: " + m_logfile.getAbsolutePath()); }else{ System.err.println("[-]Log file not found!\n[-]Terminating application."); System.exit(-1); } //simple check for validate log file if(!validate_logfile(m_logfile)){ System.err.println("[-]Log file validation failed.\n[-]Terminating application."); System.exit(-1); } detect_failure_login(m_logfile); gen_report(); save_to_file(); System.out.println("[+]All Tasks successfully done.\n[!]Terminating application. :-)"); }//-- end of main ///////////////validating log file by looking for "sshd" string public static boolean validate_logfile(File logfile) throws IOException { System.out.println("[+]Validating Log file...."); int count=0; boolean flag = false; BufferedReader stdin = new BufferedReader(new FileReader(logfile)); String read; while((read = stdin.readLine()) != null) { if(read.contains("sshd")) { count++; } if(count >= 3) { System.out.println("[+]Log file seems to be valid :-)"); flag = true; break; } } stdin.close(); return flag; }//-- end of validate function /////////////Detect Failure Login attempts public static void detect_failure_login(File logfile)throws IOException { System.out.println("[+]Reading Log file contents, please wait..."); BufferedReader stdin = new BufferedReader(new FileReader(logfile)); Pattern pattern_failure = Pattern.compile(failure_msg_REGEX,Pattern.CASE_INSENSITIVE); Pattern pattern_ip = Pattern.compile(IP_REGEX,Pattern.CASE_INSENSITIVE); String input,ip; while((input = stdin.readLine())!=null) { //Searching for Failed password String Matcher matcher = pattern_failure.matcher(input); if(matcher.find()) { //System.out.println("####found### "+ matcher.group()); //Searching for ip addresses in failure line Matcher ip_matcher = pattern_ip.matcher(input); if(ip_matcher.find()) { ip = ip_matcher.group(); //System.out.println("IP address: " + ip); //Check if ip is already added to list increase its attempt times //otherwise add the new ip to list if(ipaddresses.containsKey(ip)) { int count = ipaddresses.get(ip); count++; ipaddresses.remove(ip); ipaddresses.put(ip, count); }else{ ipaddresses.put(ip, 1); }//-- end else } }// -- end searching if }//-- End of while loop System.out.println("[+]Searching process completed."); //System.out.println(ipaddresses); stdin.close(); }//-- end of detect_failure_login ////////////Generating Report public static void gen_report() { Set mySet = ipaddresses.entrySet(); System.out.println("[+]Generating report."); System.out.println("======================================================="); System.out.println("IP Address\t\tNumber of Failure Attempts"); System.out.println("____________\t\t__________________________"); Iterator i = mySet.iterator(); while(i.hasNext()) { Map.Entry map = (Map.Entry)i.next(); System.out.print(map.getKey()+"\t\t\t" + map.getValue()); int x = Integer.parseInt(map.getValue().toString()); if(x > 10 ) { System.out.print("\t\t!! BruteForce Attack Detected !!"); blacklist.add(map.getKey().toString()); } System.out.println(); } System.out.println("======================================================="); }// End of report ///////////////Save Attackers ip to File public static void save_to_file() throws IOException { System.out.println("[+]Creating Blacklist file."); File blocklist = new File("blocklist.txt"); BufferedWriter fwout = null; FileWriter fstream = null; if(blocklist.createNewFile()) { fstream = new FileWriter(blocklist,true); fwout = new BufferedWriter(fstream); fwout.write("##################################################\n"); fwout.write("Generated by: jssh_bruteforce_blocker\n"); fwout.write("Date: " + new Date().toString() + "\n"); fwout.write("##################################################\n\n"); fwout.flush(); }else{ System.out.println("[-]Blacklist file already exist.\n[+]Adding to the End of file."); fstream = new FileWriter(blocklist,true); fwout = new BufferedWriter(fstream); } for(int i=0; i< blacklist.size();i++) { fwout.write("IP Address: " + blacklist.get(i) +"\t\tAdded Date: " + new Date().toString() + "\n"); if(i%100==0) { fwout.flush(); } } fwout.close(); /* *********************************************************** * Adding Attacker IPs to "/etc/hosts.deny" * This will stop them to connect to server again * ROOT ACCESS NEEDED TO CHANGE THIS FILE *************************************************************/ File hosts = new File("/etc/hosts.deny"); if(hosts.exists()) { System.out.println("[+]Adding attackers IP to /etc/hosts.deny"); FileWriter mywriter = new FileWriter(hosts, true); BufferedWriter mybw = new BufferedWriter(mywriter); for(int i=0;i<blacklist.size();i++){ //mybw.write("sshd: " + blacklist.get(i) + "\n"); //Blocking access to all Services mybw.write("ALL: " + blacklist.get(i) + "\n"); mybw.flush(); } }else{ System.out.println("[-]Hosts File not found in defined path: /etc/hosts.deny"); } }//-- End of save to file function }// end of file