How To: Use Flawfinder to Find Security Vulnerabilities in C Code

Step 1: Install Flawfinder

The objectively easiest and subjectively optimal method of installing the latest version of Flawfinder would be to “pip install” it. To do this, open a Command Prompt window and execute the following command:

pip install flawfinder

Step 2: Locate the Flawfinder installation

Now that you have installed Flawfinder, you may find its installation directory by executing the following command in the same Command Prompt window:

where.exe flawfinder

You will get the location of where the “flawfinder” file is as the output, it may look something like this:

Navigate to the location in the output, and you will see the blank “flawfinder” file among possibly other Python files, however with no extension, as shown below:

Found it!

Step 3: Make Flawfinder easily accessible

If you were to execute Flawfinder from any directory using the Command Prompt at this point as is, your system would not recognize it:

So, as you may need Flawfinder to be accessible from any window or workspace you may currently be in to test your C code conveniently and quickly, this step will focus on easily letting you execute Flawfinder from just about anywhere in your system!

Since this “flawfinder” file is essentially a Python file without the “.py” extension, we will now give it an extension so it is recognized in the further steps.

Rename this “flawfinder” file to “flawfinder.py” and make sure you are changing its extension, not just the file name. Upon a successful extension change, the blank icon of the file should turn to a Python file type icon, as shown below:

NOTE: You may have to enable “Show hidden files, folders, and drives”, and disable “Hide extensions for known file types” in Folder Options in order to navigate to Flawfinder’s installation path and change its extension, as shown below:

Now, let’s make Flawfinder accessible from anywhere in your system for super convenient access!

Press the Windows key on your keyboard to open up the Start Menu, and type “environment” into it; you will see the following result:

Click on it, and you will reach this panel:

Click on the “Environment Variables” button, and another window will pop up. Here, double-click on the “Path” line, and yet another window will pop up, which will look like this:

Check this list to see if you have the path to the “flawfinder.py” file, whatever it was for you in the Command Prompt output from Step #2. It is highly suggested to add this path anyway since it helps with other pip-installed packages if you want to access them easily and globally through a command line interface.

If you do not have the path in your list, you can simply add it by pressing the “New” button on the to-right and pasting the path in it (make sure you remove “flawfinder” out of it. This path should only be the directory in which “flawfinder.py” is located.

Done! Now, make sure you close all existing open Command Prompt window(s) since the changes will only take place with fresh Command Prompt windows.

Now, when you execute “flawfinder.py” from a Command Prompt window anywhere, it will recognize and execute Flawfinder, as shown below (ignore the traceback, it is due to us not supplying the C code to be tested yet):

You’re done! Flawfinder is now one of the very useful tools on your belt, available anywhere, at any time!

Step 4: Flawfind!

Need some test C code to try Flawfinder with? Here:

/* Test flawfinder.  This program won't compile or run; that's not necessary
   for this to be a useful test. */

#include 
#define hello(x) goodbye(x)
#define WOKKA "stuff"

main() {
 printf("hello\n");
}

/* This is a strcpy test. */

int demo(char *a, char *b) {
 strcpy(a, "\n"); // Did this work?
 strcpy(a, gettext("Hello there")); // Did this work?
 strcpy(b, a);
 sprintf(s, "\n");
 sprintf(s, "hello");
 sprintf(s, "hello %s", bug);
 sprintf(s, gettext("hello %s"), bug);
 sprintf(s, unknown, bug);
 printf(bf, x);
 scanf("%d", &x);
 scanf("%s", s);
 scanf("%10s", s);
 scanf("%s", s);
 gets(f); // Flawfinder: ignore
 printf("\\");
 /* Flawfinder: ignore */
 gets(f);
 gets(f);
 /* These are okay, but flawfinder version < 0.20 incorrectly used
    the first parameter as the parameter for the format string */
 syslog(LOG_ERR,"cannot open config file (%s): %s",filename,strerror(errno))
 syslog(LOG_CRIT,"malloc() failed");
 /* But this one SHOULD trigger a warning. */
 syslog(LOG_ERR, attacker_string);

}



demo2() {
  char d[20];
  char s[20];
  int n;

  _mbscpy(d,s); /* like strcpy, this doesn't check for buffer overflow */
  memcpy(d,s);
  CopyMemory(d,s);
  lstrcat(d,s);
  strncpy(d,s);
  _tcsncpy(d,s);
  strncat(d,s,10);
  strncat(d,s,sizeof(d)); /* Misuse - this should be flagged as riskier. */
  _tcsncat(d,s,sizeof(d)); /* Misuse - flag as riskier */
  n = strlen(d);
  /* This is wrong, and should be flagged as risky: */
  MultiByteToWideChar(CP_ACP,0,szName,-1,wszUserName,sizeof(wszUserName));
  /* This is also wrong, and should be flagged as risky: */
  MultiByteToWideChar(CP_ACP,0,szName,-1,wszUserName,sizeof wszUserName);
  /* This is much better: */
  MultiByteToWideChar(CP_ACP,0,szName,-1,wszUserName,sizeof(wszUserName)/sizeof(wszUserName[0]));
  /* This is much better: */
  MultiByteToWideChar(CP_ACP,0,szName,-1,wszUserName,sizeof wszUserName /sizeof(wszUserName[0]));
  /* This is an example of bad code - the third paramer is NULL, so it creates
     a NULL ACL.  Note that Flawfinder can't detect when a
     SECURITY_DESCRIPTOR structure is manually created with a NULL value
     as the ACL; doing so would require a tool that handles C/C++
     and knows about types more that flawfinder currently does.
     Anyway, this needs to be detected: */
  SetSecurityDescriptorDacl(&sd,TRUE,NULL,FALSE);
  /* This one is a bad idea - first param shouldn't be NULL */
  CreateProcess(NULL, "C:\\Program Files\\GoodGuy\\GoodGuy.exe -x", "");
  /* Test interaction of quote characters */
  printf("%c\n", 'x');
  printf("%c\n", '"');
  printf("%c\n", '\"');
  printf("%c\n", '\'');
  printf("%c\n", '\177');
  printf("%c\n", '\xfe');
  printf("%c\n", '\xd');
  printf("%c\n", '\n');
  printf("%c\n", '\\');
  printf("%c\n", "'");
}


int getopt_example(int argc,char *argv[]) {
    while ((optc = getopt_long (argc, argv, "a",longopts, NULL )) != EOF) {
    }
}

int testfile() {
  FILE *f;
  f = fopen("/etc/passwd", "r"); 
  fclose(f);
}

/* Regression test: handle \\\n after end of string */

#define assert(x) {\
 if (!(x)) {\
 fprintf(stderr,"Assertion failed.\n"\
 "File: %s\nLine: %d\n"\
 "Assertion: %s\n\n"\
 ,__FILE__,__LINE__,#x);\
 exit(1);\
 };\
 }

int accesstest() {
  int access = 0; /* Not a function call.  Should be caught by the
                     false positive test, and NOT labelled as a problem. */
}

Copy-paste this code into a blank .C file and save it.

Now, finally, here comes the actual Flawfinding time. *phew*

Step 4.1: Navigate to your C code

Navigate to whatever directory your C-code-to-be-tested is in.

Then, while holding the Shift key, right-click in an empty region in the folder, and you will see an “Open command window here” option. Click it and you will see a Command Prompt window with the current directory already set in it:

Step 4.2: Actual Flawfinding, promise!

Here’s the part where you actually Flawfind, despite all the other subheadings that have misled you into believing your Flawfinding will immediately begin…

Alright, so, in the Command Prompt window that’s in front of you, type the following and execute it:

flawfinder.py test.c

And you will see the output as:

All your C code vulnerabilities are shown in the Command Prompt window. If you wish to output all results into a text file to log it better, run the operation this way:

flawfinder.py test.c > results.txt

What this will do is, it will Flawfind and store the output in a new text document in the current directory:

There you have it! A computer telling you you should fix your C code or you will be hacked to oblivion. What a time to be alive!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.