-
Notifications
You must be signed in to change notification settings - Fork 0
/
crack.ml
125 lines (117 loc) · 3.67 KB
/
crack.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
(* Copyright (c) 2024 Max Charrier, Inès Schneider. All Rights Reserved. *)
(*#use "tools.ml"*)
open Printf
open List
open Tools
(* Type for storing user credentials *)
type t = { app : string; id : string; pw : string }
let partition_by_login
(acc : (string * string) list * (string * string) list)
(data : (string * string) list)
(clear_id : string)
(clear_pw : string)
: (string * string) list * (string * string) list =
let rec part yes no lst =
if lst = [] then
(* The order of the elements in data is preserved *)
(rev yes, rev no)
else
let (id,pw) = hd lst in
(*printf "id: %s, hash pw: %s\n" id pw;*)
(* Predicate over id and password *)
if id = clear_id && pw = hash_password clear_pw then begin
(*printf "FIND clear pw %s\n" clear_pw;*)
(* Add to the first list 'yes' that satisfy the predicate
and continue with the rest of data
*)
part ((id,clear_pw)::yes) no (tl lst)
end else
(* Otherwise, add to the second list 'no' (all the elements
that do not satisfy) and continue
*)
part yes ((id,pw)::no) (tl lst)
in
(* Call the recursive partition function with splited accumulator *)
part (fst acc) (snd acc) data
let crack_with_clear_data
(clear_data : (string * string) list)
(data : (string * string) list)
: (string * string) list * (string * string) list =
let rec aux acc lst rest =
if lst = [] then acc
else begin
let (id,pw) = hd lst in
let (yes,no) =
(* Partition based on matching clear data credentials *)
partition_by_login (fst acc,[]) rest id pw
in
(* Continue recursively with the rest of clear data
and non-matching data
*)
aux (yes,no) (tl lst) no
end
in
aux ([],[]) clear_data data
let partition_by_password
(acc : (string * string) list * (string * string) list)
(data : (string * string) list)
(clear_pw : string)
(encrypted_pw : string)
: (string * string) list * (string * string) list =
let rec part yes no lst =
if lst = [] then (rev yes, rev no)
else
let (id,pw) = hd lst in
(*printf "id: %s, hash pw: %s\n" id pw;*)
(* Predicate over password *)
if pw = encrypted_pw then begin
(*printf "FIND clear pw %s\n" clear_pw;*)
(* Add to the first list 'yes' that satisfy the predicate
and continue with the rest of data
*)
part ((id,clear_pw)::yes) no (tl lst)
end else
(* Otherwise, add to the second list 'no' (all the elements
that do not satisfy) and continue
*)
part yes ((id,pw)::no) (tl lst)
in
(* Call the recursive partition function with splited accumulator *)
part (fst acc) (snd acc) data
let crack_with_wordlist
(wl : string list)
(data : (string * string) list)
: (string * string) list * (string * string) list =
let encrypted_wl = encrypt_wordlist wl in
let rec aux acc lst1 lst2 rest =
if lst1 = [] && lst2 = [] then acc
else begin
let word = hd lst1 in
let encrypted_word = hd lst2 in
(*printf "\nword: %s, encrypted word: %s\n" word encrypted_word;*)
let (yes,no) =
(* Partition the data by comparing the encrypted word. *)
partition_by_password (fst acc,[]) rest word encrypted_word
in
(* Continue recursively with the rest of the wordlist
and non-matching data
*)
aux (yes,no) (tl lst1) (tl lst2) no
end
in
aux ([],[]) wl encrypted_wl data
let formalize_result
(app : string)
(data : (string * string) list)
: t list =
let rec aux acc lst i =
if lst = [] then begin
printf "%d password decrypted, see output for more details\n" i;
acc
end else
let (id,pw) = hd lst in
(* Add a formatted credential entry to the result *)
aux ({ app=app; id=id; pw=pw }::acc) (tl lst) (i+1)
in
(* Start the recursion with the matched credentials *)
aux [] data 0