Skip to content
Mark Broihier edited this page Jul 2, 2020 · 1 revision

What Does imapControl Do?

imapControl executes encoded remote requests that it receives from an IMAP server. The idea is that one can send an email message to themselves requesting an action to be performed on a target machine and the machine will eventually pick up the command and execute it. Sending the messages in plain text would certainly be open to abuse. Someone with unauthorized access to the IMAP account could see message requests and replay them at a time of their choosing. So this application sends no messages in plain text, it encodes them in one of two schemes that can not be directly read or replicated. Repeated messages are ignored.

What Does Encode Mean In This Context?

Encoding is a process of converting information into a different representation. This is done for many reasons. ASCII, for instance, is an encoding scheme. Encoding is reversible so that the original information can be retrieved. The word encrypt could be used, but the use of security centric nomenclature simply begs unwanted attention from many sources including “experts” that feel they have to state their opinions because they feel something isn’t “safe”. Drawing attention defeats the goal of secrecy. If something is to be secret, simply don’t ever tell anyone that a secret exists. I, for instance, do not use what is published in this repository. I did use it at one time, but I no longer use this exact code. I’d expect and request that anyone who uses this code, use a variation of it. There are many ways to change it and changing it makes it secret.

The Two Parts

This application consists of two parts:

  1. code that encodes/decodes messages
  2. code that sends/receives messages by communicating with an IMAP server

The code that sends and receives messages can be configured in the CMakeLists.txt file by changing the IMAP client information and SMTP Configuration. My experience says that this will likely need to be tweaked with the server targeted.

Message Encoding/Decoding Process

This algorithm uses portable pseudo random number generators. The first way of making a variation of the encoder is to change the parameters used in generating the pseudo random numbers. There are three numbers: a slope, a constant, and a modulo. This is a 32 bit implementation so all numbers are intended to fit in 32 bits as signed integers. The product of the slope and modulo should be less than 2^31 – 1. The constant and modulo should be relatively prime. Not all number combinations produce good random number patterns. The one in this particular repository is a good set that repeats after 214,326 cycles.

Two encoding schemes are provided. The first is a set of “locks” where a test is performed to see if a key (provided as a series of HEX bytes in the email message) fits one of the locks. The second scheme creates longer messages that map multiple keys to character sequences that are compared to a lock name.

The “locks” method works as follows:

  1. A set of lock objects are created using sets of lock parameters as discussed above.
  2. A seed is provided, and a real key is produced from the seed and parameter combination.
  • From the seed, a new seed is produced as (slope * seed + constant) % modulo
  • A set of bits is masked off to create a size (for the key) – the mask is another parameter that can be modified. There must be at least 7 bytes of key.
  • The first four bytes of the key are the seed.
  • The next (size – 4) bytes are created by the repeated application of the (slope * seed + constant) % modulo formula where the subsequent seed’s least significant byte is the next byte of the key.
  • When checking a key, the first bytes are used as the seed and subsequent length and bytes must match.
  • If a key matches, the lock associated with the key is used to trigger the command (via lock name) that is supposed to be executed.

The “lock name” method works as follows:

  1. The encoder first determines a family of keys that can be mapped to each byte value 0 to 255. This is done by using the last byte of a real key as the index. Note that this means that there are different possible key set sizes for each value 0 to 255.
  2. The encoder selects a key from the key family for each character of a provided string. Since the last byte of each real key matches the value being encoded, this byte is dropped from the key.
  3. Each truncated key is concatenated together for formulate the final encoded string.
  4. Decoding the byte stream uses the “lock” method above to determine if a key matches a lock up to the point where the next byte is the decoded character, captures that character, assumes the next four bytes are the seed for the next character to determine the next character and captures that, etc.
  5. When the bytes are all processed, if the resulting captured characters is the name of the lock, then the command associated with the lock is executed.

Protect your binaries

Your compiled code, not only your source, contains your email credentials. They can easily be extracted.