A collection of tools for covert channels.
コード例 #1
0
ファイル: BitmapSteganography.cs プロジェクト: SimWitty/Incog
        /// <summary>
        /// Read a message using the Least Significant Bit Steganographic method.
        /// </summary>
        /// <param name="path">The bitmap file to write to.</param>
        /// <param name="startingPosition">The starting byte address.</param>
        /// <param name="mathset">The set to use to determine where to update the least significant bits.</param>
        /// <param name="passphrase">The passphrase for encrypting and decrypting the message text.</param>
        /// <returns>Returns the message in Unicode characters.</returns>
        public static string SteganographyRead(string path, uint startingPosition, ChannelTools.MathematicalSet mathset, SecureString passphrase)
        {
            // Read the value in as bytes and convert to Unicode string
            byte[] cipherBytes = SteganographyReadBytes(path, startingPosition, mathset);

            // Decrypt the message
            Cryptkeeper crypt = new Cryptkeeper(passphrase);
            byte[] messageBytes = crypt.GetBytes(cipherBytes, Cryptkeeper.Action.Decrypt);
            string finaltext = new string(Encoding.Unicode.GetChars(messageBytes));

            // Find the stop character: 0xFFFF or 65,535
            int endof = finaltext.IndexOf(Convert.ToChar(ushort.MaxValue));

            // No final character? Return an empty string
            if (endof == -1) return string.Empty;

            // Return the string from the start to the stop character
            return finaltext.Substring(0, endof).TrimStart();
        }
コード例 #2
0
ファイル: BitmapSteganography.cs プロジェクト: SimWitty/Incog
        /// <summary>
        /// Read a message using the Least Significant Bit Steganographic method.
        /// </summary>
        /// <param name="path">The bitmap file to write to.</param>
        /// <param name="startingPosition">The starting byte address.</param>
        /// <param name="mathset">The set to use to determine where to update the least significant bits.</param>
        /// <returns>Returns a byte array containing the message.</returns>
        public static byte[] SteganographyReadBytes(string path, uint startingPosition, ChannelTools.MathematicalSet mathset)
        {
            // Preflight check - does the file exist?
            if (!File.Exists(path))
            {
                throw new System.ArgumentException("File not found.");
            }

            // Save the dates (we will revert later)
            FileInfo file = new FileInfo(path);
            DateTime created = file.CreationTime;
            DateTime modified = file.LastWriteTime;
            DateTime accessed = file.LastAccessTime;

            // Open the binary image and read the image into an array
            BinaryReader image = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None));
            byte[] imageBytes = image.ReadBytes((int)image.BaseStream.Length);
            long imageLength = imageBytes.Length;
            image.Close();

            // Prepare the message
            long maxMessageLength = imageLength - startingPosition;
            BitArray messageBits = new BitArray(Convert.ToInt32(maxMessageLength));

            // Prepare the set
            uint[] positions = new uint[messageBits.Length];
            uint maximum = (uint)Math.Min(uint.MaxValue, imageLength);

            // TODO: Determine a better way to estimate the length. Currently hard-coded for 4096 or approximately 2000 characters.
            uint length = 4096; // (uint)Math.Min(uint.MaxValue, messageBits.Length);

            switch (mathset)
            {
                case ChannelTools.MathematicalSet.Linear:
                    positions = ChannelTools.MathSetLinear(startingPosition, length);
                    break;
                case ChannelTools.MathematicalSet.PrimeNumbers:
                    positions = ChannelTools.MathSetSieveOfEratosthenes(startingPosition, maximum, length);
                    break;
                case ChannelTools.MathematicalSet.Random:
                    positions = ChannelTools.MathSetRandom(startingPosition, maximum, length);
                    break;
                default:
                    string error = "An unexpected mathematical set was passed into the SteganographyWrite function.";
                    throw new ApplicationException(error);
            }

            // Preflight check - does the file have enough bytes?
            if (imageLength < startingPosition)
            {
                image.Close();
                throw new System.ArgumentException("The image file is too small. Cannot continue.");
            }

            // Extract the message from the image byte array
            for (int i = 0; i < positions.Length; i++)
            {
                // Get the byte and the least significant bit
                byte currentByte = imageBytes[positions[i]];
                bool stegoBit = BinaryTools.LeastSignificantBit(currentByte);
                messageBits.Set(i, stegoBit);
            }

            // Revert the dates created, modified, and accessed
            file = new FileInfo(path);
            file.CreationTime = created;
            file.LastWriteTime = modified;
            file.LastAccessTime = accessed;

            // Convert the bits to bytes
            byte[] buffer = new byte[maxMessageLength];
            messageBits.CopyTo(buffer, 0);

            // Resize the array
            byte[] lengthBytes = new byte[4];
            Array.Copy(buffer, lengthBytes, 4);
            uint messageLength = BitConverter.ToUInt32(lengthBytes, 0);

            byte[] messageBytes = new byte[messageLength];
            Array.Copy(buffer, 4, messageBytes, 0, messageBytes.Length);

            return messageBytes;
        }
コード例 #3
0
ファイル: BitmapSteganography.cs プロジェクト: SimWitty/Incog
        /// <summary>
        /// Write a message using the Least Significant Bit Steganographic method.
        /// </summary>
        /// <param name="path">The bitmap file to write to.</param>
        /// <param name="startingPosition">The starting byte address.</param>
        /// <param name="message">The message in Unicode characters.</param>
        /// <param name="mathset">The set to use to determine where to update the least significant bits.</param>
        /// <param name="passphrase">The passphrase for encrypting and decrypting the message text.</param>
        public static void SteganographyWrite(string path, uint startingPosition, string message, ChannelTools.MathematicalSet mathset, SecureString passphrase)
        {
            // Append the stop character: 0xFFFF or 65,535
            message += Convert.ToChar(ushort.MaxValue);

            // Encrypt the message
            Cryptkeeper crypt = new Cryptkeeper(passphrase);
            byte[] cipherBytes = crypt.GetBytes(message, Cryptkeeper.Action.Encrypt);

            // Write the encoded and encrypted message
            SteganographyWrite(path, startingPosition, cipherBytes, mathset);
        }
コード例 #4
0
ファイル: BitmapSteganography.cs プロジェクト: SimWitty/Incog
        /// <summary>
        /// Write a message using the Least Significant Bit Steganographic method.
        /// </summary>
        /// <param name="path">The bitmap file to write to.</param>
        /// <param name="startingPosition">The starting byte address.</param>
        /// <param name="message">The message represented in a byte array.</param>
        /// <param name="mathset">The set to use to determine where to update the least significant bits.</param>
        public static void SteganographyWrite(string path, uint startingPosition, byte[] message, ChannelTools.MathematicalSet mathset)
        {
            // Preflight check - does the file exist?
            if (!File.Exists(path))
            {
                throw new System.ArgumentException("File not found.");
            }

            // Save the dates (we will revert later)
            FileInfo file = new FileInfo(path);
            DateTime created = file.CreationTime;
            DateTime modified = file.LastWriteTime;
            DateTime accessed = file.LastAccessTime;

            // Pre-pend the message array length
            byte[] buffer = new byte[message.Length + 4];
            byte[] lengthBytes = BitConverter.GetBytes((uint)message.Length);
            Array.Copy(lengthBytes, buffer, 4);
            Array.Copy(message, 0, buffer, 4, message.Length);

            // Open the binary image and read the image into an array
            BinaryReader image = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None));
            byte[] imageBytes = image.ReadBytes((int)image.BaseStream.Length);
            long imageLength = imageBytes.Length;
            image.Close();

            // Prepare the message
            BitArray messageBits = new BitArray(buffer);
            long maxMessageLength = imageLength - startingPosition;

            // Prepare the set
            uint[] positions = new uint[messageBits.Length];
            uint maximum = (uint)Math.Min(uint.MaxValue, imageLength);
            uint length = (uint)Math.Min(uint.MaxValue, messageBits.Length);

            switch (mathset)
            {
                case ChannelTools.MathematicalSet.Linear:
                    positions = ChannelTools.MathSetLinear(startingPosition, length);
                    break;
                case ChannelTools.MathematicalSet.PrimeNumbers:
                    positions = ChannelTools.MathSetSieveOfEratosthenes(startingPosition, maximum, length);
                    break;
                case ChannelTools.MathematicalSet.Random:
                    positions = ChannelTools.MathSetRandom(startingPosition, maximum, length);
                    break;
                default:
                    string error = "An unexpected mathematical set was passed into the SteganographyWrite function.";
                    throw new ApplicationException(error);
            }

            // Preflight check - does the file have enough bytes?
            if (imageLength < startingPosition)
            {
                image.Close();
                throw new System.ArgumentException("The image file is too small. Cannot continue.");
            }

            // Preflight check - does the file have enough bytes?
            if (maxMessageLength < messageBits.Length)
            {
                image.Close();
                throw new System.ArgumentException("The image file is too small. Cannot continue.");
            }

            // Embed the message into the image byte array
            for (int i = 0; i < positions.Length; i++)
            {
                // Get the byte and the least significant bit
                byte currentByte = imageBytes[positions[i]];
                bool imageBit = BinaryTools.LeastSignificantBit(currentByte);
                bool stegoBit = messageBits.Get(i);

                // If the imageBit is the same as the stegoBit, that is because the value is already correct.
                // If the imageBit and stegoBit do not match, update the least significant bit
                if (imageBit != stegoBit)
                {
                    currentByte = BinaryTools.SetLeastSignificantBit(currentByte, stegoBit);
                    imageBytes[positions[i]] = currentByte;
                }
            }

            // Re-open the image and update it
            BinaryWriter newImage = new BinaryWriter(new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write));
            newImage.Write(imageBytes);
            newImage.Close();

            // Revert the dates created, modified, and accessed
            file = new FileInfo(path);
            file.CreationTime = created;
            file.LastWriteTime = modified;
            file.LastAccessTime = accessed;
        }