Jump to content

Need help with Buffer Overflow Vulnerability Lab :


me_cs

Recommended Posts

Hi all , I'll very appreciate your assistance!
I need to :

"Study the web server's code, and find examples of code vulnerable to memory corruption through a buffer overflow. For each vulnerability, describe the buffer which may overflow, how you would structure the input to the web server (i.e., the HTTP request) to overflow the buffer, and whether the vulnerability can be prevented using stack canaries. Locate at least 5 different vulnerabilities."

 

the web server's code

The zookws web server consists of the following components.

- zookld, a launcher daemon that launches services configured in the file zook.conf.
- zookd, a dispatcher that routes HTTP requests to corresponding services.
- zookfs and other services that may serve static files or execute dynamic scripts.

attached below.

tnx!!

 

 

server code:

 

zook.conf

 

[zook]

port = 8080

# To run multiple services, list them separated by commas, like:

# http_svcs = first_svc, second_svc

http_svcs = zookfs_svc

extra_svcs =

 

[zookd]

cmd = zookd

 

[zookfs_svc]

cmd = zookfs

url = .*

 

zookld.c

 

/* zookld -- launcher daemon */

 

#include <openssl/conf.h>

#include <sys/param.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/wait.h>

#include <err.h>

#include <grp.h>

#include <fcntl.h>

#include <netdb.h>

#include <unistd.h>

#include <signal.h>

#include <string.h>

#include "http.h"

 

#define ZOOK_CONF "zook.conf"

#define MAX_SERVICES 256

#define MAX_GIDS 256

 

static int svcfds[MAX_SERVICES];

static char svcnames[MAX_SERVICES][256];

static int nsvcs = 0; /* actual number of services */

 

static int ngids = 0;

static gid_t gids[MAX_GIDS];

 

static int service_parse_cb(const char *, int, void *);

static int group_parse_cb(const char *, int, void *);

static pid_t launch_svc(CONF *, const char *);

static int start_server(const char *);

 

int main(int argc, char **argv)

{

char *filename = ZOOK_CONF;

CONF *conf;

long eline = 0;

char *portstr, *svcs;

int sockfd;

pid_t disppid;

int i, status;

 

/* read configuration

http://linux.die.net/man/5/config

http://www.openssl.org/docs/apps/config.html

*/

if (argc > 1)

filename = argv[1];

conf = NCONF_new(NULL);

if (!NCONF_load(conf, filename, &eline))

{

if (eline)

errx(1, "Failed parsing %s:%ld", filename, eline);

else

errx(1, "Failed opening %s", filename);

}

 

/* http server port, default 80 */

if (!(portstr = NCONF_get_string(conf, "zook", "port")))

portstr = "80";

sockfd = start_server(portstr);

warnx("Listening on port %s", portstr);

signal(SIGCHLD, SIG_IGN);

signal(SIGPIPE, SIG_IGN);

 

/* launch the dispatch daemon */

disppid = launch_svc(conf, "zookd");

/* launch http services */

if ((svcs = NCONF_get_string(conf, "zook", "http_svcs")))

CONF_parse_list(svcs, ',', 1, &service_parse_cb, conf);

 

/* send the server socket to zookd */

if (sendfd(svcfds[0], &nsvcs, sizeof(nsvcs), sockfd) < 0)

err(1, "sendfd to zookd");

close(sockfd);

 

/* send all svc sockets with their url patterns to http services */

for (i = 1; i < nsvcs; ++i)

{

char *url = NCONF_get_string(conf, svcnames, "url");

if (!url)

url = ".*";

sendfd(svcfds[0], url, strlen(url) + 1, svcfds);

close(svcfds);

}

close(svcfds[0]);

 

/* launch non-http services */

if ((svcs = NCONF_get_string(conf, "zook", "extra_svcs")))

CONF_parse_list(svcs, ',', 1, &service_parse_cb, conf);

 

NCONF_free(conf);

 

/* wait for zookd */

waitpid(disppid, &status, 0);

}

 

/* launch a service */

pid_t launch_svc(CONF *conf, const char *name)

{

int fds[2], i;

pid_t pid;

char *cmd, *args, *argv[32] = {0}, **ap, *dir;

char *groups;

long uid, gid;

 

if (nsvcs)

warnx("Launching service %d: %s", nsvcs, name);

else

warnx("Launching %s", name);

 

if (!(cmd = NCONF_get_string(conf, name, "cmd")))

errx(1, "`cmd' missing in [%s]", name);

 

if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))

err(1, "socketpair");

 

switch ((pid = fork()))

{

case -1: /* error */

err(1, "fork");

case 0: /* child */

close(fds[0]);

break;

default: /* parent */

warnx("%s: pid %d", name, pid);

close(fds[1]);

svcfds[nsvcs] = fds[0];

++nsvcs;

return pid;

}

 

/* child */

argv[0] = cmd;

/* argv[1] is used by svc to receive data from zookd */

asprintf(&argv[1], "%d", fds[1]);

 

/* split extra arguments */

if ((args = NCONF_get_string(conf, name, "args")))

{

for (ap = &argv[2]; (*ap = strsep(&args, " \t")) != NULL; )

if (**ap != '\0')

if (++ap >= &argv[31])

break;

}

 

if (NCONF_get_number_e(conf, name, "uid", &uid))

{

/* change real, effective, and saved uid to uid */

warnx("setuid %ld", uid);

}

 

if (NCONF_get_number_e(conf, name, "gid", &gid))

{

/* change real, effective, and saved gid to gid */

warnx("setgid %ld", gid);

}

 

if ((groups = NCONF_get_string(conf, name, "extra_gids")))

{

ngids = 0;

CONF_parse_list(groups, ',', 1, &group_parse_cb, NULL);

/* set the grouplist to gids */

for (i = 0; i < ngids; i++)

warnx("extra gid %d", gids);

}

 

if ((dir = NCONF_get_string(conf, name, "dir")))

{

/* chroot into dir */

}

 

signal(SIGCHLD, SIG_DFL);

signal(SIGPIPE, SIG_DFL);

 

execv(argv[0], argv);

err(1, "execv %s %s", argv[0], argv[1]);

}

 

static int service_parse_cb(const char *name, int len, void *arg)

{

if (len)

{

strncpy(svcnames[nsvcs], name, len + 1);

svcnames[nsvcs][len] = 0;

launch_svc((CONF *)arg, svcnames[nsvcs]);

}

return 1;

}

 

static int group_parse_cb(const char *gid_str, int len, void *arg)

{

char *str_nul;

 

if (len)

{

if (ngids >= MAX_GIDS)

{

warnx("Only %d additional gids allowed", MAX_GIDS);

return 1;

}

str_nul = strndup(gid_str, len); /* ugh, C */

gids[ngids++] = strtol(str_nul, NULL, 10);

free(str_nul);

}

return 1;

}

 

/* socket-bind-listen idiom */

static int start_server(const char *portstr)

{

struct addrinfo hints = {0}, *res;

int sockfd;

int e, opt = 1;

 

hints.ai_family = AF_UNSPEC;

hints.ai_socktype = SOCK_STREAM;

hints.ai_flags = AI_PASSIVE;

 

if ((e = getaddrinfo(NULL, portstr, &hints, &res)))

errx(1, "getaddrinfo: %s", gai_strerror(e));

if ((sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)

err(1, "socket");

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))

err(1, "setsockopt");

if (fcntl(sockfd, F_SETFD, FD_CLOEXEC) < 0)

err(1, "fcntl");

if (bind(sockfd, res->ai_addr, res->ai_addrlen))

err(1, "bind");

if (listen(sockfd, 5))

err(1, "listen");

freeaddrinfo(res);

 

return sockfd;

}

Zookd.c

 

/* dispatch daemon */

 

#include "http.h"

#include <err.h>

#include <regex.h>

#include <signal.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

 

#define MAX_SERVICES 256

static int nsvcs;

static int svcfds[MAX_SERVICES];

static regex_t svcurls[MAX_SERVICES];

 

static void process_client(int);

 

int main(int argc, char **argv)

{

int fd, sockfd = -1, i;

 

if (argc != 2)

errx(1, "Wrong arguments");

fd = atoi(argv[1]);

 

signal(SIGPIPE, SIG_IGN);

signal(SIGCHLD, SIG_IGN);

 

/* receive the number of services and the server socket from zookld */

if ((recvfd(fd, &nsvcs, sizeof(nsvcs), &sockfd) <= 0) || sockfd < 0)

err(1, "recvfd sockfd");

--nsvcs;

warnx("Start with %d service(s)", nsvcs);

 

/* receive url patterns of all services */

for (i = 0; i != nsvcs; ++i)

{

char url[1024], regexp[1024];

if (recvfd(fd, url, sizeof(url), &svcfds) <= 0)

err(1, "recvfd svc %d", i + 1);

/* parens are necessary here so that regexes like a|b get

parsed properly and not as (^a)|(b$) */

snprintf(regexp, sizeof(regexp), "^(%s)$", url);

if (regcomp(&svcurls, regexp, REG_EXTENDED | REG_NOSUB))

errx(1, "Bad url for service %d: %s", i + 1, url);

warnx("Dispatch %s for service %d", regexp, i + 1);

}

 

close(fd);

 

for (;;)

{

int cltfd = accept(sockfd, NULL, NULL);

if (cltfd < 0)

err(1, "accept");

process_client(cltfd);

}

}

 

static void process_client(int fd)

{

static char env[8192]; /* static variables are not on the stack */

static size_t env_len;

char reqpath[2048];

const char *errmsg;

int i;

 

/* get the request line */

if ((errmsg = http_request_line(fd, reqpath, env, &env_len)))

return http_err(fd, 500, "http_request_line: %s", errmsg);

 

for (i = 0; i < nsvcs; ++i)

{

if (!regexec(&svcurls, reqpath, 0, 0, 0))

{

warnx("Forward %s to service %d", reqpath, i + 1);

break;

}

}

 

if (i == nsvcs)

return http_err(fd, 500, "Error dispatching request: %s", reqpath);

 

if (sendfd(svcfds, env, env_len, fd) <= 0)

return http_err(fd, 500, "Error forwarding request: %s", reqpath);

 

close(fd);

}

 

Zookfs.c

 

/* file server */

 

#include "http.h"

#include <err.h>

#include <signal.h>

#include <stdlib.h>

#include <unistd.h>

 

int main(int argc, char **argv)

{

int fd;

if (argc != 2 && argc != 4)

errx(1, "Wrong arguments");

fd = atoi(argv[1]);

 

if (argc == 4) {

int uid = atoi(argv[2]);

int gid = atoi(argv[3]);

warnx("cgi uid %d, gid %d", uid, gid);

http_set_executable_uid_gid(uid, gid);

}

 

signal(SIGPIPE, SIG_IGN);

signal(SIGCHLD, SIG_IGN);

 

for (;;)

{

char envp[8192];

int sockfd = -1;

const char *errmsg;

 

/* receive socket and envp from zookd */

if ((recvfd(fd, envp, sizeof(envp), &sockfd) <= 0) || sockfd < 0)

err(1, "recvfd");

 

switch (fork())

{

case -1: /* error */

err(1, "fork");

case 0: /* child */

/* set envp */

env_deserialize(envp, sizeof(envp));

/* get all headers */

if ((errmsg = http_request_headers(sockfd)))

http_err(sockfd, 500, "http_request_headers: %s", errmsg);

else

http_serve(sockfd, getenv("REQUEST_URI"));

return 0;

default: /* parent */

close(sockfd);

break;

}

}

}

 

 

------------------------------------------------

 

 

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.