RC3 Week 6

I was working on Week 6 RC3 problems, but forgot to actually publish this post.

So here it is!


RC3 – Week 6 

“ Ok, it seems like you have exploited them. Can you tell me how to fix them? “

Oh shit. At that point I realized that I was working too hard for the flag, not for the knowledge and education.

This week’s RC3 topic and challenges were about secure coding. There were some challenges to introduce some of the secure coding concepts. Here’s what I’ve learned.


Challenge 1 – Math.py

math py

This small python code contains one of the rule of thumb for all programmers. “Eval is Evil.” The shebang line at the top shows that this is a python2 code.

Python2’s input() function is “Equivalent to eval(raw_input(prompt)).” (https://docs.python.org/2/library/functions.html#input)

Okay. What’s eval()?  “The expression argument is parsed and evaluated as a Python expression”


Thus, this simple python program will evaluate anything the user types as a python expression. Let’s do some testing.


This seems bad.

But it get’s worse.

__builtins__.__import__(‘os’).execl(‘/bin/cat’, ‘cat’, ‘/etc/passwd’)

Using python’s bulitin function, we can import os module and use it’s execl function through this python program.


If this was a very big program with a setuid, and there was this one line of “input()” instead of raw_input() …. That program/service would’ve been able to spawn a remote shell.

Eval is very dangerous; it allows any user to arbitrary execute code.

Challenge 2

Upon opening up the source code, we see a poorly written c code.

1. #include 
2. #include 
3. #include 
4. #include 
5. #include 
6. #include <sys/utsname.h>
8. static char* skies[3] = { "clear", "cloudy", "party cloudy" };
10. int main(void) {
11.     // nobody has a name this long so it should be fine
12.     char name[50];
14.     // get name and copy
15.     printf("Enter Name: ");
16.     fflush(stdout);
17.     char buf[1024];
18.     int bytesRead = 0;
19.     if((bytesRead = read(0, buf, sizeof(buf))) > 0) {
20.         // remove trailing newline
21.         if(buf[bytesRead - 1] == '\n') {
22.             buf[bytesRead - 1] = '\0';
23.         }
25.         strcpy(name, buf);
27.         time_t now;
28.         struct tm *timeInfo;
29.         char dateStr[80];
30.         char* hostname = malloc(1024 * sizeof(char));
31.         struct utsname sysInfo;
33.         srand(time(&now));
34.         uname(&sysInfo);
35.         strcpy(hostname, sysInfo.nodename);
36.         int temp = (rand() % 70) + 20;
37.         char* sky = skies[rand() % 3];
38.         free(hostname);
39.         timeInfo = localtime(&now);
40.         strftime(dateStr, 80, "%x, %I:%M%p", timeInfo);
43.         printf("================================\n");
44.         printf("||         Dashboard          ||\n");
45.         printf("================================\n");
46.         printf("Welcome, %s!\n", name);
47.         printf("Today's date is %s\n", dateStr);
48.         printf("Right now, it is %d degrees with %s skies.\n", temp, sky);
50.         // TODO: Fix this!!! it almost never works and idk what's wrong!
51.         // (find the specific code issue causing this behavior for medium 2)
52.         // printf("Hostname: %s\n", hostname);
53.         // printf("System Version: %s\n", sysInfo.version);
54.     }
55. }

As we can clearly see in line 25 and 35, the program is using strcpy, which is a function that is vulnerable to bufferoverflow attacks.


Let’s change that to strncpy, or, snprintf  functions.

snprintf(name, sizeof(name), “%s”, buf)

snprintf(hostname, sizeof(hostname), “%s”, sysInfo.nodename)

From Line 50, the author commented about some feature not working in the program. It seems like the program is trying to reach for hostname variable, which was free() -ed in line 38. While we are at it, let’s uncomment line 52, 53.

52.         printf("Hostname: %sn", hostname);
53.         printf("System Version: %sn", sysInfo.version);
54.         free(hostname);

So, let’s add comment line 38 free and add at the end of the program.

Let’s test it by inputting 3000 characters as a name.

python -c ‘print “A” * 3000’ | ./safe


Now the program is safe from bufferoverflow. Also, it’s not accessing a free() dynamically allocated heap variable. All is fine.

Usage of vulnerable functions such as

strcpy(), strcat(), gets(), sprintf()

Should be always avoided.


A. Don’t trust the user (ever)

B. Don’t let the user poke around with the server’s shell (by giving shell_exec() like a stupid)

C. If there is a time to trust the user, try to sanitize user’s input; as they will try their best to break the application. (watch out for fuzzers?)

D. Features within the application should probably start, process, and finish within the application.If the application needs a feature from the shell, input data and retrieve data from the server’s any other property, it is too dangerous.

ex) If web need to display date, use php’s date() function. Don’t use server’s shell linux date() funciton and retrieve that data to the application.

If an application lacks a feature, add the feature in the application level.