Skip to content

Instantly share code, notes, and snippets.

@kerrymilan
Last active March 10, 2023 13:19
Show Gist options
  • Save kerrymilan/694c1a308f14559c66b5d7851bf23754 to your computer and use it in GitHub Desktop.
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.
/**
* 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