Skip to content

Instantly share code, notes, and snippets.

@isra17
Created October 29, 2014 14:48
Show Gist options
  • Save isra17/8179ebf89335dd07c1cc to your computer and use it in GitHub Desktop.
Save isra17/8179ebf89335dd07c1cc to your computer and use it in GitHub Desktop.
#include <arpa/inet.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
int g_key;
int is_admin = 0;
int challenge1() {
int key = rand();
char buffer[0x100];
int user_key;
puts("Username:");
fflush(stdout);
fgets(buffer, 0x100, stdin);
printf(buffer);
fflush(stdout);
puts("key:");
fflush(stdout);
fread(&user_key, 1, 4, stdin);
return user_key != key;
}
int challenge2() {
char buffer[0x100];
int user_key;
g_key = rand();
puts("Username:");
fflush(stdout);
fgets(buffer, 0x100, stdin);
printf(buffer);
fflush(stdout);
puts("key:");
fflush(stdout);
fread(&user_key, 1, 4, stdin);
return user_key != g_key;
}
int challenge3() {
char buffer[0x100];
puts("Username:");
fflush(stdout);
fgets(buffer, 0x100, stdin);
printf(buffer);
fflush(stdout);
return !is_admin;
}
void ultimate_challenge() {
char buffer[0x1000];
fgets(buffer, 0x1000, stdin);
printf(buffer);
fflush(stdout);
fgets(buffer, 0x1000, stdin);
printf(buffer);
fflush(stdout);
printf("No shell? :(");
fflush(stdout);
}
void you_wish(char* cmd) {
system(cmd);
}
void challenge(int fd) {
dup2(fd, 0);
dup2(fd, 1);
srand(time(NULL));
if(challenge1() ||
challenge2() ||
challenge3()) {
printf("Boom!");
fflush(stdout);
exit(0);
} else {
printf("Well done, but what about getting a shell?\n");
fflush(stdout);
ultimate_challenge();
}
}
int main(int argc, char **argv) {
int rc;
int opt;
int sockfd;
int clientfd;
pid_t pid;
struct sockaddr_in saddr = {0};
// Setting the SIGCHLD handler to SIG_IGN prevents child
// processes from becoming zombies (so you do not need to
// call wait() on them).
if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
fputs("Failed to set SIGCHLD handler.", stderr);
return 1;
}
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd == -1) {
perror("socket");
return 1;
}
// Set SO_REUSEADDR. Otherwise, if the server crashes for
// any reason, you will have to wait for sockets to time
// out before you can reuse the port.
opt = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt)) != 0) {
perror("setsockopt");
return 1;
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(31337);
if (bind(sockfd, (struct sockaddr *) &saddr,
sizeof(saddr)) != 0) {
perror("bind");
return 1;
}
if (listen(sockfd, 20) != 0) {
perror("listen");
return 1;
}
while (1) {
clientfd = accept(sockfd, NULL, NULL);
if (clientfd == -1) {
perror("accept");
continue;
}
pid = fork();
if (pid == -1) {
perror("fork");
close(clientfd);
continue;
}
if (pid == 0) {
// If you do not close the socket fd, someone who
// exploits the service could call accept() on it and
// hijack other people's connections.
close(sockfd);
challenge(clientfd);
close(clientfd);
_exit(rc);
}
// If you forget to close the client fd, you could run
// out of file descriptors (it also makes the connection fd
// hard to predict, which can be annoying for someone
// writing an exploit - if you want to do this on purpose,
// use dup2 with a random fd instead :-P).
close(clientfd);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment