Добрый день. Помогите, пожалуйста, найти уязвимосте в сервере
Код:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#define PACKET_LEN 0x1000
#define PORT 7777
/* Utils functions */
void die(const char *msg)
{
perror(msg);
exit(errno);
}
char get_char(void **p)
{
char res;
res = *(char *)(*p);
(*p) += sizeof (res);
return (res);
}
short get_short(void **p)
{
short res;
res = *(short *)(*p);
(*p) += sizeof (res);
return (res);
}
int get_int(void **p)
{
int res;
res = *(int *)(*p);
(*p) += sizeof (res);
return (res);
}
char *get_str(void **p)
{
int len;
char *res;
len = get_short(p);
res = malloc(len + 1);
strlcpy(res, *p, len + 1);
(*p) += len;
return (res);
}
/* End of utils functions */
/* Handlers */
int handler_echo(void *p, size_t l)
{
#define BUF_LEN 512
#define MSG "Msg : "
#define MSG_LEN (sizeof (MSG) - 1)
char *str;
char buf[BUF_LEN + 1];
str = get_str(&p);
strcpy(buf, MSG);
strncpy(buf + MSG_LEN, str, strlen(str) + 1);
return (puts(buf));
}
int handler_rev_echo(void *p, size_t l)
{
char *str;
char *tmp;
int res = 0;
str = get_str(&p);
for (tmp = str + strlen(str) - 1; tmp != str; tmp--)
res += write(1, tmp, 1);
write(1, str, 1);
write(1, "\n", 1);
return (res);
}
int handler_cat(void *p, size_t l)
{
char *buf;
size_t len;
char *str;
str = get_str(&p);
len = l + sizeof("cat ") + 1;
if (!(buf = malloc(len)))
die("malloc");
snprintf(buf, len, "cat %s", str);
puts(buf);
system(buf);
free(buf);
return (len);
}
int handler_get_env(void *p, size_t l)
{
char *res;
char *name;
name = get_str(&p);
if (!(res = getenv(name)))
{
char buf[512];
snprintf(buf, 512, "The variable \"%s\" doesn't exist\n", name);
printf(buf);
return (-1);
}
puts(res);
}
static int g_is_running = 5;
static int (*s_handler[])(void *, size_t) =
{
handler_echo,
handler_rev_echo,
handler_cat,
handler_get_env
};
#define HANDLER_LEN (sizeof(s_handler) / sizeof (s_handler[0]))
/* End of handlers */
/* Network functions */
void init_connection(int *sockfd, struct sockaddr_in *sa, short port)
{
if ((*sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
die("socket");
bzero(sa, sizeof *sa);
sa->sin_family = AF_INET;
sa->sin_port = htons(port);
sa->sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(*sockfd, (struct sockaddr *)sa, sizeof *sa) < 0)
die("bind");
if (listen(*sockfd, 4) < 0)
die("listen");
}
int get_client(int sockfd, struct sockaddr_in *sa)
{
int res, sa_len = sizeof *sa;
if ((res = accept(sockfd, (struct sockaddr *)sa, &sa_len)) < 0)
die("accept");
return (res);
}
void get_packet(int sockfd, void *packet_ptr, int *packet_size)
{
if ((*packet_size = recv(sockfd, packet_ptr, PACKET_LEN, 0)) < 0)
die("recv");
if (!*packet_size)
exit(EXIT_SUCCESS);
}
void handle_packet(void *packet_ptr, int packet_size)
{
int packet_id;
packet_id = get_int(&packet_ptr);
packet_size -= sizeof packet_id;
if (packet_id > (int)HANDLER_LEN)
fprintf(stderr, "ID (%d) out of range\n", packet_id);
else
s_handler[packet_id](packet_ptr, packet_size);
}
/* End of network functions */
int main(int ac, char **av)
{
int sockfd, sockfd_clt, portno, clilen;
struct sockaddr_in sa;
init_connection(&sockfd, &sa, PORT);
puts("Connection initialized");
puts("Waiting for a client");
sockfd_clt = get_client(sockfd, &sa);
puts("Client connected");
printf("There is %d handler%c.\n",
HANDLER_LEN, HANDLER_LEN > 1 ? 's' : ' ');
while (g_is_running)
{
char packet_ptr[PACKET_LEN];
size_t packet_size;
bzero(packet_ptr, sizeof packet_ptr);
g_is_running--;
get_packet(sockfd_clt, packet_ptr, &packet_size);
handle_packet(packet_ptr, packet_size);
}
return (0);
}