Skip to content

Commit 6a07dd2

Browse files
committed
34C3_CTF
1 parent 2de0df6 commit 6a07dd2

8 files changed

+333
-0
lines changed
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CC=gcc
2+
CFLAGS=-Wall -O1
3+
4+
all: server
5+
6+
server: server.c billboard.so
7+
$(CC) -no-pie -DPORT=12345 -DLIB=\"billboard.so\" -o server server.c $(CFLAGS) -ldl
8+
9+
billboard.so: billboard.c
10+
$(CC) -o billboard.so -shared -fPIC billboard.c $(CFLAGS)
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#ifndef _MYLIB_H_
2+
#define _MYLIB_H_
3+
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
#include <unistd.h>
8+
9+
#include "module.h"
10+
11+
const char* name = "Digital Billboard";
12+
const char* info = "We bought a new digital billboard for CTF advertisement.\n"
13+
"\n"
14+
"Type \"help\" for help :)";
15+
16+
17+
struct billboard {
18+
char text[256];
19+
char devmode;
20+
};
21+
struct billboard bb = { .text="Placeholder", .devmode=0 };
22+
23+
void set_text(int argc, char* argv[]) {
24+
strcpy(bb.text, argv[1]);
25+
printf("Successfully set text to: %s\n", bb.text);
26+
return;
27+
}
28+
29+
void shell(int argc, char* argv[]) {
30+
if (bb.devmode) {
31+
printf("Developer access to billboard granted.\n");
32+
system("/bin/bash");
33+
} else {
34+
printf("Developer mode disabled!\n");
35+
}
36+
return;
37+
}
38+
39+
void help(int argc, char* argv[]) {
40+
printf("This is helpful.\n");
41+
return;
42+
}
43+
44+
45+
void initialize_module(module_t* module, registration_function register_command) {
46+
47+
module->name = name;
48+
module->info = info;
49+
50+
register_command("set_text", "<text>\t\t", "Set the text displayed on the board", set_text);
51+
register_command("devmode", "\t\t", "Developer mode", shell);
52+
53+
54+
strcpy(bb.text, "Welcome to 34C3 JUNIOR CTF");
55+
}
56+
57+
#endif
8.25 KB
Binary file not shown.
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef MODULE_H
2+
#define MODULE_H
3+
4+
#define MIN(a,b) (((a)<(b))?(a):(b))
5+
6+
#include <link.h>
7+
8+
typedef void (*handle_command_function)(int, char**);
9+
typedef void (*registration_function)(const char*, const char*, const char*, handle_command_function);
10+
11+
12+
13+
typedef struct command {
14+
const char* name;
15+
const char* usage;
16+
const char* description;
17+
handle_command_function function;
18+
struct command* next;
19+
} command_t;
20+
21+
typedef struct module {
22+
const char* name;
23+
const char* info;
24+
Elf64_Addr base;
25+
command_t* commands;
26+
} module_t;
27+
28+
29+
#endif

2017/34C3_CTF/Digital_Bilboard/server

14.2 KB
Binary file not shown.
+236
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
#define _GNU_SOURCE
2+
#include <sys/types.h>
3+
#include <sys/socket.h>
4+
#include <sys/wait.h>
5+
#include <unistd.h>
6+
#include <stdlib.h>
7+
#include <sys/socket.h>
8+
#include <netinet/in.h>
9+
#include <arpa/inet.h>
10+
#include <stdio.h>
11+
#include <dlfcn.h>
12+
#include <string.h>
13+
#include <pwd.h>
14+
#include <grp.h>
15+
#include <link.h>
16+
#include <dlfcn.h>
17+
18+
#include "module.h"
19+
20+
21+
#define BACKLOG 32
22+
23+
#define logf(...) fprintf(stderr, __VA_ARGS__)
24+
25+
26+
27+
module_t module;
28+
struct sockaddr_in client;
29+
30+
void (*initialize_module)(module_t* m, registration_function r);
31+
32+
void module_info(int argc, char* argv[]) {
33+
printf("************************************\n");
34+
printf("Information about the loaded module:\n");
35+
printf("Name: %s\nBase address: %p\n", module.name, (void*) module.base);
36+
printf("************************************\n");
37+
}
38+
39+
void register_command(const char* name, const char* usage, const char* desc, handle_command_function function) {
40+
command_t* command = malloc(sizeof(command_t));
41+
command->name = name;
42+
command->usage = usage;
43+
command->description = desc;
44+
command->function = function;
45+
command->next = NULL;
46+
47+
if (module.commands == NULL) {
48+
module.commands = command;
49+
return;
50+
}
51+
52+
// append to end of list
53+
command_t* cur = module.commands;
54+
while(cur->next != NULL) {
55+
cur = cur->next;
56+
}
57+
cur->next = command;
58+
}
59+
60+
void help(int argc, char* argv[]) {
61+
command_t* command = module.commands;
62+
while (command != NULL) {
63+
printf("%s %s\t(%s)\n", command->name, command->usage, command->description);
64+
command = command->next;
65+
}
66+
}
67+
68+
void load_module() {
69+
char* error;
70+
void* handle = dlopen(LIB, RTLD_LAZY);
71+
if (!handle) {
72+
logf("Error on dlopen %s: %s\n", LIB, dlerror());
73+
exit(EXIT_FAILURE);
74+
}
75+
dlerror();
76+
struct link_map* lm = (struct link_map*) handle;
77+
module.base = lm->l_addr;
78+
79+
initialize_module = dlsym(handle, "initialize_module");
80+
printf("%p\n", initialize_module);
81+
if ((error = dlerror()) != NULL) {
82+
logf("%s\n", error);
83+
exit(1);
84+
}
85+
initialize_module(&module, register_command);
86+
87+
register_command("help", "\t\t\t", "Show this information", help);
88+
register_command("modinfo", "\t\t", "Show information about the loaded module", module_info);
89+
logf("Module successfully loaded.\n");
90+
}
91+
92+
93+
94+
int init_socket() {
95+
// create socket
96+
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
97+
if (sockfd < 0) {
98+
perror("Unable to create socket.");
99+
exit(EXIT_FAILURE);
100+
}
101+
// reusable sockfd
102+
int val = 1;
103+
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof val) < 0) {
104+
perror("Unable to set socket option REUSEADDR.");
105+
exit(EXIT_FAILURE);
106+
}
107+
// bind socket
108+
struct sockaddr_in addr;
109+
addr.sin_family = AF_INET;
110+
addr.sin_addr.s_addr = INADDR_ANY;
111+
addr.sin_port = htons(PORT);
112+
if (bind(sockfd, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
113+
perror("Unable to bind socket.");
114+
exit(EXIT_FAILURE);
115+
}
116+
// set backlog
117+
if (listen(sockfd, BACKLOG) < 0) {
118+
perror("Unable to set backlog.");
119+
exit(EXIT_FAILURE);
120+
}
121+
return sockfd;
122+
}
123+
124+
125+
126+
void handle_input(char* buf) {
127+
int argc = 0;
128+
char* argv[256];
129+
char* token = strtok(buf, " \n");
130+
if (!token) {
131+
return;
132+
}
133+
while (argc < sizeof(argv) && token) {
134+
argv[argc] = token;
135+
argc++;
136+
token = strtok(NULL, " \n");
137+
}
138+
139+
command_t* cur = module.commands;
140+
while (cur != NULL) {
141+
if (!strcmp(cur->name, argv[0])) {
142+
cur->function(argc, argv);
143+
break;
144+
}
145+
cur = cur->next;
146+
}
147+
if (cur == NULL) {
148+
printf("Command not found.\n");
149+
}
150+
return;
151+
}
152+
153+
void interact() {
154+
printf("*\n* %s\n*\n%s\n> ", module.name, module.info);
155+
fflush(stdout);
156+
static char buf[4096];
157+
while (1) {
158+
if (fgets(buf, 4096, stdin) != NULL) {
159+
handle_input(buf);
160+
printf("> ");
161+
} else {
162+
break;
163+
}
164+
}
165+
}
166+
167+
void drop_privs() {
168+
char* user = "challenge";
169+
struct passwd* pw = getpwnam(user);
170+
if (pw == NULL) {
171+
logf("User \"%s\" does not exist", user);
172+
exit(EXIT_FAILURE);
173+
}
174+
if (setgroups(0, NULL) != 0) {
175+
perror("Error on setgroups");
176+
exit(EXIT_FAILURE);
177+
}
178+
if (setgid(pw->pw_gid) != 0) {
179+
perror("Error on setgid");
180+
exit(EXIT_FAILURE);
181+
}
182+
if (setuid(pw->pw_uid) != 0) {
183+
perror("Error on setuid");
184+
exit(EXIT_FAILURE);
185+
}
186+
}
187+
188+
int main(int argc, char* argv[]) {
189+
190+
int sockfd = init_socket();
191+
logf("Server listening on port %d\n", PORT);
192+
193+
if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
194+
perror("Error setting SIGCHILD handler.");
195+
return EXIT_FAILURE;
196+
}
197+
198+
load_module();
199+
200+
while (1) {
201+
socklen_t client_len = sizeof(client);
202+
int client_fd = accept(sockfd, (struct sockaddr*) &client, &client_len);
203+
if (client_fd < 0) {
204+
perror("Error creating socket for incoming connection");
205+
exit(EXIT_FAILURE);
206+
}
207+
logf("New connection from %s on port %d\n", inet_ntoa(client.sin_addr), htons(client.sin_port));
208+
209+
int pid = fork();
210+
if (pid < 0) {
211+
perror("Unable to fork");
212+
exit(EXIT_FAILURE);
213+
}
214+
215+
if (pid == 0) { // client
216+
alarm(300);
217+
close(sockfd);
218+
219+
dup2(client_fd, 0);
220+
dup2(client_fd, 1);
221+
setvbuf(stdout, NULL, _IONBF, 0);
222+
223+
drop_privs();
224+
225+
interact();
226+
227+
close(client_fd);
228+
logf("%s:%d disconnected\n", inet_ntoa(client.sin_addr), htons(client.sin_port));
229+
exit(EXIT_SUCCESS);
230+
} else { // server
231+
logf("%s:%d forked new process with pid %d\n", inet_ntoa(client.sin_addr), htons(client.sin_port), pid);
232+
close(client_fd);
233+
}
234+
235+
}
236+
}

0 commit comments

Comments
 (0)