Tiny project (STB-like header-only, 0 dependencies) for data obfuscation. Projects aims to make lightweight stealth obfuscation protocol without any signatures. Obfuscated data seems to be random to 3-party viewer (e.g. DPI/IDS)
API is extremly simple, here goes example for obfuscating data:
// Storage for output obfuscated data
uint8_t *obfuscated = NULL;
// Length of the output on success
// -1 on failure
ssize_t len = xobfs_obfs(
(uint8_t *)msg, sizeof(msg), // data: len of the data
(uint8_t *)psk, strlen(psk), // key: len of the key
&obfuscated // where to store output
);
if (len < 0) {
fprintf(stderr, "[main] failed to call xobfs_obfs\n");
return -1;
}
... // do something with obfuscated data
// was allocated in xobfs_obfs
free(obfuscated);Each call of xobfs_obfs will produce new result, with different size.
And de-obfuscation is basicly the same, just:
- change
msgandsizeof(msg)toobfs_dataandobfs_len(get it from network for example, from xobfs_obfs function) - change
xobfs_obfstoxobfs_deobfs - keep PSK the same
When developing such protocols will be very useful tool for detecting collisions between results. Here quick example on how to do that:
./scripts/build # build the test
./bin/xobfs_test > ./logs.txt
python ./entropy_test.py
python ./repeating_test.pyIf repeating_test script will show 0 substrings or about 5 substrings - that's good result, otherwise protocol is unsafe.
NOTICE!
repeating_testscript can use about 14GB of RAM Decrease number of iterations or length of the message to reduce RAM usage
Main API provides 2 functions:
-
xobfs_obfs: Obfuscates incomingdata, using givenpskuint8_t *data: Plain text/bytes, that needs to be obfuscatedsize_t data_len: Length of incoming datauint8_t *psk: Pre-shared keysize_t psk_len: Length of the keyuint8_t **output: Pointer to variable to store output
-
xobfs_deobfs: De-obfuscates givendatawithpsk. PSK needs to be the same as inxobfs_obfsuint8_t *obfs_data: Obfuscated datasize_t obfs_len: Length of incoming datauint8_t *psk: Pre-shared keysize_t psk_len: Length of the keyuint8_t **output: Pointer to variable to store output
Both functions return ssize_t: -1 on failure, size of output on success.