-
-
Save danrl/5794505 to your computer and use it in GitHub Desktop.
2013 def con ctf grandprix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <netinet/in.h> | |
#include <netdb.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <arpa/inet.h> | |
/* constants */ | |
#define NO_WAY 0 | |
#define OK 1 | |
/* data structures */ | |
struct node { | |
char d; | |
int y; | |
int x; | |
struct node *s; | |
struct node *l; | |
struct node *r; | |
}; | |
/* globals */ | |
char recvbuf[1024] = { 0 }; | |
static void exit_err(const char *msg) | |
{ | |
printf("error: %s\n", msg); | |
exit(EXIT_FAILURE); | |
} | |
/* helper functions */ | |
/* | |
* x 12345 | |
* y |-----| | |
* 1 | | | |
* 2 | | | |
* 3 | | | |
* 4 | | | |
* 5 | | | |
* 6 | | | |
* 7 | | | |
* 8 | | | |
* 9 | u | | |
* |-----| | |
*/ | |
static char getyx(int y, int x) | |
{ | |
int offset = 1; | |
offset += y * 8; | |
offset += x - 1; | |
return (char) recvbuf[offset]; | |
} | |
static int getupos(void) | |
{ | |
for (int i=1; i < 6; i++) | |
if (getyx(9, i) == 'u') | |
return i; | |
return -1; | |
} | |
static struct node *make_node(int y, int x) | |
{ | |
struct node *ptr; | |
if (y < 1 || y > 9 || x < 1 || x > 5) | |
return NULL; | |
ptr = malloc(sizeof(struct node)); | |
ptr->d = getyx(y, x); | |
ptr->y = y; | |
ptr->x = x; | |
return ptr; | |
} | |
static void build_tree (struct node *nd) | |
{ | |
nd->l = make_node(nd->y -1, nd->x -1); | |
if (nd->l) | |
build_tree(nd->l); | |
nd->s = make_node(nd->y -1, nd->x); | |
if (nd->s) | |
build_tree(nd->s); | |
nd->r = make_node(nd->y -1, nd->x +1); | |
if (nd->r) | |
build_tree(nd->r); | |
} | |
int walk_tree (struct node *nd) | |
{ | |
printf("%c", nd->d); | |
if (nd->d != ' ') | |
return NO_WAY; | |
if (nd->y == 1) | |
return OK; | |
if (nd->s && walk_tree(nd->s) == OK) | |
return OK; | |
if (nd->l && walk_tree(nd->l) == OK) | |
return OK; | |
if (nd->r && walk_tree(nd->r) == OK) | |
return OK; | |
return NO_WAY; | |
} | |
char find_way (struct node *nd) | |
{ | |
if (nd->s && walk_tree(nd->s) == OK) | |
return 's'; | |
if (nd->l && walk_tree(nd->l) == OK) | |
return 'l'; | |
if (nd->r && walk_tree(nd->r) == OK) | |
return 'r'; | |
return 's'; | |
} | |
static struct node *free_tree(struct node *nd) | |
{ | |
if (!nd) | |
return NULL; | |
nd->l = free_tree(nd->l); | |
nd->s = free_tree(nd->s); | |
nd->r = free_tree(nd->r); | |
return NULL; | |
} | |
struct node *root = NULL; | |
int main(int argc, char *argv[]) | |
{ | |
int err = 0; | |
int sfd = 0; | |
int n = 0; | |
int run = 0; | |
char sbuf[2] = { '\n' }; | |
struct sockaddr_in srvaddr; | |
sfd = socket(AF_INET, SOCK_STREAM, 0); | |
if (sfd < 0) | |
exit_err("socket"); | |
memset(&srvaddr, 0, sizeof(srvaddr)); | |
srvaddr.sin_family = AF_INET; | |
srvaddr.sin_port = htons(2038); | |
err = inet_pton(AF_INET, "50.16.11.51", &srvaddr.sin_addr); | |
if (err <= 0) | |
exit_err("pton"); | |
err = connect(sfd, (struct sockaddr *) &srvaddr, sizeof(srvaddr)); | |
if (err < 0) | |
exit_err("connect"); | |
while ((n = read(sfd, recvbuf, sizeof(recvbuf) -1)) > 0) { | |
recvbuf[n] = 0; | |
if (n == 60) { | |
write(sfd, "\n", 1); | |
} else if (n == 88) { | |
printf("round %d: ", ++run); | |
root = make_node(9, getupos()); | |
root->d = ' '; | |
build_tree(root); | |
sbuf[0] = find_way(root); | |
write(sfd, sbuf, sizeof(sbuf)); | |
root = free_tree(root); | |
printf("->%c\n", sbuf[0]); | |
} else { | |
fputs(recvbuf, stdout); | |
} | |
} | |
if (n < 0) | |
exit_err("read"); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment