www.main.lv

Don't think just code it

Menu

  • Projects
    • Robatik
    • ArpSni
  • Samples
    • FreeBSD Asm
    • Linux Asm
    • PyGame Tutorial
    • UNIX programming
    • PSP programming
    • AVR
    • Math
  • Contact

Tags

algo (1)asm (19)attractor (2)avr (2)blender (3)bug (1)c (25)coalision (2)debug (3)editor (1)elf (1)fractals (2)freebsd (3)game (3)generator (1)gimp (1)int80h (22)map (1)math (5)mit (1)nano (1)net (2)opengl (1)plugin (1)post (2)povray (1)psp (3)pygame (19)python (28)robatik (2)sdl (3)skype (2)sql (1)towers (2)tutorial (7)voronoi (1)wudu (1)

Archive

  • 2010 august (1)
  • 2010 july (2)
  • 2010 june (1)
  • 2010 april (2)
  • 2010 march (2)
  • 2010 february (2)
  • 2010 january (2)
  • 2009 december (3)
  • 2009 november (8)
  • 2009 october (3)
  • 2009 september (5)
  • 2009 august (1)
  • 2009 july (1)
  • 2009 june (1)
  • 2009 may (1)
  • 2009 april (3)
  • 2009 march (1)
  • 2009 february (2)
  • 2009 january (1)
  • 2008 october (2)
  • 2008 september (4)

2009-10-24 Making C executables smaller

There are some simple things that can be done to make C executables as small as possible.


Here is some example code we will work with:
#include <SDL/SDL.h>
 
char quit = 0;
 
int main()
{
    SDL_Surface *screen,surface;
    SDL_Event e;
    SDL_Init( SDL_INIT_VIDEO );
    screen = SDL_SetVideoMode( 400, 400, 32, SDL_SWSURFACE );
    while(!quit)
        while(SDL_PollEvent(&e)>0)
        {
            if(e.type==SDL_MOUSEBUTTONDOWN) quit=1;
            if(e.type==SDL_KEYDOWN) quit=1;
        }
    SDL_Quit();
}

Compile: gcc main.c -o main -lSDL

Size before: 5326 bytes


Execute command: strip main

strip
is included in most unix systems. It deletes some info symbols from executables
Size after: 3532 bytes

You can also try sstrip which is advanced version of strip. You can download it from ELF kickers webpage.
Execute command: sstrip main

Size after: 1960 bytes

There are some others way to decrease size of programm.


GC Masher Allows to bruteforce gcc options for smaller executable size.
I where using this options for gcsmaher
-O  -O0  -O1  -O2  -O3  -Os
-ffast-math
-fomit-frame-pointer
-fauto-inc-dec
-mpush-args
-mno-red-zone
-mstackrealign

After runnig with this options executble size is 5175 bytes and best compiling options are all posible combination. 
Combining with sstrip gives 1960 bytes. 
And there size where not reduced but some time there can be saved some bytes.

Now we will change main function with
void _start()
and return change to
asm ( \
      "movl $1,%eax\n" \
      "xor %ebx,%ebx\n" \
      "int $128\n" \
    );

One other thing is to archive your executable and cat it with unpack shell script.
a=/tmp/I;tail -n+2 $0|zcat>$a;chmod +x $a;$a;rm $a;exit

Best options and smallest size now is 563 byte. Nope this is not smallest size try to
 rename executable name to one symbol and you will get 4 extra bytes.
gcc -Os -ffast-math -fomit-frame-pointer 
-fauto-inc-dec -mpush-args -mno-red-zone -c small.c;
ld -dynamic-linker /lib/ld-linux.so.2 small.o /usr/lib/libSDL.so -o small;
strip -s -R .comment -R .gnu.version small;sstrip small;
7z a -tGZip -mx=9 small.gz small > /dev/null;
cat unpack.header small.gz > small;
chmod a+x small;rm small.gz small.o

Download Source 
Rewriting all in asm gives 526 bytes Link.
Link to other resources Link1 
Author in link has 634 bytes. With his options I have 622 bytes and using gcmasher i have 606 bytes. I have used his source in this compare.







2009-10-08 Basic HTTP server

Basic HTTP server. When you type url it shows listing of your local directory. If you tipe with path to file name noting hapens
Use:
http://*.*.*.*:/ -> disk start directory
http://*.*.*.*:/home/ -> home directory
Run:
./server port

Compile:
gcc server.c -o server

C Source


Here is also python source. It runs on port:8081 and prints in terminal HTTP request. You can see what browser sends to server.

Py Source


2009-10-30 Linux assembler SDL

Open SDL window from asm. I tryed to open SDL window from asm. And that worked. Hardest thing is defining all structures from SDL headers. Windows opening and waiting while anykey will pressed.

include 'cdecl.inc'
 
format ELF
 
extrn SDL_Init
extrn SDL_SetVideoMode
extrn SDL_PollEvent
extrn SDL_Quit
 
;video settings
SDL_INIT_VIDEO	equ 0x00000020
SDL_FULLSCREEN	equ 0x80000000
 
;event settings
SDL_KEYDOWN         equ 2
SDL_MOUSEBUTTONDOWN equ 5
 
;programm settings
SCREEN_WIDTH equ 800
SCREEN_HEIGHT equ 600
SCREEN_BPP equ 24
 
struc SDL_keysym
{
	.scancode 	db 0
	.sym 		dd 0
	.mod		dd 0
	.unicode 	dd 0
}
 
struc SDL_KeyboardEvent
{
	.type  db 0
	.which db 0
	.state db 0
	.keysym SDL_keysym
}
 
struc SDL_Event
{
	.type db 0
	union SDL_KeyboardEvent
	.empty db 0,0,0
}
 
 
section '.text' executable
public _start
_start:
	ccall SDL_Init,SDL_INIT_VIDEO
	ccall SDL_SetVideoMode, SCREEN_WIDTH , SCREEN_HEIGHT , SCREEN_BPP , SDL_FULLSCREEN
	;try to make while loop
while_run:	
	while_polleEvent:
		ccall SDL_PollEvent, event
		cmp eax, 0
		je	while_polleEventquit
		cmp byte [event.type], SDL_KEYDOWN
		jne	while_polleEvent
		mov byte [run], 0
		jmp while_polleEvent
	while_polleEventquit:
 
	; if run != 1 quit
	cmp byte [run], 1	
	je	while_run
 
	ccall SDL_Quit, 0
 
	mov eax, 1
	xor ebx, ebx
	int 80h
 
section '.data' writeable
event		SDL_Event
run 		db 		1


Compile with lines:

fasm sdl.asm sdl.o

ld -dynamic-linker /lib/ld-linux.so.2 sdl.o /usr/lib/libSDL.so -o sdl

Dowload Source



2009-11-08 Linux Assembler Make Directory

Code for creating file:


format ELF executable
 
include 'cdecl.inc'
include 'syscall.inc'
 
mode_t equ dd
 
segment readable executable
start:
	mov eax, SYS_MKDIR
	mov ebx, path
	mov ecx, [mode]
	int 80h
 
	mov eax, SYS_EXIT
	xor ebx, ebx
	int 80h
 
segment readable writeable
path	db 	"dir",0 
mode	mode_t  0777o
fasm makedir.asm -o makedir

Source


2009-11-30 Linux ShellCode 1


First shell code writened from example. Shell code is very interesting way how to execute some code.

asm source:

use32				
xor eax, eax
inc eax
xor ebx, ebx
int 80h

fasm code.asm code.bin

bin2hex output:

\x31\xc0\x40\x31\xdb\xcd\x80
C source:

#include <stdio.h>
char code[] = "\x31\xc0\x40\x31\xdb\xcd\x80";
int main()
{
  void (*ret)();
  ret = (void (*)())code;
  ret();
  printf("Nope it not working\n");
}

gcc main.c -o main


run ./main nothing happens. That exactly that code do exits from programm

Source


My variant of Bin2Hex


2009-11-30 ARP analyzer

Research in ARP protocol. Watch ARP packets , count them and show in list.

Usage
./arpsni eth0

Version 0.1
[2009nov30]

ArpSni.0.1





2009-12-12 Linux keyboard LED

Send some bytes and flash LED on you keyboards.
Run it under root. There will no be any errors if something happens.

Usage:

kbled [NumLock] [CapsLock] [ScrLock]
kbled 0 0 0


#include <stdlib.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include <linux/kd.h>
 
int main( int argc , char **argv )
{
	int rc,i;
	if (argc != 4) exit(0);
 
	rc = syscall(SYS_open,"/dev/console",O_WRONLY,7*64+7*8+7); //open cosole
	if (rc == 0) rc = 1;
 
	i = (argv[1][0]-'0')*2+(argv[2][0]-'0')*4+(argv[3][0]-'0');
	ioctl( rc , KDSETLED , i );
 
	return 0;
}

Source




2009-12-14 Linux PC speaker

PC speaker can make sound you whant. Here is small PC speaker player. Set notes , set time
delay and you on. You shold run this code under root if nothing happends.

int main()
{
	int rc,i;
	note *curent_song;
	curent_song = song;
	struct timespec t1;
	rc = syscall(SYS_open,"/dev/console",O_WRONLY,7*8*64+7*8+7); //open cosole
	if (rc == 0)
		rc = 1;
 
	ioctl( rc, KIOCSOUND , 0 );	
	ioctl( rc , KDSETLED , 7 );
 
	i = 0;
	while ( curent_song[i].n != 0 )
	{
		ioctl( rc , KIOCSOUND , curent_song[i].n );
		msleep( (curent_song[i].t) );
		ioctl( rc , KDSETLED , i&0x0007 );
		i++;
	}
	ioctl( rc , KDSETLED , 0 );
	ioctl( rc, KIOCSOUND , 0 );
 
	return 0;
}

Source


2009-12-25 Linux Format String Attack 1

Format string attack is attack for C formated strings. Format string function is prinrf() there are other

functions that support format string.


C code for bad used printf():

int main( int argc, char **argv )
{
	static int i = 0;
	char text[1000];
	strcpy(text, argv[1]);
	printf("%.8x\n",&i);
	printf("No way it never will works because value of i=%d\n",i);
	printf( text );
	printf("\nValue of i=%d\n",i);
	return 0;
}
First output is adress of static i

Than we outputing values of i and call printf() with first argument fo prgramm.

and then watching value if i

Run: ./e1 'Halolo'
Output:

08049674
No way it never will works because value of i=0
Halolo
Value of i=0
Run: ./e1 'Halolo%s'

Output:

08049674
No way it never will works because value of i=0Halolo(null)
Value of i=0&nbsp;

Run:  ./e1 $'\x74\x96\x04\x08_%x'

Output:

08049674
No way it never will works because value of i=0
t�_0
Value of i=0

Read about %n in format string:

Run: ./e1 $'\x74\x96\x04\x08_%x_%n'

Output:

08049674
No way it never will works because value of i=0
Segmentation fault
Run: ./e1 $'\x74\x96\x04\x08_%x_%x_%x_%x_%x_%n'
Output:
08049674
No way it never will works because value of i=0
t�_0_8_40_4_4_
Value of i=16
Run: ./e1 $'\x74\x96\x04\x08_%x_%x_%x_%x_%.1201x_%n'

Output:

08049674
No way it never will works because value of i=0
t�_0_8_40_4_000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000004_
Value of i=1216

Now you can input almost any value to i








2010-01-24 Linux Local Descriptor Table

If 0x80**** adreeses is default nope. You can setup your own. Compiler will not see them
but you can do it. Setup LDT and you will see it.

use32
mov dword [0] ,"Hall"
mov dword [4] ,"Ball"
mov dword [8] ,"Mall"
mov dword [12],0x00000000
yes everything starts from 0x0


#include <stdlib.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <asm/ldt.h>
 
char new_segment[16];
 
int main()
{
	int r;
 
	struct user_desc *ldt;
 
	ldt = (struct user_desc*)malloc(sizeof(struct user_desc));
 
	ldt->entry_number = 0;
	ldt->base_addr = ((unsigned long)&new_segment);
	ldt->limit = 16;
	ldt->seg_32bit = 0x1;
	ldt->contents = 0x0;
	ldt->read_exec_only = 0x0;
	ldt->limit_in_pages = 0x0;
	ldt->seg_not_present = 0x0;
	ldt->useable = 0x1;
 
	printf("Start\n");
	r = syscall( __NR_modify_ldt, 1 , ldt , sizeof(struct user_desc) );
	if ( r == -1 )
	{
		printf("Sorry\n");
		exit( 0 );
	}
	asm("pushl %ds");
	asm("movl $0x7, %eax"); /* 0111: 0-Index 1-Using the LDT table 11-RPL of 3 */
	asm("movl %eax, %ds");	
	asm(".byte 0xc7,0x5,0x0,0x0,0x0,0x0,0x48,0x61,\                   0x6c,0x6c,0xc7,0x5,0x4,0x0,0x0,0x0,\                   0x42,0x61,0x6c,0x6c,0xc7,0x5,0x8,0x0,\                   0x0,0x0,0x4d,0x61,0x6c,0x6c,0xc7,0x5,\                   0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0");
	asm("popl %ds");
	printf("End\n");
 
	printf("Segment [%s]\n",new_segment);
 
	free( ldt );
 
	return 0;
}
asm(".byte ... ") is code.bin

Compile:
fasm code.asm code.bin
gcc main.c -o main


Source


2010-02-23 Linux antidebug 1

When ptrace is used for programm debugin then only one ptrace can be attached to programm
when we trying run ptrace with PTRACE_TRACEME then we get  -1. I tested with gdb,ald. Also this method should
work with IDApro

#include <stdlib.h>
#include <stdio.h>
#include <sys/ptrace.h>
 
long int ptraced()
{
	return (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1);
}
 
int main()
{
	if ( ptraced() )
	{
		printf("Ptraced!\n");
	}
	return 0;
}


Source




2010-02-26 Linux antidebug 2

This is dirty solution it checks programms argv[0] name with your defined name
when running debuger such as gdb or ald name is chaned to fullpath name
user defined name from terminal is './main'.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
 
int main( int argc , char **argv )
{
	pid_t pid,ppid;
	FILE *f;
	char str[128];
	char spid[10];
 
	//openfile and write ppid
	f = fopen( "pid.txt" , "w" );
	pid = getpid();
	fprintf(f,"%d ",pid);
	fclose( f );
	f = fopen( "pid.txt" , "r" );
	fscanf( f , "%s" , spid );
	fclose( f );
 
	strcpy( str , "cat /proc/" );
	strcat( str , &spid[0] );
	strcat( str , "/cmdline");
	printf( "[%s]\n", spid );
	system( str );
 
	printf("\n");
}

Dirty function that makes dirty solution at one place
int badppid( const char *real_name )
{
	pid_t pid,ppid;
	FILE *f;
	char str[128];
	char spid[10];
		f = fopen( "pid.txt" , "w" );
	pid = getpid();
	fprintf(f,"%d ",pid);
	fclose( f );
 
 
	f = fopen( "pid.txt" , "r" );
	fscanf( f , "%s" , spid );
	fclose( f );
 
 
	strcpy( str , "cat /proc/" );
	strcat( str , &spid[0] );
	strcat( str , "/cmdline > name.txt");
	system( str );
 
	f = fopen( "name.txt" , "r" );
	fscanf( f , "%s" , str );
	fclose( f );
	if ( strncmp(str,real_name,strlen(real_name)) != 0 )
	{
		return -1;
	}
 
	return 0;
}


Source


2010-03-05 Linux antidebug 3

Now we will try to make disasm output whery unclear. We make jump with eax register
Programm 1

main:
	push lbl+1
	pop eax
	jmp eax	
lbl:
	db 0xe8
	mov eax, 4
	mov ebx, 1
	mov ecx, msg1
	mov edx, msg1_size
	int 80h
 
	mov eax, 1
	mov ebx, 0
	int 80h
Output is same as source. Nothing changes

Dissassembler output 1

│ ....... ! main:                           ;xref o80482d7                                       │
│ ....... !   push        offset_804837d                                                         │
│ 8048379 !   pop         eax                                                                    │
│ 804837a !   jmp         eax                                                                    │
│ 804837c     db          0e8h                                                                   │
│ 804837d !                                                                                      │
│ ....... ! offset_804837d:                 ;xref o8048374                                       │
│ ....... !   mov         eax, 4                                                                 │
│ 8048382 !   mov         ebx, 1                                                                 │
│ 8048387 !   mov         ecx, strz_I_am_running__8049568                                        │
│ 804838c !   mov         edx, 0eh                                                               │
│ 8048391 !   int         80h                                                                    │
│ 8048393 !   mov         eax, 1                                                                 │
│ 8048398 !   mov         ebx, 0                                                                 │
│ 804839d !   int         80h
Here we add only one instruction. We get jump adress and add 1. Disasm cannot calculate adress of jmp.

Programm 2
Like in first programm disasm think that we push correct adress and disasm it. And our byte 0xe9 is used
for disasm output. That nice.
main:
	push lbl
	pop eax
	inc eax
	jmp eax
lbl:
	db 0xe9
	mov eax, 4
	mov ebx, 1
	mov ecx, msg1
	mov edx, msg1_size
	int 80h
 
	mov eax, 1
	mov ebx, 0
	int 80h


Dissassembler output 2
│ ....... ! main:                           ;xref o80482d7                                       │
│ ....... !   push        offset_804837d                                                         │
│ 8048379 !   pop         eax                                                                    │
│ 804837a !   inc         eax                                                                    │
│ 804837b !   jmp         eax                                                                    │
│ 804837d !                                                                                      │
│ ....... ! offset_804837d:                 ;xref o8048374                                       │
│ ....... !   jmp         804883ah                                                               │
│ 8048382     add         [ebx+1], bh                                                            │
│ 8048388     mov         ecx, 8049568h                                                          │
│ 804838d     mov         edx, 0eh                                                               │
│ 8048392     int         80h                                                                    │
│ 8048394     mov         eax, 1                                                                 │
│ 8048399     mov         ebx, 0                                                                 │
│ 804839e     int         80h

Now we add nop instruction after every line of our code. It doesnt have any imapct on programm work.

Programm 3
main:
	push lbl
	pop eax
	inc eax
	jmp eax
lbl:
	db 0xe9
	mov eax, 4
	nop 
	mov ebx, 1
	nop
	mov ecx, msg1
	nop
	mov edx, msg1_size
	int 80h
 
	mov eax, 1
	mov ebx, 0
	jmp lbl2+1
lbl2:
	db 0xe9
	int 80h
Disasm output now is very nice. Output isnt very good. For first time when you view this output it is very unclear
about what exactly is done by this code.

Dissassembler output 3
│ ....... ! main:                           ;xref o80482d7                                       │
│ ....... !   push        offset_804837d                                                         │
│ 8048379 !   pop         eax                                                                    │
│ 804837a !   inc         eax                                                                    │
│ 804837b !   jmp         eax                                                                    │
│ 804837d !                                                                                      │
│ ....... ! offset_804837d:                 ;xref o8048374                                       │
│ ....... !   jmp         804883ah                                                               │
│ 8048382     add         [eax+1bbh], dl                                                         │
│ 8048388     add         [eax+49578b9h], dl                                                     │
│ 804838e     or          [eax+0ebah], dl                                                        │
│ 8048394     add         ch, cl                                                                 │
│ 8048396     cmp         byte ptr [eax+1], 0bbh                                                 │
│ 804839d     add         [eax], al                                                              │
│ 804839f     add         [eax], al                                                              │
│ 80483a1     jmp         80483a4h                                                               │
│ 80483a3     jmp         98950475h

Here is one more way how to make unclear jumo to other place. We using function
and inside function we change return adress by 1.

Programm 4

Thats also works fine. Disasm dont know real return adress ans and use 0xe8 as he think is better.
main:
	call fun
	db 0xe8
	mov eax, 4
	mov ebx, 1
	mov ecx, msg1
	mov edx, msg1_size
	int 80h
 
	mov eax, 1
	mov ebx, 0
	int 80h
 
fun:
	pop ebp
	inc ebp
	push ebp
	ret




Dissassembler output 4

│ ....... ! main:                           ;xref o80482d7                                       │
│ ....... !   call        sub_804839c                                                            │
│ 8048379 !   call        8048836h                                                               │
│ 804837e !   add         [ebx+1], bh                                                            │
│ 8048384 !   mov         ecx, strz_I_am_running__8049568                                        │
│ 8048389 !   mov         edx, 0eh                                                               │
│ 804838e !   int         80h                                                                    │
│ 8048390 !   mov         eax, 1                                                                 │
│ 8048395 !   mov         ebx, 0                                                                 │
│ 804839a !   int         80h                                                                    │
│ 804839c !                                                                                      │
│ ....... ! ;-----------------------                                                             │
│ ....... ! ;  S U B R O U T I N E                                                               │
│ ....... ! ;-----------------------                                                             │
│ ....... ! sub_804839c:                    ;xref c8048374                                       │
│ ....... !   pop         ebp                                                                    │
│ 804839d !   inc         ebp                                                                    │
│ 804839e !   push        ebp                                                                    │
│ 804839f !   ret


Source


2010-04-24 CVS 2010-1160 Exploiting nano

CVE-2010-1160 Nano Changed File Symlink Privilege Escalation

Usualy if I have to edit some file I am using nano editor.
It is almost on every distribution and easy and fast to use. Some time ago i hated vim
beacouse of Ctrl-D =] and that way used nano or pico. Now I know how to exit from vim :q!. After this bug
reported in  CVE i was exited to check it out in real life. It is first bug that i have fully tested.

This bug is fixed in newest versions. Testing all nano version this bug works
on < 2.1.7 versions now on my system is latest nano version and I have
compiled many < 2.1.7 versions to test this bug.

To get your nano version run:
$ nano -V

When user is editing file nano don't check if it is edited by some
one else. When saving file it simply save it and dont check if it was modified. If file was changed by some one else
then nano will overwrite it with his text. But it can be changed to symlink that points to other file. How to use it in real life:

1) Open file with nano
2) Change file or set symlink
3) Make changes in file and save file in nano
4) See result in symlinked file

Everytning looks like
$nano text.txt
Now some one do:
$ls -s empty.txt text.txt
Nano save
whach you save in text.txt

In  python it looks like:

os.remove( "text.txt" )
open( "empty.txt" , "w" ).close()
os.symlink( "empty.txt" , "text.txt"
Python step by step

If you are root and opening file with owner isnt you. Than owner while you
editing his file can set
symlink to some "/etc/important.conf" and you will overwrite it with some
other unrelated info. This can make some harm to your system.

How can it be exploited in real life by "small unpreviliged user". Make some interesting file
that root will interested in. Make some process that whachs nanos running in system. If nano opened file is our , symlink it.

1)Detect running nano in system
2)Check with file is opened
3)If file is yours make symlink

Nano catch

Script is only for user and dont work if you try to symlink root opened nano. It makes
all steps as described above. Change script variables for your tests:
debug = True
nano = "nano-2.0.9"
user = "user"
sym_path="/home/user/empty.txt"
Tested only with python 2.6.5


Simply be uptodated or if you using old nano dont open with privileged user unpriveleged user files.
It will save you from this bug.


Linkage:
[1] http://osvdb.org/show/osvdb/63872
[2] http://cve.mitre.org/cgi-bin/cvename.cgi?name=2010-1160
[3] http://drosenbe.blogspot.com/2010/03/nano-as-root.html
[4] http://svn.savannah.gnu.org/viewvc/trunk/nano/ChangeLog?revision=4503&root=nano&view=markup



© 2010