Friday, 10 January 2014

Learning assembly with GDB

Learning assembly with GDB

Let's start by disassembling a program with GDB and learning how to read the output. Type the following program into a text file and save it as simple.c:
int main()
{
    int a = 5;
    int b = a + 6;
    return 0;
}
Now compile it with debugging symbols and no optimizations and then run GDB:1
$ CFLAGS="-g -O0" make simple
cc -g -O0    simple.c   -o simple
$ gdb simple
Inside GDB, we'll break on main and run until we get to the return statement. We put the number 2 after next to specify that we want to run next twice:
(gdb) break main
(gdb) run
(gdb) next 2
Now let's use the disassemble command to show the assembly instructions for the current function. You can also pass a function name to disassemble to specify a different function to examine.
(gdb) disassemble
Dump of assembler code for function main:
0x0000000100000f50 <main+0>:    push   %rbp
0x0000000100000f51 <main+1>:    mov    %rsp,%rbp
0x0000000100000f54 <main+4>:    mov    $0x0,%eax
0x0000000100000f59 <main+9>:    movl   $0x0,-0x4(%rbp)
0x0000000100000f60 <main+16>:   movl   $0x5,-0x8(%rbp)
0x0000000100000f67 <main+23>:   mov    -0x8(%rbp),%ecx
0x0000000100000f6a <main+26>:   add    $0x6,%ecx
0x0000000100000f70 <main+32>:   mov    %ecx,-0xc(%rbp)
0x0000000100000f73 <main+35>:   pop    %rbp
0x0000000100000f74 <main+36>:   retq   
End of assembler dump.
The disassemble command defaults to outputting instructions in AT&T syntax, which is the same syntax used by the GNU assembler.2 Instructions in AT&T syntax are of the format mnemonic source, destination. The mnemonic is a human readable name for the instruction. Source and destination are operands and can be immediate values, registers, memory addresses, or labels. Immediate values are constants, and are prefixed by a $. For instance, $0x5 represents the number 5 in hexadecimal. Register names are prefixed by a %.

Registers

It's worth taking a quick detour to understand registers. Registers are data storage locations directly on the CPU. With some exceptions, the size, or width, of a CPU's registers define its architecture. So if you have a 64-bit CPU, your registers will be 64 bits wide. The same is true of 32-bit CPUs (32-bit registers), 16-bit CPUs, and so on.3 Registers are very fast to access and are often the operands for arithmetic and logic operations.
The x86 family has a number of general and special purpose registers. General purpose registers can be used for any operation and their value has no particular meaning to the CPU. On the other hand, the CPU relies on special purpose registers for its own operation and the values stored in them have a specific meaning depending on the register. In our example above, %eax and %ecx are general purpose registers, while %rbp and %rsp are special purpose registers. %rbp is the base pointer, which points to the base of the current stack frame, and %rsp is the stack pointer, which points to the top of the current stack frame. %rbp always has a higher value than %rsp because the stack starts at a high memory address and grows downwards. If you are unfamiliar with the call stack, you can find a good introduction on Wikipedia.
One quirk of the x86 family is that it has maintained backwards compatibility all the way back to the 16-bit 8086 processor. As x86 moved from 16-bit to 32-bit to 64-bit, the registers were expanded and given new names so as to not break backwards compatibility with code that was written for older, narrower CPUs.
Take the general purpose register AX, which is 16 bits wide. The high byte can be accessed with the name AH, and the low byte with the name AL. When the 32-bit 80386 came out, the Extended AX register, or EAX, referred to the 32-bit register, while AX continued to refer to a 16-bit register that made up the lower half of EAX. Similarly, when the x86_64 architecture came out, the "R" prefix was used and EAX made up the lower half of the 64-bit RAX register. I've included a diagram below based on a Wikipedia article to help visualize the relationships I described:
|__64__|__56__|__48__|__40__|__32__|__24__|__16__|__8___|
|__________________________RAX__________________________|
|xxxxxxxxxxxxxxxxxxxxxxxxxxx|____________EAX____________|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|_____AX______|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|__AH__|__AL__|

Back to the code

This should be enough information to start reading our disassembled program.
0x0000000100000f50 <main+0>:    push   %rbp
0x0000000100000f51 <main+1>:    mov    %rsp,%rbp
The first two instructions are called the function prologue or preamble. First we push the old base pointer onto the stack to save it for later. Then we copy the value of the stack pointer to the base pointer. After this, %rbp points to the base of main's stack frame.
0x0000000100000f54 <main+4>:    mov    $0x0,%eax
This instruction copies 0 into %eax. The x86 calling convention dictates that a function's return value is stored in %eax, so the above instruction sets us up to return 0 at the end of our function.
0x0000000100000f59 <main+9>:    movl   $0x0,-0x4(%rbp)
Here we have something we haven't encountered before: -0x4(%rbp). The parentheses let us know that this is a memory address. Here, %rbp is called the base register, and -0x4 is the displacement. This is equivalent to %rbp + -0x4. Because the stack grows downwards, subtracting 4 from the base of the current stack frame moves us into the current frame itself, where local variables are stored. This means that this instruction stores 0 at %rbp - 4. It took me a while to figure out what this line was for, but it seems that clang allocates a hidden local variable for an implicit return value from main.
You'll also notice that the mnemonic has the suffix l. This signifies that the operands will be long (32 bits for integers). Other valid suffixes are byte, short, word, quad, and ten. If you see an instruction that does not have a suffix, the size of the operands are inferred from the size of the source or destination register. For instance, in the previous line, %eax is 32 bits wide, so the mov instruction is inferred to be movl.
0x0000000100000f60 <main+16>:   movl   $0x5,-0x8(%rbp)
Now we're getting into the meat of our sample program! The first line of assembly is the first line of C in main and stores the number 5 in the next available local variable slot (%rbp - 0x8), 4 bytes down from our last local variable. That's the location of a. We can use GDB to verify this:
(gdb) x &a
0x7fff5fbff768: 0x00000005
(gdb) x $rbp - 8
0x7fff5fbff768: 0x00000005
Note that the memory addresses are the same. You'll notice that GDB sets up variables for our registers, but like all variables in GDB, we prefix it with a $ rather than the % used in AT&T assembly.
0x0000000100000f67 <main+23>:   mov    -0x8(%rbp),%ecx
0x0000000100000f6a <main+26>:   add    $0x6,%ecx
0x0000000100000f70 <main+32>:   mov    %ecx,-0xc(%rbp)
We then move a into %ecx, one of our general purpose registers, add 6 to it and store the result in %rbp - 0xc. This is the second line of C in main. You've maybe figured out that %rbp - 0xc is b, which we can verify in GDB:
(gdb) x &b
0x7fff5fbff764: 0x0000000b
(gdb) x $rbp - 0xc
0x7fff5fbff764: 0x0000000b
The rest of main is just cleanup, called the function epilogue:
0x0000000100000f73 <main+35>:   pop    %rbp
0x0000000100000f74 <main+36>:   retq   
We pop the old base pointer off the stack and store it back in %rbp and then retq jumps back to our return address, which is also stored in the stack frame.
So far we've used GDB to disassemble a short C program, gone over how to read AT&T assembly syntax, and covered registers and memory address operands. We've also used GDB to verify where our local variables are stored in relation to %rbp. Now we're going to use our newly acquired skills to explain how static local variables work.

Understanding static local variables

Static local variables are a very cool feature of C. In a nutshell, they are local variables that only get initialized once and persist their values across multiple calls to the function where they are defined. A simple use case for static local variables is a Python-style generator. Here's one that generates all of the natural numbers up to INT_MAX:
/* static.c */
#include <stdio.h>
int natural_generator()
{
        int a = 1;
        static int b = -1;
        b += 1;
        return a + b;
}

int main()
{
        printf("%d\n", natural_generator());
        printf("%d\n", natural_generator());
        printf("%d\n", natural_generator());

        return 0;
}
When compiled and run, this program prints the first three natural numbers:
$ CFLAGS="-g -O0" make static
cc -g -O0    static.c   -o static
$ ./static
1
2
3
But how does this work? To understand static locals, we're going to jump into GDB and look at the assembly. I've removed the address information that GDB adds to the disassembly so that everything fits on screen:
$ gdb static
(gdb) break natural_generator
(gdb) run
(gdb) disassemble
Dump of assembler code for function natural_generator:
push   %rbp
mov    %rsp,%rbp
movl   $0x1,-0x4(%rbp)
mov    0x177(%rip),%eax        # 0x100001018 <natural_generator.b>
add    $0x1,%eax
mov    %eax,0x16c(%rip)        # 0x100001018 <natural_generator.b>
mov    -0x4(%rbp),%eax
add    0x163(%rip),%eax        # 0x100001018 <natural_generator.b>
pop    %rbp
retq   
End of assembler dump.
The first thing we need to do is figure out what instruction we're on. We can do that by examining the instruction pointer or program counter. The instruction pointer is a register that stores the memory address of the next instruction. On x86_64, that register is %rip. We can access the instruction pointer using the $rip variable, or alternatively we can use the architecture independent $pc:
(gdb) x/i $pc
0x100000e94 <natural_generator+4>:  movl   $0x1,-0x4(%rbp)
The instruction pointer always contains the address of the next instruction to be run, which means the third instruction hasn't been run yet, but is about to be.
Because knowing the next instruction is useful, we're going to make GDB show us the next instruction every time the program stops. In GDB 7.0 or later, you can just run set disassemble-next-line on, which shows all the instructions that make up the next line of source, but we're using Mac OS X, which only ships with GDB 6.3, so we'll have to resort to the display command. display is like x, except it evaluates its expression every time our program stops:
(gdb) display/i $pc
1: x/i $pc  0x100000e94 <natural_generator+4>:  movl   $0x1,-0x4(%rbp)
Now GDB is set up to always show us the next instruction before showing its prompt.
We're already past the function prologue, which we covered earlier, so we'll start right at the third instruction. This corresponds to the first source line that assigns 1 to a. Instead of next, which moves to the next source line, we'll use nexti, which moves to the next assembly instruction. Afterwards we'll examine %rbp - 0x4 to verify our hypothesis that a is stored at %rbp - 0x4.
(gdb) nexti
7           b += 1;
1: x/i $pc  mov   0x177(%rip),%eax # 0x100001018 <natural_generator.b>
(gdb) x $rbp - 0x4
0x7fff5fbff78c: 0x00000001
(gdb) x &a
0x7fff5fbff78c: 0x00000001
They are the same, just as we expected. The next instruction is more interesting:
mov    0x177(%rip),%eax        # 0x100001018 <natural_generator.b>
This is where we'd expect to find the line static int b = -1;, but it looks substantially different than anything we've seen before. For one thing, there's no reference to the stack frame where we'd normally expect to find local variables. There's not even a -0x1! Instead, we have an instruction that loads 0x100001018, located somewhere after the instruction pointer, into %eax. GDB gives us a helpful comment with the result of the memory operand calculation and a hint telling us that natural_generator.b is stored at this address. Let's run this instruction and figure out what's going on:
(gdb) nexti
(gdb) p $rax
$3 = 4294967295
(gdb) p/x $rax
$5 = 0xffffffff
Even though the disassembly shows %eax as the destination, we print $rax, because GDB only sets up variables for full width registers.
In this situation, we need to remember that while variables have types that specify if they are signed or unsigned, registers don't, so GDB is printing the value of %rax unsigned. Let's try again, by casting %rax to a signed int:
(gdb) p (int)$rax
$11 = -1
It looks like we've found b. We can double check this by using the x command:
(gdb) x/d 0x100001018
0x100001018 <natural_generator.b>:  -1
(gdb) x/d &b
0x100001018 <natural_generator.b>:  -1
So not only is b stored at a low memory address outside of the stack, it's also initialized to -1 before natural_generator is even called. In fact, even if you disassembled the entire program, you wouldn't find any code that sets b to -1. This is because the value for b is hardcoded in a different section of the sample executable, and it's loaded into memory along with all the machine code by the operating system's loader when the process is launched.4
With this out of the way, things start to make more sense. After storing b in %eax, we move to the next line of source where we increment b. This corresponds to the next two instructions:
add    $0x1,%eax
mov    %eax,0x16c(%rip)        # 0x100001018 <natural_generator.b>
Here we add 1 to %eax and store the result back into memory. Let's run these instructions and verify the result:
(gdb) nexti 2
(gdb) x/d &b
0x100001018 <natural_generator.b>:  0
(gdb) p (int)$rax
$15 = 0
The next two instructions set us up to return a + b:
mov    -0x4(%rbp),%eax
add    0x163(%rip),%eax        # 0x100001018 <natural_generator.b>
Here we load a into %eax and then add b. At this point, we'd expect %eax to be 1. Let's verify:
(gdb) nexti 2
(gdb) p $rax
$16 = 1
%eax is used to store the return value from natural_generator, so we're all set up for the epilogue which cleans up the stack and returns:
pop    %rbp
retq   
Now we understand how b is initialized, let's see what happens when we run natural_generator again:
(gdb) continue
Continuing.
1

Breakpoint 1, natural_generator () at static.c:5
5           int a = 1;
1: x/i $pc  0x100000e94 <natural_generator+4>:  movl   $0x1,-0x4(%rbp)
(gdb) x &b
0x100001018 <natural_generator.b>:  0
Because b is not stored on the stack with other local variables, it's still zero when natural_generator is called again. No matter how many times our generator is called, b will always retain its previous value. This is because it's stored outside the stack and initialized when the loader moves the program into memory, rather than by any of our machine code.

Conclusion

We began by going over how to read assembly and how to disassemble a program with GDB. Afterwards, we covered how static local variables work, which we could not have done without disassembling our executable.
We spent a lot of time alternating between reading the assembly instructions and verifying our hypotheses in GDB. It may seem repetitive, but there's a very important reason for doing things this way: the best way to learn something abstract is to make it more concrete, and one of the best way to make something more concrete is to use tools that let you peel back layers of abstraction. The best way to to learn these tools is to force yourself to use them until they're second nature.

Tuesday, 15 October 2013

Network Mapper: nmap

Nmap (“Network Mapper”) is an open source tool for network exploration and security auditing.

SYNOPSIS
       nmap [Scan Type...] [Options] {target specification}


let's consider that we want to know which operating system is running on a remote computer system. To do this, use following command-

#nmap -O remote_system_ip

Remote OS detection
nmap uses TCP/IP Stack fingerprinting  to detect remote OS. Nmap sends a series of TCP and UDP packets to the remote host and examines practically every bit in the responses. Nmap compares the results to its nmap-os-db.


To scan range of IP address

#nmap 192.168.10.0/24       scan  192.168.10.0 to 192.168.10.255
or
#nmap 192.168.10.0-255
or
nmap 192.168.10-14.0-23

Only Ping scan -sP (Skip port scan)

This option tells Nmap not to do a port scan after host discovery, and only print out the available hosts

#nmap -sP 192.168.6.24

Don’t ping -PN (No ping)

 If we use this option, nmap simply won’t send any ICMP echo requests to the target.

#nmap -PN 192.168.6.24

ARP Ping scan

#nmap -PR 192.168.6.24

This –PR option will start to execute an ARP (Address Resolution Protocol) ping scan on the specified target host.

All Ports Scan

The -p option along with a  “*” is used to scan all the TCP/IP ports (which are 65,535 in number) on the target host.

#nmap -p “*” 10.10.6.204


Select TCP or UDP protocol

Finally, using option -p we may also select some ports to scan depending upon which protocol they use- either TCP or UDP.

#nmap -p T:100-1000 10.10.6.204

#nmap -p U:100-1000 10.10.6.204
In examples a port range with (T), that implies TCP only, is specified. We can also mention U in case we want to scan UDP ports.

Service version detection

The -sV option is used to determine version of different services running on a host.

#nmap -sV localhost

Sunday, 13 October 2013

Buffer Overflow Attack Explained with a C Program Example


In this buffer overflow tutorial, we will discuss the basics of the following :
  • What is buffer overflow?
  • How a buffer overflow happens?
  • How a buffer overflow attack takes place?
  • How to avoid buffer overrun?
We’ll keep the explanation and examples simple enough for you to understand the concept completely. We’ll also use C programming language to explain the buffer overflow concept.

What is Buffer Overflow?

A buffer, in terms of a program in execution, can be thought of as a region of computer’s main memory that has certain boundaries in context with the program variable that references this memory.
For example :
char buff[10]
In the above example, ‘buff’ represents an array of 10 bytes where buff[0] is the left boundary and buff[9] is the right boundary of the buffer.
Lets take another example :
int arr[10]
In the above example, ‘arr’ represents an array of 10 integers. Now assuming that the size of integer is 4 bytes, the total buffer size of ‘arr’ is 10*4 = 40 bytes. Similar to the first example, arr[0] refers to the left boundary while arr[9] refers to the right boundary.
By now it should be clear what a buffer means. Moving on lets understand when a buffer overflows.
A buffer is said to be overflown when the data (meant to be written into memory buffer) gets written past the left or the right boundary of the buffer. This way the data gets written to a portion of memory which does not belong to the program variable that references the buffer.
Here is an example :
char buff[10];
buff[10] = 'a';
In the above example, we declared an array of size 10 bytes. Please note that index 0 to index 9 can used to refer these 10 bytes of buffer. But, in the next line, we index 10 was used to store the value ‘a’. This is the point where buffer overrun happens because data gets written beyond the right boundary of the buffer.
It is also important for you to understand how GCC compilation process works to create a C executable.

Why are buffer overflows harmful?

Some of us may think that though a buffer overflow is a bad programming practice but so is an unused variable on stack, then why there is so much hullabaloo around it? What is the harm buffer overrun can cause to the application?
Well, if in one line we have to summarize the answer to these questions then it would be :
Buffer overflows, if undetected, can cause your program to crash or produce unexpected results.
Lets understand a couple of scenarios which justify the answer mentioned above.
1. Consider a scenario where you have allocated 10 bytes on heap memory:
char *ptr  = (char*) malloc(10);
Now, if you try to do something like this :
ptr[10] = 'c';
Then this may lead to crash in most of the cases. The reason being, a pointer is not allowed to access heap memory that does not belong to it.
2. Consider another scenario where you try to fill a buffer (on stack) beyond it’s capacity :
char buff[10] = {0};
strcpy(buff, "This String Will Overflow the Buffer");
As you can see that the strcpy() function will write the complete string in the array ‘buff’ but as the size of ‘buff’ is less than the size of string so the data will get written past the right boundary of array ‘buff’. Now, depending on the compiler you are using, chances are high that this will get unnoticed during compilation and would not crash during execution. The simple reason being that stack memory belongs to program so any buffer overflow in this memory could get unnoticed.
So in these kind of scenarios, buffer over flow quietly corrupts the neighbouring memory and if the corrupted memory is being used by the program then it can cause unexpected results.
You also need to understand how you can prevent stack smashing attacks with GCC.

Buffer Overflow Attacks

Until now we discussed about what buffer overflows can do to your programs. We learned how a program could crash or give unexpected results due to buffer overflows. Horrifying isn’t it ? But, that it is not the worst part.
It gets worse when an attacker comes to know about a buffer over flow in your program and he/she exploits it. Confused? Consider this example :
#include <stdio.h>
#include <string.h>

int main(void)
{
    char buff[15];
    int pass = 0;

    printf("\n Enter the password : \n");
    gets(buff);

    if(strcmp(buff, "manish"))
    {
        printf ("\n Wrong Password \n");
    }
    else
    {
        printf ("\n Correct Password \n");
        pass = 1;
    }

    if(pass)
    {
       /* Now Give root or admin rights to user*/
        printf ("\n Root privileges given to the user \n");
    }

    return 0;
}
The program above simulates scenario where a program expects a password from user and if the password is correct then it grants root privileges to the user.
Let’s the run the program with correct password ie ‘manish’ :
$ ./bfrovrflw 

 Enter the password :
manish

 Correct Password 

 Root privileges given to the user
This works as expected. The passwords match and root privileges are given.
But do you know that there is a possibility of buffer overflow in this program. The gets() function does not check the array bounds and can even write string of length greater than the size of the buffer to which the string is written. Now, can you even imagine what can an attacker do with this kind of a loophole?
Here is an example :
$ ./bfrovrflw 

 Enter the password :
hhhhhhhhhhhhhhhhhhhh

 Wrong Password 

 Root privileges given to the user
In the above example, even after entering a wrong password, the program worked as if you gave the correct password.
There is a logic behind the output above. What attacker did was, he/she supplied an input of length greater than what buffer can hold and at a particular length of input the buffer overflow so took place that it overwrote the memory of integer ‘pass’. So despite of a wrong password, the value of ‘pass’ became non zero and hence root privileges were granted to an attacker.
There are several other advanced techniques (like code injection and execution) through which buffer over flow attacks can be done but it is always important to first know about the basics of buffer, it’s overflow and why it is harmful.
To avoid buffer overflow attacks, the general advice that is given to programmers is to follow good programming practices. For example:
  • Make sure that the memory auditing is done properly in the program using utilities like valgrind memcheck
  • Use fgets() instead of gets().
  • Use strncmp() instead of strcmp(), strncpy() instead of strcpy() and so on.

Saturday, 12 October 2013

Performance Analysis With Perf

Requires debugging symbols to be installed
            kernel-debuginfo / vmlinux for kernel
            Applications compiled with -g

By default Perf commands restricted to root
             Security checks can be disabled (temporarily) with
             #echo 0 > / proc / sys / kernel / perf_event_paranoid

#perf list
  

Lists all events supported by the current architecture
Any event names in first column can be used
Hardware events use the PMU
       Low overhead
Software events are triggered by the kernel
Many hardware events missing
       Can be set as a raw event
       Documented by CPU manufacturers

#perf record
Reads performance data and generates a file in the current directory:
       file name: perf.data

Can generate a large dataset if profiling the whole system
Or if recording with call-graphs (-g)
Which is event is recorded can be specified with -e:
#perf record -e instructions sleep 5
#perf record -e LLC-loads /usr/bin/firefox

Recording can be restricted in different ways
          1) Specific command (default)
              #perf record command
          2)All CPU's for the duration of specified command
              #perf record -a commmand
          3)Specific CPU's only
              #perf record -C CPU_number command

command : any command you want to check
CPU_number: 0,1,2 i.e id of cpu you want to check
#perf report

To generate report (using perf.data file)




Attaching perf to exesting process

#perf record -p $(pidof process)

Attaching to thread using tid

#perf record -t thread_id

For group of thread

#perf record -G groupname

Saturday, 15 June 2013

How to Compile Linux Kernel from Source

Linux kernel is the important part of all Linux family of operating systems including Ubuntu, CentOS, and Fedora.

In this tutorial, we’ll explain how to compile Linux kernel from source.

1.Download Kernel source from kernel.org

 # wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.3.tar.xz
 

2. Untar the kernel source 

 # tar -xvJf linux-3.9.3.tar.xz
 

3. Configure kernel

 # cd linux-3.9.3

 # make menuconfig

 
We will use the default config provided by the kernel. So select “Save” and save the config in the file name “.config”
 

4. Compile the kernel 

   # make

 5. Compile Kernel modules 

  # make modules 

6. Install kernel modules

  # make modules_install

7. Install new kernel

  # make install

 8. Boot with new kernel

 #  reboot

Pipe

Pipes may be considered as open files that have no corresponding image in filesystems.

Pipes are created by pipe() system call  by a process , pipe() system call returns a pair of file descriptor .  Descriptor can be passed to decedents through  fork() system call. Process can read from pipe using read() system call and can write using write() system call.

POSIX defines only half-duplex (even pipe() returns 2 descriptor each process must close one before using other)  pipes .
Other Unix system such as System V 4 implement full-duplex pipes.

example : ls | more 
Internally what is  happening ?

1.Invokes the pipe() system call , say  return vale is file descriptor 3 (read channel) and 4(write channel)
2.Invokes fork() system call twice.
3.Invokes the close() system call .
 
The first child process executes ls and perform following operations
1. Invokes dup2(4,1) to copy file descriptor 4 to 1 .
2.Invokes close() system call to release file descriptors 3 and 4.
3.Invokes the execve() system call to execute the ls program  ,the program writes output to the file that has descriptor 1 (standard output) . i.e. it writes into the pipe.

The second child process executes more program and perform following operations
1.Invokes dup2(3,0) to copy file descriptor 3 to 0. (now file descriptor 0 is read channel )
2..Invokes close() system call to release file descriptors 3 and 4.
3.Invokes the execve() system call to execute the more program. The program reads its input from file with descriptor 0(by default) i.e from pipe (now)


If two or more process read or write to same pipe they must explicitly synchronize their access by using file locking or IPC semaphores