Last active
March 10, 2023 13:19
-
-
Save kerrymilan/694c1a308f14559c66b5d7851bf23754 to your computer and use it in GitHub Desktop.
Utility to decrypt AESCFB128-encrypted (e.g. $8$...) ConfD config values. This is intended to be used in cases where the encryption keys are stored in the device's database (*.cdb) files rather than in confd.conf.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ConfD Decrypt Utility | |
* | |
* Prerequisites: | |
* * AESCFB128-encrypted (e.g. $8$) config values | |
* * May work on DES3CBC as well; untested | |
* * CDB files from target device | |
* * confd.conf file from target device | |
* * At minimum, AESCFB128 key and initVector values | |
* * gcc/make | |
* Installation instructions: | |
* * Download ConfD Basic | |
* * https://www.tail-f.com/confd-basic/ | |
* * https://developer.cisco.com/site/confD/ | |
* * https://software.cisco.com/download/home/286331271/type/286331347/ | |
* * Note: This script was tested against v7.8.3 | |
* * Unzip the downloaded file into the current directory | |
* * Run ./confd-basic-<version>.linux.x86_64.installer.bin | |
* * Install to ./confd/ | |
* * Store the ConfD root | |
* * export CONFD_DIR=$(pwd)/confd/ | |
* * Unpack the included ConfD examples archive, build the "crypto1" example, | |
* and copy the required header into the ConfD include directory | |
* * tar xzf confd-basic-<version>.examples.tar.gz | |
* * cd confd-basic-7.8.3/examples.confd/crypto/crypto1 | |
* * make | |
* * cp smp.h ${CONFD_DIR}/include/ | |
* * Build this utility with the following command: | |
* * gcc -I${CONFD_DIR}/include/ \ | |
* -Wl,-rpath=${CONFD_DIR}/lib/ \ | |
* -L${CONFD_DIR}/lib/ -Wall \ | |
* -o confd-decrypt confd-decrypt.cpp \ | |
* -lconfd -lcrypto -fpermissive | |
* * Extract the <initVector> and <key> values from the target device | |
* * confd_cmd -dd -c "get_object /confd_dyncfg:confdConfig/encryptedStrings/AESCFB128" | |
* * Copy the CDB files (A.cdb, B.cdb, O.cdb) into the ConfD root | |
* * cp ${SOME_PATH}/\*.cdb ${CONFD_DIR}/var/confd/cdb/ | |
* * Edit ${CONFD_DIR}/etc/confd/confd.conf | |
* * Copy the previously extracted <key> and <initVector> values into the | |
* <AESCFB128> block | |
* * Start the ConfD daemon | |
* * ${CONFD_DIR}/bin/confd --foreground -v | |
* * Run this utility | |
* * ./confd-decrypt '$8$...' | |
* Notes: | |
* * If the target device is running a current (or compatible) ConfD version, | |
* it may be possible to have this utility interact with the device's ConfD | |
* daemon rather than building, configuring, and installing a local copy. | |
* * The CDB copy step is probably not necessary if the initVector and Key | |
* values can be extracted using confd_cmd. | |
**/ | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <sys/poll.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <cstring> | |
#include "confd_lib.h" | |
#include "confd_dp.h" | |
#include "confd_events.h" | |
#include "confd_ha.h" | |
#include "confd_cdb.h" | |
#include "confd_maapi.h" | |
#include "smp.h" | |
static void install_keys(struct sockaddr_in *addr) { | |
struct confd_daemon_ctx *dctx; | |
int ctlsock = socket(PF_INET, SOCK_STREAM, 0); | |
dctx = confd_init_daemon("MDS"); | |
int ctls = ctlsock = confd_connect(dctx, ctlsock, CONTROL_SOCKET, (struct sockaddr*)addr, sizeof (*addr)); | |
if (ctls < 0) { | |
printf("Could not connect to control socket: %i\n", ctls); | |
exit(ctls); | |
} | |
confd_install_crypto_keys(dctx); | |
close(ctlsock); | |
confd_release_daemon(dctx); | |
} | |
static void get_clear_text(struct sockaddr_in *addr, FILE *f, char *ciphertext) { | |
int rsock = socket(PF_INET, SOCK_STREAM, 0); | |
install_keys(addr); | |
cdb_connect(rsock, CDB_READ_SOCKET, (struct sockaddr*)addr, sizeof(*addr)); | |
cdb_start_session(rsock, CDB_RUNNING); | |
char dstr[BUFSIZ]; | |
confd_decrypt(ciphertext, strlen(ciphertext), dstr); | |
printf("Decrypted value: %s\n", dstr); | |
cdb_end_session(rsock), | |
cdb_close(rsock); | |
} | |
int main(int argc, char **argv) { | |
if (argv[1] == NULL) { | |
printf("Usage: %s <ciphertext>\n", argv[0]); | |
exit(1); | |
} | |
char confd_addr[] = "127.0.0.1"; | |
int confd_port = 4565; | |
struct sockaddr_in addr; | |
struct in_addr in; | |
inet_aton(confd_addr, &in); | |
addr.sin_addr.s_addr = in.s_addr; | |
addr.sin_family = AF_INET; | |
addr.sin_port = htons(confd_port); | |
confd_init(argv[0], stderr, CONFD_TRACE); | |
get_clear_text(&addr, stdout, argv[1]); | |
exit(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment