Redes Sociales

miércoles, 12 de diciembre de 2018

Notes on symmetric and assymetric encryption and hashing algorithms

In the following weeks I will start working more deeply with OPENSSL and the different encryption algorithms used. This is a summary of most existing encryption and hashing algorithms. It's based on the notes by Rakhesh Sasidharan.

Symmetric key algorithms (Private key cryptography)

Explanation:Both parties share a private key (kept secret between them). Symmetric key algorithms are what you use for encryption. For example: encryption of traffic between a server and client, as well as encryption of data on a disk.

  • DES – Data Encryption Standard – designed at IBM. DES is a standard. The actual algorithm used is also called DES or sometimes DEA (Digital Encryption Algorithm). DES is now considered insecure (mainly due to a small key size of 56-bits). DES is a block cipher.
    • Triple DES (3DES) applies the DES algorithm thrice and thus has better practical security. It has 3 keys of 56-bits each (applied to each pass of DES/ DEA).
    • DES-X is another variant.
  • IDEA – International Data Encryption Algorithm. Considered to be a good and secure algorithm. Patented but free for non-commercial use. IDEA is a block cipher.
  • AES – Advanced Encryption Standard – is the successor to DES. AES is based on the Rijndael cipher. There was a competition to choose the cipher that will become the AES. The Rijndael cipher won the competition. However, there are some differences between Rijndael and its implementation in AES. Most CPUs now include hardware AES support making it very fast. AES and Rjindael are block ciphers. AES can operate in many modes.
    • AES-GCM (AES operating in Galois/Counter Mode (GCM)) is preferred (check this blog post too). It is fast and secure and works similar to stream ciphers. Can achieve high speeds on low hardware too. Only supported on TLS 1.2 and above.
    • AES-CBC is what older clients commonly use. AES-CBC mode is susceptible to attacks such as Lucky13 and BEAST.
  • Blowfish – designed by Bruce Schneier as an alternative to DES; no issues so far, but can be attacked if the key is weak, better to use Twofish or Threefish. Patent free. In public domain. Much faster than DES and IDEA but not as fast as RC4. Uses variable size keys of 32 to 448 bits. Considered secure. Designed for fast CPUs, now slower / old er CPUs.Blowfish is a block cipher.
  • Twofish – designed by Bruce Schneier and others as a successor to Blowfish. Was one of the finalists in the AES competition.Most CPUs now include hardware AES support making it very fast than Twofish.Patent free. In public domain.Uses keys of size 128, 192, or 256 bits. Designed to be more flexible than Blowfish (in terms of hardware requirements). Twofish is a block cipher.
  • Threefish – designed by Bruce Schneier and others.Threefish is a block cipher.
  • Serpent – designed by Ross Anderson, Eli Biham, and Lars Knudsen. Was one of the finalists in the AES competition. Patent free. In public domain. Has a more conservative approach to security than other AES competition finalists. Serpent is a block cipher.
  • MARS – designed by Don Coppersmith (who was involved in DES) and others at IBM. Was one of the finalists in the AES competition.
  • RC6 – Rivest Cipher 6 or Ron’s Code 6 – designed by Ron Rivest and others. Was one of the finalists in the AES competition. Proprietary algorithm. Patented by RSA Security.
  • RC5 is a predecessor of RC6. Other siblings include RC2 and RC4. RC5 and RC6 are block ciphers.
  • RC4 – Rivest Cipher 4, or Ron’s Code 4 – also known as ARC4 or ARCFOUR (Alleged RC4). Used to be an unpatented trade-secret for RSA Data Security Inc (RSADSI). Then someone posted the source code online, anonymously, and it got into the public domain. Very fast, but less studied than other algorithms. RC4 is good if the key is never reused. Then its considered secure by many. In practice RC4 is not recommended. TLS 1.1 and above forbid RC4 (also this RFC). CloudFlare recommends against it (check this blog post too). Microsoft recommends against it. Current recommendations overall are to use TLS 1.2 (which forbids RC4) and use AES-GCM. RC4 is a stream cipher. It’s the most widely used stream cipher. Recently block ciphers were found to have issues (e.g. BEAST, Lucky13) because of which RC4 rose in importance. Now such attacks are mitigated (use GCM mode for instance) and RC4 is strongly recommended against.

Asymmetric key algorithms (Public key cryptography)

Explanation:Each party has a private key (kept secret) and a public key (known to all). These are used in the following way:

Public keys are used for encrypting, Private keys are used for decrypting.

For example: to send something encrypted to a party use its public key and send the encrypted data. Since only that party has the corresponding private key, only that party can decrypt it. (No point encrypting it with your private key as anyone can then decrypt with your public key!)

Private keys are used for signing, Public keys are used for verifying.

For example: to digitally sign something, encrypt it with your private key (usually a hash is made and the hash encrypted). Anyone can decrypt this data (or decrypt the hash & data and perform a hash themselves to verify your hash and their hash match) and verify that since it was signed by your private key the data belongs to you.

These algorithms are usually used to digitally sign data and/ or exchange a secret key which can be used with a symmetric key algorithm to encrypt further data. They are often not used for encrypting the conversation either because they can’t (DSA, Diffie-Hellman) or because the yield is low and there are speed constraints (RSA). Most of these algorithms make use of hashing functions (see below) for internal purposes.

  • RSA – short for the surnames of its designers Ron Rivest, Adi Shamir and Leonard Adleman. Not used to encrypt data directly because of speed constraints and also because its yield is small (see this post for a good explanation; also this TechNet article). Usually RSA is used to share a secret key and then a symmetric key algorithm is used for the actual encryption. RSA can be used for digital signing but is slower. DSA (see below) is preferred. However, RSA signatures are faster to verify. To sign data a hash is made of it and the hash encrypted with the private key. (Note: RSA requires that a hash be made rather than encrypt the data itself). RSA does not require the use of any particular hash function. Public and Private keys are based on two large prime numbers which must be kept secret. RSA’s security is based on the fact that factorization of large integers is difficult. (The public and private keys are large integers which are derived from the two large prime numbers).
    • PKCS#1 is a standard for implementing the RSA algorithm. The RSA algorithm can be attacked if certain criteria are met so the PKCS#1 defines things such that these criteria are not met. See this post for more info. Was originally patented by the RSA but has since (circa 2000) expired. SSH v1 only uses RSA keys (for identity verification). RSA is supported by all versions of SSL/ TLS.
  • DSA – Digital Signature Algorithm – designed by the NSA as part of the Digital Signature Standard (DSS). Used for digital signing. Does not do encryption. (But implementations can do encryption using RSA or ElGamal encryption). DSA is fast at signing but slow at verifying. It mandates the use of SHA hashes when computing digital signatures. Unlike RSA which makes a hash of the data and then encrypts it to sign the message – and this data plus encrypted hash is what’s used to verify the signature – DSA has a different process. DSA generates a digital signature composed of two 160-bit numbers directly from the private key and a hash of the data to be signed. The corresponding public key can be used to verify the signature. The verifying is slow. A note about speed: DSA is faster at signing, slow at verifying. RSA is faster at verifying, slow at signing. The significance of this is different from what you may think. Signing can be used to sign data, it can also be used for authentication. For instance, when using SSH you sign some data with your private key and send to the server. The server verifies the signature and if it succeeds you are authenticated. In such a situation it doesn’t matter that DSA verification is slow because it usually happens on a powerful server. DSA signing, which happens on a relatively slower computer/ phone/ tablet is a much faster process and so less intensive on the processor. In such a scenario DSA is preferred! Remember: where the slow/ fast activity occurs also matters. DSA can be used only for signing. So DSA has to use something like Diffie-Hellman to generate another key for encrypting the conversation.

    This is a good thing as it allows for Perfect Forward Secrecy (PFS).

    • Forward Secrecy => the shared key used for encrypting conversation between two parties is not related to their public/ private key.
    • Perfect Forward Secrecy => in addition to the above, the shared keys are generated for each conversation and are independent of each other.

    Also, because DSA can be used only for digital signatures and not encryption, it is usually not subject to export or import restrictions. Therefore it can be used more widely. Patented but made available royalty free. DSA’s security is based on the discrete logarithm problem. SSH v2 can use RSA or DSA keys (for identity verification). It prefers DSA because RSA used to be patent protected. But now that the patents have expired RSA is supported.

  • ECDSA – Elliptic Curve DSA. Variant of DSA that uses Elliptic Curve Cryptography (ECC). DSA (and ECDSA) requires random numbers. If the random number generator is weak then the private key can be figured out from the traffic. See this blog post and RFC for good explanations.

    • ECC is based on Elliptic Curves theory and solving the “Elliptic Curve Discrete Logarithm Problem (ECDLP)” problem which is considered very hard to break. ECC keys are better than RSA & DSA keys in that the algorithm is harder to break. So not only are ECC keys more future proof, you can also use smaller length keys (for instance a 256-bit ECC key is as secure as a 3248-bit RSA key). Although the ECDLP is hard to solve, there are many attacks that can successfully break ECC if the curve chosen in the implementation if poor. For good ECC security one must use SafeCurves. For example Curve25519 by D.J. Bernstein. Used in Bitcoin and extensively in iOS for instance. Many web servers are adopting it too.
  • ElGamal – designed by Taher ElGamal. Used by GnuPG and recent versions of PGP. Taher ElGamal also designed the ElGamal signature, of which the DSA is a variant. ElGamal signature is not widely used but DSA is.
  • Diffie-Hellman (DH) – designed by Whitfield Diffie, Martin Hellman and Ralph Merkle. Does not do encryption or signing. It is only used for arriving at a shared key. Unlike RSA where a shared key is chosen by one of the parties and sent to the other via encryption, here the shared key is generated as part of the conversation – neither parties get to choose the key.

    Here’s how it works in brief: (1) the two parties agree upon a large prime number and a smaller number in public, (2) each party then picks a secret number (the private key) for itself and calculates another number (the public key) based on this secret number, the prime number, and the smaller number, (3) the public keys are shared to each other and using each others public key, the prime number, and the small number, each party can calculate the (same) shared key. The beauty of the math involved in this algorithm is that even though a snooper knows the prime number, the small number, and the two public keys, it still cannot deduce the private keys or the shared key! The two parties publicly derive a shared key such that no one snooping on their conversation can derive the key themselves.

    Has two versions:

    • A fixed/ static version (called “DH”) where all conversations use the same key,
    • An ephemeral version (called “EDH” (Ephermeral Diffie-Hellman) or “DHE” (Diffie-Hellman Ephemeral)) where every conversation has a different key.

    Its security too is based on the discrete logarithm problem (like DSA). SSHv2 uses DH as its key exchange protocol.

Hashing functions

Explanation:Hashing functions take input data and return a value (called a hash or digest). The input and message digest have a one-to-one mapping, such that given an input you get a unique digest and even a small change to the input will result in a different digest. Hashes are one way functions – given an input you can easily create a digest, but given a digest it is practically impossible to generate the input that created it.

  • MD2 – Message-Digest 2 – designed by Ron Rivest. Is optimized for 8-bit computers. Creates a digest of 128-bits. No longer considered secure but is still in use in Public Key Infrastructure (PKI) certificates but is being phased out.
  • MD4 – Message-Digest 4 – designed by Ron Rivest. Creates a digest of 128-bits. It is used to create NTLM password hashes in Windows NT, XP, Vista, and 7. MD4 is no longer recommended as there are attacks that can generate collisions (i.e. the same hash for different input).
  • MD5 – Message-Digest 5 – designed by Ron Rivest to replace MD4. As with MD4 it creates a digest of 128-bits. MD5 too is no longer recommended as vulnerabilities have been found in it and actively exploited.
  • MD6 – Message-Digest 6 – designed by Ron Rivest and others.
  • SHA 0 (a.k.a. SHA) – Secure Hash Algorithm 0 – designed by the NSA. Creates a 160-bit hash. Not widely used.
  • SHA-1 – Secure Hash Algorithm 1 – designed by the NSA. Creates a 160-bit hash. Is very similar to SHA-0 but corrects many alleged weaknesses. Is related to MD-4 too. Is very widely used but is not recommended as there are theoretical attacks on it that could become practical as technology improves.
  • SHA-2 is the new recommendation. Microsoft and Google will stop accepting certificates with SHA-1 hashes, for instance, from January 2017. SHA-2 – Secure Hash Algorithm 2 – designed by the NSA. Significantly different from SHA-1. Patented. But royalty free. SHA-2 defines a family of hash functions. There are theoretical attacks against SHA-2 but no practical ones.
    • Creates hashes of 224, 256, 384 or 512 bits. These variants are called SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256.
    • SHA-256 and SHA-512 new hash functions. They are similar to each other. These are the popular functions of this family.
    • SHA-512 is supported by TrueCrypt.
    • SHA-256 is used by DKIM signing.
    • SHA-256 and SHA-512 are recommended for DNSSEC.
    • SHA-224 and SHA-384 are truncated versions of the above two.
    • SHA-512/224 and SHA-512/256 are also truncated versions of the above two with some other differences.
  • SHA-3 – Secure Hash Algorithm 3 – winner of the NIST hash function competition. Not meant to replace SHA-2 currently. The actual algorithm name is Keccak.

Some more hash functions are:

  • Whirlpool – designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto. Patent free. In public domain. Creates a 512-digest. Supported by TrueCrypt.
  • RIPEMD – RACE Integrity Primitives Evaluation Message Digest . Based on the design principles of MD-4. Similar in performance to SHA-1. Not widely used however. Was designed in a the open academic community and meant to be an alternative to the NSA designed SHA-1 and SHA-2. Creates 128-bit hashes. There are many variants now: RIPEMD-128 creates 128-bit hashes (as the original RIPEMD hash), RIPEMD-160 creates 160-bit hashes, RIPEMD-256 creates 256-bit hashes, RIPEMD-320 creates 320-bit hashes.

Misc

  • PEM (Privacy Enhanced Mail) is the preferred format for storing private keys, digital certificates (the public key), and trusted Certificate Authorities (CAs). Supports storing multiple certificates (e.g. a certificate chain). If a chain is stored, then first certificate is the server certificate, next is issuer certificate, and so on. Last one can be self-signed or (of a root CA). The file begins with the line ----BEGIN CERTIFICATE---- and ends with the line ----END CERTIFICATE----. The data is in a text format. Private key files (i.e. private keys not stored in a keystore) must be in PKCS#5/PKCS#8 PEM format.
  • DER (Distinguished Encoding Rules) is another format. Can only contain one certificate. The data is in a binary format.
  • JKS (Java KeyStore) is the preferred format for key stores.
  • P7B (Public-Key Cryptography Standards #7 (PKCS #7)) is a format for storing digital certificates (no private keys) Supports storing multiple certificates. More about PKCS at WikiPedia. PKCS#7 is used to sign and/ or encrypt messages under a PKI. Also to disseminate certificates.
  • PFX/P12 (Public-Key Cryptography Standards #12 (PKCS #12)) is a format for storing private keys, digital certificates (the public key), and trusted CAs. PFX is a predecessor to PKCS#12. Usually protected with a password-based symmetric key.
  • CER is a format for storing a single digital certificate (no private keys) Base64-encoded or DER-encoded X.509 certificates.
  • SSL/TLS are protocols that use the above
  • SSL – Secure Sockets Layer; TLS – Transport Layer Security SSL has version 1.0 to 3.0. SSL version 3.1 became TLS 1.0. TLS has version 1.0 to 1.2. SSL and TLS are not interoperable (TLS 1.0 can have some of the newer features disabled, and hence security weakened, to make it interoperable with SSL 3.0) Used for authentication and encryption. Makes use of the ciphers above.

martes, 4 de diciembre de 2018

Explanation of CVE-2017-8464

table of Contents

[0x01].Introduction

[0x02].lnk file format parsing

[0x03]. Patch comparison

[0x04]. Vulnerability analysis

[0x05]. About detection

[0x06].Other

[0x01].Introduction

In June 2017, Microsoft's patch day announced two 0day vulnerabilities in the wild, CVE-2017-8464 (LNK vulnerability) and CVE-2017-8543 (vulnerability in Search service). This article will briefly analyze the causes and related uses of the LNK vulnerability.

For more information, please see:

  • https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-8464
  • http://www.securityfocus.com/bid/98818

Vulnerability affected version:

  • Microsoft Windows 10 3
  • Microsoft Windows 7 1
  • Microsoft Windows 8 1
  • Microsoft Windows 8.1 2
  • Microsoft Windows Server 2008 2
  • Microsoft Windows Server 2012 2
  • Microsoft Windows Server 2016

[0x02].lnk file format parsing

Lnk file is a relatively simple file format, but because the operation involves shell programming, COM related and other WINDOWS foundation, it is not very easy to fully understand the relevant information. It's not as clear and easy to parse as a complex PE file. A typical lnk file format is as follows:

              **********************.lnk file format ******************

              +---------------------------+
              | lnk file header |
              +---------------------------+ >------.
              | Shell Item Id List | |
              +---------------------------+ |
              | File location info | |
              +---------------------------+ |
              | Description string | |
              +---------------------------+ ---
              Relative path string | Not all of these sections must exist. If they exist, they should be arranged in this order.
              +---------------------------+ ---
              | Working directory string | |
              +---------------------------+ |
              | Command line string | |
              +---------------------------+ |
              | Icon filename string | |
              +---------------------------+ >------.
              | Extra stuff |
              +---------------------------+

The location related to this vulnerability is 1) Shell Item Id List , 2) Extra stuff. For a more detailed introduction to the LNK file format, please refer to this or this links.

Some security companies mentioned that this vulnerability is very similar to the CVE-2010-2568 used by Stuxnet. In fact, there are some truths, all related to the use of the control panel shortcut CPL loading, but there are a certain difference.

The main factor is still in the Shell Item Id List section, which describes the path portion of the shortcut. For example, if I have a c:\a\b\c\x.jpg file, then after creating a shortcut for this file, a shell Item ID list structure will be generated.

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F

00000040 4B 01 14 00 K
00000050 1F 50 E0 4F D0 20 EA 3A 69 10 A2 D8 08 00 2B 30 P郞??i (20) +0
00000060 30 9D 19 00 2F 43 3A 5C 00 00 00 00 00 00 00 00 0 /C:\
00000070 00 00 00 00 00 00 00 00 00 00 00 00 44 00 31 00 00 D 1
00000080 00 00 00 E7 4A 01 73 10 00 61 00 34 00 09 00 04 鏙 s a 4
00000090 00 EF BE E7 4A 01 73 E7 4A 01 73 2E 00 00 00 7A 锞鏙 s鏙 s. z
000000A0 65 01 00 00 00 4F 02 00 00 00 00 00 00 00 00 00 00 e O
000000B0 00 00 00 00 00 DB B6 E5 00 61 00 00 00 10 00 44 鄱?a D
000000C0 00 31 00 00 00 00 00 E7 4A 01 73 10 00 62 00 34 1 鏙 s b 4
000000D0 00 09 00 04 00 EF BE E7 4A 01 73 E7 4A 01 73 2E 锞鏙 s鏙 s.
000000E0 00 00 00 D3 65 01 00 00 00 20 01 00 00 00 00 00 觘
000000F0 00 00 00 00 00 00 00 00 00 00 69 96 E5 00 62 00 00 i栧 b
00000100 00 10 00 44 00 31 00 00 00 00 00 E7 4A C3 73 10 D 1 鏙胹
00000110 00 63 00 34 00 09 00 04 00 EF BE E7 4A 01 73 E7 c 4 锞鏙 s?
00000120 4A C3 73 2E 00 00 00 E9 65 01 00 00 00 1F 00 00 J胹.
00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 EC BF 2D 炜-
00000140 01 63 00 00 00 10 00 50 00 32 00 AE 3D 04 00 9F c P 2 ? ?
00000150 2F 00 80 20 00 78 2E 4A 50 47 00 3C 00 09 00 04 / € x.JPG <
00000160 00 EF BE E7 4A C1 73 E7 4A C1 73 2E 00 00 00 F2 velvet velvet.
00000170 65 01 00 00 00 64 00 00 00 00 00 00 00 00 00 00 00 e d
00000180 00 00 00 00 00 00 00 00 00

This part can be expressed as a structure

Struct ShellItem{
DWORD size;
SHITEMID item[1]; //The surface here is a variable section, which can grow with the increase of the directory.
}

Typedef struct _SHITEMID
      {
        Unsigned short int cb; //the length of this section
        Unsigned char abID[0]; //Define a mutable structure
      }SHITEMID, *LPSHITEMID;
    

Generally speaking, SHITEMID[0] represents my computer.

\x14\x00 (here is the length)
\x1F (type)
\x50 (unknown)
\xE0\x4F\xD0\x20\xEA\x3A\x69\x10\xA2\xD8\x08\x00\x2B\x30\x30\x9D(GUID)

The above GUID conversion is HKEY_CLASSES_ROOT\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}, you can query on your own computer.

The default upper directory of the shortcut is started from here. According to this structure, you can find the corresponding \a, \b, \c, x.jpg. SHITEMID[1], SHITEMID[2], SHITEMID[3], SHITEMID[4] structure information

Then, the shortcut for the control panel will be different, SHITEMID[0] - corresponding to my computer information,

SHITEMID[1] - Corresponds to the GUID information of the control panel, usually \x19\x00\x2F\x43\x3A\x5C\x00\x00\x00\x00\x00\x00
SHITEMID[2] - Corresponding to the specific control panel cpl program information, the standard control panel shortcut will add its own path information to the extra stuff structure.

For example, if you create a shortcut to Auto Play in the control panel, you can view the information of Extra data. You can see a GUID. You can find out which cpl function program is corresponding to the query. Auto Play:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace\
{9C60DE1E-E5FC-40f4-A487-460851A8D915}

According to the previous experience of analyzing CVE-2010-2568, the SHITEMID[1] of the vulnerability fills the GUID information of the control panel {21EC2020-3AEA-1069-A2DD-08002B30309D} SHITEMID[2] adds the corresponding cpl program path. According to the analysis of CVE-2017-8464, simply adding the path information of the cpl program will not trigger the vulnerability, and a special Extra data message must be constructed.  

[0x03]. Patch comparison

   Analysis platform: win7 x86
   File: shell32.dll (pre-patch: 6.1.7601.1892, post-patch: 6.1.7600.23806)

   Through path diff, you can see that Microsoft has patched a lot of places this time. According to the last experience, it is natural to query the CPL_LoadCPLModule function to be called.

...
CAutoComplete::_OnSearchComplete(SearchResults *,_DPA *)                                                      738F086E CAutoComplete::_OnSearchComplete(SearchResults *,_DPA *)
Kfapi::CFolderRedirector::Redirect(_GUID const &,HWND__ *,ulong,ushort const *,_GUID const *,uint,ushort * *) 73B61419 kfapi::CFolderRedirector::Redirect(_GUID const &,HWND__ *,ulong,ushort Const *, _GUID const *, uint, ushort * *)
CopyStreamToFile(IStream *, ushort const *, unsigned __int64)                                                 73B16E33 CopyStreamToFile(IStream *, ushort const *, unsigned __int64)
CControlPanelFolder::_GetPidlFromAppletId(ushort const *,_ITEMID_CHILD * *)                                   73AF300B CControlPanelFolder::_GetPidlFromAppletId(ushort const *,_ITEMID_CHILD * *)
CAutoComplete::_AppendNext(int)                                                                               73AA4538 CAutoComplete::_AppendNext(int)
CAutoComplete::_AppendPrevious(int)                                                                           73AA460E CAutoComplete::_AppendPrevious(int)
CGrep::_InitializeChunkBuffer(void)                                                                           73B9066F CGrep::_InitializeChunkBuffer(void)
...

    Among them, the patch code of CControlPanelFolder::_GetPidlFromAppletId(ushort const *, _ITEMID_CHILD * *) is related to the CPL_LoadCPLModule function. A very important point is here:

  If ( SHExpandEnvironmentStringsW(&Start, &v17, 260) )
        {
          If ( CControlPanelFolder::_IsRegisteredCPLApplet(v11, &v17) ) // --- Added a checksum
          {
            V12 = 0;
            V7 = CPL_LoadCPLModule(&v17, 0);
            If ( v7 )
            {
              V13 = 0;
              Do
              {
                V8 = (struct _DSA *)*((_DWORD *)v7 + 135);
                If ( v6 >= *(_DWORD *)v8 )
                  Break;
                V9 = DSA_GetItemPtr(v8, v6);
                If ( v9 )
                {
                  V12 = IDControlCreate(
         ...
        }

    At this point, we already know that the key is how to trigger the path of this vulnerability, call CPL_LoadCPLModule, because if there is no problem there, then Microsoft will not use _IsRegisteredCPLApplet Filter because CVE-2010-2568 is also patched with this mechanism.

[0x04]. Vulnerability analysis

All the way back we can get a trigger path:

CControlPanelFolder::ParseDisplayName (The specific reference to CControlPanelFolder::ParseDisplayName cannot be seen in IDA)
--> CControlPanelFolder::_GetPidlFromAppletId
-->CPL_LoadCPLModule

Therefore, the call to CControlPanelFolder::ParseDisplayName should be implemented through a dynamic object virtual table function call. Setting breakpoints in CControlPanelFolder::ParseDisplayName, arbitrarily open the file directory where .lnk exists, it is difficult to get a trigger. Note that the usual lnk file is missing some information or the corresponding field is incorrect.

Using the sample of CVE-2010-2568 for testing, this breakpoint cannot be triggered. But when I printed the execution path letter, I saw some notable places, and the call will be executed according to the previous vulnerability.

_DecodeSpecialFolder. But this function is not actually executed completely.

46 101 [ 2] SHLWAPI!SHReadDataBlockList
    3 0 [ 3] SHLWAPI!__security_check_cookie eax = 0
   48 104 [ 2] SHLWAPI!SHReadDataBlockList eax = 0
  119 3446 [ 1] SHELL32!CShellLink::_LoadFromStream
   16 0 [ 2] SHELL32!CShellLink::_DecodeSpecialFolder
   11 0 [ 3] SHLWAPI!SHFindDataBlock eax = 0
   22 11 [ 2] SHELL32!CShellLink::_DecodeSpecialFolder
   11 0 [ 3] SHLWAPI!SHFindDataBlock eax = 0
   27 22 [ 2] SHELL32!CShellLink::_DecodeSpecialFolder
    5 0 [ 3] SHELL32!SHFree
    8 0 [ 3] ole32!CoTaskMemFree
    7 0 [ 4] ole32!CRetailMalloc_Free eax = 76b076bc
   10 7 [ 3] ole32!CoTaskMemFree eax = 76b076bc
   33 44 [ 2] SHELL32!CShellLink::_DecodeSpecialFolder
    3 0 [ 3] SHELL32!__security_check_cookie eax = 76b076bc



void __thiscall CShellLink::_DecodeSpecialFolder(CShellLink *this)
{
  CShellLink *v1; // esi@1
  int v2; // eax@1
  int v3; // edi@1
  signed int v4; // eax@3
  signed int v5; // eax@5
  int v6; // ecx@5
  char *v7; // edi@7
  unsigned int v8; // ebx@7
  int i; // eax@7
  bool v10; // zf@9
  const ITEMIDLIST *v11; // eax@13
  ITEMIDLIST *v12; // ebx@14
  ITEMIDLIST *v13; // edi@15
  int v14; // eax@15
  int v15; // esi@15
  int v16; // eax@15
  int v17; // eax@20
  int v18; // edi@20
  const struct _ITEMIDLIST_RELATIVE *pidl; // [sp+Ch] [bp-Ch]@7
  ITEMIDLIST *pidla; // [sp+Ch] [bp-Ch]@13
  LPITEMIDLIST v21; // [sp+10h] [bp-8h]@1

  v21 = 0;
  v1 = this;
  v2 = SHFindDataBlock(*((_DWORD *)this + 57), 0xA000000B); 
  v3 = v2;
  
  if ( v2 )  //If the search is successful, then it will continue, otherwise release ILFree (pidla);)
  {
    if ( !CShellLink::_ShouldDecodeSpecialFolder(v1, (const struct _GUID *)(v2 + 8)) )
      goto LABEL_19;
    v4 = 0x4000;
    if ( *((_DWORD *)v1 + 65) & 0x400000 )
      v4 = 20480;
    v5 = SHGetKnownFolderIDList(v3 + 8, v4, 0, &v21);
    v6 = *(_DWORD *)(v3 + 24);
  }
  else
  {
    v17 = SHFindDataBlock(*((_DWORD *)v1 + 57), 0xA0000005);
    v18 = v17;
    if ( !v17 )
      goto LABEL_19;
    v21 = SHCloneSpecialIDList(0, *(_DWORD *)(v17 + 8), 0);
    v6 = *(_DWORD *)(v18 + 12);
    v5 = v21 != 0 ? 0 : -2147024882;
  }

Obviously, SHFindDataBlock is a failure, because the DataBlock she is searching for is missing. See the LNK file manual to see that the Extra Data structure is mentioned. It involves a lot of structure and its signature information, showing that the parameter when called above is its signature information, 0xA0000005, 0xA000000B

 ConsoleDataBlock - 0xA0000002
 ConsoleFEDataBlock - 0xA0000004
 EnvironmentVariableDataBlock - 0xA0000001
 IconEnvironmentDataBlock - 0xA0000007
 PropertyStoreDataBlock - 0xA0000009
 SpecialFolderDataBlock - 0xA0000005 (parameters mentioned in the function above)
 KnownFolderDataBlock - 0xA000000B (parameters mentioned in the function above)

   Therefore, based on the CVE-2010-2568 sample, you can add an ExtraData data, and then add the SpecialFolderDataBlock and the KnownFolderDataBlock experiments.    Specific format:

   Struct KnownFolderDataBlock{
    DWORD BlockSize;
DWORD BlockSignature;
CHAR GUID[16];
DWORD offset;
   }

   
   KnownFolderDataBlock:
   \x1C\x00\x00\x00\x0B\x00\x00\xA0\x19\x27\x6D\x74\x59\x74\x6A\x2D\x63\x1A\x9D\x7f\x63\x24\x8C\x6D\x00 \x00x00\x03

The GUID in the middle specifically points to the special file ID. It does not seem to be clear in the document. Only some GUIDs that exist already exist, and the test is repeated. There is no success (if there is a friend who has successfully tested, please also give pointers).    

The structure of the SpecialFolderDataBlock is relatively simple:

   Struct SpecialFolderDataBlock{
    DWORD BlockSize;
DWORD BlockSignature;
DWORD ID;
DWORD offset;
   }


   Add these data: \x10\x00\x00\x00\x05\x00\x00\xA0\x03\x00\x00\x00\x28\x00\x00\x00\x00\x00

   Note that 0x28 inside is offset according to the manual.

A 32-bit, unsigned integer that specifies the location of the ItemID of the first child
Segment of the IDList specified by SpecialFolderID. This value is the offset, in bytes, into the

Link target IDList.

   Here I calculate the difference between SHITEMID[2] - SHITEMID[0].

   This way, you can see the call stackl where the .lnk file is loaded.

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F

00000080 00 00 00 6A 00 00 00 00 00 00 05 01 05 01 46 00 j F
00000090 3A 00 5C 00 2E 00 5C 00 2E 00 5C 00 2E 00 5C 00:... \ \ \ \
000000A0 2E 00 5C 00 2E 00 74 00 65 00 73 00 74 00 2E 00. \. T e s t.
000000B0 63 00 70 00 6C 00 00 00 c p l

The final loading situation: SHExpandEnvironmentStringsW will get the system directory and the following directory spliced ​​into a system path SHELL32!CControlPanelFolder::_GetPidlFromAppletId+0x160:

75ec3da3 50 push eax
0:017> db eax
0583cde4 43 00 3a 00 5c 00 57 00-69 00 6e 00 64 00 6f 00 C.:.\.W.i.n.d.o.
0583cdf4 77 00 73 00 5c 00 73 00-79 00 73 00 74 00 65 00 w.s. \. S.y.s.t.e.
0583ce04 6d 00 33 00 32 00 5c 00-2e 00 74 00 65 00 73 00 m.3.2.\...t.e.s.
0583ce14 74 00 2e 00 63 00 70 00-6c 00 2c 00 00 00 15 09 t...c.p.l.,.....
0583ce24 38 ce 83 05 18 6f a0 76-d8 ed 15 09 70 f4 c6 75 8....o.v....p..u
0583ce34 53 00 6f 00 66 00 74 00-77 00 61 00 72 00 65 00 S.o.f.t.w.a.r.e.
0583ce44 5c 00 4d 00 69 00 63 00-72 00 6f 00 73 00 6f 00 \.M.i.c.r.o.s.o.
0583ce54 66 00 74 00 5c 00 57 00-69 00 6e 00 64 00 6f 00 f.t.\.W.i.n.d.o.

0:013> kv
ChildEBP RetAddr  Args to Child              
0499d114 75ec3f52 08ec3a48 0499d21c 75c70180 SHELL32!CControlPanelFolder::_GetPidlFromAppletId+0x181 (FPO: [Non-Fpo])
0499d140 75c5799b 08cabc38 00000000 08d5a800 SHELL32!CControlPanelFolder::ParseDisplayName+0x49 (FPO: [Non-Fpo])
0499d1c4 75c5f0af 090ddaac 00000000 08d5a800 SHELL32!CRegFolder::ParseDisplayName+0x93 (FPO: [Non-Fpo])
0499d238 75c606cd 090de3dc 00347098 75c7a660 SHELL32!ReparseRelativeIDList+0x137 (FPO: [Non-Fpo])
0499d27c 75c60715 00000000 00347070 08ead300 SHELL32!TranslateAliasWithEvent+0xa6 (FPO: [Non-Fpo])
0499d294 75c2e84e 00347070 08ead300 05c06258 SHELL32!TranslateAlias+0x15 (FPO: [Non-Fpo])
0499d2c0 75c2e5e3 00000000 00000000 05d5e0c8 SHELL32!CShellLink::_DecodeSpecialFolder+0xf9 (FPO: [Non-Fpo])
0499e584 75beca18 08f4c6d8 00000000 00000000 SHELL32!CShellLink::_LoadFromStream+0x39f (FPO: [Non-Fpo])
0499e7b4 75bec987 0499e840 00000000 0499e7f0 SHELL32!CShellLink::_LoadFromFile+0x90 (FPO: [Non-Fpo])
0499e7c4 75bec8dc 05d5e0dc 0499e840 00000000 SHELL32!CShellLink::Load+0x32 (FPO: [Non-Fpo])
0499e7f0 75bec933 05d5e0d0 0499e840 00000000 SHELL32!InitializeFileHandlerWithFile+0x6a (FPO: [Non-Fpo])
0499ea4c 75c38be0 00000000 0499eaa0 00000002 SHELL32!CFileSysItemString::HandlerCreateInstance+0x168 (FPO: [Non-Fpo])
0499eb04 75c42626 00000000 00000000 00000000 SHELL32!CFileSysItemString::LoadHandler+0x16b (FPO: [Non-Fpo])
0499efb4 75c42674 00000000 00000001 0499f00c SHELL32!CFSFolder::_BindHandler+0x1d1 (FPO: [Non-Fpo])
0499efd4 75bf9aa6 09058198 00000000 00000001 SHELL32!CFSFolder::GetUIObjectOf+0x21 (FPO: [Non-Fpo])
0499f490 75c3128d 09058180 05b4c0b8 05b4c0b8 SHELL32!CFSFolder::_GetPerceivedType+0x60 (FPO: [Non-Fpo])
0499f4b0 75c371fd 00000000 05b4c0b8 05b4c0b8 SHELL32!CFSFolder::_GetInnateDetailsFromHelper+0x47 (FPO: [Non-Fpo])
0499f4e0 75c31398 00000000 05b4c0b8 75c632ac SHELL32!CFSFolder::_GetInnateDetailsWithHandlerExceptions+0x61 (FPO: [Non-Fpo])
0499f4fc 75c3134c 05b4c0b8 75c632ac 0499f578 SHELL32!CFSFolder::_GetInnateDetails+0x18 (FPO: [Non-Fpo])
0499f538 75c312e9 05b4c0b8 75c632ac 0499f578 SHELL32!CFSFolder::_GetInnateDetailsAsVariant+0x41 (FPO: [Non-Fpo])
0499f580 75c0e197 09058198 05b4c0b8 75c632ac SHELL32!CFSFolder::GetDetailsEx+0x40 (FPO: [Non-Fpo])
0499f5b0 75c0ed8d 09058198 05b4c0b8 09056584 SHELL32!GetPerceivedType+0x44 (FPO: [Non-Fpo])
0499f5f8 75c0dc3a 0499f61c 08d6d4e0 09056584 SHELL32!GetFolderTypeFromItems+0xd8 (FPO: [Non-Fpo])
0499f63c 75c0d99c 08d6d4e0 09056584 09058198 SHELL32!CEnumTask::_CalculateFolderType+0x2f (FPO: [Non-Fpo])
0499f698 75c09e63 09058198 0499f6f0 0499f6ec SHELL32!CEnumTask::_IncrFillEnumToView+0x192 (FPO: [Non-Fpo])
0499f6f8 75c09fcd 09058198 00000001 755f81eb SHELL32!CEnumTask::_IncrEnumFolder+0x2b5 (FPO: [Non-Fpo])
0499f73c 75c38226 09056550 01000000 80000000 SHELL32!CEnumTask::InternalResumeRT+0x325 (FPO: [Non-Fpo])
0499f75c 75c761fb 09056564 7fffffff 05cb7708 SHELL32!CRunnableTask::Run+0xce (FPO: [Non-Fpo])
0499f778 75c78a8b 0499f7b4 00000000 090b62d8 SHELL32!CShellTask::TT_Run+0x167 (FPO: [Non-Fpo])
0499f7c0 75c78bbf 0499f7d8 7753b2b1 05cb7708 SHELL32!CShellTaskThread::ThreadProc+0xa3 (FPO: [Non-Fpo])
0499f7c8 7753b2b1 05cb7708 03de89a8 0499f84c SHELL32!CShellTaskThread::s_ThreadProc+0x1b (FPO: [Non-Fpo])
0499f7d8 773dd7c4 090b62d8 7322bf39 03de89a8 SHLWAPI!ExecuteWorkItemThreadProc+0xe (FPO: [Non-Fpo])   

Microsoft's repair method is to judge in _IsRegisteredCPLApplet, the incoming DLL path to be loaded and the default existing .cpl path match, if the input path does not exist in the whitelist, then return False, no DLLs are loaded.

For the patch function: He wants to determine if it exists in a list. Get the first element first, then compare them in order: 76f136bb ff30 push dword ptr [eax] ds:0023:067f1170=038bf1a0

0:002> db 038bf1a0
038bf1a0 43 00 3a 00 5c 00 50 00-52 00 4f 00 47 00 52 00 C.:.\.P.R.O.G.R.
038bf1b0 41 00 7e 00 31 00 5c 00-4d 00 49 00 46 00 35 00 A.~.1.\.M.I.F.5.
038bf1c0 42 00 41 00 7e 00 31 00-5c 00 4f 00 66 00 66 00 B.A.~.1.\.O.f.f.
038bf1d0 69 00 63 00 65 00 31 00-34 00 5c 00 4d 00 4c 00 i.c.e.1.4.\.M.L.
038bf1e0 43 00 46 00 47 00 33 00-32 00 2e 00 43 00 50 00 C.F.G.3.2...C.P.
038bf1f0 4c 00 00 00 00 00 05 10-66 a6 ec 53 ff ff 00 8c L.......f..S....
038bf200 57 00 69 00 6e 00 64 00-6f 00 77 00 73 00 20 00 W.i.n.d.o.w.s.
038bf210 77 00 69 00 6c 00 6c 00-20 00 69 00 6e 00 73 00 w.i.l.l. .i.n.s.

Second cycle
0:002> db 0692e7d0
0692e7d0 43 00 3a 00 5c 00 57 00-69 00 6e 00 64 00 6f 00 C.:.\.W.i.n.d.o.
0692e7e0 77 00 73 00 5c 00 73 00-79 00 73 00 74 00 65 00 w.s.\.s.y.s.t.e.
0692e7f0 6d 00 33 00 32 00 5c 00-77 00 73 00 63 00 75 00 m.3.2.\.w.s.c.u.
0692e800 69 00 2e 00 63 00 70 00-6c 00 00 00 6c 00 00 00 i...c.p.l...l...
0692e810 33 f7 4b 53 01 00 00 80-14 00 4c 00 45 00 33 00 3.KS...L.E.3.
0692e820 43 00 42 00 46 00 39 00-32 00 41 00 33 00 34 00 C.B.F.9.2.A.3.4.
0692e830 36 00 46 00 33 00 34 00-30 00 42 00 31 00 39 00 6.F.3.4.0.B.1.9.
0692e840 31 00 35 00 38 00 43 00-32 00 35 00 42 00 43 00 1.5.8.C.2.5.B.C.
the third time:
0:002> db poi(eax)
0384a9c0 43 00 3a 00 5c 00 57 00-69 00 6e 00 64 00 6f 00 C.:.\.W.i.n.d.o.
0384a9d0 77 00 73 00 5c 00 73 00-79 00 73 00 74 00 65 00 w.s.\.s.y.s.t.e.
0384a9e0 6d 00 33 00 32 00 5c 00-46 00 6c 00 61 00 73 00 m.3.2.\.F.l.a.s.
0384a9f0 68 00 50 00 6c 00 61 00-79 00 65 00 72 00 43 00 h.P.l.a.y.e.r.C.
0384aa00 50 00 4c 00 41 00 70 00-70 00 2e 00 63 00 70 00 P.L.A.p.p...c.p.
0384aa10 6c 00 00 00 00 00 6e 00-ea 57 13 53 73 00 00 80 l.....n..W.Ss...
0384aa20 32 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 2...............
0384aa30 01 00 00 00 00 00 00 00-a0 71 60 06 e8 95 a5 76 .........q`....v
  

This way, even if you try to load the path, it will be rejected because it is no longer in the whitelist.

[0x05]. About detection

    In order to detect this vulnerability generically, it needs to be an unconventional format detection for the shell item id list.

SHITEMID[0] = \x1F\x50\xE0\x4F\xD0\x20\xEA\x3A\x69\x10\xA2\xD8\x08\x00\x2B\x30\x9D
    SHITEMID[1] = \x2E\x1E\x20\x20\xEC\x21\xEA\x3A\x69\x10\xA2\xDD\x08\x00\x2B\x30\x30\x9D
    

In addition, for ExtraDtat:

ExtraData.BlockSize = 0x00000010
ExtraData.BlockSignature = 0xA0000005

The detection logic is as follows:

If(SHITEMID[0] == "\x1f \x50 ..." & SHITEMID[1] = "\x2e \x1f ...")
{
If(SHITEMID[2] in (".\\" || ".dll"))
{
If(ExtraData.BlockSize = 0x00000010 && ExtraData.BlockSignature = 0xA0000005)
{
Alert("Found CVE-2017-8464 Vulnerability\n");
}
}
}

[0x06].Other

Limited to the lack of understanding of KnownFolderDataBlock and a more in-depth analysis of related calls, it is not certain whether the KnownFolderDataBlock must be associated with this vulnerability, but apparently Microsoft. The way to fix this vulnerability is based on whitelist filtering. Even if the KnownFolderDataBlock can be triggered, it will not load successfully.

[references]

  • [MS-SHLLINK]-160714.pdf
  • Https://msdn.microsoft.com/en-us/library/dd891343.aspx

The looking glass service

Many internet agents offer (ISPs, IXPs, etc) what it's called the looking glass service . Only in this web site a full list of 1150 looking glass services are offered: http://www.bgplookingglass.com.

Looking glass services are a great way to understand if a target is up and how to reach it.

It's important to note that the Looking Glass service can be configured on Juniper, Cisco (IOS o IOS-XR), Extreme (NetIron), Quagga, BIRD, OpenBGPd, Vyatta/VyOS/EdgeOS, or FRRouting routers.

OTOH, it's necessary to install a Looking Glass client in a web server in order to be able to use the service. There exist a number of Looking Glass (often called LG) service software packages that can be installed in a web server. . In Ubuntu/Debian we can find:

# apt-cache search looking | grep glass
rancid-cgi - looking glass CGI based on rancid tools

However, the only documentation found about this package is this website, which means it's not widely used.

We al have MRLG (See http://mrlg.op-sec.us/), but it seems quite old...

Nevertheless, the typical LG software used is the standard version of Looking Glass obtained from Version6.net. A good source explaining how to install it in a CentOS distro is: http://amar-linux.blogspot.com/2013/06/setting-up-bgp-looking-glass-centos-6.html. It can also be found in its github reporsitory: https://github.com/version6net/lg.

All of them are services developed in Perl, however we can find other solutions developed in PHP, IE (https://github.com/respawner/looking-glass ...which is fully documented in https://looking-glass.readthedocs.io.

HOW DOES IT WORK

For the normal functioning of the Looking Glass service it's necessary to have access to router's ports 2601 and 2605. The software generally connects to these ports via telnet. Generally credentials for this telnet are stored in a config file and the LG software simply connects via telnet to the router and sends BGP commands, returning the output to the web service. The typical BGP commands are like "sh ip bgp".

Therefore it's necessary to open 2601 and 2605 ports in the firewalls before the LG service to work properly. It will also be necessary to have a working NGINX or Apache Web server. Finally the appropiate libraries will have to be installed (depending on each solution).

On the other hand the router will have to be prepared to wait allow BGP commands remotely. For instance configuration for a Juniper OS (at least for the PHP solution previously mentioned) is the following:https://looking-glass.readthedocs.io/en/latest/juniper/. A restricted user in the router is recommended for the telnet connection and BGP command execution.

Trying to get a Bro Cluster to work

After developing an analyzer as a plugin, I had to develop a number of bro scripts to make my tool work. Finally they were 4 bro scripts. We prepared a Cluster infrastructure with two worker nodes, each with two network interfaces, one of them listening in two different VLANs and the other in the monitoring network. And a manager&proxy node running in the monitoring network only.

The installation was quite smooth. Used a Debian Jessy 64bits and followed instructions found in the Bro website. After installation, both workers and the manager seemed to work fine. Not exactly.

Briefly, in Manager node, bro scripts should be copied in

[1] /usr/local/bro/share/bro/site

...broctl should be configured modifying values of:

[2] /usr/local/bro/etc/broctl.cfg

...logs would be copied to:

[3] /mnt/logs/current

...given the different and deep-named directories I decided to create some symbolic links to them in my /home/bro directory:

root@Manager:/home/bro# ls -l
total 8
drwxr-xr-x 6 bro  bro  4096 Jun  7 13:38 aux_files
drwxr-xr-x 3 bro  bro  4096 May 31 13:30 bro
lrwxrwxrwx 1 root root   29 Jun  8 13:51 broctl.cfg -> /usr/local/bro/etc/broctl.cfg
lrwxrwxrwx 1 root root   17 Jun  8 13:50 logs -> /mnt/logs/current
lrwxrwxrwx 1 root root   29 Jun  8 13:50 site -> /usr/local/bro/share/bro/site

These are the steps to follow when any change have to be introduced in the configuration or bro scripts:

  1. Modify bro scripts located in [1]
  2. Modify (if necessary) broctl options in [2]
  3. launch Bro Control (broctl)
  4. check
  5. deploy

All broctl commands, which can be looked up using the 'help' command, are actually python scripts located in:

[4] /usr/local/bro/lib/broctl/Brocontrol

It's not difficult to understand what they are doing if you know a little bit of Python. For instance, deploy and install commands are run with the control.py python script.

Basically, when a 'deploy' is sent in broctl, the scripts in [1] are copied to:

[5] /home/bro/bro/spoolinstalled-scripts-do-not-touch/site

...both in the manager and all worker nodes.

Why these directories?. Well, this is configured in the broctl.cfg [2] file. In this file there are a number of variables that will allow us to configure directories and bro-scripts like:

  1. PolicyDirSiteInstall: Directory where all bro scripts are copied both in workers and manager nodes. By default is ${SpoolDir}/installed-scripts-do-not-touch/site. In my case is the directory mentioned in [5].
  2. SitePolicyPath: Colon-separated list of Directories to search for site-specific policy (bro) files. For each such directory, all files and subdirectories are copied to PolicyDirSiteInstall during broctl ‘install’ or ‘deploy’. By default is /usr/local/bro/share/bro/site.
  3. SitePolicyWorker: Space-separated list of bro scripts that should be run in EVERY worker node of the cluster. By default its value is local-worker.bro, which is an empty bro script. They will be copied to ALL nodes of the cluster when a 'deploy' or 'install' commands are launched. If we want to run different scripts in both nodes, the process consist in installing the script for one worker (in all nodes) and then, modify nodes.cfg file, modify this variable and send an 'update' command in broctl.
  4. sitepolicyworker=my-prot-worker-main.bro my-prot-aux-functions.bro
    
  5. sitepolicymanager: Space-separated list of bro scripts that should be run in the manager node. In my case this script manages notices generated by workers.
  6. sitepolicymanager=manager_notice_policy.bro
    
  7. LogDir: Location of the log directory where log files will be archived each rotation interval.
    LogDir = /mnt/logs
    

Of course, there are many other interesting options that can be modified for BroControl. Have a llo to the BroControl documentation website.

Using a bro analyzer as a plugin in a Bro Cluster

One of the problem I faced was that all bro scripts running in the worker nodes, monitored a proprietary protocol for which I had developed an analyzer as a plugin. If run standalone both in the manager and worker nodes, the script and the proprietary analyzer worked fine. But if run as a cluster, the scripts seemed not to understand proprietary network traffic. After a couple of checks I found that the plugin was not being 'loaded' by bro in the workers. Then I realized that the problem should be the Plugin directory where Bro was looking for the plugin. Soon I found that there are two different options in broctl.cfg file that could help me:

  • Env_Vars:A comma-separated list of environment variables (e.g. env_vars=VAR1=123, VAR2=456) to set on all nodes immediately before starting Bro. Node-specific values (specified in the node configuration file) override these global values.
  • Env_Vars=BRO_PLUGIN_PATH=/home/bro/aux_files/plugin
    
  • SitePluginPath:Directories to search for custom plugins (i.e., plugins that are not included with broctl), separated by colons.
  • SitePluginPath=/home/bro/aux_files/plugin
    

...but somehow, after deploying, it didn't work.

A little bit of research led to the /usr/local/bro/share/broctl/scripts/run-bro script, where I found that apparently only three environment variables were set, regardless of what I wrote in the broctl.cfg file:

...
echo "PATH=${PATH}" >.env_vars
echo "BROPATH=${BROPATH}" >>.env_vars
echo "CLUSTER_NODE=${CLUSTER_NODE}" >>.env_vars
echo "BRO_PLUGIN_PATH=${BRO_PLUGIN_PATH}" >>.env_vars
...

I just added the last line, et voila!, my analyzer was working fine!... well, not so fine. Some thing didn't work. Somehow some events were not noticed to the manager node, some log file were not created in the manager LogDir, and a config file was not read.



The fact of cluster logging

My first move was to read the stderr.log and stdout.log files stored in the manager node BUT, somehow, even if I filled my scripts with 'print' instructions, the stdout.log was empty!...

...until I found the /usr/local/bro/share/bro/base/frameworks/cluster/nodes directory. Here you can find some redef options for the worker, manager and proxy nodes. And one of these options was:

## Don't do any local logging.
redef Log::enable_local_logging = F;

...setting this option to True and deploying again, made the workers to start logging locally in the following directory of the worker nodes:

[7] /home/bro/bro/spool/worker-n/

There I found the reporter.log, that showed me that there was a mistake in one of my bro scripts. Curiously, the reporter.log file in the manager was empty, which means that logs are NOT COPIED from the workers to the manager node. That's the reason why two of my log files did not appear in the manager node but they were in the workers' log [7] directory.

The fact is, log files correspond to the node where you find them. stdout.log of the worker nodes will show the standard output of the bro scripts running in the workers, while stdout.log in the manager correspond to what the manager policy script is sending to the standard output.

Regarding the protocol log files, we find some network traffic messages in the Manager but these are not all the network traffic messages received in the worker, only about 1 out of 10 messages received in the worker nodes are actually logged in the manager, and this is something we still have to understand.



Opening a config file in the workers

My third problem was related with a config file that should be opened both by the workers and the manager bro scripts. I was trying to open it with something like:

Input::add_event([$source="config.cfg", $reader=Input::READER_RAW, $name="conf", $fields=Val, $ev=config_entry]);

The solution came when I realized that I had to use the full file path, which should be the same both in the worker and the manager nodes:

Input::add_event([$source="/home/bro/bro/spool/installed-scripts-do-not-touch/site/config.cfg", $reader=Input::READER_RAW, $name="conf", $fields=Val, $ev=config_entry]);

This made it work.



The cluster bro processes structure

Now I had to be able to send my local worker log files to the manager. First of all I tried to understand the process structure.

In every worker node there are three bro processes:

root@Mario:/usr/local# ps -ef | grep bro
root      25139      1  0 Jun08 ?        00:00:00 /bin/bash /usr/local/bro/share/broctl/scripts/run-bro -1 -i eth0 -U .status -p broctl -p broctl-live -p local -p worker-1 local.bro broctl base/frameworks/cluster my-prot.bro broctl/auto
root      25145  25139 20 Jun08 ?        03:38:50 /usr/local/bro/bin/bro -i eth0 -U .status -p broctl -p broctl-live -p local -p worker-1 local.bro broctl base/frameworks/cluster my-prot.bro broctl/auto
root      25148  25145  0 Jun08 ?        00:00:09 /usr/local/bro/bin/bro -i eth0 -U .status -p broctl -p broctl-live -p local -p worker-1 local.bro broctl base/frameworks/cluster my-prot.bro broctl/auto

So the first was the parent of one of the bro processes which forked to the other one. Parameters where passed to the run-bro script mainly on run bro as nohup with all the same parameters:

...
mybro=${bro}
...
nohup "$mybro" "$@" &
...

So, the question was, why is the working bro process forking?. lsof command was very useful for that:

root@worker-1:/usr/local# lsof | grep 25145 | egrep -v "\.bro|\.so|pipe" | grep 25186
bro:      25145 25186        root  cwd       DIR                8,1      4096     656821 /home/bro/bro/spool/worker-1
bro:      25145 25186        root  rtd       DIR                8,1      4096          2 /
bro:      25145 25186        root  txt       REG                8,1 134900600    1315052 /usr/local/bro/bin/bro
bro:      25145 25186        root    1w      REG                8,1       188     655382 /home/bro/bro/spool/worker-1/stdout.log
bro:      25145 25186        root    2w      REG                8,1        97     655383 /home/bro/bro/spool/worker-1/stderr.log
bro:      25145 25186        root    4u     IPv4             152650       0t0        UDP 192.168.1.10:41394->192.168.1.5:domain 
bro:      25145 25186        root  202u     pack             152653       0t0        ALL type=SOCK_RAW
bro:      25145 25186        root  260r      REG                8,1       739     657284 /home/bro/bro/spool/installed-scripts-do-not-touch/site/config.cfg
bro:      25145 25186        root  272u     unix 0xffff88007a6abb80       0t0     152656 socket
bro:      25145 25186        root  273w      REG                8,1 283722769     656833 /home/bro/bro/spool/worker-1/my-prot.log
bro:      25145 25186        root  279w      REG                8,1    301214     656838 /home/bro/bro/spool/worker-1/communication.log
bro:      25145 25186        root  280w      REG                8,1     42471     656841 /home/bro/bro/spool/worker-1/weird.log
bro:      25145 25186        root  281w      REG                8,1       447     656844 /home/bro/bro/spool/worker-1/reporter.log



root@worker-1:/usr/local# lsof | grep 25148 | egrep -v "\.bro|\.so|pipe" 
bro       25148              root  cwd       DIR                8,1      4096     656821 /home/bro/bro/spool/worker-1
bro       25148              root  rtd       DIR                8,1      4096          2 /
bro       25148              root  txt       REG                8,1 134900600    1315052 /usr/local/bro/bin/bro
bro       25148              root    0u     IPv4             151842       0t0        TCP 192.168.1.10:35948->192.168.1.20:47762 (ESTABLISHED)
bro       25148              root    4u     IPv4             152650       0t0        UDP 192.168.1.10:41394->192.168.1.5:domain 
bro       25148              root  202u     pack             152653       0t0        ALL type=SOCK_RAW
bro       25148              root  260r      REG                8,1       739     657284 /home/bro/bro/spool/installed-scripts-do-not-touch/site/config.cfg
bro       25148              root  273u     unix 0xffff88007a6ab040       0t0     152657 socket
bro       25148              root  279u     IPv4             151845       0t0        TCP 192.168.1.10:57286->192.168.1.20:47761 (ESTABLISHED)
bro       25148              root  284u     IPv4             151850       0t0        TCP *:47763 (LISTEN)
bro       25148              root  285u     IPv6             151851       0t0        TCP *:47763 (LISTEN)

So, the first bro process (parent), is responsible for listening on the monitoring interface and writing local log files, while the second (child) is responsible for communicating with the manager (two different connections) and listening from the proxy.

In the manager node, there are two processes for the proxy and another two for the manager:

root@Manager:/home/bro/site# ps -ef | grep bro
root      38193      1  0 Jun08 ?        00:00:00 /bin/bash /usr/local/bro/share/broctl/scripts/run-bro -1 -U .status -p broctl -p broctl-live -p local -p manager local.bro broctl base/frameworks/cluster notice_policy.bro broctl/auto
root      38199  38193  3 Jun08 ?        00:37:58 /usr/local/bro/bin/bro -U .status -p broctl -p broctl-live -p local -p manager local.bro broctl base/frameworks/cluster notice_policy.bro broctl/auto
root      38201  38199  0 Jun08 ?        00:00:21 /usr/local/bro/bin/bro -U .status -p broctl -p broctl-live -p local -p manager local.bro broctl base/frameworks/cluster notice_policy.bro broctl/auto


root      38236      1  0 Jun08 ?        00:00:00 /bin/bash /usr/local/bro/share/broctl/scripts/run-bro -1 -U .status -p broctl -p broctl-live -p local -p proxy-1 local.bro broctl base/frameworks/cluster local-proxy broctl/auto
root      38242  38236  3 Jun08 ?        00:40:23 /usr/local/bro/bin/bro -U .status -p broctl -p broctl-live -p local -p proxy-1 local.bro broctl base/frameworks/cluster local-proxy broctl/auto
root      38243  38242  0 Jun08 ?        00:00:03 /usr/local/bro/bin/bro -U .status -p broctl -p broctl-live -p local -p proxy-1 local.bro broctl base/frameworks/cluster local-proxy broctl/auto

Netstat showed the open connections among them and the workers.

root@Manager:/home/bro/site# netstat -tupan | grep bro
tcp        0      0 0.0.0.0:47761           0.0.0.0:*               LISTEN      38201/bro       
tcp        0      0 0.0.0.0:47762           0.0.0.0:*               LISTEN      38243/bro       
tcp        0      0 192.168.1.20:47762         192.168.1.10:35948         ESTABLISHED 38243/bro       
tcp        0      0 192.168.1.20:47761         192.168.1.20:38523         ESTABLISHED 38201/bro       
tcp        0      0 192.168.1.20:38523         192.168.1.20:47761         ESTABLISHED 38243/bro       
tcp        0      0 192.168.1.20:47761         192.168.1.11:57110         ESTABLISHED 38201/bro       
tcp        0      0 192.168.1.20:47762         192.168.1.11:45263         ESTABLISHED 38243/bro       
tcp        0      0 192.168.1.20:47761         192.168.1.10:57286         ESTABLISHED 38201/bro       
tcp6       0      0 :::47761                :::*                    LISTEN      38201/bro       
tcp6       0      0 :::47762                :::*                    LISTEN      38243/bro       
udp        0      0 192.168.1.20:44445         192.168.1.5:53             ESTABLISHED 38242/bro       
udp        0      0 192.168.1.20:35156         192.168.1.5:53             ESTABLISHED 38199/bro  

So, to summarize:

  • The proxy (child process) has one connection to every worker node.
  • The manager (child process) has one connection to every worker node.
  • The proxy and the manager (boy child processes) are connected through a socket (ports 47761 to 38523, in this case)
  • Both proxy and manager parents are more interested in logging processes (they are resposible for writing logs to disk) and DNS resolution

Fine, but we still don't know where are those proprietary logs lost. Installed tcpdump and it quickly showed me that the proprietary protocol logs were being sent from the worker to the manager node and received by the manager child process.

So it seemed the problem should be in my manager policy script. It just implemented the hook of Notice::policy...

hook Notice::policy(not:Notice::Info)

lunes, 29 de octubre de 2018

The APX logic file format

The APX file format

The APX File has a variable size because it stores a lot of different information.

In general terms, the APX file is composed by a first section with general information of the strategy (timestamps, versions, owners, CRCs, the internal strategy password). This section is about 2000 bytes long.

The next section determines the number of Holding registers (MW%), register constants (KW%) and coils (M%) and store all the constant values. This section size depends on the number of constants specified.

The next section stores the error messages that could send the PLC to Unity Pro.

The next section stores network information (IPs, network masks, SNMP configuration, NTP configuration, SMTP configuration, etc.) of all the networking modules associated with the PLC.

The next section stores the strategy in binary format. It also stores chunks of bytes which are ZLIB compressed, when uncompressed they turned to be XML files with configuration information.

So the main structure is:

  1. General information section
  2. Registers and coils
  3. Error messages
  4. Network information
  5. Strategy in binary format


General information section

This section comprises of a number of subsections, separated by a “0E <16-bit CRC> 00 00” separator.

The first subsections are the following:

As we can see, these first blocks, start with 2 or 3 ASCII character (APX subsection, SD subsection, RT subsection…)

At the end of all these blocks, we can see the signature prevoiously mentioned (“E0 16-bit CRC 00 00”).

In the first block, bytes 11 to 15 are 4 byte CRC, in this case “00 C8 2D 0D” that will be repeated in 4 or 5 places of the first section.

We think that 16-bit-CRC values we find all along the APX file validate the starting subsection (they always appear in the beginning of a subsection (or the end of the previous one, which is the same).



Subsections This first subsection is two bytes smaller when it belongs to the TSX premium PLC. The two different bytes seem to be two “00” bytes before the end of the subsection (before “93E0”).

The second subsection is also four bytes smaller when it belongs to the TSX Premium PLC.

Strange enough, the third subsection (corresponding to “RT” ASCII characters) is much longer in the TSX PLC ( 110 vs 64 bytes).

This is because in a TSX PLC APX file, subsections 4 and 5 do not exist and its information is stored (in short) in those extra 56 bytes (prohect date and timestamp, versions, etc.).

This would be the fourth subsection:

This is the fifth subsection:

This subsection stores project information like timestamps, versions, etc, and it's accessed when a message “00 03 00” is sent to the PLC.

And this is the sixth subsection, it also stores some information about the project.

After the project version information come 1024 (0400h) blank bytes intended to store the project description.

And these are the following subsections. Note that Subsection 7 is sent when a “00 03 04” request is done.

However this is not the structure of this section if take into account how the file is read or write in the upload / download process:

The thin blue lines indicate how the bytes are read or write during the strategy upload/download process. It has nothing to do with the separators previously mentioned.

In the red boxes we can see the four-byte-CRC value which is repeated at least 4 time all along the APX file. The small red boxes are the 16-bit CRC values. These 16 bit CRC change on every regeneration of the project, even when the project has NOT changed at all.



Section 2. Registers and coils

In section 2 there are no subsections any more.

Starting in offset AA0h come a bunch of bytes that define the number of bytes stored by holding registers (MW%), constants (KW%, in offset B2 – FF 01 – 1023 bytes – 512 register constants) and coils (M%).

After B00 line come as many bytes as indicated in the KW% constant value (0b02h). In this case they are 01 FF (little endian) bytes. That means that the register constants will be stored in the APX file from 0B0Ch offset to 0D0Bh offset.



Section 3. Error messages

Starting on 0D0Ch, start a block with all error messages:

This block ends with four bytes set to FF (first black box):

It's important to note that both this section and the next start with four bytes “01 00 00 00”, and that subsections seem to start “01 00 A0 00”



Section 4. Network information

Following the end of the error message list, we can see two subsection separators and in the third subsection we can see, in the three coloured boxes the internal IPs of our PLC (in little endian format). In this case “CD 0D 1E 0A” stands for 10.30.13.205, “0A 1E 0D 01” stands for 10.30.13.1 (the gateway IP) and “00 FF FF FF” is the netmask, 255.255.255.0.

After more than 3000 “00” bytes come the next network information.

In offset 2350h (in our case) appear the SNMP configuration, with snmp keys (“public1, public2, public3”), SysLocation (“KKKKKKK...”) and SysContact data (“123456789...”), administration IP and other SNMP information.

Next comes SMTP information with the SMTP server IP address, port, username (“root”), password (“123456789012”). It also stores SMTP From, To and subject information.

This information could allow a malicious attacker to send emails on behalf the PLC.

Then it comes a section of repetitive characters:

In blue we can see the TSX automate APX File and in white the Modicon M340 one. There are some differences but it's a list of “DC053C” values.

From my point of view, this is a way of synchronization.

If the strategy has several cards configured, a “FF FF FF FF” separator comes and the process start again.



Section 5. Binary Strategy code

After the Network information come what we think is the strategy binary code and some blobs of ZLIB bytes.

This section is divided in “PK” subsections:

As we can see after the corresponding “?? E0 CRC16 00 00” signature, comes a “PK” signature an another PK, compressed subsection comes.

This occurs up to 9 times until the end of OUR strategy. Some of these PK files seem to be compressed data, other, with this aspect seem binary data:

The PK signatures appear in our strategy in offsets:

  • 000050F0h
  • 000052B0h
  • 00005C10h
  • 00005CF6h
  • 000064C4h
  • 000066A5h
  • 000066FAh
  • 000069C4h
  • 00006AEDh
  • 000010065h
  • 000010207h

As we can see, their size is small except for one, which is the only one with binary aspect.

Using the binwalk tool it found at least 5 ZLIB blobs, stored in two different PK subsections.

When decompressed these ZLIB blobs found that some of them were compressed XML files, while other stored ST functions:

On the big PK subsection we can even understand the binary code. We tried a simple program and tried to find it in the binary code. And we found it:

Written in our own assembler language we could understand where was it stored and how was it run.



Changes in the APX after a regeneration with no changes at all

We have detected that regenerating a project with no change in it, the APX file generated contains 36 different bytes.

The different bytes are the following:

APX subsection
00000Bh (4 bytes) → CRC32 value

SD Subsection
00003Ch (2 bytes) → SD subsection CRC16 value
000067h (4 bytes) → Copy of the CRC32 value
00006Eh (1 byte) → Regeneration Version number

RT Subsection
000164h (2 bytes) → RT subsection CRC16 value

000284h (2 bytes) → 4th Subsection CRC16 value
0002AFh (3 bytes) → Timestamp
0002B7h (3 bytes) → same timestamp
0002E5h (4 bytes) → Copy of the CRC32 value
0002EDh (4 bytes) → Copy of the CRC32 value
0002F1h (4 bytes) → Copy of the CRC32 value
000301h (1 byte) → Unknown
000355h (1 byte) → Version number
000359h (1 byte) → Unknown


Modification of the file

We were unable to upload an strategy to the PLC with ANY modification. And this must be caused by the CRC checks.

¿Why do we know it's a CRC value?

Running an strings command against the Firmware binary file we find the following function names (related with CRC):

It's clear that CRC16 flags and CRC 32 values are computed all along the APX File.

I tried to calculate the CRC 32 value of entire file, starting from byte 1 to byte 3000. None of them did the trick.

I also tried to calculate 16-bit CRC values of the different subsection. Couldn't get the correct CRC.

As mentioned earlier, we think that 16-bit-CRC values we find all along the APX file validate the starting subsection (they always appear in the beginning of a subsection (or the end of the previous one, which is the same).

sábado, 30 de junio de 2018

Snort rules for modbus and Unity traffic

Snort rules for industrial traffic are important to detect any strange behaviour. DigitalBond did already detect a number of rules which are included at the bottom of this post. However the number of snort rules detected here is much higher.

Taking a look at the Modbus specification and after my research in the Unity/UMAS protocol I have detected a total of 51 snort rules that detect anomalous Modbus and Unity traffic. This is the list of rules:

This is the whole listing:

Modbus protocol rules

RULE 1

Explanation: REQUEST MODBUS 0x01 --> BYTES 4-5 ==> Values should not be above 07D0h -->See Pag 12 modbus specification

alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|";
offset:2; depth:2; content:"|01|";offset:7; depth:1; byte_test: 2,>,0x07D0,10;
msg="Modbus TCP 0x01: Too many coils to read requested. Possible DoS";
classtype:attempted-dos; sid:987000001; rev:1; priority:1;)


RULE 2

Explanation: RESPONSE MODBUS 0x81 --> BYTE 2 (EXCEPTION CODE) ==> 0x01 o 0x02 o 0x03 o 0x04 --> See Pag 12 modbus specification

alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|81|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x01: Response exception code not allowed"; sid:987000002; rev:1; priority:1;)


RULE 3

Explanation: REQUEST MODBUS 0x02 --> BYTES 4-5 ==> Should not be higher than 07D0h -->See Pag 13 modbus specification

alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|02|"; offset:7; depth:1; byte_test: 2,>,0x07D0,10; msg="Modbus TCP 0x02: Too many inputs to read requested. Possible DoS"; classtype: attempted-dos; sid:987000003; rev:1; priority:1;)

RULE 4



Explanation --> RESPONSE MODBUS 0x82 --> BYTE 2 (EXCEPTION CODE) ==> 0x01 o 0x02 o 0x03 o 0x04 --> See Pag 13 modbus specification

alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|82|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x02: Response exception code not allowed"; sid:987000004; rev:1; priority:1;)



RULE 5

Explanation: REQUEST MODBUS 0x03 --> BYTES 4-5 ==> Should not be higher than 0x007D --> See Pag 15 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|03|"; offset:7; depth:1; -->  BYTE_test: 2,>,0x007D,10; msg="Modbus TCP 0x03: Too many holding registers to read requested. Possible DoS"; classtype: attempted-dos;sid:987000005; rev:1; priority:1;)




RULE 6

Explanation --> RESPONSE MODBUS 0x83 --> BYTE 2 (EXCEPTION CODE) ==> 0x01 o 0x02 o 0x03 o 0x04 --> See Pag 15 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|83|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x03: Response exception code not allowed"; sid:987000006; rev:1; priority:1;classtype: non-standard-protocol;)




RULE 7

Explanation: REQUEST MODBUS 0x04 --> BYTES 4-5 ==> Should not be higher than 0x007D --> See Pag 16 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|04|"; offset:7; depth:1; -->  BYTE_test: 2,>,0x007D,10; msg="Modbus TCP 0x04: Too many input registers to read requested. Possible DoS"; classtype: attempted-dos; sid:987000007; rev:1; priority:1;)




RULE 8

Explanation --> RESPONSE MODBUS 0x84 --> BYTE 2 (EXCEPTION CODE) ==> 0x01 o 0x02 o 0x03 o 0x04 --> See Pag 16 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|84|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x04: Response exception code not allowed"; classtype: non-standard-protocol; sid:987000008; rev:1; priority:3;)




RULE 9

Explanation: REQUEST MODBUS 0x05 --> BYTES 4-5 ==> Allowed values 0x0000 or 0xFF00 --> See Pag 17 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|05|"; offset:7; depth:1; content:"!|00 00|FF 00|"; offset:10, depth:2;  msg="Modbus TCP 0x05: Coil output value not allowed"; sid:987000009; rev:1; priority:1;)




RULE 10

Explanation --> RESPONSE MODBUS 0x05 --> BYTE 4-5 ==> Allowed values: 0x0000 or 0xFF00 --> See Pag 18 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|05|"; offset:7; depth:1; content:"!|00 00|FF 00|"; offset:10, depth:2;  msg="Modbus TCP 0x05: Coil value incorrect"; sid:987000010; rev:1; priority:1;)




RULE 11

Explanation --> RESPONSE MODBUS 0x85 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values 0x01 or 0x02 or 0x03 or 0x04 --> See Pag 18 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|85|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x05: Response exception code not allowed"; sid:987000011; rev:1; priority:3;classtype: non-standard-protocol;)




RULE 12

Explanation --> RESPONSE MODBUS 0x86 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 1 to 4 --> See Pag 19 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|86|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x06: Response exception code not allowed"; sid:987000012; rev:1; priority:3;classtype: non-standard-protocol;)




RULE 13

Explanation --> RESPONSE MODBUS 0x87 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 01 or 04 --> See Pag 20 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|87|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x07: Response exception code not allowed"; sid:987000013; rev:1; priority:3;classtype: non-standard-protocol;)




RULE 14

Explanation --> RESPONSE MODBUS 0x88 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 01 or 03 or 04 --> See Pag 22 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|88|"; offset:7; depth:1; content:!"|01|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x08: Response exception code not allowed"; sid:987000014; rev:1; priority:3;classtype: non-standard-protocol;)




RULE 15

Explanation --> RESPONSE MODBUS 0x8B --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 01 or 04 --> See Pag 25 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|8B|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x0B: Response exception code not allowed"; sid:987000015; rev:1; priority:1;)




RULE 16

Explanation --> RESPONSE MODBUS 0x8C --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 01 or 04 --> See Pag 27 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|8C|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x0C: Response exception code not allowed"; sid:987000016; rev:1; priority:3;classtype: non-standard-protocol;)




RULE 17

Explanation: REQUEST MODBUS 0x0F --> BYTES 4-5 ==> Should not be higher than 0x07B0 --> See Pag 29 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|0F|"; offset:7; depth:1; -->  BYTE_test: 2,>,0x07B0,10; msg="Modbus TCP 0x0F: Too many coils to write requested"; sid:987000017; rev:1; priority:1;)




RULE 18

Explanation --> RESPONSE MODBUS 0x0F --> BYTES 4-5 ==> Should not be higher than 0x07B0 --> See Pag 29 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|0F|"; offset:7; depth:1; -->  BYTE_test: 2,>,0x07B0,10; msg="Modbus TCP 0x0F: Too many coils responded"; sid:987000018; rev:1; priority:1;)




RULE 19

Explanation --> RESPONSE MODBUS 0x8F --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x04 --> See Pag 29 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|8F|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x0F: Response exception code not allowed"; sid:987000019; rev:1; priority:3;classtype: non-standard-protocol;)




RULE 20

Explanation: REQUEST MODBUS 0x10 --> BYTES 4-5 ==> Should not be over 0x007B --> See Pag 29 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|10|"; offset:7; depth:1; -->  BYTE_test: 2,>,0x007B,10; msg="Modbus TCP 0x10: Too many registers to write requested"; sid:987000020; rev:1; priority:1;)




RULE 21

Explanation --> RESPONSE MODBUS 0x10 --> BYTE 4-5 ==> Should not be higher than 0x007B --> See Pag 31 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|0F|"; offset:7; depth:1; -->  BYTE_test: 2,>,0x007B,10; msg="Modbus TCP 0x10: Too many registers responded"; sid:987000021; rev:1; priority:1;)




RULE 22

Explanation --> RESPONSE MODBUS 0x90 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x04 --> See Pag 31 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|90|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x10: Response exception code not allowed"; sid:987000022; rev:1; priority:3;classtype: non-standard-protocol;)




RULE 23

Explanation --> RESPONSE MODBUS 0x91 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 0x01 or 0x04 --> See Pag 32 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|91|"; offset:7; depth:1; content:!"|01|04|"; offset:8, depth:1;  msg="Modbus TCP 0x11: Response exception code not allowed"; sid:987000023; rev:1; priority:1;)




RULE 24

Explanation: REQUEST MODBUS 0x14 --> BYTE 2 ==> Allowed values: From 0x07 to 0xF5 --> See Pag 33 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|14|"; offset:7; depth:1; -->  BYTE_test: 1,>,0xF5,8; msg="Modbus TCP Request 0x14: message -->  BYTE count incorrect"; sid:987000124; rev:1; priority:1;)
alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|14|"; offset:7; depth:1; -->  BYTE_test: 1,<,0x07,8; msg="Modbus TCP Request 0x14: message -->  BYTE cunt incorrect"; sid:987000224; rev:1; priority:1;)




RULE 28

Explanation --> RESPONSE MODBUS 0x14 --> BYTE 2 ==> Allowed values: 0x07 to 0xF5 --> See Pag 33 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|14|"; offset:7; depth:1; -->  BYTE_test: 1,>,0xF5,8; msg="Modbus TCP Response 0x14: message -->  BYTE count incorrect"; sid:987000128; rev:1; priority:1;)
alert tcp $ $MODBUS_PLC 502 -> EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|14|"; offset:7; depth:1; -->  BYTE_test: 1,<,0x07,8; msg="Modbus TCP Response 0x14: message -->  BYTE cunt incorrect"; sid:987000228; rev:1; priority:1;)




RULE 31

Explanation --> RESPONSE MODBUS 0x94 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x04 or 0x08 --> See Pag 33 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|94|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x14: Response exception code not allowed"; sid:987000031; rev:1; priority:3;classtype: non-standard-protocol;)




RULE 32

Explanation: REQUEST MODBUS 0x15 --> BYTE 2 ==> Allowed values: 0x09 to 0xFB --> See Pag 34 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|15|"; offset:7; depth:1; -->  BYTE_test: 1,>,0xFB,8; msg="Modbus TCP Request 0x15: message -->  BYTE count incorrect"; sid:987000132; rev:1; priority:1;)
alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|15|"; offset:7; depth:1; -->  BYTE_test: 1,<,0x09,8; msg="Modbus TCP Request 0x15: message -->  BYTE cunt incorrect"; sid:987000232; rev:1; priority:1;)




RULE 36

Explanation --> RESPONSE MODBUS 0x15 --> BYTE 2 ==> Allowed values: 0x09 to 0xFB --> See Pag 35 modbus specification

 alert tcp $MODBUS_PLC 502 -> EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|15|"; offset:7; depth:1; -->  BYTE_test: 1,>,0xFB,8; msg="Modbus TCP Response 0x15: message -->  BYTE count incorrect"; sid:987000132; rev:1; priority:1;)
alert tcp $ $MODBUS_PLC 502 -> EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|15|"; offset:7; depth:1; -->  BYTE_test: 1,<,0x09,8; msg="Modbus TCP Response 0x15: message -->  BYTE cunt incorrect"; sid:987000232; rev:1; priority:1;)



RULE 40

Explanation --> RESPONSE MODBUS 0x95 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x04 or 0x08 --> See Pag 35 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|95|"; offset:7; depth:1; content:!"|01|02|03|04|08|"; offset:8, depth:1;  msg="Modbus TCP 0x15: Response exception code not allowed"; sid:987000040; rev:1; priority:3;classtype: non-standard-protocol;)




RULE 41

Explanation --> RESPONSE MODBUS 0x96 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x04 --> See Pag 37 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|96|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x16: Response exception code not allowed"; sid:987000041; rev:1; priority:3; classtype: non-standard-protocol;)




RULE 42

Explanation: REQUEST MODBUS 0x17 --> BYTES 4 and 5 ==> Allowed values: 0x0001 to 0x007D --> See Pag 38 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|17|"; offset:7; depth:1; -->  BYTE_test: 1,>,0x7D,10; msg="Modbus TCP Request 0x17: incorrect register count to read"; sid:987000142; rev:1; priority:1;)
alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|17|"; offset:7; depth:1; -->  BYTE_test: 1,<,0x01,10; msg="Modbus TCP Request 0x17: incorrect register count to read"; sid:987000242; rev:1; priority:1;)



RULE 43

Explanation: REQUEST MODBUS 0x17 --> BYTES 8 and 9 ==> Allowed values: 0x0001 a 0x0079 --> See Pag 38 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|17|"; offset:7; depth:1; -->  BYTE_test: 1,>,0x79,14; msg="Modbus TCP Request 0x17: incorrect register count to write"; sid:987000143; rev:1; priority:1;)
 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|17|"; offset:7; depth:1; -->  BYTE_test: 1,<,0x01,14; msg="Modbus TCP Request 0x17: incorrect register count to write"; sid:987000243; rev:1; priority:1;)




RULE 44

Explanation --> RESPONSE MODBUS 0x97 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x04 --> See Pag 39 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|97|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x17: Response exception code not allowed"; sid:987000044; rev:1; priority:3; classtype: non-standard-protocol;)




RULE 45

Explanation --> RESPONSE MODBUS 0x18 --> BYTES 2y3 ==> Allowed values: Should be lower than 0x0041 --> See Pag 41 modbus specification

 alert tcp $MODBUS_PLC 502 -> EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|18|"; offset:7; depth:1; -->  BYTE_test: 1,>,0x41,8; msg="Modbus TCP Response 0x18: message -->  BYTE count incorrect"; sid:987000145; rev:1; priority:1;)




RULE 46

Explanation --> RESPONSE MODBUS 0x18 --> BYTES 4y5 ==> Allowed values: 0x0001 to 0x001F --> See Pag 41 modbus specification

 alert tcp $MODBUS_PLC 502 -> EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|18|"; offset:7; depth:1; -->  BYTE_test: 1,>,0x1F,10; msg="Modbus TCP Response 0x18: message FIFO count incorrect"; sid:987000146; rev:1; priority:1;)
 alert tcp $ $MODBUS_PLC 502 -> EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|18|"; offset:7; depth:1; -->  BYTE_test: 1,<,0x01,10; msg="Modbus TCP Response 0x15: message FIFO count incorrect"; sid:987000246; rev:1; priority:1;)




RULE 47

Explanation --> RESPONSE MODBUS 0x98 --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x04 --> See Pag 41 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|98|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x18: Response exception code not allowed"; sid:987000047; rev:1; priority:3; classtype: non-standard-protocol;)




RULE 48

Explanation: REQUEST MODBUS 0x2B --> BYTE 2 ==> Allowed values: 0x0D or 0x0B --> See Pag 43 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|2B|"; offset:7; depth:1; content:"!|0D|0B|"; offset:8, depth:1;  msg="Modbus TCP Request 0x2B: Incorrect MEI Type"; sid:987000048; rev:1; priority:3; classtype: non-standard-protocol;)




RULE 49

Explanation --> RESPONSE MODBUS 0x2B --> BYTE 2 ==> Allowed values: 0x0D or 0x0B --> See Pag 43 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|2B|"; offset:7; depth:1; content:"!|0D|0B|"; offset:8, depth:1;  msg="Modbus TCP Response 0x2B: Incorrect MEI Type"; sid:987000049; rev:1; priority:3; classtype: non-standard-protocol;)




RULE 50

Explanation --> RESPONSE MODBUS 0xAB --> BYTE 2 (EXCEPTION CODE) ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x04 --> See Pag 44 modbus specification

 alert tcp $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|AB|"; offset:7; depth:1; content:!"|01|02|03|04|"; offset:8, depth:1;  msg="Modbus TCP 0x2B: Response exception code not allowed"; sid:987000050; rev:1; priority:3; classtype: non-standard-protocol;)




RULE 51

Explanation: REQUEST MODBUS 0x2B. --> BYTE 2=0x0E --> BYTE 3 ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x04 --> See Pag 44 modbus specification

 alert tcp $EXTERNAL any -> $MODBUS_PLC 502 (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|2B|"; offset:7; depth:1; content:"|0E|"; offset:8; depth:1; content:"!|01|02|03|04|"; offset:9, depth:1;  msg="Modbus TCP Request 0x2B: Incorrect Read Device ID Code"; sid:987000051; rev:1; priority:3; classtype: non-standard-protocol;)




RULE 52

Explanation --> RESPONSE MODBUS 0x2B. --> BYTE 2=0x0E --> BYTE 3 ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x04 --> See Pag 44 modbus specification

 alert tcp  $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|2B|"; offset:7; depth:1; content:"|0E|"; offset:8; depth:1; content:"!|01|02|03|04|"; offset:9, depth:1;  msg="Modbus TCP Response 0x2B: Incorrect Read Device ID Code"; sid:987000052; rev:1; priority:3; classtype: non-standard-protocol;)




RULE 53

Explanation --> RESPONSE MODBUS 0x2B. --> BYTE 2=0x0E --> BYTE 4 ==> Allowed values: 0x01 or 0x02 or 0x03 or 0x81 or 0x82 or 0x83 --> See Pag 44 modbus specification

 alert tcp  $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|2B|"; offset:7; depth:1; content:"|0E|"; offset:8; depth:1; content:"!|01|02|03|81|82|83|"; offset:10, depth:1;  msg="Modbus TCP Response 0x2B: Incorrect Conformity Level"; sid:987000053; rev:1; priority:3; classtype: non-standard-protocol;)


 


RULE 54

Explanation --> RESPONSE MODBUS 0x2B. --> BYTE 2=0x0E --> BYTE 5 ==> Allowed values: 0x00 o 0xFF --> See Pag 44 modbus specification

 alert tcp  $MODBUS_PLC 502 -> $EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; content:"|2B|"; offset:7; depth:1; content:"|0E|"; offset:8; depth:1; content:"!|00|FF|"; offset:11, depth:1;  msg="Modbus TCP Response 0x2B: Incorrect Conformity Level"; sid:987000054; rev:1; priority:3; classtype: non-standard-protocol;)




RULE 55

Explanation --> RESPONSE MODBUS MAYOR QUE 0x80 --> BYTE 2 ==> Allowed values: Should be lower than 0x0B --> See Pag 49 modbus specification

 alert tcp $MODBUS_PLC 502 -> EXTERNAL any (flow:from_client, established; content:"|00 00|"; offset:2; depth:2; -->  BYTE_test: 1,>,0x80,7; -->  BYTE_test: 1,<,0x0B,8; msg="Modbus TCP: Incorrect exception code"; sid:987000155; rev:1; priority:1;)

Unity protocol rules

RULE 56

Explanation: REQUEST MODBUS 0x5A --> BYTE 3=0x23 --> System Bit or Word Modification

 alert tcp any any -> any 502 (msg:"Schneider PLC UMAS Write System bit/word request";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|23|";offset:9;depth:1;sid:987000110;)



RULE 57

Explanation: REQUEST MODBUS 0x5A --> BYTE 3=0x30 --> Strategy upload request

 alert tcp any any -> any 502 (msg:"Schneider PLC UMAS Initialize strategy upload request";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|30|";offset:9;depth:1;sid:987000111;)



RULE 58

Explanation: REQUEST MODBUS 0x5A --> BYTE 3=0x33 --> Strategy upload start

 alert tcp any any -> any 502 (msg:"Schneider PLC UMAS Initialize strategy download request";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|33|";offset:9;depth:1;sid:987000112;)



RULE 59

Explanation: REQUEST MODBUS 0x5A --> BYTE 3=0x36 --> BYTE4=0x02 --> Restore from backup request

 alert tcp any any -> any 502 (msg:"Schneider PLC UMAS strategy restore backup request";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|36 02|";offset:9;depth:2;sid:987000113;)



RULE 60

Explanation: REQUEST MODBUS 0x5A --> BYTE 3=0x36 --> BYTE4=0x04 --> Remove backup request

 alert tcp any any -> any 502 (msg:"Schneider PLC UMAS strategy remove backup request";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|36 04|";offset:9;depth:2;sid:987000114;)



RULE 61

Explanation: REQUEST MODBUS 0x5A. --> BYTE 3=0x40 --> PLC Start request

 alert tcp any any -> any 502 (msg:"Schneider PLC(Quantumn) uses function code 90 for communications the Unity pro software/Set PLC CPU STOP";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|40|";offset:9;depth:1;sid:114;)



RULE 62

Explanation: REQUEST MODBUS 0x5A. --> BYTE 3=0x41 --> PLC Stop request

 alert tcp any any -> any 502 (msg:"Schneider PLC(Quantumn) uses function code 90 for communications the Unity pro software/Set PLC CPU Restart";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|41|";offset:9;depth:1;sid:115;)