Markopy
Utilizing Markov Models for brute forcing attacks
modelMatrix.cpp
Go to the documentation of this file.
1 /** @file modelMatrix.cpp
2  * @brief An extension of Markov::API::MarkovPasswords
3  * @authors Ata Hakçıl
4  *
5  * This class shows superior performance compared to the traditional model at Markov::API::MarkovPasswords
6  *
7  * @copydoc Markov::API::ModelMatrix
8  */
9 
10 #include "modelMatrix.h"
11 #include <map>
12 #include <cstring>
13 #include <thread>
14 
16  this->ready = false;
17 }
18 
19 void Markov::API::ModelMatrix::Import(const char *filename){
23 }
24 
25 void Markov::API::ModelMatrix::Train(const char *datasetFileName, char delimiter, int threads){
27  this->Markov::API::MarkovPasswords::Train(datasetFileName,delimiter,threads);
29 }
30 
32  if(this->ready) return false;
33  this->matrixSize = this->StarterNode()->edgesV.size() + 2;
34 
35  this->matrixIndex = new char[this->matrixSize];
36  this->totalEdgeWeights = new long int[this->matrixSize];
37 
38  this->edgeMatrix = new char*[this->matrixSize];
39  for(int i=0;i<this->matrixSize;i++){
40  this->edgeMatrix[i] = new char[this->matrixSize];
41  }
42  this->valueMatrix = new long int*[this->matrixSize];
43  for(int i=0;i<this->matrixSize;i++){
44  this->valueMatrix[i] = new long int[this->matrixSize];
45  }
46  std::map< char, Node< char > * > *nodes;
47  nodes = this->Nodes();
48  int i=0;
49  for (auto const& [repr, node] : *nodes){
50  if(repr!=0) this->matrixIndex[i] = repr;
51  else this->matrixIndex[i] = 199;
53  for(int j=0;j<this->matrixSize;j++){
54  char val = node->NodeValue();
55  if(val < 0){
56  for(int k=0;k<this->matrixSize;k++){
57  this->valueMatrix[i][k] = 0;
58  this->edgeMatrix[i][k] = 255;
59  }
60  break;
61  }
62  else if(node->NodeValue() == 0 && j>(this->matrixSize-3)){
63  this->valueMatrix[i][j] = 0;
64  this->edgeMatrix[i][j] = 255;
65  }else if(j==(this->matrixSize-1)) {
66  this->valueMatrix[i][j] = 0;
67  this->edgeMatrix[i][j] = 255;
68  }else{
69  this->valueMatrix[i][j] = node->edgesV[j]->EdgeWeight();
70  this->edgeMatrix[i][j] = node->edgesV[j]->RightNode()->NodeValue();
71  }
72 
73  }
74  i++;
75  }
76  this->ready = true;
77  return true;
78  //this->DumpJSON();
79 }
80 
82  if(!this->ready) return false;
83  delete[] this->matrixIndex;
84  delete[] this->totalEdgeWeights;
85 
86  for(int i=0;i<this->matrixSize;i++){
87  delete[] this->edgeMatrix[i];
88  }
89  delete[] this->edgeMatrix;
90 
91  for(int i=0;i<this->matrixSize;i++){
92  delete[] this->valueMatrix[i];
93  }
94  delete[] this->valueMatrix;
95 
96  this->matrixSize = -1;
97  this->ready = false;
98  return true;
99 }
100 
102 
103  std::cout << "{\n \"index\": \"";
104  for(int i=0;i<this->matrixSize;i++){
105  if(this->matrixIndex[i]=='"') std::cout << "\\\"";
106  else if(this->matrixIndex[i]=='\\') std::cout << "\\\\";
107  else if(this->matrixIndex[i]==0) std::cout << "\\\\x00";
108  else if(i==0) std::cout << "\\\\xff";
109  else if(this->matrixIndex[i]=='\n') std::cout << "\\n";
110  else std::cout << this->matrixIndex[i];
111  }
112  std::cout <<
113  "\",\n"
114  " \"edgemap\": {\n";
115 
116  for(int i=0;i<this->matrixSize;i++){
117  if(this->matrixIndex[i]=='"') std::cout << " \"\\\"\": [";
118  else if(this->matrixIndex[i]=='\\') std::cout << " \"\\\\\": [";
119  else if(this->matrixIndex[i]==0) std::cout << " \"\\\\x00\": [";
120  else if(this->matrixIndex[i]<0) std::cout << " \"\\\\xff\": [";
121  else std::cout << " \"" << this->matrixIndex[i] << "\": [";
122  for(int j=0;j<this->matrixSize;j++){
123  if(this->edgeMatrix[i][j]=='"') std::cout << "\"\\\"\"";
124  else if(this->edgeMatrix[i][j]=='\\') std::cout << "\"\\\\\"";
125  else if(this->edgeMatrix[i][j]==0) std::cout << "\"\\\\x00\"";
126  else if(this->edgeMatrix[i][j]<0) std::cout << "\"\\\\xff\"";
127  else if(this->matrixIndex[i]=='\n') std::cout << "\"\\n\"";
128  else std::cout << "\"" << this->edgeMatrix[i][j] << "\"";
129  if(j!=this->matrixSize-1) std::cout << ", ";
130  }
131  std::cout << "],\n";
132  }
133  std::cout << "},\n";
134 
135  std::cout << "\" weightmap\": {\n";
136  for(int i=0;i<this->matrixSize;i++){
137  if(this->matrixIndex[i]=='"') std::cout << " \"\\\"\": [";
138  else if(this->matrixIndex[i]=='\\') std::cout << " \"\\\\\": [";
139  else if(this->matrixIndex[i]==0) std::cout << " \"\\\\x00\": [";
140  else if(this->matrixIndex[i]<0) std::cout << " \"\\\\xff\": [";
141  else std::cout << " \"" << this->matrixIndex[i] << "\": [";
142 
143  for(int j=0;j<this->matrixSize;j++){
144  std::cout << this->valueMatrix[i][j];
145  if(j!=this->matrixSize-1) std::cout << ", ";
146  }
147  std::cout << "],\n";
148  }
149  std::cout << " }\n}\n";
150 }
151 
152 
153 void Markov::API::ModelMatrix::FastRandomWalkThread(std::mutex *mlock, std::ofstream *wordlist, unsigned long int n, int minLen, int maxLen, int id, bool bFileIO){
154  if(n==0) return;
155 
156  Markov::Random::Marsaglia MarsagliaRandomEngine;
157  char* e;
158  char *res = new char[(maxLen+2)*n];
159  int index = 0;
160  char next;
161  int len=0;
162  long int selection;
163  char cur;
164  long int bufferctr = 0;
165  for (int i = 0; i < n; i++) {
166  cur=199;
167  len=0;
168  while (true) {
169  e = strchr(this->matrixIndex, cur);
170  index = e - this->matrixIndex;
171  selection = MarsagliaRandomEngine.random() % this->totalEdgeWeights[index];
172  for(int j=0;j<this->matrixSize;j++){
173  selection -= this->valueMatrix[index][j];
174  if (selection < 0){
175  next = this->edgeMatrix[index][j];
176  break;
177  }
178  }
179 
180  if (len >= maxLen) break;
181  else if ((next < 0) && (len < minLen)) continue;
182  else if (next < 0) break;
183  cur = next;
184  res[bufferctr + len++] = cur;
185  }
186  res[bufferctr + len++] = '\n';
187  bufferctr+=len;
188 
189  }
190  if(bFileIO){
191  mlock->lock();
192  *wordlist << res;
193  mlock->unlock();
194  }else{
195  mlock->lock();
196  std::cout << res;
197  mlock->unlock();
198  }
199  delete res;
200 
201 }
202 
203 
204 int Markov::API::ModelMatrix::FastRandomWalk(unsigned long int n, std::ofstream *wordlist, int minLen, int maxLen, int threads, bool bFileIO){
205 
206 
207  std::mutex mlock;
208  if(n<=50000000ull) this->FastRandomWalkPartition(&mlock, wordlist, n, minLen, maxLen, bFileIO, threads);
209  else{
210  int numberOfPartitions = n/50000000ull;
211  for(int i=0;i<numberOfPartitions;i++)
212  this->FastRandomWalkPartition(&mlock, wordlist, 50000000ull, minLen, maxLen, bFileIO, threads);
213  }
214  return 0;
215 }
216 
217 int Markov::API::ModelMatrix::FastRandomWalk(unsigned long int n, const char* wordlistFileName, int minLen, int maxLen, int threads, bool bFileIO){
218  std::ofstream wordlist;
219  if(bFileIO)
220  wordlist.open(wordlistFileName);
221  this->FastRandomWalk(n, &wordlist, minLen, maxLen, threads, bFileIO);
222  return 0;
223 }
224 
225 void Markov::API::ModelMatrix::FastRandomWalkPartition(std::mutex *mlock, std::ofstream *wordlist, unsigned long int n, int minLen, int maxLen, bool bFileIO, int threads){
226 
227  int iterationsPerThread = n/threads;
228  int iterationsPerThreadCarryOver = n%threads;
229 
230  std::vector<std::thread*> threadsV;
231 
232  int id = 0;
233  for(int i=0;i<threads;i++){
234  threadsV.push_back(new std::thread(&Markov::API::ModelMatrix::FastRandomWalkThread, this, mlock, wordlist, iterationsPerThread, minLen, maxLen, id, bFileIO));
235  id++;
236  }
237 
238  threadsV.push_back(new std::thread(&Markov::API::ModelMatrix::FastRandomWalkThread, this, mlock, wordlist, iterationsPerThreadCarryOver, minLen, maxLen, id, bFileIO));
239 
240  for(int i=0;i<threads;i++){
241  threadsV[i]->join();
242  }
243 }