| 0. 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. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. | /* * character-set based brute-forcing algorithm * (c) 2004 by [email protected] * * usage: ./crunch <from-len> <to-len> [charset] [-t [FIXED]@@@@] [-s startblock] * * e.g: ./crunch 3 7 abcdef * * This example will compute all passwords between 3 and 7 chars * using 'abcdef' as the character set and dump it to stdout. * * Options: * * -t [FIXED]@@@@ : allows you to specify a pattern, eg: @@god@@@@ * where the only the @'s will change * * -s : allows you to specify the starting string, eg: 03god22fs * * * This code can be easily adapted for use in brute-force attacks * against network services or cryptography. * * Compiles on: linux, ms visual c++, freebsd * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define TRUE 1 #define FALSE 0 char def_charset[] = "abcdefghijklmnopqrstuvwxyz"; unsigned int inc[128]; int finished(char *block, char *charset, char *templ) { unsigned int i; if(templ[0]==0) { for(i=0;i<strlen(block);i++) if(inc[i] < strlen(charset)-1) return FALSE; } else { for(i=0;i<strlen(block);i++) if(templ[i]=='@' && (inc[i] < strlen(charset)-1)) return FALSE; } return TRUE; } void increment(char *block, int len, char *charset, char *templ) { int i; for(i=strlen(block)-1;i>-1;i--) { if(templ[0]==0 || templ[i]=='@') { if(inc[i] < strlen(charset)-1) { inc[i]++; block[i] = charset[inc[i]]; i=-1; } else { block[i] = charset[0]; inc[i] = 0; } } else { } } } void chunk(int start, int end, char *charset, char *templ, char *startblock) { int i,j,k,t; char block[128]; if(end-start <0) return; if(templ[0]==0) t=0; else t=1; for(i=start;i<=end;i++) { memset(block,0,sizeof(block)); for(j=0;j<i;j++) { if(startblock[0]==0) { if(t==0) { block[j] = charset[0]; inc[j] = 0; } else { if(templ[j]=='@') { block[j] = charset[0]; inc[j] = 0; } else block[j] = templ[j]; } } else { block[j] = startblock[j]; for(k=0;k<strlen(charset);k++) if(block[j]==charset[k]) inc[j] = k; } } printf("%s\n",block); while(!finished(block,charset,templ)) { increment(block,i,charset,templ); printf("%s\n",block); } } } int main(int argc, char *argv[]) { int i,j,flag,min,max; char charset[256]; char templ[256]; char startblock[256]; if(argc<3) { printf("usage: %s <from-len> <to-len> [charset] [-t [FIXED]@@@@] [-s startblock]\n",argv[0]); return 0; } memset(charset,0,sizeof(charset)); memset(templ,0,sizeof(templ)); memset(startblock,0,sizeof(startblock)); /* remove duplicate characters from charset */ if(argc>3) { for(i=0;i<strlen(argv[3]);i++) { flag = 0; for(j=0;j<strlen(charset);j++) if(argv[3][i] == charset[j]) flag = 1; if(flag==0) strncat(charset,&argv[3][i],1); } } else strncpy(charset,def_charset,strlen(def_charset)); min = atoi(argv[1]); max = atoi(argv[2]); for(i=1;i<argc-1;i++) { if(strncmp(argv[i],"-t",2)==0) { strncpy(templ,argv[i+1],strlen(argv[i+1])); } if(strncmp(argv[i],"-s",2)==0) { if(strlen(argv[i+1]) >min) { printf("Warning: starting length increased to %d.\n",strlen(argv[i+1])); min = strlen(argv[i+1]); } if(strlen(argv[i+1]) <min) { printf("Warning: minimum length decreased to %d.\n",strlen(argv[i+1])); min = strlen(argv[i+1]); } strncpy(startblock,argv[i+1],strlen(argv[i+1])); } } chunk(min,max,charset,templ,startblock); return 0; } |