本文主要记录已加密zip压缩包的破解,密码为数字的暴力破解方式,仅用于实验研究。
我只尝试了两种破解方式,一种是利用Archpr工具(仅windows平台可用),另一种利用了John(kali系统内置,支持windows和linux系统),主要思路为java利用
Runtime.getRuntime();
调用cmd命令去执行破解工作,然后分析破解后的密码文件,获取密码,进行下一步的解压缩,解压缩成功后,可以将过程中的文件清除,减少硬盘占用,本次示例代码截至到获取密码阶段,后续代码就不赘述了。
直接上代码,首先是Archpr版
package org.example;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* Hello world!
*
*/
public class Archpr2Zip
{
static String url = "E:\\Elcomsoft Password Recovery\\Advanced Archive Password Recovery\\ARCHPR.exe ";
static String pwdFileRoot ="E:\\";
public static void main(String[] args) throws ExecutionException, InterruptedException {
String pwdFile = pwdFileRoot+String.valueOf(System.currentTimeMillis());
String zipFile = "E:\\c.zip";//解压路径
execCommand(zipFile,pwdFile);
System.out.println("密码:"+getPwd(pwdFile));
// UnZipUtils.unZip(zipFile,dest,pwd);
}
public static void execCommand(String zipName,String pwdFile) {
try {
Runtime runtime = Runtime.getRuntime();
// 打开任务管理器,exec方法调用后返回 Process 进程对象
String cmd = " /a:b /c:d /min:6 /max:6 /sf:000000 /smartexit:"+pwdFile+ " "+zipName;
Process process = runtime.exec(url+cmd);
// 等待进程对象执行完成,并返回“退出值”,0 为正常,其他为异常
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
String line = "";
while ((line=bufferedReader.readLine())!=null){
System.out.println(line);
}
int exitValue = process.waitFor();
System.out.println("exitValue: " + exitValue);
// 销毁process对象
process.destroy();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
public static String getPwd(String pwdFile) {
//--------------读取文本-------------//
BufferedReader br = null;
try {
File file = new File(pwdFile);
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis, "UTF16");//避免中文乱码
br = new BufferedReader(isr);
List<String> list = new ArrayList<String>();
String str_line = "";
//逐行读取文本
while ((str_line = br.readLine()) != null) {
list.add(str_line);
if (str_line.indexOf("这个文件的口令 :") > -1) {
String pwd = str_line.substring(str_line.indexOf("这个文件的口令 :")+10);
return pwd;
}
}
//读取文件并执行业务
//.... list
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return "";
}
}
另一种是John版本
package org.example;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* Hello world!
*
*/
public class John2Zip
{
static String johnurl_zip = "E:\\john-1.9.0-jumbo-1-win64\\john-1.9.0-jumbo-1-win64\\run\\zip2john.exe";
static String johnurl_john = "E:\\john-1.9.0-jumbo-1-win64\\john-1.9.0-jumbo-1-win64\\run\\john.exe";
static String pwdFileRoot = "E:\\";
public static void main(String[] args) throws ExecutionException, InterruptedException {
String pwdFile = pwdFileRoot+String.valueOf(System.currentTimeMillis());
String zipFile = "E:\\settings.zip";
String dest = "E:\\test\\";//解压路径
// delFile(fpath);
execCommandZip2John(zipFile,pwdFile);
execCommandJohnHash(pwdFile);
System.out.println(execCommandShow(pwdFile));
// UnZipUtils.unZip(zipFile,dest,pwd);
}
public static void execCommandZip2John(String zipName,String pwdFile) {
try {
Runtime runtime = Runtime.getRuntime();
// 打开任务管理器,exec方法调用后返回 Process 进程对象
String cmd = " "+zipName+" > "+pwdFile;
Process process = runtime.exec(johnurl_zip+cmd);
// 等待进程对象执行完成,并返回“退出值”,0 为正常,其他为异常
FileWriter ft = new FileWriter(pwdFile);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
String line = "";
while ((line=bufferedReader.readLine())!=null){
ft.write(line);
System.out.println(line);
}
ft.flush();
int exitValue = process.waitFor();
System.out.println("exitValue: " + exitValue);
// 销毁process对象
process.destroy();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
public static void execCommandJohnHash(String pwdFile) {
try {
Runtime runtime = Runtime.getRuntime();
// 打开任务管理器,exec方法调用后返回 Process 进程对象
String cmd = " --incremental=digits "+pwdFile;
Process process = runtime.exec(johnurl_john+cmd);
// 等待进程对象执行完成,并返回“退出值”,0 为正常,其他为异常
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
String line = "";
while ((line=bufferedReader.readLine())!=null){
System.out.println(line);
}
int exitValue = process.waitFor();
System.out.println("exitValue: " + exitValue);
// 销毁process对象
process.destroy();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
public static String execCommandShow(String pwdFile) {
try {
Runtime runtime = Runtime.getRuntime();
// 打开任务管理器,exec方法调用后返回 Process 进程对象
String cmd = " --show "+pwdFile;
Process process = runtime.exec(johnurl_john+cmd);
// 等待进程对象执行完成,并返回“退出值”,0 为正常,其他为异常
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
String line = "";
while ((line=bufferedReader.readLine())!=null){
if(line.split(":").length>1){
String pwd = line.split(":")[1];
System.out.println("密码--------------->"+pwd) ;
return pwd;
}
}
int exitValue = process.waitFor();
System.out.println("exitValue: " + exitValue);
// 销毁process对象
process.destroy();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return "";
}
public static void delFile(String fileName){
try{
File file = new File(fileName);
file.deleteOnExit();
System.out.println("del finish");
}catch (Exception e){
e.printStackTrace();
}
}
}
以上就是个人的笔记,主要用于试验和学习,望大家多多指正!
另,如果已知密码范围比如纯数字或是有固定的格式可以自己生成一个字典,字典里面穷举所有密码,这时候效率会更高,命令如下:
john.exe --wordlist=dict.lst --fork=4 hash
其中dict.lst为字典文件,fork为开启的线程数,多核cpu开启多线程,性能更高,破解更快!