Video Contents

- Base64 encoding - code template walk-through [0:00]
- Encoding payloads with certutil.exe [1:42]
- Code compilation and demo under debugger [5:26]
- Limitation of Base64 encoding as a mean of obfuscation [8:37]

Addendum

Base64 Encoding

Base64 is a binary-to-text encoding scheme that represents binary data as an ASCII string. It is commonly used to encode binary data such as images, audio files, and binary executable files, into a text format that can be easily transmitted over protocols that handle only text data, such as email or URLs.

In Base64, each group of 3 bytes (24 bits) is converted into 4 ASCII characters. The encoded characters consist of a limited set of 64 printable ASCII characters, which include uppercase and lowercase letters, digits, and three additional characters with one (=) often used as padding. Here's an Base64 alphabet as defined in RFC 4648:

  Idx  |  Char  |  Idx  |  Char  |  Idx  |  Char  |  Idx  |  Char
-------+--------+-------+--------+-------+--------+-------+--------
    0  |   A    |  16   |   Q    |  32   |   g    |  48   |   w
    1  |   B    |  17   |   R    |  33   |   h    |  49   |   x
    2  |   C    |  18   |   S    |  34   |   i    |  50   |   y
    3  |   D    |  19   |   T    |  35   |   j    |  51   |   z
    4  |   E    |  20   |   U    |  36   |   k    |  52   |   0
    5  |   F    |  21   |   V    |  37   |   l    |  53   |   1
    6  |   G    |  22   |   W    |  38   |   m    |  54   |   2
    7  |   H    |  23   |   X    |  39   |   n    |  55   |   3
    8  |   I    |  24   |   Y    |  40   |   o    |  56   |   4
    9  |   J    |  25   |   Z    |  41   |   p    |  57   |   5
   10  |   K    |  26   |   a    |  42   |   q    |  58   |   6
   11  |   L    |  27   |   b    |  43   |   r    |  59   |   7
   12  |   M    |  28   |   c    |  44   |   s    |  60   |   8
   13  |   N    |  29   |   d    |  45   |   t    |  61   |   9
   14  |   O    |  30   |   e    |  46   |   u    |  62   |   +
   15  |   P    |  31   |   f    |  47   |   v    |  63   |   /

The resulting Base64-encoded string is typically longer than the original binary data, as it uses 6 bits of the original data to represent each character in the encoded string.

Key Windows API functions

Windows API provides functions to encode and decode Base64 data. Two common functions for this purpose are CryptBinaryToString() and CryptStringToBinary(), which are part of the Cryptography API.

CryptStringToBinary() converts a formatted string into an array of bytes. This function can be found in the crypt32.dll library.

CryptStringToBinary() function has the following prototype:

BOOL CryptStringToBinaryA(
  LPCSTR pszString,  // pointer to a string that contains the formatted string to be converted.
  DWORD  cchString,  // number of characters of the formatted string to be converted, not including the terminating NULL
  DWORD  dwFlags,    // indicates the format of the string to be converted, ex. CRYPT_STRING_BASE64, CRYPT_STRING_HEXASCII, CRYPT_STRING_BINARY, etc.
  BYTE   *pbBinary,  // pointer to a buffer that receives the returned sequence of bytes
  DWORD  *pcbBinary, // pointer to a variable which on entry contains the size of the pbBinary (in bytes). After return, it contains the number of bytes copied to the buffer
  DWORD  *pdwSkip,   // pointer to a value that receives the number of characters skipped to reach the beginning of the -----BEGIN ...----- header
  DWORD  *pdwFlags   // pointer to a value that receives the flags actually used in the conversion. Can be NULL (skipped)
);

Return value

If the function succeeds, the return value is nonzero (TRUE). Otherwise, the return value is zero (FALSE).

External Resources

Base64 Encode and Decode in C