Guest User

Untitled

a guest
Jan 24th, 2011
541
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  *
  3.  *  ___         _____
  4.  * |   |  ____ /
  5.  * |---  |____ |____,  ____
  6.  * |   \ |____      |  ---- PIRE!
  7.  * |    \      _____/
  8.  *
  9.  * res-pire : open source re-implementation of stupid x-pire.net
  10.  *
  11.  * this file handles the whole decryption. it is such an incredible
  12.  * mess, i immediately feel sick by just looking at it. however,
  13.  * written in <1h and it works like a charm.
  14.  *
  15.  * to compile, don't forget to link:
  16.  * -ljpeg   : libjpeg for parsing input (encrypted) image
  17.  * -lcurl   : libcurl for querying the keyserver
  18.  * -lcrypto : openssl for decryption
  19.  *
  20.  * Also, you won't notice, but this is actually C++ code. but i
  21.  * felt like hacking so....anyways, you should compile using a
  22.  * c++ compiler, nevertheless :P
  23.  *
  24.  * THIS IS A "PROTOTYPE"
  25.  * consider this as a prototype to use as a base for further
  26.  * development (in case there was a use for further developent...)
  27.  *
  28.  * Still ToDo (naa, rather not)
  29.  * = Handle CAPTCHAs
  30.  * = Locally store (cache) keys
  31.  * = I think for facebook/stuff there is an additional step
  32.  *   of reed-solomon FEC required. Whatever.
  33.  *
  34.  *
  35.  **/
  36. #include <cstdio>
  37. #include <cstdlib>
  38. #include <cstring>
  39. #include <jpeglib.h>
  40. #include <openssl/evp.h>
  41. #include <openssl/sha.h>
  42. #include <curl/curl.h>
  43.  
  44. /* -------------- JPEG STUFF -------------------- */
  45. const static JOCTET EOI_BUFFER[1] = { JPEG_EOI };
  46. struct my_source_mgr {
  47.     struct jpeg_source_mgr  pub;
  48.     const JOCTET            *data;
  49.     size_t                  len;
  50. };
  51.  
  52. static void my_init_source(j_decompress_ptr cinfo) {}
  53.  
  54. static boolean my_fill_input_buffer(j_decompress_ptr cinfo) {
  55.     my_source_mgr* src = (my_source_mgr*)cinfo->src;
  56.     src->pub.next_input_byte = EOI_BUFFER;
  57.     src->pub.bytes_in_buffer = 1;
  58.     return TRUE;
  59. }
  60. static void my_skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
  61.     my_source_mgr* src = (my_source_mgr*)cinfo->src;
  62.     if (src->pub.bytes_in_buffer < (unsigned long)num_bytes) {
  63.         src->pub.next_input_byte = EOI_BUFFER;
  64.         src->pub.bytes_in_buffer = 1;
  65.     } else {
  66.         src->pub.next_input_byte += num_bytes;
  67.         src->pub.bytes_in_buffer -= num_bytes;
  68.     }
  69. }
  70. static void my_term_source(j_decompress_ptr cinfo) {}
  71.  
  72. static void my_set_source_mgr(j_decompress_ptr cinfo, const char* data, size_t len) {
  73.     my_source_mgr* src;
  74.     if (cinfo->src == 0) { // if this is first time;  allocate memory
  75.         cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)
  76.             ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(my_source_mgr));
  77.     }
  78.     src = (my_source_mgr*) cinfo->src;
  79.     src->pub.init_source = my_init_source;
  80.     src->pub.fill_input_buffer = my_fill_input_buffer;
  81.     src->pub.skip_input_data = my_skip_input_data;
  82.     src->pub.resync_to_restart = jpeg_resync_to_restart; // default
  83.     src->pub.term_source = my_term_source;
  84.     // fill the buffers
  85.     src->data = (const JOCTET *)data;
  86.     src->len = len;
  87.     src->pub.bytes_in_buffer = len;
  88.     src->pub.next_input_byte = src->data;
  89. }
  90.  
  91.  
  92. /* -------------- CURL STUFF -------------------- */
  93. struct curlreq_mem {
  94.     char *memory;
  95.     size_t size;
  96. };
  97. static size_t curlreq_mem_cb(void *ptr, size_t size, size_t nmemb, void *data) {
  98.     size_t realsize = size*nmemb;
  99.     struct curlreq_mem *mem = (struct curlreq_mem*)data;
  100.     if(NULL==mem->memory) {
  101.         mem->memory = (char*)malloc(realsize+1);
  102.         mem->size = 0;
  103.     } else {
  104.         mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
  105.     }
  106.     if(NULL==mem->memory) {
  107.         fprintf(stderr, "ARGH MEMORY ISSUE WITH CURL!\n");
  108.         exit(-1);
  109.     }
  110.     memcpy( &(mem->memory[mem->size]), ptr, realsize );
  111.     mem->size += realsize;
  112.     mem->memory[mem->size] = 0;
  113.     return realsize;
  114. }
  115.  
  116. /* -------------- Main Code -------------------- */
  117.  
  118. int main(int argc, char* argv[]) {
  119.     if(argc<2) {
  120.         fprintf(stderr,"%s <filename>\n", argv[0]);
  121.         return 1;
  122.     }
  123.  
  124.  
  125.     FILE *fd = fopen(argv[1], "r");
  126.     if(!fd) {
  127.         return 1;
  128.     }
  129.  
  130.     /* completely read file to memory */
  131.     fseek(fd, 0L, SEEK_END);
  132.     long total_size = ftell(fd);
  133.     fseek(fd, 0L, SEEK_SET);
  134.  
  135.     char *buffer = new char[total_size];
  136.     long left = total_size;
  137.     char *p = buffer;
  138.     while(left) {
  139.         size_t done = fread(p, 1, left, fd);
  140.         if(0==done) {
  141.             break;
  142.         }
  143.         p += done;
  144.         left -= done;
  145.     }
  146.     fclose(fd);
  147.     if(left) {
  148.  
  149.         delete [] buffer;
  150.         return 1;
  151.     }
  152.  
  153.     unsigned image_id = 0;
  154.     char *server_address;
  155.     char *encrypted_data = NULL;
  156.     unsigned encrypted_data_length = 0;
  157.     char *decrypted_image = NULL;
  158.     unsigned decrypted_len = 0;
  159.  
  160.     char *key_in;
  161.  
  162.     unsigned char md[SHA256_DIGEST_LENGTH];
  163.     unsigned char md_string[2*SHA256_DIGEST_LENGTH];
  164.  
  165.     /** let libjpeg parse **/
  166.     {
  167.         struct jpeg_decompress_struct cinfo;
  168.         struct jpeg_error_mgr jerr;
  169.         cinfo.err = jpeg_std_error(&jerr);
  170.         jpeg_create_decompress(&cinfo);
  171.         my_set_source_mgr(&cinfo, buffer, total_size);
  172.  
  173.         jpeg_save_markers(&cinfo, JPEG_COM, 0xFFFF);
  174.  
  175.         jpeg_read_header(&cinfo, TRUE);
  176.         /* process markers */
  177.         int count = 0;
  178.         {
  179.             jpeg_saved_marker_ptr marker;
  180.             for(marker=cinfo.marker_list; marker!=NULL; marker=marker->next) {
  181.                 if(marker->marker == JPEG_COM) {
  182.                     switch(count++) {
  183.                         case 0: // ID
  184.                             image_id = atoi((const char*)marker->data);
  185.                             break;
  186.                         case 1: // Server-Address
  187.                             server_address = (char*)malloc(marker->data_length+1);
  188.                             memcpy(server_address, marker->data, marker->data_length);
  189.                             server_address[marker->data_length]=0;
  190.                             break;
  191.                         case 2: // unknown
  192.                             break;
  193.                         case 3: // encrypted image
  194.                             encrypted_data = (char*)malloc(marker->data_length);
  195.                             memcpy(encrypted_data, marker->data, marker->data_length);
  196.                             encrypted_data_length = marker->data_length;
  197.                             break;
  198.                     }
  199.                 }
  200.             }
  201.         }
  202.     }
  203.     printf(">> marker_id = %d\n", image_id);
  204.     printf(">> server = %s\n", server_address);
  205.  
  206.     /** compute hash of encrypted data **/
  207.     {
  208.         SHA256_CTX ctx;
  209.         //unsigned char md[SHA256_DIGEST_LENGTH];
  210.         SHA256_Init(&ctx);
  211.         SHA256_Update(&ctx, encrypted_data, encrypted_data_length);
  212.         SHA256_Final(md, &ctx);
  213.         for(int i=0; i<SHA256_DIGEST_LENGTH; ++i) {
  214.             printf("%02X",md[i]);
  215.             sprintf((char*)&md_string[2*i], "%02x", md[i]);
  216.         }
  217.         printf("\n");
  218.     }
  219.  
  220.     /** request key from server **/
  221.     {
  222.         struct curlreq_mem mtmp;
  223.         //mtmp.memory = (char*)malloc(1);
  224.         mtmp.memory = NULL;
  225.  
  226.         CURL *curl;
  227.         curl_global_init(CURL_GLOBAL_ALL);
  228.         curl = curl_easy_init();
  229.  
  230.         char url[512];
  231.         sprintf(url, "%s/api/get_key.json?key_id=%d&image_hash=%s", server_address, image_id, md_string);
  232.         printf(">> url->%s\n", url);
  233.  
  234.         curl_easy_setopt(curl, CURLOPT_URL, url);
  235.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
  236.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
  237.        
  238.         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlreq_mem_cb);
  239.         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&mtmp);
  240.  
  241.         curl_easy_perform(curl);
  242.  
  243.         //printf("DONE!\n%s\n", mtmp.memory);
  244.  
  245.         /* extract key */
  246.         /* ("parse" json) */
  247.         char *ptr = mtmp.memory;
  248.         while(ptr<mtmp.memory+mtmp.size && memcmp(ptr, "\"key\":", 6))
  249.             ptr++;
  250.         if(ptr<mtmp.memory+mtmp.size) {
  251.             ptr += 7;
  252.             char *ptr_start = ptr;
  253.             char *ptr_end = ptr+1;
  254.             while(ptr_end<mtmp.memory+mtmp.size && *ptr_end!='\"')
  255.                 ptr_end++;
  256.             if(ptr_end>=mtmp.memory+mtmp.size) {
  257.                 printf("error parsing key from json :(\n");
  258.                 exit(-1);
  259.             }
  260.             unsigned len = ptr_end - ptr_start;
  261.             key_in = (char*)malloc(len+1);
  262.             memcpy(key_in, ptr_start, len);
  263.             key_in[len]=0;
  264.  
  265.         } else {
  266.             printf("Could not get key from server! :(\n");
  267.             exit(-1);
  268.         }
  269.  
  270.         curl_easy_cleanup(curl);
  271.         curl_global_cleanup();
  272.     }
  273.  
  274.     printf(">> key=%s\n", key_in);
  275.  
  276.     unsigned char aes_key[16];
  277.     unsigned char aes_iv[16];
  278.  
  279.     /** derive AES key + decrypt **/
  280.     {
  281.         unsigned len = strlen(key_in);
  282.  
  283.         const EVP_CIPHER *type = EVP_aes_128_cbc();
  284.         EVP_BytesToKey(type, EVP_sha1(), NULL, (const unsigned char*)key_in, len, 5, aes_key, aes_iv);
  285.  
  286.         unsigned char *decrypted = (unsigned char*)malloc(encrypted_data_length);
  287.         int p_len = encrypted_data_length;
  288.         int f_len;
  289.  
  290.         EVP_CIPHER_CTX ctx;
  291.         EVP_CIPHER_CTX_init(&ctx);
  292.         EVP_DecryptInit_ex(&ctx, type, NULL, aes_key, aes_iv);
  293.         EVP_DecryptUpdate(&ctx, decrypted, &p_len, (const unsigned char*)encrypted_data, encrypted_data_length);
  294.         EVP_DecryptFinal(&ctx, decrypted+p_len, &f_len);
  295.  
  296.         /* sanity check if JPEG file */
  297.         unsigned SOI = *((unsigned*)decrypted);
  298.  
  299.         if(SOI==0xE0FFD8FF||SOI==0xFFD8FFE0) { // i'm cool so i care for the big endians around ;)
  300.             printf("valid JPEG decrypted, hurray\n");
  301.         } else {
  302.             printf("decryption failed :(\n");
  303.             exit(-1);
  304.         }
  305.  
  306.         decrypted_image = (char*)decrypted;
  307.         decrypted_len = p_len;
  308.     }
  309.  
  310.     /** write output **/
  311.     {
  312.         FILE *fd = fopen("output.jpg", "w");
  313.         char *ptrout = decrypted_image;
  314.         size_t left = decrypted_len;
  315.  
  316.         while(left) {
  317.             size_t w = fwrite(ptrout, 1, left, fd);
  318.             if(!w) break;
  319.             left -= w;
  320.             ptrout+= w;
  321.         }
  322.         fclose(fd);
  323.     }
  324.  
  325.     return 0;
  326. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×