2/1/2013
W internecie krąży exploit na grepa. Podatność typu int overflow powoduje segmentation fault. Na szczęście exploit jest lokalny, a zagrożenie niewielkie — mimo wszystko warto przyjrzeć się temu bliżej.
Błąd występuje od początku istnienia grepa, było o nim głośno już w marcu, a wykorzystuje to, że grep ma problem z przetwarzaniem linii, których długość nie “mieści się” w typie int (np. >2 GiB na 64 bitowych hostach).
Swojego grepa łatwo można przetestować na tę podatność, wydając następujące polecenie:
$ perl -e 'print "x"x(2**31)' | grep x > /dev/null
lub
$ perl -e 'print "\nx"x(2**31)' | grep -c x > /dev/null
Spodziewany wynik na podatnych wersjach grepa:
Segmentation fault (core dumped)
Chciaż błąd został już załatany w grepie 2.11, to poprawka nie została jeszcze rozdrystrybuowana do repozytoriów Ubuntu i Redhata, dlatego jak szacuje odkrywca, sporo systemów dalej jest “podatnych”.
Coraz bardziej zbliżamy się do mitycznego emacsem przez sendmail… ;-)
~ $ perl -e ‘print “\nx”x(2**31)’ | grep -c x > /dev/null
Out of memory!
“Out of memory!” ;)
To z perla
I tu dobrze widać różnicę między takim Ubuntu, a dystrybucjami live (jak Gentoo), gdzie grep 2.11 trafił do portage w… marcu 2012, a 2.12 został oznaczy stable w sierpniu.
Takie samo odnoszę wrażenie odnośnie Debiana. Ps. Bawiłem
się CentOS’em gdyby nie walka z zależnościami pakietów to zakochał
bym się w Redhat’owyh okienkach ;)
$ lsb_release -ir Distributor ID: Ubuntu Release: 12.10 $
grep -V grep (GNU grep) 2.12
dystrybucja live a rolling to dwie różne rzeczy
różnicę też dobrze widać w niezbyt dobrze przetestowanych
pakietach, fuckupach i ilościach godzin spędzonych przy naprawianiu
zjebawek na produkcji :]
Debian 6.0.6 – > problem nie występuje.
na GNU grepa.
Z “Out of memory” można sobie poradzić np. tak:
$ cat /dev/zero | tr ” ‘x’ | dd bs=1M iflag=fullblock count=2048 | grep -c x > /dev/null
Ehh, w tr między uszami jest backslash-zero.
Potwierdzam, w Debianie brak problemu. Wersja 6.06
$ perl -e ‘print “x”x(2**31)’ | grep x > /dev/null
$ grep -V
GNU grep 2.6.3
(debian squeeze)
[andrzejl@wishmacer ~]$ perl -e ‘print “x”x(2**31)’ | grep x > /dev/null
[andrzejl@wishmacer ~]$ perl -e ‘print “\nx”x(2**31)’ | grep -c x > /dev/null
[andrzejl@wishmacer ~]$ pacman -Q | grep ‘grep’
grep 2.14-1
[andrzejl@wishmacer ~]$ uname -a
Linux wishmacer.loc 3.7.1-2-ARCH #1 SMP PREEMPT Thu Dec 20 19:35:59 CET 2012 i686 GNU/Linux
[andrzejl@wishmacer ~]$
użytkownicy Windowsa i Androida nie mają takich problemów :)
Mają za to pierdylion innych :P
Android jest Linuxem, a na Cyanogenmod 10 jest grep,
więc?
Pod Windowsa też jest grep ;]
A to w android grepa nie ma? Nie wiedzialem…
Jest grep w Androidzie, ale nie GNU grep, tylko ten z
busybox. Czyli problem nie występuje. Btw. na Debianie exploit nie
działa ;P
@AndrzejL Wygląda na to, że nie.
https://groups.google.com/forum/?fromgroups=#!topic/android-developers/G469pYJz158
Mea culpa. Jak nie ma to nie ma… Uzywalem to myslalem ze jest ;) a tu widac chodzi o insza inszosc ;).
Pozdrawiam.
Andrzej
[modinfo@arch-pc ~]$ perl -e ‘print “\nx”x(2**31)’ | grep
-c x > /dev/null Out of memory! [modinfo@arch-pc ~]$ grep -V
grep (GNU grep) 2.14 OS Archlinux
I po co ten szum? Lokalny błąd na program który od początku
istnienia działa bez suid.. I kto co tym wyexploituje?
A gdyby w skrypcie odpalanym z roota byl uzyty grep na pliku, ktory mozesz podlozyc jako normal-user? Trzeba latac wszystkie problemy bo nigdy nie wiadomo na co wpadnie atakujacy ;-)
dreadlish@borium ~ $ perl -e ‘print “x”x(2**31)’ | grep x > /dev/null
Out of memory!
dreadlish@borium ~ $ grep –version
grep (GNU grep) 2.14
co do tego, co ktoś w komentarzu napisał:
dreadlish@borium ~ $ cat /dev/zero | tr ” ‘x’ | dd bs=1M iflag=fullblock count=2048 | grep -c x > /dev/null
grep: pamięć wyczerpana
segfaulta dalej nie widzę.
whoops. my phail, nie doczytałem dokładnie ;)
$ perl -e ‘print “\nx”x(2**29)’
Out of memory!
I nie mam szans na przetestowanie tej dziury :-(
Description: Ubuntu 10.04.4 LTS
2.6.32-45-generic #101-Ubuntu SMP Mon Dec 3 15:41:13 UTC 2012 i686 GNU/Linux
Btw. nie ma w tym artykule przypadkiem typo? Chyba na
32-bitowych systemach int mieści wielkości tylko do 2GB, a nie na
64?
Jeżeli jako licznik używasz inta, masz 2 GB zasięgu (od 0 do 2^31 – 1). Jeżeli unsigned inta, możesz zaindeksować 4 GB danych (od 0 do 2^32 – 1). Z jakiegoś powodu grep musi używać inta ze znakiem.
Napisałem koniec, zapomniałem o początku: Zarówno na x86, jak i x86_64, int zajmuje 32 bity. Inna jest wielkość wskaźnika.
Ponadto, oczywiście zakres unsigned nie zaczyna się od 0, tylko od -2^31.
Arch, problemu brak jak u poprzedników: pamięć wyczerpana
lub Out of memory!, zależnie od polecenia. (Ł)ubuntu i redhat to
pewnie jedyne ciągle podatne systemy, naturalnie z tych
aktualizowanych przez użytkowników
Skąd przekonanie, że Debian 6.0.6 z grepem z paczki w wersji 2.6.3-3 jest OK? U mnie pięknie segfaultuje. Poza tym ściągnięcie źródeł z repo Debiana nie wykazuje obecności linkowanego patcha.
jak rzekła młodziutka Cerro do króla Vridanka na ich
pierwszej schadzce: “Niebrzydka rzecz, ale czy ma jakieś
zastosowanie praktyczne?”
Ubuntu 12.04 jeszcze podatne ;)
Na arch-linuxie 64 bit wszytko ok. Nic dziwnego GNU Grep 2.14.
Na Slackware 14.0, grep-2.14 problem nie występuje
Testowałem na tosterze z NetBSD. Po kilkudziesięciu sekundach, z tostera wyskakuje gorąca grzanka, czyli proces się zakończył. Nie mam tylko pewności, czy to zamierzony efekt, czy grep grzeje maszynę a potem się wywala.
Wie ktoś może, jak odróżnić tost po segfaulcie od takiego zwykłego? Czy powinienem szukać core dumpa na powierzchni pieczywa, a jeśli tak, to po której stronie grzanki on będzie?
Musisz mieć pieczywo DDB :)
mazdac@egida ~ $ perl -e ‘print “x”x(2**31)’ | grep x > /dev/null
mazdac@egida ~ $ eix grep -I
[I] sys-apps/grep
Available versions: 2.5.4-r1 (~)2.6.3 (~)2.7 (~)2.8 2.9 (~)2.10 (~)2.11 2.12 [M](~)2.13 2.14 {nls pcre}
Installed versions: 2.14(00:00:51 23.08.2012)(nls pcre)
Homepage: http://www.gnu.org/software/grep/
Description: GNU regular expression matcher
mazdac@egida ~ $ uname -a
Linux egida 3.7.1 #1 SMP Fri Dec 21 02:23:49 CET 2012 x86_64 Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz GenuineIntel GNU/Linux
przykro mi, nie działa :/
Debian squeeze 64bit:
user@host:~$ perl -e ‘print “x”x(2**31)’ | grep x > /dev/null
grep: (standardowe wejście): Nie można przydzielić pamięci
Ej, prawie mi kompa to zawiesiło:/ RAM poleciał do góry,
potem swap. Ledwo ctrl+c zadziałało. 3.7.1-1-desktop grep (GNU
grep) 2.13
U mnie na Fedorze, grep 2.14 drugie polecenie zaraz się
kończy bez błędu, a pierwsze leci i leci i leci… i tylko
temperatura się powoli zwiększa. Ciekawe czy w końcu by się zaczął
palić :P
Na OS X też nie dał rady skończyć bo nie mogłem patrzeć jak
się zamulił, ale problem chyba nie dotyczy [code] ~ Rafal$ grep -V
grep (BSD grep) 2.5.1-FreeBSD [/code]
Działa :) Segmentation fault (core dumped)
Moja Nokia N900 z już niesupportowanym system jest odporna
;). Aż wygodnie wpisywać te chińskie znacznki na klwaiaturze QWERTY
z poszerzonym mapowaniem.
Fedora 17 (Cud Wołowy) ciekawie reaguje. Nie wyświetla mi info o braku pamięci lub “segmentation fault…”. Zamiast tego -“Xorg server Crashed”, dwa razy, czyli X jeszcze wstawały po zarżnięciu i chciały żyć.
Z punktu widzenia użytkownika pojawiają się lagi które stają się coraz dłuższe, ostatni nim kursor się ruszył trwał 6 sekund. Ruszanie touchpada nie daje rezultatów współmiernych do wygłaskania. Nadawanie z klawiatury jest dalej akceptowane, ale nie w czasie rzeczywistym, trzeba trochę poczekać nim system to zauważy lub wyświetli.
Nie sprawdzałem jak by to działało w konsoli.
Najbardziej irytujące jest to że odpaliłem to bez przywilejów, ze zwykłego usera, a zeżarło mi wszystkie zasoby.
Jak myślicie, czy załatali dziurę?
System miał update 2 stycznia.
A dmesg sprawdzałeś? Pewnie skończyła się pamięć i Linux wywołał handler OoM (out-of-memory), który zabija heurystycznie wybrane (w praktyce losowe!) procesy.
“Najbardziej irytujące jest to że odpaliłem to bez przywilejów, ze zwykłego usera, a zeżarło mi wszystkie zasoby.”
/etc/security/limits.conf
a co za roznica czy jest suid czy nie i czy lokal czy nie
skoro do 3/4 firm mozna wjechac sqlmapem?
Doświadczenie pokazuje, że do firm lepiej wjeżdża się ciężarówką (ew. spychaczem, patrz: Killdozer), niż sqlmap’em. Oczywiście taką z rejestracją ‘ OR 1=1 — , żeby potem nas nie namierzyli.
hardy@twardy:~$ perl -e ‘print “x”x(2**31)’ | grep x > /dev/null
hardy@twardy:~$ perl -e ‘print “\nx”x(2**31)’ | grep -c x > /dev/null
Out of memory during string extend at -e line 1.
hardy@twardy:~$ cat /etc/debian_version
7.0
hardy@twardy:~$
Jednak SID to SID >;-þ
slack 13.37 [20:54:47 –> pi in ~]$ perl -e ‘print
“x”x(2**31)’ | grep x > /dev/null [20:54:51 –> pi in
~]$ grep -V grep (GNU grep) 2.7 Copyright (C) 2010 Free Software
Foundation, Inc. License GPLv3+: GNU GPL version 3 or later . This
is free software: you are free to change and redistribute it. There
is NO WARRANTY, to the extent permitted by law. Written by Mike
Haertel and others, see . [20:55:03 –> pi in ~]$
A zawsze podczas aktualizacji systemu dziwiło mnie, że w
paczkach typu grep czy cat jeszcze jest co poprawiać :)
Na CentOSie 5.8 (32bit jak i 64bit) z pakietem
grep-2.5.1-55.el5 wyrzuca błąd 2: “grep: line too long” – segfaulta
nie ma. Na CentOSie 6.3 (64 bit) z pakietem grep-2.6.3-3.el6
segfault jest.
A u mnie jakoś nie działa… Co robię źle? :-) $ cat
/etc/issue.net Ubuntu 12.04.1 LTS $ grep -V grep (GNU grep) 2.10
Copyright (C) 2011 Free Software Foundation, Inc. Licencja GPLv3+:
GNU GPL wersja 3 albo późniejsza http://gnu.org/licenses/gpl.html $
perl -e ‘print “x”x(2**31)’ | grep x > /dev/null $ perl -e
‘print “\nx”x(2**31)’ | grep -c x > /dev/null Out of memory
during string extend at -e line 1. $
zastanawia mnie ile osób piszących “emacsem przez sendmail”
kiedykolwiek probowało o co z tym tak naprawde chodzi a dla ilu to
po prosty wytrych do słownych popisów “wiedzy”??
A u mnie .. ten generator znaków w perlu nie działa ;p
OS: Windows 8
Perl: Strawberry Perl 5.16.2.1 (32bit)
log:
C:\Windows\system32>which perl
C:\strawberry\perl\bin\perl.exe
C:\Windows\system32>perl -v
This is perl 5, version 16, subversion 2 (v5.16.2) built for MSWin32-x86-multi-thread (…)
C:\Windows\system32>perl -e “print \”x\”x(2**31)”
(pusto)
C:\Windows\system32>perl -e “print \”x\”x(2**30)”
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(i wiele więcej x)
Backtrack R3 – problem nie występuje…
Chodzi oczywiście o wersję 5 R3 ;)
z0rro@localhost: perl -e ‘print “x”x(2**31)’ | grep x > /dev/null
bash: błąd składni przy nieoczekiwanym znaczniku `(‘
he..he… :(
Fajnie, że wreszcie opisali tu na blogu, co przeciętny czytelnik niebezpiecznika może sprawdzić u siebie na kompie :)
Na Arch Linux oczywiście wszystko okey. Zalety rolling-distro, chociaż z drugiej rodziny Debiana Testing też bardzo lubię ;)