Wednesday, February 21, 2007

What are HEADER FILES ?

Tonight i began to write a linklist and a stack data structer implementation. It will be the most strong when it is completed. I try to complete it untill this sunday.
For now i want to tell about the header files. what are they for? Why do we need a header file like iostream.h or linklist.h?
When we are in the development, we generally want to write our class declarition to a header file and the methods definitions to a source file ( cpp ). This makes development more modular and easy.
However i want to talk about another issue about header files! It is a low level detail. Why do compilers, linkers (!), loaders (!) need these files?

If you dont know what are stored in the header files you can look inside of them. They contain ( at least they should contain ) only the declaritons of functions! For instance when we write an int ADD( int , int ) function, the definition of the function (i.e body ) doesnt exist in the header file. In fact definition of functions are stored in libraries. So, why the compiler, linker and loader want them?

The answers are really simple. However if you dont know the differences between compiler and linker, you may have some diffucties to understand the facts. So lets introduce these concepts with a few lines:

Compiler: compiles the C code :) its job is creating the object code from the source files. object files contain object code, debug information, symbols, segment informations etc.

Linker: Assume that your project consists of 2 source files. One source file contains a function and another source file uses this function inside it. When we compile them we have two object files because i tell you that compiler generates object files. So these two object files have to be linked in order to create an executable file. Linkers job is linking the object files which compiler generates.

Loader: Everything goes fine and finally we have an executable file. However there is a problem, it is stored in the secondary disk. When i want to execute it, the loader works and load this program to the memory, makes neccessary operations such as memory management process management and then our program becomes a process on the memory :)

It is worth to mention that compilers and linkers are part of the development tools while loaders are the parts of the operating system.

Anyway, you now have a basic knowledge about compilers, linkers and loaders. So is it important to have a header file?
Now i intorduce the purpose of the header file; Header files are required because they are used for type ( prototype ) checking!
Ok, so lets examine when we need this checking mechanism.
When we compile a source file, compiler looks for syntax errors. It is important the provide the correct syntaxes to compiler. So header files tell the compiler that this function has a prototype like this. Then compiler decides whether the programmer codes the application by correct function calls or not!
We see that compiler needs them because of checking the syntax.
For the linkers and loaders, header files arent important. Because they know that compiler generates the object code and control the syntax of the code before generating this object code. So linker basically links the neccessary libraries, object files and create the executable. Loader takes this executable and loads the memory. The definitions of the functions are stored in shared libraries and the in the executable itself. NOT in the header files!!!

However, what if we write the function definition to the inside of the header file!!
This means that we are bad programmers:) because our program may depend this header file in order to work correctly.

I ve tried to explain the roles of the compiler, linker and loader. In addition, i ve tried to give a brief summary about the header files. See you later!

Wednesday, February 14, 2007

A Puzzle in C++

Today i want to introduce you a puzzle :) Indeed, it is a design problem! We will define the problem and explain the solution step by step. If you are ready lets begin!

One day someone came to me and said that "Hey emreknlk, i need a special class that at one time only one instance has to be allowed to live in the memory. I use this class as a special source consumer so there shouldnt be more than one instance of this class. At most one instance, do you understand me ha?"

and i said, "Hey john, be relax man, it is easy to implement. just watch it".

So, you understand the problem. We design a class that at most one object is allowed to be created. I mean, if there is no object around, you could create one. However, if there is an object, so there shouldnt be one more!

Before reading the solution, you can try to solve it by yourself.

Ok, let's implement this class otherwise john will be angry :p

There may be multiple solutions to this design problem. If you design in another way you can share it with us by putting a comment;)

Firstly i want to put the constructor of the class to the private area! Noone can create an object directly! Lets say the class name will be "CUnique".

CUnique inst; <- by putting the constructor to private, this line produce compiler error.

We prevent creating an instance of this class by putting the constructor to private area. However we have a problem, according to the problem, it should be allowed to create one instance. If we mark the ctor ( constructor ) as private then we cant create any instance!

For solving this problem, we simply define a static boolean member "isAllowedToCreate" and a static member function "createInstance". Purpose is very easy to understand. createInstance function can access to private constructor because it is a class method. If isAllowedToCreate is true then the call to createInstance returns an instance of this class by calling the constructor inside the static function. In addition, isAllowedToCreate variable has to be assigned to false otherwise multiple calls to createInstance function returns multiple instances which is prohibited. It is certain that "isAllowedToCreate" member has to be put to the private area, otherwise programmers can reach it and change it to the true value.

So, lets look at the below code:

class CUnique{

int Id; //a private member of class

//We define contructor in private section so that nobody can access it
//from the outside of the class.
CUnique( int ID = 0 ): Id( ID ) {}

//we define a boolean variable for knowing if an instance is allowed to be created.
static bool isAllowedToCreate;

public:

//this static function is used to create an instance if there hasnt been created yet
static CUnique* createInstance( int ID = 0 ){

if( isAllowedToCreate ){
isAllowedToCreate = false;
return (new CUnique( ID ));
}

//if there is an existing instance then returns NULL
return static_cast< CUnique* >(0) ;
}

int getId() const { return this->Id; }
};

looks fine, isnt it? If isAllowedToCreate is true we can create an instance. But it has a serios problem! What if we delete the instance that we have created! There will be no object around but worse thing is that isAllowedToCreate has the value false! We can never create an instance again although it is legal! So make an action and write a destructor to this class.

//in destructor set the boolean variable true for creating new instance.
~CUnique(){
isAllowedToCreate = true;
}


Yes now it looks really fine. isnt it? We can create only one instance and if we delete this instance we can create another. However, you sholdnt believe to me because i am lying! We can create one instance it is true, but we can go further and create one another! Indeed we can create hundreds of objects which live together at the same time! Lets look at this:

CUnique *ptr1 , *ptr2;
ptr2 = CUnique::createInstance();
ptr1 = new CUnique( *ptr2 );

We simply call the copy constructor!! if we dont write a copy contructor, compiler will provide one for us which copy every single byte of one instance to anohter. However if we write a copy constructor compiler wont provide it for us. We should simply put the copy constructor to the private area like constructor! If anyone tries to use it, compiler will generate an error saying that you can not access a private member.

Our final class contains a copy constructor and destructor is:

class CUnique{

int Id; //a private member of class

//We define contructor in private section so that nobody can access it
//from the outside of the class.
CUnique( int ID = 0 ): Id( ID ) {}

//put copy constructor to private area!
CUnique( CUnique& ){}

//we define a boolean variable for knowing if an instance is allowed to be created.
static bool isAllowedToCreate;

public:

//this static function is used to create an instance if there hasnt created yet
static CUnique* createInstance( int ID = 0 ){

if( isAllowedToCreate ){
isAllowedToCreate = false;
return (new CUnique( ID ));
}

//if there is an existing instance then returns NULL
return static_cast<CUnique* >(0) ;
}

int getId() const { return this->Id; }

//in destructor set the boolean variable true for creating new instance.
~CUnique(){
isAllowedToCreate = true;
}
};

bool CUnique::isAllowedToCreate = true;

I write a test case, please read the comments and inspect the output:

int main(){

CUnique *ptr1 , *ptr2;

//create the first instance
ptr1 = ptr1->createInstance();

//this call returns NULL, because another instance is living
ptr2 = CUnique::createInstance();

cout << "ptr1's address:" << int ( ptr1 ) << endl ;
cout << "ptr2's address:" << int( ptr2 ) << endl ;

//delete the unique instance !!!!
delete ptr1;

//now this call returns an instance to ptr2 because there is no instance around.
ptr2 = CUnique::createInstance();
cout << "ptr2's address:" << int( ptr2 ) << endl ;

ptr1 = ptr1->createInstance();
cout << "ptr1's address:" << int( ptr1 ) << endl ;

return 0;
}


OUTPUT is:
ptr1's address:3362632
ptr2's address:0
ptr2's address:3362632
ptr1's address:0
Press any key to continue . . .


Dont forget that ptr2 = ptr1; is always a valid assignment but this doesnt mean there are multiple instances. Both pointers point the same object by this assignment.

Is this the final class? Can you crate an instance more than once with this class? I dont give the answers of these questions:) see you soon!

Tuesday, February 13, 2007

Advanced Pointer Operations in C/C++

I like pointers i love pointers i use pointers so i want to explain 3 things about pointers. These are
1) Pointer to pointers
2) Pointer to functions
3) A strange syntax:)

There are much things to say. Lets begin with Pointer to pointer.

1) Pointer to pointer

Why do we need a pointer which points to a pointer? It is a common question which may be asked by a person who doesnt know much about the memory and the pointers.
Basically a pointer is a 4byte variable and nothing more. It just stores an address as a value inside it. Before explaining what a pointer to pointer is, lets examine the below code:

#include
using namespace std;

int main(){
char character = 'E';

char *ptr = &character; //pointer stores an ADDRESS ( address of character )

cout << "Address of ptr:" << &ptr << endl;
cout << "Content of ptr :"<< hex <<(int) ptr < cout << "Address of character:" << (int )&character << endl;
cout <<"Content of character:"<<*ptr <
return 0;
}

output:
Address of ptr:0x22ff68
Content of ptr :22ff6f
Address of character:22ff6f
Content of character:E
Press any key to continue . . .

we see that, ptr is a variable, it has own address and it stores the address of a variable in it. Puttin a * at the begining of a pointer provide us the value which is stored in the variable whose address is stored in pointer variable.

Most of us know about it. So why a pointer to pointer is neccessary? There may be some cases requiring some changes on pointers! For example, if we need to change a pointer's content which is passed to a function, we must use a pointer to point that pointer. Lets see the wrong example:

we write a function which takes a pointer and wants to assign its value to NULL:

void wrongChange( char* ptr ){
ptr = NULL;
}

and see the test case:

int main(){
char character = 'E';

char *ptr = &character; //pointer stores an ADDRESS ( address of character )

cout << "Content of ptr :"<< hex <<(int) ptr < wrongChange( ptr );
cout << "Content of ptr :"<< hex <<(int) ptr <
return 0;
}

Output is:
Content of ptr :22ff6f
Content of ptr :22ff6f
Press any key to continue . . .

You see that pointer's content doesnt change in main function. The ptr pointer in main function still points to the same address. This is because we tell it to do like this. Lets examine the wrongChange function:
1) Purpose is assigning the pointers content to NULL
2) When we call wrongChange, it allocates a variable in its stack for its local ptr.
3) After allocating a space in its stack, it copies the value of input argument which is provided by main function to its local ptr. Note that its local ptr is completly different than the ptr which is defined in main.
4) Local variable ptr is a pointer too, because we defined it as a pointer in argument list. So it is very normal to assign it a NULL value.
5) We assign a NULL value to the local ptr. However the ptr which is defined in main is still same because its address is very very different from the local ptr which is defined in stack of wrongChange function.

We see the reason why our ptr in main function is not change. Lets make some correction in our wrongChange function and rename it as correctChange :)

void correctChange( char** ptr ){
*ptr = NULL;
}

What we do in correctChange is changing the input parameter from char* to char**
Now our local ptr which is again created in stack of correctChange can point to a pointer! You can easily quess that the pointer which local ptr points will be the pointer which is given as an input paramter from main function.
A key point is that, when we call the correctChange function we shold provide a parameter which is an address of a pointer. So after we derefer the local ptr by putting an asterix, we reach the pointer which we want to change!

Our test case looks like:
int main(){
char character = 'E';

char *ptr = &character; //pointer stores an ADDRESS ( address of character )

cout << "Content of ptr :"<< hex <<(int) ptr < correctChange( &ptr );
cout << "Content of ptr :"<< hex <<(int) ptr <
return 0;
}

Output is:
Content of ptr :22ff6f
Content of ptr :0
Press any key to continue . . .

look at the call in main function. We give the pointer's address to correctChange by using ampersand ( i.e. &ptr ). So correctChange function uses that address to reach the pointer. Moreover if we use double * in correctChange function, we obtain the value of character variable. I mean, **ptr gives the value of 'E' in correctChange because the first asterix reaches the pointer ptr which is defined in main and the second one reaches the variable which ptr ( in main ) points to.

A major usage area of pointer to pointers is in data structers head/root pointers. For example if we want to add a node to the begining of the list, we must give the address of the head pointer to the addNode function. Because if we dont do like this, the node which we want to add, will be added to a begining of the list probably. Yes it is true, indeed it is added to the begining but the head pointer isnt updated because of using a local head pointer! We must change the head pointer for adding a node to the head of the link list. You can try and you will see ;)

2) Pointer to functions

It is also possible to point a pointer to a function. A function name is an address where the codes for that function begins. If you dont believe to me lets look at this code:

#include
using namespace std;

void function(){
cout <<"emreknlk." << endl;
}

int main(){

cout << hex << (int) function << endl;

return 0;
}

Output is:
40128a
Press any key to continue .

Now, we prove it in other ways. We can point a pointer to a function. It requires a little knowledge about how to create a pointer for pointing a function. However it is very easy. The below codes are self explanatory. Please follow the comments carefully. Begin with a simple example:

#include
using namespace std;

void function(){
cout <<"emreknlk." << endl;
}

int main(){

//first void is return type of function
//(*ptr) says that this is a pointer :)
//(void) means this function does not takes an input parameter
void (*ptr)( void );

//now we can point this ptr to function.
//the ptr's definition and function's prototype is same, it is safe to point
ptr = function;

//now ptr means function, they are same, they point to same address
//call the function by using ptr !!!
ptr();

return 0;
}

output is
emreknlk.


You see that, after we create a proper pointer to our function, we simply assign function to ptr and call the ptr instead of function. They both points the same address so our function is executed properly. At this example, the function has no return type and has no input parameter. However, it is also very easy for functions which takes paramters and returns a variable. Lets see an example:

#include
using namespace std;

double multiply( int num1, float num2 ){
return num1 * num2;
}

int main(){

//double is return type of function
//(*ptr) says that this is a pointer :)
//(int,float) means this function takes two input which are int and float variables
double (*ptr)( int , float );

//now we can point this ptr to function.
//the ptr's definition and function's prototype is same, it is safe to point
ptr = multiply;

//now ptr means multiply function, they are same, they point to same address
//call the function by using ptr !!!
cout <<"3*5.5 = " << ptr( 3, 5.5 ) << endl;

return 0;
}

output is:
3*5.5 = 16.5
Press any key to continue . . .

Usage are of pointer to functions is very large. There can be a switch mechanism for determining the function that want to be called at run time. I also compare this mechanism with the polymorphism. In polymorphism the function being called is determined in run time too by using virtual methods. You can also use pointer to functions
for fun:)


3) A strange syntax

Yesterday, i spoke with my friends and we realized that some of our friends hadnt know a syntax in C. I want to introduce it in here briefly.

Look at that code:

int main(){

char name[] = "emreknlk";

cout << name[3] << endl; //first line
cout << 3[name] << endl; //second line

cout << *(name+3) << endl; //third line
cout << *(3+name) << endl; //last line:)

return 0;
}

output:
e
e
e
e

All four line produce the same result! Look at the second line, is it a little strange? This code is perfectly correct because of the arithmetics provide the same result for four line. What compiler does is adding two constants to each other, evaluates the sum as the address of a variable and takes the variable in that address.
You know that the array name is a constant pointer which points to begining of the array. So name[3] means take the variable from name+3. In addition to this arithmetic 3[name] means take the variable from 3+name which is the same address with first.

Lets see a slightly different code:

char name[] = "emreknlk";
cout << &2[name-2] << endl;

Output is : emreknlk

This is C and this is why i like it, why i love it, why i use it:)

Saturday, February 10, 2007

Buffer Overrun

Today i will talk about another security issue. Buffer overrun is a dangerous and destructive concept which shouldnt be exist in our codes. It has many forms like stack buffer overruns , heap buffer overruns, index out of bounds, ascii- unicode conflictions. However, i want to explain you only stack buffer overruns and leave the rest to you :)

When we look at the history of computer software, there were millions of dollars costs of these attacks. By using the buffer overflow attacks a hacker can reach lots of valuable informations or can destroy the whole system at once.

Before starting, i want to give some information about the C calling convention.
When we call a C function for a function, the caller function push the parameters to the stack in reverse order so the first parameter will be on the top of the stack and it is popped first. In addition when the called function wants to return to the caller it pops the return address of the caller from the stack and jump to there by taking this address. At this point, you can imagine that if the called function takes the wrong address from the stack, it jumps somewhere different then it shold jump to!

I want to show you with a simple example:
( My code is compiled in unix with gcc. I dont use Visual studio because it makes lots of optimization and has lots of flags which prevent overflow in debug mode )


#include stdio.h
#include string.h

void BufferOverFlow( char* str ){

char buffer[4];

//see the stack
printf("stack looks like: %p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n");

strcpy( buffer , str ); //copy without controlling anything

//see the stack after copying str to buffer
printf("Now stack looks like: %p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n");
}


void Information(){
printf("My credit card number: 333445566\n");
printf("My password: emreknlk\n");
}

int main(){

//last 4byte is the address of information function
char str[12]={1,2,3,4,5,6,7,8,0xb2,0x83,0x04,0x08};

printf("Address of Information:%p\n",Information);

BufferOverFlow(str); //call only BufferOverFlow function


return 0;
}


Lets look at the code. In the main function we simply call the BufferOverFlow function. Normally, we expect that BufferOverFlow function executes its code and returns to main again.
In our application we also have an important function whose name is Information. We dont want to show this function to anyone without permission.
However in the BufferOverFlow function, there is a bufferover flow exists. We dont control the str string while copying it to local variable buffer! buffer can take at most 4 byte because it is an char array of 4 elements, but we give it 12 elements and change the stacks content by overflow. Indeed, we change the return value which is stored in stack too. We give a new value as the Information function address so that BufferOverFlow function returns to Information function and all our data is displayed on the screen!! Look at the output:

-bash-2.05b$ ./buff
Address of Information:0x80483b2 <--This is the information functions address
stack looks like: 0x8e4062 <--Stack content in BufferOverFlow function
0x9caec0
0x80485b1
0xbfff8b48
0x9ccab8
0xbfff8b68
0x804843b <-- This is the return value that we override
0xbfff8b50
Now stack looks like: 0xbfff8b50 <-- After copying str to buffer
0x9caec0
0x80485b1
0xbfff8b48
0x4030201 <-- 1 2 3 4
0x8070605 <-- 5 6 7 8 ( overflow )
0x80483b2 <-- LOOK! the return value has changed! New value
0x9ccab8 is the address of Information!!!
My credit card number: 333445566 <-- Information function executes its body!
My password: emreknlk <-- my credit card and password are in the hackers
Segmentation fault hand :(
-bash-2.05b$

Yes we call another function by hacking the stack. The address of the functions can be obtained by using a debugger. And input parameter can be prepared by inspecting the code by running it with some input paramters.

In this post, we handle the buffer overrun issue. It has many forms and we show an example to stack buffer overflow. For preventing this issue, the code must be robust and safe libraries and functions should be used when coding the application.
See you again.

Thursday, February 08, 2007

Using PIPEs to TEST your application

Today, i will talk about pipes and how to use them. A pipe is a data flow from one direction to another direction and vice versa. Imagine that you have to write an application and this application takes some input parameters from another application which runs at the same time. There are several ways of IPC. One way is that, one application prints its results to a file, and the other application reads from this file and use it as an input provider!
However, today i introduce a different way of speaking. Pipe is a data flow mechanism. We can create pipes between 2 process so that one writes its data to pipe and another reads from that pipe. I give my example for unix systems in C.

Now the story is;
At the lowel level, main process defines an array with two elements:

int descriptors[2];

This array holds our file descriptors. So we must say to kernel that this array is used as a pipe:

pipe( descriptors );

After this call we can use descriptor[0] for reading from the pipe, and descriptor[1] for writing to that pipe. So, we write to one end, read from the other end of the pipe ( a flow is created ).

Using a pipe in a process is meanless unless this process try to communicate with outside. So i create a second process with a fork system call.

fork();

This call returns the pid of the child to the parent process, and returns 0 to the child process. I may explain the fork call at a later time but for now it is enough to know that calling a fork from a process creates a child process. So now we have 2 processes at our memory, these are the main process and its child. Now we pass some arguments from parent ( main ) process to child by using the pipe that we created just before.

In the parent process code, we simply write:

write( descriptors[1] , buff , strlen( buff) );

So look at the first parameter. It is the pipe that we created. We write the buffer to pipe's writable end.

In the child process code, we simply write:

read( descriptors[0] , buff , 22 );

Now we read from the pipe ( descriptors[0] ) and store the buffer in buff.

I hope you understand what the pipe is:) Here i give you complete code then i write a code for testing a program automatically by using pipe.

#include stdio.h
#include unistd.h


int main(){

int isParent;
char buff[255];

int descriptors[2];

if ( pipe( descriptors ) < 0 )
return 1;

isParent = fork();

if( isParent ) {
//parent process

strcpy( buff , "Hi, this is emreknlk!");

write( descriptors[1] , buff , strlen( buff) );

printf("Hi this is parent\n");

}else{
//child process
sleep( 1 );

read( descriptors[0] , buff , 22 );

printf("Hi this is child, buffer is: %s\n",buff);

}

close( descriptors[0] );
close( descriptors[1] );

return 0;

}


The output of this program:
-bash-2.05b$ ./pipe
Hi this is parent
-bash-2.05b$ Hi this is child, buffer is: Hi, this is emreknlk!

-bash-2.05b$


Now are you ready for making some differences!
Suppose that you have to test 100 different code which are written by 100 different person. What would you do? if this number is smaller, lets say 10, you can test it by manually by executing each of them and providing the neccessary inputs.
When the number of codes that must be tested become larger, then a code can be written for testing them automatically.

Assume that, we want to test this simple application:

#include stdio.h

int main(){

int number, i, fact = 1;

scanf("%d",&number); //take the number for calculating factorial

//calculate factorial
for( i = 2; i <= number ; i++)
fact *= i;

//print result to screen
printf("%d\n",fact);

return 0;
}


We will write a code for testing this code. tester should provide input to application and control the result which is calculated by application.
For this purpose it is clear that, in our test code we must create two pipe for writing input parameter from test code to application (i.e number variable ) and writing result from application to test code (i.e fact ).

After we compile the above code we rename it as app. Our test code for testing this factorial code is:

#include stdio.h
#include string.h
#include unistd.h
#include fcntl.h

int main(){

int isParent,n;
char buff[255];

int des1[2];
int des2[2];

if ( pipe( des1 ) < 0 || pipe( des2 ) < 0 )
return 1;

isParent = fork();

if( isParent ) {
//parent process

write( des1[1], "5\n" , 3 ); //send value to our application

do{
n =read( des2[0], buff , 255 ); //get the result!
}while( n<= 0);

if( strncmp(buff,"120\n",n) == 0 )
printf("Test Succeed!\n");
else
printf("Test Failed %s\n",buff);

}else{
//child process
close( STDIN_FILENO );
close( STDOUT_FILENO );
dup2( des1[0] , STDIN_FILENO ); //change des1[0] to stdin of child
dup2( des2[1], STDOUT_FILENO ); //change des2[1] to stdout of the child

close( des1[0] );
close( des1[1] );
close( des2[0] );
close( des2[1] );

if ( execlp("./app","./app",(char*)NULL) < 0 )
exit(1);
}

return 0;

}


In my computer this test passes and Test Succeed message appears on my screen.
Here i give a brief explanation about test code.

For child process: We replace its stdout and stdin with the pipe descriptors so when it wants to write to stdout, the test code can reach it from the pipe by reading it and when it wants to read an input from stdin, it can read the value from the pipe.
execlp command is used for replacing the context of the child process with the our factorial application. Here app is the name of our factorial application.

For parent process: It is the code which tests the factorial application. It simply send an input value ( i.e 5 ) to the factorial application and controls the return value if it is 120.

By using this automatic tool we can test lots of application which take one parameter , calculate the factorial and print the result. So some conventions must be exist. For example if the factorial application prints the result by this way:
"Factorial is 120"
Then our test code will be fail because it expects only the result ( i.e 120 )

I try to give the simplest example for writing a test tool. I plan to write about IO methods and IO multiplexing for writing much detail about this topic. See you later :)

Wednesday, February 07, 2007

A Security Issue - Threat modelling

Today, i talk about an important topic. Currently i ve been reading the book "Writing Secure Code". And one of its chapter is about Threat Modelling. So i want to give a brief summary about Threat Modelling.

Threat Modelling is important when designing a software, because if you dont identify your enemys probably you will fail! Threat modelling covers the concepts of determining threats and how to solve them.

Threat modelling provides extra advanteges to designers like finding bugs at earlier stages, understanding the project and its flow diagram, testing application at later stages.

So, How it should be organized? Threat modelling consists of 7 main parts. These are:

1) Creating the team for threat modelling
2) Separete the project into smaller parts
3) Analyze and find the threats for the project
4) Mark threats according to importance order
5) Determine the responds for threats
6) Identify the correct technique for solving the issue
7) Identify the correct technolgy for this technique.

So, think that we apply once these steps to out project in desing phase. Is it enough? The answer is no because this should be a iterative process. Noone can find all the threats at 1 step.

Lets inspect this 7 stages now...

1) Creating the team for threat modelling

Theat modelling team should contain at least 1 member of every phase of the project teams. So testers ,designers and coders should be included. Also a sales person may be in the team because he can explain the product features to customers more clearly.
Maximum number of members should be approximetly 10. Because too much people in the team may cause complexities.

2) Separete the project into smaller parts

This is a decomposition part of the application. Data flow diagrams (DFDs) can be used for this purpose. Level of the DFD is also important. Too much decomposition is not required in the threat modelling. In the application design phase this decomposition goes deeper than threat modelling.
Another issue at this step is, while decomposing there should be no conservation about the how to fix this threat, or the solutions. This step exists just for identifying threats while decomposing the modules.

3) Analyze and find the threats for the project

STRIDE
STRIDE is a technique for determining the threats in the application.

S : Spoofing identfy : Attackers show theirselves as another person who have grant privileges or access to the system. In http authentication it is possible to behave like this.

T: Tampering with data: Attackers change the data intentionally. Databases are the common targets.

R: Repudiation: This concept is important especially in e-commerce. Denying some operations because of being illegal. So for instance attackers may try to buy some things from the e-commerce web pages

I: Information disclosure: Attackers may try to access some informations like files, passwords although they havent any access privileges. This concept is related with spoofing. By spoofing, anyone can access any information on remote machine.

D: Denial of Service: Sometimes valid users for the systems can be blocked for the system. The usage of the system for them may be restriceted. This attacks generally occured to the servers so normal users are prevented to login.

E: Elevation of privilege: Probably this is the worst thing that attackers gain the administrator privileges and all system may be collapsed!

So i try to explain STRIDE method for determining the threats in applications. Certainly there can be another criteria that should be considered. STRIDE method is just a classification of common threats.

4) Mark threats according to importance order

After determining the threats for the application, now it is time to give marks to each of them. The highest mark the threat has, the biggest importance it has.

DREAD method

D: Damage potential: If attackes attacks with this threat, what will be the degree of the damage to the system.
R: Reproducibility: Is it easy to produce same attacks again and again.
E: Exploitability: Is it required much effort or experiment to make an attack
A: Affected Users: What is the percentege of the persons that will be affeceted by this threat
D: Discoverability: is this attack can be easly discovered? It is hard to meausre this metric.

After giving points to eeach of this metric, we find the total mark for this threat. Every threat which is determined in step three, should be marked by using a mark method like DREAD. So we can give decisions with these threats.

5) Determine the responds for threats

We analyze, determine and give marks. So it is time to take an action:) Basicly we can do 4 things:
A) Take no action :) This is not a good idea ;)
B) Say everything to your customers : this is not a good idea too. Because users generally skip the warning messages or they cant give the right decisions.
C) Disable the feature: Remove the threat with the feature from the project.
D) Fix it! : i think it is the best solution :)

6) Identify the correct technique for solving the issue
Every threat has different solution technique. According to STRIDE categories, choose the appropriate technique for the threat.

7) Identify the correct technolgy for this technique.
Finally, choose the technolgy for implementing the technique that is determined in step 6.



So, at this post i try to give you a small knowledge about the threat modelling. It is useful for applications because if we dont know our enemies, the project couldnt be successful. Threat modelling has lot of advantages and easy to process.

Reference: Writing Secure Code Second Edition.

See you soon :)

Saturday, February 03, 2007

Decision...

Hi all my friends,
I have a new decision about my blog that i ll write my new posts in english. I want to write in english because i see that some portion of the world miss the chance of reading my blog :))
So, the first thing that i want to say that, we have a wonderful saturday in this weekend. We had a small workshop in OraTurk about the oracle cost base optimizer. And the enjoyest part of this is being together with my friends and sharing the knowledge!
I try to explain the B-tree indexes and clustering factor to my collegues at this workshop. Also i had taken lots of pictures with my 6.0Mp casio camera:) So here i put one of them here..


see you till the next post :)