home *** CD-ROM | disk | FTP | other *** search
/ KeyGen Studio 2002 / KeyGen_Studio_2002.iso / Tutorials / CrackMesCbjNet / duxtool1.txt < prev    next >
Encoding:
Text File  |  2001-09-21  |  7.5 KB  |  281 lines

  1. First ToolMe challenge solution
  2. by the_dux
  3.  
  4. So, nice work to do this time...
  5. As I read on the disclaimer the goal for this is to code a
  6. simple tool that is able to encrypt a name (and a serial)
  7. in a bitmap file (using the steganography technique).
  8. First of all, we've to know a bit what's steganography is
  9. so get out there and try to get some infos about it and
  10. then after you read what it is and how it work search for
  11. a text on how a bitmap file is composed (header, various
  12. infos, etc.). You'll need these infos cause the program 
  13. read the name and the key from a bitmap and from its pixels
  14. so...
  15. Well, I can't explain all the disassembled code line by line
  16. because it's huge and I think it's not so usefull, also 
  17. because I assume you can at any time read and translate it.
  18. Here is the algo used to read the name and the key from the
  19. file:
  20.  
  21. first of all we get infos from the header to know where the
  22. infos about pixel start in the bmp file.
  23.  
  24. a)then we read 3 bytes from the file (the RGB infos) and we 
  25. xor them ( first_byte XOR second_byte XOR third_byte ). As
  26. you know steganography usually take last bit and so the 
  27. program do ANDing the result of XORs with 1 (=> we get the
  28. last bit).
  29.  
  30. We repeat 8 times this loop
  31.  
  32.  
  33. b)Now we have 8 bits taken from 8 pixel, we must merge them
  34. to get a single byte (first letter of name).
  35.  
  36. We repeat 100 times a) and b) till we get an array (length 100)
  37. with the name, a zero byte (0x00), the key, a zero byte(0x00)
  38. and some others garbage we could trash.
  39.  
  40. The program goes on and extract from this string the name and
  41. the key.
  42. Till now it does nothing more than reading some bits from the
  43. bitmap that could have an irrilevant importance (because even
  44. if we haven't a real name encrypted in the file it can reigster
  45. anyway) so there's a simple algo that check the relation between
  46. name and key.
  47. The algo simply XOR the key with the phrase "Obscurity is not
  48. security!" and verify if the result contain the name.
  49.  
  50. Now we've to do a sort of keygen that will consist in two part:
  51. the first that ask the user a name and then compute the regkey
  52. from it (it's very simple... we've only to xor the name with
  53. the phrase above);
  54. the second part it's the longer and it's where we write the name
  55. and the code into the file.
  56. I wrote the program in C and here is the source
  57. (it's not very good, but it work)
  58.  
  59. ----------------------------=CUT HERE=--------------------------
  60. // Stega Tool Name/Key Encoder
  61.  
  62. #include <stdio.h>
  63. #include <stdlib.h>
  64.  
  65. // Header
  66. #define BMPHEADER 14
  67.  
  68. typedef struct {
  69.  long bmpIHSize;
  70.  long bmpCUsed;
  71.  long bmpCType;
  72.  int bmpBPP;
  73.  long bmpHeight;
  74.  long bmpWidth;
  75. } bmpInfo;
  76.  
  77. char magic[] = "Obscurity is not security!";
  78.  
  79. long func_40160E( FILE *fbmp )
  80. {
  81.  int cx;
  82.  long res;
  83.  
  84.  fseek( fbmp, BMPHEADER+10, SEEK_SET );
  85.  fread( &cx, 2, 1, fbmp );
  86.  if ( cx > 8 ) return 0;
  87.  res = cx * 2;
  88.  res += res*2;
  89.  return res;
  90. }
  91.  
  92. long func_40162C( FILE *fbmp )
  93. {
  94.  int cx;
  95.  
  96.  fseek( fbmp, BMPHEADER+14, SEEK_SET );
  97.  fread( &cx, 2, 1, fbmp );
  98.  if ( cx > 8 ) return 0;
  99.  return (cx*8);
  100. }
  101.  
  102. int main()
  103. {
  104.  char nfile[256], regkey[100], cp, c, cn, nome[26], reg[26];
  105.  FILE *fbmp;
  106.  bmpInfo bi;
  107.  long bmpPStart, ft;
  108.  int AddStart=0, i, b, bits[8], ci, counter;
  109.  
  110.  printf( "File to patch: " );
  111.  scanf( "%s", (char*)&nfile );
  112.  // Get name and create the key
  113.  memset( ®, 0, sizeof(reg) );
  114.  memset( &nome, 0, sizeof(nome) );
  115.  printf( "Name to encode: " );
  116.  scanf( "%s", (char*)&nome );
  117.  // Simplest encryption algo...
  118.  for (i=0; i<strlen((char*)&nome); i++ ) reg[i] = nome[i] ^ magic[i];
  119.  
  120.  fbmp = fopen( (char*)&nfile, "r+" );
  121.  // si posiziona all'inizio dell'infoheader
  122.  fseek( fbmp, BMPHEADER, SEEK_SET );
  123.  // dimensione header
  124.  fread( &bi.bmpIHSize, sizeof(long), 1, fbmp );
  125.  switch( bi.bmpIHSize )
  126.  {
  127.   case 12:
  128.    bmpPStart = func_40160E( fbmp );
  129.    break;
  130.   case 40:
  131.    fseek( fbmp, BMPHEADER+16, SEEK_SET );
  132.    fread( &bi.bmpCType, sizeof(long), 1, fbmp );
  133.    if ( bi.bmpCType == 3 ) AddStart = 12;
  134.    fseek( fbmp, BMPHEADER+32, SEEK_SET );
  135.    fread( &bi.bmpCUsed, sizeof(long), 1, fbmp );
  136.    if ( bi.bmpCUsed ) bmpPStart = bi.bmpCUsed*4;
  137.    else bmpPStart = func_40162C( fbmp );
  138.    break;
  139.   case 108:
  140.    fseek( fbmp, BMPHEADER+32, SEEK_SET );
  141.    fread( &bi.bmpCUsed, sizeof(long), 1, fbmp );
  142.    if ( bi.bmpCUsed ) bmpPStart = bi.bmpCUsed*4;
  143.    else bmpPStart = func_40162C( fbmp );
  144.    break;
  145.  }
  146.  // 401644h
  147.  // Get the bmp pixel's infos entry point
  148.  bmpPStart+=AddStart+14+bi.bmpIHSize;
  149.  // Bit Per Pixel
  150.  fseek( fbmp, BMPHEADER+14, SEEK_SET );
  151.  fread( &bi.bmpBPP, 2, 1, fbmp );
  152.  bi.bmpBPP/=8;
  153.  // Height
  154.  fseek( fbmp, BMPHEADER+8, SEEK_SET );
  155.  fread( &bi.bmpHeight, sizeof(long), 1, fbmp );
  156.  // Width
  157.  fseek( fbmp, BMPHEADER+4, SEEK_SET );
  158.  fread( &bi.bmpWidth, sizeof(long), 1, fbmp );
  159.  bi.bmpWidth*=bi.bmpBPP;
  160.  memset( ®key, 0, sizeof(regkey) );
  161.  bi.bmpWidth+=2;
  162.  fseek( fbmp, bmpPStart, SEEK_SET );
  163.  /* Encrypt the name and the code in the file
  164.     Rules: the last bit of RGB's byte are xored
  165.      and the result is the bit to be extracted
  166.  */
  167.  ft = ftell(fbmp);
  168.  // Start with the name
  169.  for( i=0; i<strlen((char*)&nome); i++ )
  170.  {
  171.   ci = (int)nome[i];
  172.   memset( &bits, 0, sizeof(bits) );
  173.   // Get every single bit of current char
  174.   for( counter=7; counter!=0; counter-- )
  175.   {
  176.    bits[counter] = ci % 2;
  177.    ci/=2;
  178.   }
  179.   // Decide wich byte to modify
  180.   for( counter=0; counter<8; counter++ )
  181.   {
  182.    fseek( fbmp, ft, SEEK_SET );
  183.    fread( &cp, 1, 1, fbmp );
  184.    fread( &c, 1, 1, fbmp );
  185.    fread( &cn, 1, 1, fbmp );
  186.    cp = cp^cn;
  187.    c = c^cp;
  188.    c &= 1;
  189.    if ( (int)c != bits[counter] ) cn--;
  190.    if ((int)cn == -1 ) cn=1;
  191.    fseek( fbmp, -1, SEEK_CUR );
  192.    fwrite( &cn, 1, 1, fbmp );
  193.    ft = ftell(fbmp);
  194.    fclose(fbmp);
  195.    fbmp=fopen((char*)&nfile, "r+" );
  196.   }
  197.  }
  198.  // Zero at the end of name
  199.  for( counter=0; counter<8; counter++ )
  200.  {
  201.   fseek( fbmp, ft, SEEK_SET );
  202.   fread( &cp, 1, 1, fbmp );
  203.   fread( &c, 1, 1, fbmp );
  204.   fread( &cn, 1, 1, fbmp );
  205.   cp = cp^cn;
  206.   c ^= cp;
  207.   c &= 1;
  208.   if ( (int)c ) cn--;
  209.   if ((int)cn==-1) cn=1;
  210.   // write it
  211.   fseek( fbmp, -1, SEEK_CUR );
  212.   fwrite( &cn, 1, 1, fbmp );
  213.   ft = ftell(fbmp);
  214.   fclose(fbmp);
  215.   fbmp=fopen((char*)&nfile, "r+" );
  216.  }
  217.  // write reg key
  218.  for( i=0; i<strlen((char*)®); i++ )
  219.  {
  220.   ci = (int)reg[i];
  221.   memset( &bits, 0, sizeof(bits) );
  222.   // Get every single bit of current char
  223.   for( counter=7; counter!=0; counter-- )
  224.   {
  225.    bits[counter] = ci % 2;
  226.    ci/=2;
  227.   }
  228.   // Decide wich byte to modify
  229.   for( counter=0; counter<8; counter++ )
  230.   {
  231.    fseek( fbmp, ft, SEEK_SET );
  232.    fread( &cp, 1, 1, fbmp );
  233.    fread( &c, 1, 1, fbmp );
  234.    fread( &cn, 1, 1, fbmp );
  235.    cp = cp^cn;
  236.    c = c^cp;
  237.    c &= 1;
  238.    if ( (int)c != bits[counter] ) cn--;
  239.    if ((int)cn==-1) cn=1;
  240.    // write it
  241.    fseek( fbmp, -1, SEEK_CUR );
  242.    fwrite( &cn, 1, 1, fbmp );
  243.    ft = ftell(fbmp);
  244.    fclose(fbmp);
  245.    fbmp=fopen((char*)&nfile, "r+" );
  246.   }
  247.  }
  248.  // Zero at the end of key
  249.  for( counter=0; counter<8; counter++ )
  250.  {
  251.   fseek( fbmp, ft, SEEK_SET );
  252.   fread( &cp, 1, 1, fbmp );
  253.   fread( &c, 1, 1, fbmp );
  254.   fread( &cn, 1, 1, fbmp );
  255.   cp = cp^cn;
  256.   c ^= cp;
  257.   c &= 1;
  258.   if ( (int)c ) cn--;
  259.   if ((int)cn==-1) cn=1;
  260.   // write it
  261.   fseek( fbmp, -1, SEEK_CUR );
  262.   fwrite( &cn, 1, 1, fbmp );
  263.   ft = ftell(fbmp);
  264.   fclose(fbmp);
  265.   fbmp=fopen((char*)&nfile, "r+" );
  266.  }
  267.  fclose(fbmp);
  268.  return 0;
  269. }
  270. ----------------------------=AND HERE=--------------------------
  271.  
  272. final notes:
  273. this program work well with 24bit bitmaps but i think it couldn't
  274. work with other resolutions.
  275. To make it work simply put, at the end of each for loop with fread
  276. some lines to recalculate the position inside the file (ie. if you
  277. have 24bit you read 3byte at times but less if you're in a smaller
  278. resolution).
  279.  
  280. the_dux, 25 April 2001
  281.