Brute Force

Nesselbrand

Bekanntes Mitglied
Wie kann ich es reaslisieren, dass ich mit einem Bruteforce hack zum beispiel eine mit passwort gesicherte Word datei cracken kann. Also wie kann ich es schaffen, dass die möglichkeiten bei word ausprobiert werden?
 

mihe7

Top Contributor
Aus Word VBA heraus, sollte das in etwa so funktionieren:
Code:
Function canOpen(docFile as String, password As String) as Boolean
    On Error Goto canOpen_Err
    checkPassword := False
    Documents.Open FileName:=docFile, PasswordDocument := password
    checkPassword := True
canOpen_Err:
Exit Function
 

abc66

Top Contributor
Ok ,viele haben damit einfach massive Probleme, deswegen...
Java:
public static class SIter implements Iterable<String> {
	private char[] a;
	/**
	 * three is the maximum length
	 */
	private int[] is = new int[3];
	/**
	 * at least one character
	 */
	private int l = 1;

	public SIter(char... a) {
		if (a == null || a.length == 0) {
			throw new IllegalArgumentException("a == null || a.length == 0");
		}
		this.a = a;
	}

	@Override
	public Iterator<String> iterator() {
		return new Iterator<String>() {
			@Override
			public boolean hasNext() {
				return l <= is.length;
			}

			@Override
			public String next() {
				String s = "";
				for (int i = 0; i < l; i++) {
					s += a[is[i]];
				}
				for (int j = 0; j < is.length; j++) {
					is[j]++;
					if (is[j] < a.length) {
						break;
					}
					is[j] = 0;
					if (j == l - 1) {
						l++;
						break;
					}
				}
				return s;
			}
		};
	}
}

public static void main(String[] args) {
	for (String s : new SIter('a', 'b', 'c', 'd')) {
		System.out.println(s);
	}
}

Ausgabe
Code:
a
b
c
d
aa
ba
ca
da
ab
bb
cb
db
ac
bc
cc
dc
ad
bd
cd
dd
aaa
baa
caa
daa
aba
bba
cba
dba
aca
bca
cca
dca
ada
bda
cda
dda
aab
bab
cab
dab
abb
bbb
cbb
dbb
acb
bcb
ccb
dcb
adb
bdb
cdb
ddb
aac
bac
cac
dac
abc
bbc
cbc
dbc
acc
bcc
ccc
dcc
adc
bdc
cdc
ddc
aad
bad
cad
dad
abd
bbd
cbd
dbd
acd
bcd
ccd
dcd
add
bdd
cdd
ddd

Das sollten eigentlich alle Möglichkeiten sein

(Oder könnte man das noch einfacher schreiben? )
 

Nesselbrand

Bekanntes Mitglied
Function canOpen(docFile as String, password As String) as Boolean
On Error Goto canOpen_Err
checkPassword := False
Documents.Open FileName:=docFile, PasswordDocument := password
checkPassword := True
canOpen_Err:
Exit Function

aslo ich kann das einfach in meinem java code verwenden?
 

abc66

Top Contributor
Ich habe das einmal jetzt für ZipCrypto geschrieben und den Prozessor gequält... Für eine Passwortlänge von 3 Zeichen und der Menge a-zA-Z dauert alles zu testen schon extrem lange.

@Nesselbrand Niemand darf das wissen, aber ich kenne mich mit Word und Excel nicht aus... Aber ist es nicht so, dass Du ein anderes Dokument öffnest und darin das Makro?
 

mihe7

Top Contributor
Was soll ich Dir denn sagen? Ich habe Dir doch schon einen Lösungsvorschlag und einen Ansatz gegeben, der ohne OLE-Automation auskommt.

Aus Java heraus OLE-Automation zu betreiben, dürfte mit JNA und JACOB funktionieren. Alternativ könntest Du auch Maus- und Tastatur aus Java heraus steuern (java.awt.Robot), das ist aber die mit Abstand schlechteste aller Möglichkeiten.

Bleibt noch der o. g. Vorschlag über Apache POI, den Du versuchen kannst. POI arbeitet auf Dateiebene, so dass auf dem Rechner kein Word installiert sein muss. Persönlich nutze ich POI allerdings ausschließlich für Exceldateien, die darüber hinaus nicht mit einem Passwort geschützt sind. Daher kann ich Dir auch nicht sagen, inwiefern POI zum Lesen passwortgeschützter Word-Dokumente geeignet ist.
 

httpdigest

Top Contributor
(Oder könnte man das noch einfacher schreiben? )
Java:
import java.util.stream.*;
public class StringPermutations {
  private static final char[] ALPHABET = { 'a', 'b', 'c', 'd', 'e', 'f' };
  private static String cvt(long v, int sb) {
    return (v --> sb ? cvt(v / sb, sb) : "") + ALPHABET[(int) (v % sb)];
  }
  public static Stream<String> combinations() {
    return iterate(1L, i -> i + 1L).mapToObj(i -> cvt(i, ALPHABET.length));
  }
  public static void main(String[] args) {
    combinations().forEach(System.out::println);
  }
}
 
Zuletzt bearbeitet:

abc66

Top Contributor
Extrem langsam:
Code:
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>Zips1</groupId>
	<artifactId>Zips1</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>4.1.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>4.1.1</version>
		</dependency>
	</dependencies>
</project>

Java:
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Iterator;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import org.apache.poi.poifs.crypt.Decryptor;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

public class M {
	public static class SIter implements Iterable<String> {
		private char[] a;
		/**
		 * five is the maximum length
		 */
		private int[] is = new int[5];
		/**
		 * at least one character
		 */
		private int l = 1;

		public SIter(char... a) {
			if (a == null || a.length == 0) {
				throw new IllegalArgumentException("a == null || a.length == 0");
			}
			this.a = a;
		}

		@Override
		public Iterator<String> iterator() {
			return new Iterator<String>() {
				@Override
				public boolean hasNext() {
					return l <= is.length;
				}

				@Override
				public String next() {
					String s = "";
					for (int i = 0; i < l; i++) {
						s += a[is[i]];
					}
					for (int j = 0; j < is.length; j++) {
						is[j]++;
						if (is[j] < a.length) {
							break;
						}
						is[j] = 0;
						if (j == l - 1) {
							l++;
							break;
						}
					}
					return s;
				}
			};
		}
	}

	public static void main(String[] args) throws IOException {
		JFileChooser c = new JFileChooser();
		c.showOpenDialog(null);
		File f = c.getSelectedFile();
		EncryptionInfo ei = new EncryptionInfo(new POIFSFileSystem(f));
		Decryptor d = ei.getDecryptor();

		String pw = null;
		try {
			for (String s : new SIter("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !\"#$%&'()*+,-./:;".toCharArray())) { // beschränke das auf die tatsächlichen Zeichen
				if (d.verifyPassword(s)) {
					pw = s;
					break;
				}
			}
		} catch (GeneralSecurityException e) {
			e.printStackTrace();
		}
		JOptionPane.showConfirmDialog(null, "Password: " + pw);
	}
}

@httpdigest Das war nicht mit einfacher gemeint. Also nein, ist nicht einfacher zu schreiben.
 

abc66

Top Contributor
a) Bei Streams das Problem, dass aus diesen nicht einfach heraus gesprungen werden kann.
b) long ist als Zählvariable begrenzt.
c) nicht lesbar und testbar.
 

httpdigest

Top Contributor
Bei Streams das Problem, dass aus diesen nicht einfach heraus gesprungen werden kann.
Den Kontrollfluss einer Methode beliebig zu verändern ist mit Streams nicht nötig, da sie selbst lazy ausgewertet werden. Der Aufrufer entscheidet in diesem Fall, ob er noch mehr Elemente haben möchte, oder nicht. Wo und warum willst du da herausspringen?
long ist als Zählvariable begrenzt.
In diesem Fall hast du Recht.
"Lesbarkeit" ist Gewöhnungssache. Ich finde dein langes for-schleifen-mit-breaks-und-if-bedingungen-und-Indexarithmetik-Monster persönlich viel unleserlicher als meine zwei Zeilen Code (der effektive Code in den Methoden cvt und combinations).
Tests sollten die Schnittstelle testen und die sieht bei uns beiden gleich aus: Es entsteht ein Iterator bzw. Stream aus Strings. Auch ist der Input bei uns beiden derselbe: Ein Alphabet. Das kann man in beiden Fällen sehr gut testen. Natürlich kann man bei mir das aktuell fixe Alphabet als Parameter reinziehen. Ändert an dem Algorithmus nichts.

Nicht zuletzt ist "funktional zu denken" ein Paradigment-shift, der genauso gut funktioniert wie imperativ.

EDIT: Mögliche Implementierung und Test:
Java:
import static java.util.stream.LongStream.*;
import static org.junit.jupiter.api.Assertions.*;
import java.util.stream.*;
import org.junit.jupiter.api.Test;
public class StringPermutations {
  private static String cvt(long v, char[] alphabet) {
    int sb = alphabet.length;
    return (v --> sb ? cvt(v / sb, alphabet) : "") + alphabet[(int) (v % sb)];
  }
  public static Stream<String> combinations(char[] alphabet) {
    return iterate(1L, i -> i + 1L).mapToObj(i -> cvt(i, alphabet));
  }

  // Ein möglicher Test dazu (natürlich in einer separaten Test-Klasse):

  @Test
  public void testFirstStringWithLength2() {
    // given
    char[] ALPHABET = {'a', 'b', 'c'};

    // when
    // als 4. String sollte "aa" kommen
    String actual = combinations(ALPHABET).skip(3).findFirst().get();

    // then
    assertEquals("aa", actual);
  }
}
 
Zuletzt bearbeitet:

Nesselbrand

Bekanntes Mitglied
Ich kann irgendwie keine word dateien verschicken aber du kannst dir eigentlich eine ganz einfach machen ich habe da nähmlich nichts reingeschrieben ich wollte dass nur mal so zum testen ausprobieren
 

Ähnliche Java Themen

Neue Themen


Oben