Guest User

Untitled

a guest
Jan 17th, 2014
1,141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.32 KB | None | 0 0
  1. /* vimzipper.c - read in a vim-encrypted file and wrap it as an encrypted
  2. * zip archive so that it can be directly attacked using the
  3. * widely-known zip encryption breakers like PKcrack.
  4. *
  5. * Richard Jones
  6. * December 26, 2006
  7. *
  8. * Background
  9. * ----------
  10. * This tool was written to facilitate the cracking of text files that
  11. * have been encrypted using the "vim -x" facility of the popular vim
  12. * editor. Such files will be known as "vim-x" files henceforth in this
  13. * file. The encryption used by vim-x (as of v6.1) is identical to
  14. * that of PKZIP (and InfoZip, NetZip, WinZip, etc.) so they can be
  15. * decrypted without knowing the encryption password using the well-known
  16. * plain text attack first described by Eli Biham and Paul Kocher in
  17. *
  18. * ``A Known Plaintext Attack on the PKZIP Stream Cipher'',
  19. * Fast Software Encryption 2, Proceedings of the Leuven Workshop,
  20. * LNCS 1008, December 1994.
  21. *
  22. * The PKZIP standard encryption scheme has continued to be broadly used,
  23. * in spite of its weak security, because of it was able to evade the strict
  24. * U.S. export controls on encryption software that were in place in the
  25. * 1990's. It was also favored because of its efficiency and its widely
  26. * published implementations. The original "vi" editor (and its command
  27. * line equivalent ex) on solaris had a -x argument which enabled users
  28. * to encrypt disk images of text created in the editor with a password,
  29. * based upon the unix "crypt" clib function. The authors of the vim
  30. * "vi improved" editor for Linux/Windows (see web site http://www.vim.org)
  31. * implemented a similar functionality, but based it on the PKZIP encryption
  32. * algorithm instead of crypt. By the mid-1980's a text file encoded using
  33. * crypt could be broken using automatic brute-force methods within a matter
  34. * of hours on a desktop PC. Unfortunately, within the following decade
  35. * the PKZIP algorithm had suffered a similar fate. However, the makers of
  36. * vim stuck with the zip algorithm, probably for compatibility reasons and
  37. * to avoid legal export restrictions associated with strong encryption
  38. * algorithms. As a result, those of us who like the convenience of "vi -x"
  39. * are stuck with managing its weaknesses and making sure our most sensitive
  40. * data are protected in other ways.
  41. *
  42. * Method:
  43. * -------
  44. * The attack described by Biham and Kocher relies on the user having access
  45. * to a fragment of the decrypted file and knowing its offset in the file
  46. * byte stream. This is not very useful if the attacker has no other way
  47. * to guess the contents of a file than to look at the filename and size
  48. * of the encrypted file. However, in an archive containing many files, there
  49. * may be one for which an unencrypted copy can be found elsewhere. Once
  50. * that is done, the archive encryption is all but broken. A number of
  51. * programs implementing plain-text attacks on various types of zip files
  52. * are widely available for download. A very good one is PKcrack by Peter
  53. * Conrad.
  54. *
  55. * PKcrack can work either on files inside zip archives or on the extracted
  56. * contents, and requires only the first 13 bytes of one file in order to
  57. * uniquely find the encryption key. The key is a set of 3 4-byte integers
  58. * that completely contains the internal state of the encryption engine at
  59. * the start of the file. Normally it is generated by the zip utility from
  60. * a password chosen by the user, but it is the key itself that is needed to
  61. * decrypt the archive, not the password. In cases where the user has chosen
  62. * a very complex password, PKcrack can quickly report the initial keys. It
  63. * also supports a reverse search for the password, but this is a brute-force
  64. * attack and not very effective against good passwords. With the key only,
  65. * the entire zip file can be instantly decrypted with no errors. The point
  66. * of vimzipper is to wrap a vim-x file within a zip archive so that the
  67. * PKcrack tools can be used to decipher it.
  68. *
  69. * Differences between vim-x files and zip archives
  70. * -------------------------------------------------
  71. * Commonly the zip utility compresses text files before it stores them in
  72. * an archive. This should be a good defence against plain-text attacks
  73. * because it makes the contents of the first few bytes of a file dependent
  74. * on the contents of the entire file. However, the PKZIP encryption rules
  75. * state that a 12-byte random string must be prepended to the encrypted data
  76. * stream, and it seems that zip utility software authors have not been very
  77. * careful about making it random. In 2001 Michael Stay ([email protected])
  78. * published a note reporting that the 12-byte string prepended by the
  79. * popular WinZip program is highly predictable. Furthermore, the encryption
  80. * engine is initialized afresh (with the same password) at the beginning of
  81. * each archived file, so that combining these 12 characters with the header
  82. * of any structured file can serve as the known plain-text for a plain-text
  83. * attack. Using this knowledge it is possible to crack a zip archive that
  84. * contains a typical user's home directory within a couple of hours on a
  85. * desktop PC.
  86. *
  87. * These efficient methods are not effective against most most vim-x files
  88. * because (so far) there is no generally effective strategy for predicting
  89. * the contents of a text file created in an editor. However, vim-x files
  90. * are not compressed prior to encryption, so plain-text attacks using a
  91. * short file fragment are still effective. This means that trying a random
  92. * selection of common phrases (or computer language keywords for source
  93. * files) placed at random offsets within the file has a good chance of
  94. * success within a relatively short period of time. The basic weakness of
  95. * PKZIP is that the key space is not very large, a fact that remains no
  96. * matter how long a password is chosen.
  97. *
  98. * Usage:
  99. * ------
  100. * Mounting an attack on a vim-x file requires two steps.
  101. * 1. Use vimzipper to transform the vim-x file into a zip archive.
  102. * The output zip file from vimzipper is not fully zip-compatible, but
  103. * it can be scanned by zipinfo and analyzed by pkcrack and other zip
  104. * file decryption tools.
  105. * 2. Run pkcrack in the usual way on the zip file to extract the keys.
  106. * 3. Run zipdecrypt on the zip file to create the decrypted output file
  107. * in the form of a zip file like the original one, without encryption.
  108. */
  109.  
  110. #include <stdlib.h>
  111. #include <stdio.h>
  112.  
  113. int main(int argc, char* argv[])
  114. {
  115. int arg;
  116. char *command;
  117. char *p1,*p2;
  118. FILE* zipfd;
  119. int done;
  120.  
  121. if ((argc < 3) || (argc > 999)) {
  122. fprintf(stderr,"\n Usage: vimzipper <outfile.zip> <vim-x-file> ... \n\n");
  123. exit(1);
  124. }
  125.  
  126. // issue the zip command to create the archive
  127.  
  128. p1 = command = malloc(80);
  129. p2 = p1+80;
  130. for (arg=0; arg < argc; ++arg) {
  131. if (p1+strlen(argv[arg])+1 >= p2) {
  132. int size = p2-command;
  133. p2 = malloc(size+80);
  134. strncpy(p2,command,size);
  135. p1 += p2-command;
  136. free(command);
  137. command = p2;
  138. p2 += size+80;
  139. }
  140. if (arg == 0) {
  141. char zipper[] = "zip";
  142. snprintf(p1,strlen(zipper)+1,"%s",zipper);
  143. p1 += strlen(zipper);
  144. }
  145. else {
  146. strncpy(p1,argv[arg],strlen(argv[arg])+1);
  147. p1 += strlen(argv[arg]);
  148. }
  149. strncpy(p1," ",2);
  150. ++p1;
  151. }
  152. unlink(argv[1]);
  153. if (system(command) != 0) {
  154. fprintf(stderr,"Error: zip command returned failure code, giving up!\n");
  155. exit(1);
  156. }
  157.  
  158. // go through and mark all vim-x files as zip-encrypted
  159.  
  160. zipfd = fopen(argv[1],"r+");
  161. if (zipfd == 0) {
  162. fprintf(stderr,"Error: unable to create output zip archive %s!\n",
  163. argv[1]);
  164. exit(1);
  165. }
  166. done = 0;
  167. while (done == 0) {
  168. int16_t sign[4];
  169. struct zip_hdr_t {
  170. int16_t gpb;
  171. int16_t comp;
  172. int16_t time;
  173. int16_t date;
  174. int32_t crc;
  175. int32_t csize;
  176. int32_t uncsize;
  177. int16_t flen;
  178. int16_t extralen;
  179. } hdr;
  180. int extras[32];
  181. FILE *fd;
  182. char filename[999];
  183. char magic[15];
  184. long int pos_hdr;
  185. int count = fread(&sign,sizeof(int16_t),3,zipfd);
  186. if (sign[0] != 0x4b50) {
  187. fprintf(stderr,"Error: unrecognized header %x found in archive!\n",
  188. sign[1]);
  189. exit(1);
  190. }
  191. switch (sign[1]) {
  192. case 0x0201:
  193. count = fread(&sign[3],sizeof(int16_t),1,zipfd);
  194. pos_hdr = ftell(zipfd);
  195. count += fread(&hdr,sizeof(struct zip_hdr_t),1,zipfd);
  196. count += fread(&extras,14,1,zipfd);
  197. count += fread(&filename,hdr.flen,1,zipfd);
  198. break;
  199. case 0x0403:
  200. pos_hdr = ftell(zipfd);
  201. count = fread(&hdr,sizeof(struct zip_hdr_t),1,zipfd);
  202. count += fread(&filename,hdr.flen,1,zipfd);
  203. break;
  204. case 0x0605:
  205. done = 1;
  206. continue;
  207. default:
  208. fprintf(stderr,"Error: unrecognized header %x found in archive!\n",
  209. sign[1]);
  210. exit(1);
  211. }
  212. filename[hdr.flen] = '\0';
  213. if ((fd = fopen(filename,"r")) == 0) {
  214. fprintf(stderr,"Error: input file %s cannot be openned!\n",
  215. filename);
  216. exit(1);
  217. }
  218. else {
  219. int bc = fread(&magic,1,12,fd);
  220. if ((bc == 12) && (strncmp(magic,"VimCrypt~01!",12) == 0)) {
  221. hdr.gpb |= 1;
  222. hdr.uncsize -= 12;
  223. fseek(zipfd,pos_hdr,SEEK_SET);
  224. bc = fwrite(&hdr,sizeof(struct zip_hdr_t),1,zipfd);
  225. if (sign[1] == 0x0403) {
  226. printf(" touching up %s header (vim encrypted)\n",filename);
  227. }
  228. else if (sign[1] == 0x0201) {
  229. printf(" touching up %s trailer (vim encrypted)\n",filename);
  230. }
  231. }
  232. fclose(fd);
  233. }
  234. pos_hdr += sizeof(struct zip_hdr_t);
  235. pos_hdr += hdr.flen;
  236. pos_hdr += hdr.extralen;
  237. switch (sign[1]) {
  238. case 0x0201:
  239. pos_hdr += 14;
  240. break;
  241. case 0x0403:
  242. pos_hdr += hdr.csize;
  243. }
  244. fseek(zipfd,pos_hdr,SEEK_SET);
  245. }
  246. fclose(zipfd);
  247. }
Advertisement
Add Comment
Please, Sign In to add comment