Solidshield Systemic
Overview
Solidshield Systemic enables a strong baseline protection for binaries and can be used by itself or complemented by Solidshield code protection modes. Binaries are protected in confidentiality and integrity on both cold storage and at run-time, featuring anti-dumping, run-time integrity checks and protection of dependencies countering both static and dynamic analysis attacks.
Introduction
Solidshield Systemic works by encrypting the binary with a symmetric (AES) key and signing encrypted data with a private (RSA) key.
Both keys are supplied at protection time, when binary is loaded at run-time, the protected program does the following:
- Verifies the signature of encrypted data using the public RSA signing key
- Decrypts the encrypted data (code and read-only data) using the symmetric key
RSA public key can be supplied as an environment variable or hardcoded inside the binary. AES symmetric key can be obfuscated and embedded inside the binary, manipulated only through the Solidshield Virtual Machine, to maximize its confidentiality.
When used together with Solidshield Activation, AES decryption key is shipped inside the hardware-dependent unlock token, assuring the confidentiality of the binary on non-activated environments.
To go beyond the integrity check at launch, Systemic can trigger checks at run-time without impacting performances.
Supported targets
- ELF x86-64
- ELF x86
- PE x86
- PE x86-64
- Java
Run-time integrity
To implement run-time security, standard resolution technique of imported functions is replaced by Solidshield obfuscated code, realizing a three-fold objective:
- Anti-dumping: saving a decrypted binary from memory will result in code that is bound to the specific run-time context and not reusable even on the same machine.
- Run-time integrity: Systemic self-profiling code allows to dynamically trigger integrity checks conditionally to run-time usage intensity of each symbol/function
- Dependencies confidentiality: the list of imported function is no longer visible with a simple static analysis binary, but require dynamic analysis.
Metadata
Systemic allows to embed encrypted metadata inside binaries, to insert watermarks or other meaningful information that can be accessed from protected binaries by providing the decryption key as environment variable.
By default it includes MD5 of input file, protection date, wrapper version and the output of ldd
and readelf --dyn-syms
commands, to list original library dependencies and original dynamic symbols table.
Example
# ./checksummer test-data
Checksum result: 1F
# SLD_MD_KEY="wrong_decryption_key" ./checksummer
[process exits with status code 124]
# SLD_DEBUG=1 SLD_MD_KEY="wrong_decryption_key" ./checksummer
Metadata decryption FAILED, check MD key.
[process exits with status code 124]
# SLD_MD_KEY="897B93945372A76001F3014B2B8062891E610D79F427189E1F49137DA88651F0" ./checksummer
Solidshield v8.7.0.0, protection on 2019-04-23 10:11:11
Input file MD5: b112cac99906a711d6bc49e3ca5ae5b2
Original shared object dependencies
linux-vdso.so.1 (0x00007ffe409b1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2cc8832000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2cc8c23000)
Symbol table '.dynsym' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND clock@GLIBC_2.2.5 (2)
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND close@GLIBC_2.2.5 (2)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND read@GLIBC_2.2.5 (2)
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
6: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND open@GLIBC_2.2.5 (2)
8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fwrite@GLIBC_2.2.5 (2)
9: 0000000000601060 8 OBJECT GLOBAL DEFAULT 25 stderr@GLIBC_2.2.5 (2)
Custom metadata:
Dear Solidshield,
this protected version was made for your eyes only.
Technical details
Dynamic adjustments
Systemic dynamically adjusts import protection at run-time, by disabling the feature for each import that is invoked too frequently.
Note
This adaptive regulation uses default preset values tweaked to optimize most use-cases, but they can be overridden to deal with any corner case.
Function invocation frequency is measured every SLD_IW_BURSTSSAMPLES samples andanti-dumping, run-time integrity checks and protection of dependencies countering both static and dynamic analysis attacks. Introduction
anti-dumping, run-time integrity checks and protection of dependencies countering both static and dynamic analysis attacks. Introduction
anti-dumping, run-time integrity checks and protection of dependencies countering both static and dynamic analysis attacks. Introduction
every time the invocation rate for a sample exceeds the allowed threshold SLD_IW_MAXCALLSSEC, the violation counter for the symbol is incremented. When this counter exceeds amount of allowed excesses SLD_IW_MAXBURSTS, the treatment for this function will be disabled entirely.
Protection parameters
Description | SSP Project Field | sldcmd Parameters |
---|---|---|
Enable systemic | "systemic": true | false | -systemic |
Enable anti-dumping, run-time integrity via protection of imports | "wrapImports": true | false | -wrapimports |
Signing private .pem key content | "signingPrivate": "-----BEGIN RSA PRIVATE KEY-----..." | |
Signing public .pem key content | "signingPublic": "-----BEGIN PUBLIC KEY-----" | |
Full path for the signing private .pem key file | -sys-sig-pri "<PEMfilePath>" |
|
Full path for the signing public .pem key file | -sys-sig-pub "<PEMfilePath>" |
|
Hex string representing the symmetric encryption key | "encryptionSymmetricKey": "" | -sys-sym-key "<hexKey, eg: A1B2C3...>" |
String containing custom metadata to encrypt inside the binary | "metadata": "" | -sys-metadata "<multiline string>" |
AES-256-CBC encryption key string used to encrypt metadata | "metadatakey": "" | -sys-metadata-key "<string>" |
Run-time parameters
Environment variable | Description |
---|---|
SLD_SYSTEMIC_VERIFY_KEY | Path pointing to the PEM file corresponding to the Public RSA verify key |
SLD_MD_KEY | String key used to decrypt metadata embedded at protection time. If the key is supplied the executable will print decrypted metadata end exit the process with error code 0. Otherwise will behave normally. |
**SLD_DEBUG ** | If set to "1" a verbose output is printed to stdout in case of error, to complement the exit code with human-friendliness. |
Tweak mode parameters
TWEAK mode environment var | Description |
---|---|
SLD_PROFILE_LOGFILE | Path to the log file used to append execution information. |
SLD_IW_BURSTSSAMPLES | The amount of invocations used to sample the elapsed time. (default value 100) |
SLD_IW_MAXCALLSSEC | The maximum amount of calls per second, after which the violation counter will be incremented. (default value 20) |
SLD_IW_MAXBURSTS | The maximum amount of violations tolerated, before disabling the treatment for the import. (default value 3) |
Error Exit codes
Exit Code | Description |
---|---|
120 | Error verifying signature, possibly public key was either wrong or not supplied. |
121 | Could not change memory protection (either writeable before decrypting or non-writeable after decryption) |
122 | Error when performing symmetric decryption. Possible HMAC mismatch. |
124 | Error when decrypting metadata with supplied key. Check the SLD_MD_KEY. |
Command-line usage examples
Providing everything as command-line argument, without an existing SSP project file:
# connection detail
serverHost=10.0.2.104:443
username="admin@solidshield.com"
password="demoadmin"
# systemic encryption symmetric AES key
aesKey=E76B2413958B001EE76B2413958B001EE76B2413958B001EE76B2413958B001E
./sldcmd-lin64.exe -i "tests/sortingtest2.exe" -o "out/" -h "$serverHost" -n "Test Product" -u "$username" -w "$password" -systemic -wrapimports -sys-sig-pub "keys/signing-public.pem" -sys-sig-pri "keys/signing-private.pem" -sys-sym-key "$aesKey"