C Programming - Self Exploit

Self Exploit < Code Snippet >.

strcpy !!!! Is she the culprit?

Note: Tested on Redhat Linux i386 platform.


#include < string.h >
#include < stdio.h >
#include < stdlib.h >

int payload();
int exploit(char *d);

int main() {
int distance;
char a[512] = {0};
distance = exploit(NULL);
memset(a, 0xFF, distance);
*(void**)(a + distance) = &payload;
*(void**)(a + distance + sizeof(void*)) = 0;
exploit(a);
return 255;
}

/*
* This overflows its own buffers and
* causes the return to jump to payload()
*/

int exploit(char *d) {
char a[400] = {0};
void *i;
int distance = 0;
char payld[sizeof(void*) + 1];
void *myret;
void *z;

if (!d) {
myret = __builtin_return_address(0);
for (i = (void*)a; *(void**)i != myret; i++) distance++;
return distance;
}
strcpy(a,d);
return 1;
}

int payload() {
printf("Payload executed successfully!\n");
_exit(0);
}

Labels:

Posted by - at 1:40 am | 3 comments read on

C Programming - Program that prints itself

This program output will print the program itself


int main()
{
char c[]="int main()%c{%cchar c[]=%c%s%c;%cprintf(c,10,10,34,c,34,10,10,10);%c}%c";
printf(c,10,10,34,c,34,10,10,10);
}

Labels:

Posted by - at 9:38 pm | 0 comments read on

C Programming - Print In Reverse-Order

This is only for printing, we are not storing the reversed output anywhere and another shortcoming is that it will cause SEGFAULT for a huge length string.

Recursive main() calling!! For beginners it will be a great to surprise to call main() function within main() it, but wait, Isn't main() also a function?


/* reverse.c */
#include

int main()
{
char ch;
if ( (ch=getchar()) != '\n' ) {
main();
printf("%c",ch);
}
}/* EOF */


Is it necessary to have a main() function for success full compilation (there is no function main() written anywhere in any of our translation unit)

No, We can write a variable named main, and that is enough for the compilation phase to succeed.

/* withoutmain.c */
int main;
/* EOF */

Labels:

Posted by - at 3:58 am | 0 comments read on

C Programming - Extract Token from Strings

glibc implementation of strtok for i386 platform.



static char *olds;
void *rawmemchr (const void *s, int c)
{
register unsigned long int d0;
register unsigned char *res;
__asm__ __volatile__
("cld\n\t"
"repne; scasb\n\t"
: "=D" (res), "=&c" (d0)
: "a" (c), "0" (s), "1" (0xffffffff),
"m" ( *(struct { char __x[0xfffffff]; } *)s)
: "cc");
return res - 1;
}



char *strtok (char *s, const char *delim)
{
char *token;
if (s == NULL) s = olds;

/* Scan leading delimiters. */
s += strspn (s, delim);
if (*s == '\0') {
olds = s;
return NULL;
}

/* Find the end of the token. */
token = s;
s = strpbrk (token, delim);
if (s == NULL)
/* This token finishes the string. */
olds = rawmemchr (token, '\0');
else {
/* Terminate the token and make OLDS point past it. */
*s = '\0';
olds = s + 1;
}
return token;
}



Notes:

This was extracted from glibc-2.3.6 (sysdeps/generic/strtok.c)

Labels:

Posted by - at 10:17 pm | 0 comments read on

C Programming - Heap Overview

An Overview of Heap Overflow

Each threads of a running program has a stack where local variables are stored. In linux all program has a .BSS (global and static uninitialized varibles) and .DATA segment (global and static initialized varibles) along with other segments used by malloc() and allocated with brk() - Sets the end of data segment to the values specified or mmap() - map file into memory, it ask length bytes starting at offset from the file specified by the file descriptor fd into memory, preferably at address start.




malloc() breaks up a chunk of memory allocated using brk() into small parts and gives the user one of those part when a request is made.
It used various techniques like smallest-first, best-fit, next best fit, first-fit etc.
Lot of meta-data about the location of the chunks, ths size of the chunks and other special area for small parts.
All these is information are organized into buckets and in some others into balanced tree structure.

So like stack overflow we can overflow heap also, by overwriting those meta-data.

One such vulenrable program is cprog1.c


/* cprog1.c */
#define BLOCKSIZE 666

int main(int argc, char *argv[])
{
char *pcBuf1, *pcBuf2;
pcBuf1 = (char *) malloc (BLOCKSIZE);
pcBuf2 = (char *) malloc (BLOCKSIZE);

printf("Buffer 1: %p Buffer 2: %p\n",pcBuf1,pcBuf2)

strcpy(pcBuf1,argv[1]);

free(pcBuf2);
free(pcBuf1);
}
/* EOF */

$> gcc -o cprog1 cprog1.c
$> ./cprog1
Buffer1: 0x9017008 Buffer2: 0x90172a8
*** glibc detected *** double free or corruption (out): 0x90172a8 ***
Aborted


Here we are overflowing
Buffer2
with the data in
argv[1]
.
malloc implementations, including Linux's dlmalloc, store extra information in a free chunk. As free chunks can be used to store information about other chunks.

Note: The output of all the programs discussed here will be complier/platform dependent.

Instead of malloc we could have used something like

p = (char *) sbrk(BLOCKSIZE);


But it isn't efficient, portable. What about free?


Allocation Algorithms :

Following are some of the memory allocation algorithms used.


  • First Fit


    • Keep a linked list of free node

    • Search for the first one that's BIG enough


  • Best Fit


    • Keep a linked list of free node

    • Search for the smallest one that's BIG enough


  • Free list: A circular list


Labels:

Posted by - at 1:08 pm | 1 comments read on

C Programming - String Length!!

glibc implementation of strlen for i386 platform.

Cool!

size_t
strlen (const char *str)
{
int cnt;

asm("cld\n" /* Search forward. */
/* Some old versions of gas need `repne' instead of `repnz'. */
"repnz\n" /* Look for a zero byte. */
"scasb" /* %0, %1, %3 */ :
"=c" (cnt) : "D" (str), "0" (-1), "a" (0));

return -2 - cnt;
}


Note: This was extracted from glibc-2.3.6 (sysdeps/i386/strlen.c)

Labels:

Posted by - at 11:39 pm | 0 comments read on

My Favourites

My Favourite Casts:

Unlimited Enlightenment!!!!



Posted by - at 11:21 pm | 0 comments read on

C Programming - ShellCoding Series - Episode #1 (AUDIO)

At last ended up creating AUDIO!


    Overview of Linux Process Memory Model
    Overview Stack Segment
    Stack Segment Population
    Stack Segment Manipulation


Download MP3| AAC
Next Episode: Writing ShellCode for Spawing a Shell (/bin/sh)



Show Notes:

Program1:

/* program1.c */
int f(int i, int j, int k)
{
char buffer1[5];
char buffer2[10];
}

int main()
{
f(1,2,3);
}


Disassembly of Program1.c:

$> gdb -q program1
(no debugging symbols found)...
(gdb) disass main
Dump of assembler code for function main:
0x0804833c : push %ebp
0x0804833d : mov %esp,%ebp
0x0804833f : sub $0x8,%esp
0x08048342 : and $0xfffffff0,%esp
0x08048345 : mov $0x0,%eax
0x0804834a : add $0xf,%eax
0x0804834d : add $0xf,%eax
0x08048350 : shr $0x4,%eax
0x08048353 : shl $0x4,%eax
0x08048356 : sub %eax,%esp
0x08048358 : push $0x3
0x0804835a : push $0x2
0x0804835c : push $0x1
0x0804835e : call 0x8048334
0x08048363 : add $0xc,%esp
0x08048366 : leave
0x08048367 : ret
End of assembler dump.
(gdb) diasass f
Dump of assembler code for function f:
0x08048334 : push %ebp
0x08048335 : mov %esp,%ebp
0x08048337 : sub $0x28,%esp
0x0804833a : leave
0x0804833b : ret
End of assembler dump.
(gdb) quit


Program2:

/* program2.c */
void f()
{
int i;
*(&i+2) += 7;
}

int main()
{
int i = 10;
f();
i = 20;
printf("i = %d\n",i);
}


Disassemble for Program2.c:

$> gdb -q program2
(no debugging symbols found)...

(gdb) disass main
Dump of assembler code for function main:
0x08048376 : push %ebp
0x08048377 : mov %esp,%ebp
0x08048379 : sub $0x8,%esp
0x0804837c : and $0xfffffff0,%esp
0x0804837f : mov $0x0,%eax
0x08048384 : add $0xf,%eax
0x08048387 : add $0xf,%eax
0x0804838a : shr $0x4,%eax
0x0804838d : shl $0x4,%eax
0x08048390 : sub %eax,%esp
0x08048392 : movl $0xa,0xfffffffc(%ebp)
0x08048399 : call 0x8048368
0x0804839e : movl $0x14,0xfffffffc(%ebp)
0x080483a5 : sub $0x8,%esp
0x080483a8 : pushl 0xfffffffc(%ebp)
0x080483ab : push $0x804849c
0x080483b0 : call 0x80482b0
0x080483b5 : add $0x10,%esp
0x080483b8 : leave
0x080483b9 : ret
0x080483ba : nop
0x080483bb : nop
End of assembler dump.

(gdb) disass f
Dump of assembler code for function f:
0x08048368 : push %ebp
0x08048369 : mov %esp,%ebp
0x0804836b : sub $0x4,%esp
0x0804836e : lea 0x4(%ebp),%eax
0x08048371 : addl $0x7,(%eax)
0x08048374 : leave
0x08048375 : ret
End of assembler dump.
(gdb) quit

Reference:
"Smashing Stack for Fun and Profit" by Aleph One

Thanks to:
Podcaster Confessions by Joseph Nilo.
ScreenCasts seems to be a perfect fit!! One of my favourite screencast is
by Don McAllister

Labels:

Posted by - at 8:19 am | 0 comments read on

Network Sniffing - Cain & Abel!



I ran cain & abel to listen to my ethernet adapater.


The surprising stuff was that I didn't if have to do an ARP Poisioning!!! bcoz all the machines was connected to a HUB.
Posted by - at 9:43 pm | 0 comments read on

C Programming - Bit Twiddling Hack

Some Bit Twiddling code snippets!!


Bit Twiddling Hacks


Contents:

# Compute the sign of an integer

# Compute the integer absolute value (abs) without branching

# Compute the minimum (min) or maximum (max) of two integers without branching

# Determining if an integer is a power of 2

# Sign extending
* Sign extending from a constant bit width
* Sign extending from a variable bit-width
* Sign extending from a variable bit-width in 3 operations

# Conditionally set or clear bits without branching

# Merge bits from two values according to a mask

# Counting bits set
* Counting bits set, naive way
* Counting bits set by lookup table
* Counting bits set, Brian Kernighan's way
* Counting bits set in 12, 24, or 32-bit words using 64-bit instructions
* Counting bits set, in parallel

# Computing parity (1 if an odd number of bits set, 0 otherwise)
* Compute parity of a word the naive way
* Compute parity by lookup table
* Compute parity of a byte using 64-bit multiply and modulus division
* Compute parity in parallel

# Swapping Values
* Swapping values with XOR
* Swapping individual bits with XOR

# Reversing bit sequences

* Reverse bits the obvious way
* Reverse bits in word by lookup table
* Reverse the bits in a byte with 3 operations (64-bit muliply and modulus division)
* Reverse the bits in a byte with 4 operations (64-bit multiply, no division)
* Reverse the bits in a byte with 7 operations (no 64-bit, only 32)
* Reverse an N-bit quantity in parallel with 5 * lg(N) operations

# Modulus division (aka computing remainders)

* Computing modulus division by 1 << s without a division operation (obvious)
* Computing modulus division by (1 << s) - 1 without a division operation
* Computing modulus division by (1 << s) - 1 in parallel without a division operation

# Finding integer log base 2 of an integer (aka the position of the highest bit set)

* Find the log base 2 of an integer with the MSB N set in O(N) operations (the obvious way)
* Find the integer log base 2 of an integer with an 64-bit IEEE float
* Find the log base 2 of an integer with a lookup table
* Find the log base 2 of an N-bit integer in O(lg(N)) operations
* Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup

# Find integer log base 10 of an integer

# Find integer log base 2 of a 32-bit IEEE float

# Find integer log base 2 of the pow(2, r)-root of a 32-bit IEEE float (for unsigned integer r)

# Counting consecutive trailing zero bits (or finding bit indices)

* Count the consecutive zero bits (trailing) on the right in parallel
* Count the consecutive zero bits (trailing) on the right by binary search
* Count the consecutive zero bits (trailing) on the right by casting to a float
* Count the consecutive zero bits (trailing) on the right with modulus division and lookup
* Count the consecutive zero bits (trailing) on the right with multiply and lookup

# Round up to the next highest power of 2 by float casting

# Round up to the next highest power of 2

# Interleaving bits (aka computing Morton Numbers)

* Interleave bits the obvious way
* Interleave bits by table lookup
* Interleave bits with 64-bit multiply
* Interleave bits by Binary Magic Numbers

# Testing for ranges of bytes in a word (and counting occurances found)

* Determine if a word has a zero byte
* Determine if a word has byte less than n
* Determine if a word has a byte greater than n
* Determine if a word has a byte between m and n


Bit Twiddling Hacks

Labels:

Posted by - at 9:13 pm | 0 comments read on

Operating System/Data Structures/Machine Structures Classes from Berkeley

Following are RSS feeds for MOST WANTED!!!

Labels:

Posted by - at 11:06 pm | 0 comments read on

C Programming - Stack Segment


#include < stdio.h >
main()
{
char i=10;
char *ptr=&i;
unsigned long j;
for(j=0; j<4294967296; j++) printf("%u -- %d\n",ptr+j, *(ptr+j));
}

Platform used: Redhat Linux E.L 4.0 on Intel P4 2.8Ghz

We got a SEG fault when (ptr+j) crosses 3GB. Why?


It does not seem to be an authentic explanation to me as well, but learn something from this.

PAE (Physical Address Extension) enabled kernel will support physical memory greater than 4GB upto 64GB which a CPU can address. Process under a kernel which is not enabled with PAE support can only address upto 4GB of which 1GB is reserved by kernel

Linux uses segmentation + paging for memory management. It uses 4 segments

Code Segment (Kernel Space)
Data/Stack Segment (Kernel Space)
Code Segment (User Space)
Data/Stack Segment (User Space)

Kernel Space is from 0xC0000000 - 0xFFFFFFFF ( 3GB - 4GB)
User Space is from 0x00000000 - 0xBFFFFFFF ( 0GB - 3GB)
 
4 GB--->| | |
| Kernel | | Kernel Space (Code + Data/Stack)
| | __|
3 GB--->|----------------| __
| | |
| | |
2 GB--->| | |
| Tasks | | User Space (Code + Data/Stack)
| | |
1 GB--->| | |
| | |
|________________| __|
0x00000000

Labels:

Posted by - at 8:16 am | 0 comments read on

Archives

  • May 2011
  • February 2009
  • December 2008
  • November 2008
  • October 2008
  • August 2008
  • April 2008
  • December 2007
  • November 2007
  • January 2007
  • December 2006
  • October 2006
  • September 2006
  • June 2006
  • May 2006
  • April 2006
  • March 2006
  • February 2006
  • January 2006
  • December 2005
  • November 2005
  • October 2005

Links