You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

271 lines
12 KiB

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "set1/xor_char_finder.h"
  5. #include "utils/common.h"
  6. #include "utils/base64.h"
  7. #include "utils/xor.h"
  8. #include "utils/hamming.h"
  9. #include "set1/ecb.h"
  10. #define SET1_T8_INPUT_FILE "etc/set1_t8.txt"
  11. char guess_encryption_key_letter(const char ciphertext_hex[])
  12. {
  13. struct frequency_t max_score;
  14. const int ciphertext_len = strlen(ciphertext_hex) / 2;
  15. unsigned char* ciphertext_xor = new unsigned char[ciphertext_len];
  16. convert_string_to_hex(ciphertext_hex, ciphertext_len*2, ciphertext_xor);
  17. xor_char_finder(ciphertext_xor, max_score, ciphertext_len);
  18. delete [] ciphertext_xor;
  19. return max_score.letter;
  20. }
  21. FUNC(set1_challenge3_test)
  22. {
  23. static const char ciphertext[] = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736";
  24. unsigned char buf[2];
  25. char ret;
  26. ret = guess_encryption_key_letter(ciphertext);
  27. sprintf((char*)buf, "%c", ret);
  28. check(ret == 'X', buf);
  29. }
  30. FUNC_E
  31. FUNC(xor_char_finder_test)
  32. {
  33. // "This is my simple text."
  34. unsigned char buf[256];
  35. const char ciphertext_A[] = "15292832612832612c386132282c312d2461352439356f"; // A Encrypted
  36. const char ciphertext_5[] = "615d5c46155c4615584c15465c584559501541504d411b"; // 5 Encrypted
  37. const char ciphertext_h[] = "3c00011b48011b480511481b010518040d481c0d101c46"; // h Encrypted
  38. const char ciphertext_long[] = "1a252421286d223925283f6d28352e283d392422233e6d202c346d3e392421216d222e2e383f616d3925243e6d2028392522296d243e6d2e2c212128296d3e2c2b286d2f282e2c383e286d3e382f3e39243938392422233e6d2c213a2c343e6d393f24283e6d39226d3f2839383f236d2c6d383e2c2f21286d3e393f24232a6d24233e39282c296d222b6d3f2c243e24232a6d2c236d28352e283d39242223636d04236d2c23223925283f6d3e28233e28616d3e2c2b28123e382f3e39243938392865646d202c346d2f286d2c2334392524232a6d223925283f6d39252c236d3e2c2b28616d3e24232e286d24396d3a2421216d3e242128233921346d242a23223f286d202c212b223f2028296d3928203d212c39283e6d2e2223392c242324232a6d292c232a2124232a6d29282124202439283f3e616d3823202c392e2528296d2f3f2c2e283e616d223f6d3d212c2e2825222129283f3e6d39252c396d2c3f286d2322396d3b2c2124296d1d34392522236d2429282339242b24283f3e63"; // M
  39. char got;
  40. got = guess_encryption_key_letter(ciphertext_A);
  41. sprintf((char*)buf, "Returned: [%c]", got);
  42. check(got == 'A', buf);
  43. got = guess_encryption_key_letter(ciphertext_5);
  44. sprintf((char*)buf, "Returned: [%c]", got);
  45. check(got == '5', buf);
  46. got = guess_encryption_key_letter(ciphertext_h);
  47. sprintf((char*)buf, "Returned: [%c]", got);
  48. check(got == 'h', buf);
  49. got = guess_encryption_key_letter(ciphertext_long);
  50. sprintf((char*)buf, "Returned: [%c]", got);
  51. check(got == 'M', buf);
  52. }
  53. FUNC_E
  54. FUNC(set1_challange4_test)
  55. {
  56. FILE* fp;
  57. char* line=NULL;
  58. size_t len=0;
  59. int line_nb = 0;
  60. unsigned char hexdump[30];
  61. unsigned char* p_hexdump = hexdump;
  62. fp=fopen("etc/set1_t4_input.txt", "r");
  63. if(fp==NULL)
  64. {
  65. fprintf(stderr, "etc/set1_t4_input.txt not found");
  66. return;
  67. }
  68. while( getline(&line, &len, fp) != -1 )
  69. {
  70. ++line_nb;
  71. // printf("%s",line);
  72. struct frequency_t max_score;
  73. max_score.letter=0x0;
  74. max_score.score = 0;
  75. // -----------------------------------------------------------------------------
  76. //
  77. // 1. Convert ASCII ciphertext to HEX
  78. //
  79. // -----------------------------------------------------------------------------
  80. const int ciphertext_len = strlen(line) / 2;
  81. unsigned char ciphertext_xor[ciphertext_len];
  82. unsigned char* p_ciphertext_xor = ciphertext_xor;
  83. convert_string_to_hex(line, ciphertext_len*2, p_ciphertext_xor);
  84. xor_char_finder(p_ciphertext_xor, max_score, ciphertext_len);
  85. if(max_score.letter != 0x00)
  86. {
  87. // printf("%d -> %c\n", line_nb, max_score.letter);
  88. convert_string_to_hex(line, 60, p_hexdump);
  89. for(int i=0; i<30;++i)
  90. {
  91. // printf("%c", hexdump[i]^max_score.letter);
  92. }
  93. // printf("\n");
  94. }
  95. free(line); line=0; len=0;
  96. }
  97. free(line);
  98. }
  99. FUNC_E
  100. FUNC(set1_challenge_5_test)
  101. {
  102. const unsigned char ch1[] = "Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal";
  103. const unsigned char xor_val[] = "ICE";
  104. const unsigned char expected[] = {
  105. 0x0b,0x36,0x37,0x27,0x2a,0x2b,0x2e,0x63,0x62,0x2c,0x2e,0x69,0x69,0x2a,0x23,0x69,
  106. 0x3a,0x2a,0x3c,0x63,0x24,0x20,0x2d,0x62,0x3d,0x63,0x34,0x3c,0x2a,0x26,0x22,0x63,
  107. 0x24,0x27,0x27,0x65,0x27,0x2a,0x28,0x2b,0x2f,0x20,0x43,0x0a,0x65,0x2e,0x2c,0x65,
  108. 0x2a,0x31,0x24,0x33,0x3a,0x65,0x3e,0x2b,0x20,0x27,0x63,0x0c,0x69,0x2b,0x20,0x28,
  109. 0x31,0x65,0x28,0x63,0x26,0x30,0x2e,0x27,0x28,0x2f};
  110. unsigned char o_ch1[256];
  111. memset(o_ch1, '\0', 256);
  112. unsigned char* po_ch1 = o_ch1;
  113. xor_repeatedly(xor_val, 3, ch1, sizeof(ch1), po_ch1);
  114. for(unsigned i=0; i<sizeof(expected)/sizeof(unsigned char); ++i)
  115. check( expected[i] == po_ch1[i] );
  116. }
  117. FUNC_E
  118. FUNC(set1_challenge_6_test)
  119. {
  120. const unsigned max_block_size=200;
  121. char base64_buf[1024*1024]; // 1 MB
  122. char error_buf[256];
  123. unsigned char out_buf[1024*1024];
  124. unsigned char hex_buf[1024*1024];
  125. unsigned long len=read_file_to_buffer("etc/set1_t6.txt", base64_buf);
  126. base64_buf[len]='\0';
  127. len=base64_to_hex((unsigned char*)base64_buf, len, hex_buf);
  128. convert_hex_to_string(hex_buf, len, base64_buf);
  129. // now base64_buf contains string with ciphertext that is HEX-encoded
  130. memset(out_buf,0,sizeof(out_buf));
  131. int best_key_size = find_best_keysize(base64_buf, strlen(base64_buf));
  132. check(best_key_size==29);
  133. best_key_size=crack_repeted_xor(base64_buf, out_buf, best_key_size);
  134. // check(memcmp(expected_plaintext1, out_buf, sizeof(expected_plaintext1))==0, out_buf);
  135. // OZAPTF: to do, it works just need correct check
  136. // check(memcmp(expected_plaintext3, buf, sizeof(expected_plaintext3))==0, buf);
  137. }
  138. FUNC_E
  139. FUNC(crack_repeted_xor_test)
  140. {
  141. unsigned char error_buf[256];
  142. unsigned char expected_plaintext1[] = "Big bang theory: Ok, go home crazy men. Very well, I can't keep up with this secret anylonger. Ok, you listen to me but it's not any of your bussiness. Got it? Worst bed time story every. Regardless of your feelings I would like to break with this guy.";
  143. unsigned char expected_plaintext2[] = "This is an english text that is going to be encrypted with multiple characters. Then I need to write algorithm that will decrypt it. The way to decrypt it is to first calculate hamming distance in order to guess length of the key. This may fail, but maybe will work. So then I'll decrypt it in some fancy way and that's it. It will work, I'm sure about it. OK, now I'm done with this stupid text. Second episode of Big Bang theory is starting.";
  144. unsigned char expected_plaintext3[] = "Big bang theory: Ok, go home crazy men. Very well, I can't keep up with this secret anylonger. Ok, you listen to me but it's not any of your bussiness. Got it? Worst bed time story every. Regardless of your feelings I would like to break with this guy.";
  145. unsigned char expected_plaintext4[] = "Big bang theory: Ok, go home crazy men. Very well, I can't keep up with this secret anylonger. Ok, you listen to me but it's not any of your bussiness. Got it? Worst bed time story every. Regardless of your feelings I would like to break with this guy.";
  146. // password is 'short'
  147. char hex_str1[] = "310108521612060852001b0d00000d4948201958530f00521c1c050a52170109150b541e0d015c54250d1d0b54040d031e5853214f11151d4f1b521f160d1f52010348181b001b481b1a1d00481c1717010d1b52151d11031d1a140d1d5c543c0343520d1c1d4f1e1d001c0a1c5407074f1f11530a1a06541a1c4801541d071b52151d114f1d125311000706530a1a01071a060a01075d48281d0053011b4d5424071d0100530a0a16540701021754001c00000d530d1917060a464f201114091d1618161b1c521b1548161d0101480917111f0101150753214f051b06040b52181a030a52001c480d001112034f051d07004f061c1a1b4f15010a46";
  148. // Pass is 'DupaBladaPass'
  149. char hex_str2[] = "101d191262051244003e41161d231919122a4c1501192441071b25015008314c060b083e0653072b55120462090f0713291107162055070836044109143c151a03281050022a0d130502240401006a5524092702412d413e04161764011f41351e08100470001f142b0719152a01411009311553042d191c4126090216182015531a305b50352a094113002941071c6411150230151110413915531a3755040e620a081612244110122816050d2318044409310c1e1a2a1250052b1f15050f3304531a2a551f1326091344153f411406210603412e090f031538411c15640118046207041d4f70351b1a37551d003b4c0705083c4d53113101500c231503014127081f1f64021f13294241370e70151b162a5539462e0041000433130a033055191562050f44123f0c165322141e023b4c16051870001d1764011800364b124408244f533a305507082e0041130e220a5f530d521d41311913014131031c06305519156c4c2e2f4d700f1c04643c570c62080e0a0470161a072c5504092b1f41171525111a17640115193642413704330e1d176410000831030501413f0753312d125023230206441538041c013d551912621f15051324081d146a";
  150. // don't know what's the password but len is 20
  151. char hex_str3[] = "31060a450f0e1c024c1b06021f130a49572019485308024505001f004c0c1c060a18531e12015c44250a1f1c4d18170900434e2e5002121d501b520f160a1d45181f5212051b064704091a00571c1707010a19450c010b0903010902024f533c1c43521d1c1a4d09041c0600024f1a08500c1653151a06441a1b4a164d011d114c0e001e500e15530e000716530d18161e061c001f1c4047370e07531e1b4d4424001f16194f1000084f1a0e1d0453000300001d530a1b001f165c453e0a090602051f16041c520b154f140a181d5203090a020e1e0600533e4f050b06030945010619004c1b0147121316121c4f050d07074d11050601450b1a1749";
  152. // this doesn't work. password is 'tie'
  153. char hex_str4[] = "360002540b041a0e450001001b1b1c4e492a1f45451306451c060811490606081f0d490811074b543f00061045030c091845453d490615074200490e110c15541c15541e0c00014500010c074916110a17111d4515071c18060b130c175a492a1f45450d061054050c071d001a49111b4908114907011d451d1d4207490b1b1d4515071c54060354100a011b45161c1607000b111a165a49221b1d451d1d5a543e0a061a11540b001049111d0400541a111b1b1c540c13111b1c5a4937110e04060d09111a1654060354100a011b45120c0018000b131a453d49121b1c091049091d0200541d0a540b1711080e541e0c00014500010c07490201104b";
  154. unsigned char buf[1024*1024];
  155. memset(buf,0,sizeof(buf));
  156. int best_key_size = find_best_keysize(hex_str1, strlen(hex_str1));
  157. crack_repeted_xor(hex_str1, buf, best_key_size);
  158. sprintf((char*)error_buf, "Wrong keysize. Expected 5 got %d\n", best_key_size);
  159. check(best_key_size==5, error_buf);
  160. check(memcmp(expected_plaintext1, buf, sizeof(expected_plaintext1))==0, buf);
  161. // here I have to reduce key size otherwise with keylength 39 there is better score
  162. memset(buf,0,sizeof(buf));
  163. best_key_size = find_best_keysize(hex_str2, strlen(hex_str2),2,38);
  164. crack_repeted_xor(hex_str2, buf, best_key_size);
  165. sprintf((char*)error_buf, "Wrong keysize. Expected 13 got %d\n", best_key_size);
  166. check(best_key_size==13, error_buf);
  167. check(memcmp(expected_plaintext2, buf, sizeof(expected_plaintext2))==0, buf);
  168. // here I have to reduce key size otherwise with keylength 39 there is better score
  169. memset(buf,0,sizeof(buf));
  170. best_key_size = find_best_keysize(hex_str3, strlen(hex_str3));
  171. crack_repeted_xor(hex_str3, buf, best_key_size);
  172. sprintf((char*)error_buf, "Wrong keysize. Expected 20 got %d\n", best_key_size);
  173. check(best_key_size==20, error_buf);
  174. check(memcmp(expected_plaintext3, buf, sizeof(expected_plaintext3))==0, buf);
  175. }
  176. FUNC_E
  177. FUNC(set1_challenge_7_test)
  178. {
  179. const unsigned char pass[]="YELLOW SUBMARINE";
  180. const char expected_first_line[] = "I'm back and I'm ringin' the bell";
  181. unsigned char ciphertext[1024*1024]; // 1 MB
  182. unsigned long len=read_file_to_buffer("etc/set1_t7.txt", (char*)ciphertext);
  183. unsigned char buff[1024*1024];
  184. unsigned char hex[1024*1024];
  185. int ret;
  186. ret = base64_to_hex(ciphertext, len, &hex[0]);
  187. ret = ecb_decrypt(hex, ret, pass, sizeof(pass), &buff[0]);
  188. check(memcmp(buff, expected_first_line, strlen(expected_first_line))==0);
  189. }
  190. FUNC_E
  191. FUNC(set1_challenge_8_test)
  192. {
  193. FILE* fh=NULL;
  194. if( (fh=fopen(SET1_T8_INPUT_FILE, "rb")) == 0 )
  195. {
  196. fprintf(stderr, "File %s doesn't exist. Exiting...\n", SET1_T8_INPUT_FILE);
  197. exit(1);
  198. }
  199. int first,second;
  200. char* line=NULL;
  201. size_t len=0;
  202. int bytes_read=0;
  203. int current_line=0;
  204. while( (bytes_read=getline(&line, &len, fh)) != -1 )
  205. {
  206. ++current_line;
  207. if(same_blocks(line, 32, &first, &second))
  208. {
  209. break;
  210. }
  211. free(line);
  212. line=NULL;
  213. }
  214. free(line);
  215. fclose(fh);
  216. check(current_line==133);
  217. check(first==2);
  218. check(second==4);
  219. }
  220. FUNC_E