Debugowanie w systemie Windows za pomocą Immunity Debugger

https://chacker.pl/

Popularnym debugerem w trybie użytkownika jest Immunity Debugger, który możesz pobrać ze strony https://www.immunityinc.com/products/debugger/. W momencie pisania tego tekstu stabilną wersją jest wersja 1.85, używana w tym rozdziale. Główny ekran Immunity Debugger jest podzielony na pięć sekcji. Sekcja „Code” lub „Disassembler” (w lewym górnym rogu) służy do przeglądania zdemontowanych modułów. Sekcja „Registers” (w prawym górnym rogu) służy do monitorowania stanu rejestrów w czasie rzeczywistym. Sekcja „Hex Dump” lub „Data” (w lewym dolnym rogu) służy do przeglądania surowego heksadecymalnego pliku binarnego. Sekcja „Stack” (w prawym dolnym rogu) służy do przeglądania stosu w czasie rzeczywistym. Możesz zobaczyć te sekcje na nadchodzącym obrazku. Sekcja „Information” (w lewym środkowym rogu) służy do wyświetlania informacji o instrukcji wyróżnionej w sekcji Code. Każda sekcja ma menu kontekstowe dostępne po kliknięciu prawym przyciskiem myszy w tej sekcji. Immunity Debugger ma również oparty na Pythonie interfejs powłoki na dole okna debugera, aby umożliwić automatyzację różnych zadań, a także wykonywanie skryptów, aby pomóc w rozwijaniu exploitów. Mimo że dostępne są inne aktywnie utrzymywane debugery, społeczność użytkowników stworzyła bogate w funkcje rozszerzenia, takie jak Mona.py od Corelanc0d3r. Przed kontynuowaniem pobierz i zainstaluj Immunity Debugger z podanego wyżej łącza. Możesz rozpocząć debugowanie programu za pomocą Immunity Debugger na kilka sposobów:

  • Otwórz Immunity Debugger i wybierz Plik | Otwórz.
  • Otwórz Immunity Debugger i wybierz Plik | Dołącz.

• Wywołaj Immunity Debugger z wiersza poleceń — na przykład z wiersza poleceń Windows IDLE Python, w następujący sposób:

  • Otwórz Immunity Debugger i wybierz Plik | Otwórz.
  • Otwórz Immunity Debugger i wybierz Plik | Dołącz.

• Wywołaj Immunity Debugger z wiersza poleceń — na przykład z wiersza poleceń Windows IDLE Python, w następujący sposób:

Poprzednia linia poleceń uruchomi meet.exe wewnątrz Immunity Debugger, jak pokazano tutaj:

Debuger może wychwycić wyjątek, a jeśli tak się stanie, musisz przekazać wyjątek, naciskając SHIFT-F9, aby przejść do domyślnego punktu przerwania w punkcie wejścia programu. Podczas nauki Immunity Debugger będziesz chciał znać typowe polecenia wymienione w Tabeli  (jeśli używasz hosta macOS do przekazywania tych poleceń do maszyny wirtualnej Windows, może być konieczne zamapowanie powiązań klawiszy).

Debuger może wychwycić wyjątek, a jeśli tak się stanie, musisz przekazać wyjątek, naciskając SHIFT-F9, aby przejść do domyślnego punktu przerwania w punkcie wejścia programu. Podczas nauki Immunity Debugger będziesz chciał znać typowe polecenia wymienione w Tabeli  (jeśli używasz hosta macOS do przekazywania tych poleceń do maszyny wirtualnej Windows, może być konieczne zamapowanie powiązań klawiszy).

W tym przypadku możemy zobaczyć główny moduł wykonywalny dla meet.exe wymieniony jako pierwszy, a następnie różne biblioteki DLL. Ta informacja jest przydatna, ponieważ, jak zobaczysz później, te moduły zawierają kody operacji, które są dostępne podczas eksploatacji. Należy pamiętać, że adresowanie będzie się różnić w każdym systemie ze względu na randomizację układu przestrzeni adresowej (ASLR) i inne czynniki.

Opcje kompilatora Windows

https://chacker.pl/

Jeśli wpiszesz cl.exe /?, otrzymasz ogromną listę opcji kompilatora. Jednak większość z nich nie jest dla nas interesująca w tym momencie. Tabela  zawiera listę i opis flag, których będziesz używać.

Ponieważ będziemy teraz używać debugera, skompilujmy meet.exe z pełnymi informacjami debugowania i wyłączmy funkcjonalność stack canary.

UWAGA: Przełącznik /GS włącza implementację ochrony stack canary firmy Microsoft, która jest dość skuteczna w zatrzymywaniu ataków przepełnienia bufora. Aby dowiedzieć się więcej o istniejących lukach w oprogramowaniu (zanim ta funkcja stała się dostępna), wyłączymy ją za pomocą flagi /GS–.

Wykonaj następujący krok, aby skompilować wersję programu meet.c, której będziesz używać w laboratorium

Świetnie, teraz, gdy masz plik wykonywalny zbudowany z informacjami debugowania, czas zainstalować debuger i sprawdzić, jak debugowanie w systemie Windows wypada w porównaniu z debugowaniem w systemie Unix. W tym laboratorium użyłeś programu Visual Studio 2019 Community Edition do skompilowania programów hello.c i meet.c. Skompilowaliśmy program meet.c z pełnymi informacjami debugowania, które pomogą nam w następnym laboratorium. Przyjrzeliśmy się również różnym flagom kompilatora, których można użyć do wykonywania działań, takich jak wyłączenie kontroli łagodzenia eksploitów /GS.

Kompilacja w systemie Windows

https://chacker.pl/

Microsoft C/C++ Optimizing Compiler and Linker są dostępne bezpłatnie na stronie https://visualstudio.microsoft.com/vs/community/. W tym laboratorium korzystamy z systemu Windows 10 w wersji 20H2. Pobierz i uruchom instalator z poprzedniego łącza. Gdy pojawi się monit, w kategorii Workloads wybierz opcję Desktop Development with C++ i odznacz wszystkie inne opcje z wyjątkiem następujących:

  • MSVC v142 – narzędzia do kompilacji VS 2019 C++ x64/x86
  • Windows 10 SDK (10.0.19041.0)

Możesz również zaakceptować wszystkie opcjonalne ustawienia domyślne; pamiętaj jednak, że każde z nich zajmuje dodatkowe miejsce na dysku twardym. Konkretny numer kompilacji zestawu SDK może się różnić w zależności od tego, kiedy wykonasz pobieranie. Po pobraniu i prostej instalacji powinieneś mieć łącze w menu Start do wersji Visual Studio 2019 Community. Kliknij przycisk Start systemu Windows i wpisz prompt. Spowoduje to wyświetlenie okna pokazującego różne skróty wiersza poleceń. Kliknij dwukrotnie ten zatytułowany Developer Command Prompt lub VS 2019. Jest to specjalny wiersz poleceń ze środowiskiem skonfigurowanym do kompilowania kodu. Jeśli nie możesz go znaleźć za pomocą menu Start, spróbuj wyszukać „Developer Command Prompt” w katalogu głównym dysku C:. Często znajduje się on w C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools. Po otwarciu wiersza poleceń dla programistów przejdź do folderu C:\grayhat. Aby przetestować wiersz poleceń, zacznijmy od programów hello.c i meet.c. Używając edytora tekstu, takiego jak Notepad.exe, wpisz następujący przykładowy kod i zapisz go w pliku o nazwie hello.c znajdującym się w folderze C:\grayhat:

Kompilator Windows to cl.exe. Przekazanie nazwy pliku źródłowego do kompilatora generuje hello.exe, jak pokazano tutaj:

Przejdźmy do zbudowania kolejnego programu, meet.exe. Utwórz plik kodu źródłowego meet.c z następującym kodem i skompiluj go w systemie Windows za pomocą cl.exe:

Kompilowanie i debugowanie programów Windows

https://chacker.pl/

Narzędzia programistyczne nie są dołączone do systemu Windows, ale na szczęście Visual Studio Community Edition pozwala kompilować programy do celów edukacyjnych. (Jeśli masz już licencjonowaną kopię, świetnie — możesz jej swobodnie użyć w tym rozdziale). Możesz bezpłatnie pobrać ten sam kompilator, który Microsoft dołącza do Visual Studio 2019 Community Edition. W tej sekcji pokażemy, jak skonfigurować podstawową stację roboczą do wykrywania luk w zabezpieczeniach systemu Windows. Można również użyć programu Visual Studio 2022.

Podstawowe wykorzystanie systemu Windows

https://chacker.pl/

Microsoft Windows jest zdecydowanie najczęściej używanym systemem operacyjnym, zarówno do użytku profesjonalnego, jak i osobistego. Procenty pokazane na tym rysunku często się zmieniają; jednak daje on dobry pogląd na ogólny udział w rynku systemów operacyjnych.  Windows 10 zdominował z 67 procentami rynku, podczas gdy Windows 7 powoli spada, ale nadal ma prawie 20 procent rynku. Jeśli chodzi o ogólne wykorzystanie i polowanie na exploity 0-day, powinno być stosunkowo jasne, które systemy operacyjne Windows są potencjalnie lukratywnymi celami. Windows 7 często stanowi łatwiejszy cel w porównaniu do Windows 10, ponieważ niektóre funkcje zabezpieczeń i łagodzenia zagrożeń są niedostępne dla Windows 7, takie jak Control Flow Guard (CFG). Przykłady godnych uwagi funkcji i łagodzenia zagrożeń podano później. Często zdarza się, że luka w zabezpieczeniach odkryta w jednej wersji systemu Windows wpływa na wiele innych wersji, starszych i nowszych. Prawdopodobnie w nadchodzących latach udział systemu Windows 11 w rynku znacznie wzrośnie.

Podsumowanie

https://chacker.pl/

Użyliśmy podatnego modułu jądra i różnych konfiguracji jądra, aby przejść przez wiele sposobów łagodzenia zagrożeń i kilka sposobów ich obejścia. Prosty exploit ret2usr został uruchomiony na niezabezpieczonym jądrze, aby zrozumieć podstawy eksploatacji jądra. Następnie zaczęliśmy dodawać funkcje łagodzenia zagrożeń Stack Canaries, SMEP, KPTI, SMAP i KASLR i przeszliśmy przez kilka technik ich obejścia. Te techniki eksploatacji jądra zapewniają przydatną bazę wiedzy, aby rozpocząć wykrywanie wektorów ataków jądra, odkrywanie błędów bezpieczeństwa i zrozumienie możliwych łańcuchów eksploatacji w celu uzyskania pełnej kontroli nad podatnym systemem. Techniki ochrony zmieniają się, a strategie ich pokonania ewoluują.

Pokonywanie losowego układu przestrzeni adresowej jądra (KASLR)

https://chacker.pl/

KASLR5 działa podobnie do ochrony przestrzeni użytkownika ASLR, losując układ adresów bazowych jądra za każdym razem, gdy system jest uruchamiany. Jeśli możemy uzyskać wyciek niezawodnego adresu pamięci, obejście tej ochrony byłoby trywialne. Ponieważ mamy dowolny warunek odczytu, oto kroki, które wykonamy, aby obliczyć bazę jądra:

1. Zmodyfikuj program leak.c, aby uruchomić getchar() przed wysłaniem ładunku. Da nam to czas na dołączenie GDB (lub uszkodzenie GDB, jeśli jest już dołączony) i potwierdzenie, czy adres jest niezawodny. Następnie ponownie skompiluj leak.c po dodaniu getchar(). Kod powinien wyglądać następująco:

  1. Wykonaj proces kilka razy, aby upewnić się, że adres, który próbujemy, zawsze wskazuje na tę samą instrukcję:

Teraz otwórz nowy terminal i pobierz instrukcje, do których wskazują te adresy, używając polecenia x/i GDB. Jeśli powtórzysz to kilka razy, zauważysz, że piąty adres, indeks 4 naszej tablicy wycieków, zawsze wskazuje na tę samą instrukcję:

Wiedząc, że nasz niezawodny adres znajduje się pod indeksem 4 naszej tablicy wycieków, kontynuujmy pracę z wyłączonym KASLR (run4.sh), aby uprościć obliczenia. Nasze kolejne kroki będą następujące:

1. Uruchom run4.sh, a następnie pobierz adres bazowy jądra, odczytując pierwszy wiersz /proc/kallsyms i odejmując piąty adres zwrócony przez plik binarny ./leak, aby uzyskać odległość między wyciekiem a bazą jądra:

Następnie wyjdź z QEMU i użyj Pythona, aby uzyskać odległość między wyciekiem a bazą jądra:

  1. Zmodyfikuj nasz kod źródłowy exploit4.c, aby utworzyć nową zmienną unsigned long, kernel_base, której wartością będzie leak[4] – 0x14c174. Kod powinien wyglądać następująco:

  1. Oblicz odległość każdego adresu statycznego z tymi względnymi do bazy jądra. Naprawmy gadżet pop rdi; ret;, a później możesz powtórzyć ten sam proces ze wszystkimi gadżetami. Po otwarciu QEMU z wyłączonym KASLR (run4.sh) i dołączeniu GDB, odejmij adres bazowy jądra (0xffffffff81000000) od adresu gadżetu pop rdi; ret; (0xffffffff811ad2ec):

Wprowadź zmianę w kodzie exploita, która powinna wyglądać następująco:

Gdy skończysz pobierać adresy względne, źródło Twojego exploita powinno wyglądać tak jak to w ~/GHHv6/ch12/shared/exploit5/exploit.c. Skompilujmy i uruchommy nasz nowy exploit:

Omijanie zapobiegania dostępowi w trybie nadzorcy (SMAP)

https://chacker.pl/

SMAP to funkcja bezpieczeństwa wprowadzona do jądra Linux w 2012 r. przez firmę Intel.3 Polega ona na uczynieniu stron przestrzeni użytkownika niedostępnymi, gdy proces znajduje się w przestrzeni jądra. Tę funkcję włącza się, ustawiając dwudziesty pierwszy bit rejestru CR4 na on

Ta funkcja znacznie komplikuje sprawy, gdy ładunek ROP znajduje się na stronach pamięci trybu użytkownika; jednak ponieważ wszystkie gadżety z naszego poprzedniego exploita znajdują się w przestrzeni jądra, SMAP nie powstrzyma nas przed eskalacją uprawnień! Potwierdźmy to, uruchamiając run4.sh (który włącza funkcję łagodzenia exploitów SMAP) i nasz poprzedni exploit (exploit3):

SMAP skomplikuje sprawy w bardziej ograniczonych sytuacjach, w których potrzebujemy mmap do zbudowania fałszywego stosu w przestrzeni adresowej trybu użytkownika, a następnie użycia gadżetu stack pivot do przygotowania bardziej złożonego łańcucha ROP. Najczęstszą metodą osiągnięcia obejścia SMEP i SMAP było nadużywanie funkcji native_write_cr4 do ustawienia bitów 20 i 21 na wyłączone z rejestru CR4. Jednak począwszy od wersji jądra 5.3,4 CR4 jest przypinane podczas rozruchu, a funkcja native_write_cr4 teraz ponownie ustawia bity SMAP i SMEP, jeśli rejestr CR4 został zmodyfikowany. Nie należy tego uważać za funkcję łagodzącą ROP (taką jak Control Flow Integrity), ale raczej za usunięcie szybkiego, jednorazowego zwycięstwa dla autorów exploitów jądra. Istnieje duże prawdopodobieństwo, że systemy produkcyjne mają wiele modułów jądra i sterowników urządzeń zapewniających wiele przydatnych gadżetów do osiągnięcia tego samego celu. Tak jest w przypadku funkcji ghh_seek wbudowanej w nasze jądro jako przykładu. Jeśli rozmontujesz funkcję ghh_seek, powinieneś zobaczyć kod przeznaczony do innych celów:

Jednakże 3-bajtowa, niespójna interpretacja tych kodów operacji skutkuje bardzo użytecznym gadżetem do modyfikacji rejestru CR4:

Dopóki możemy wykorzystywać i łączyć istniejący kod w gadżetach ROP wpływających na rejestr CR4, ominięcie funkcji łagodzenia nadużyć SMEP i SMAP pozostanie możliwe. Mimo że ominęliśmy już SMAP w naszym poprzednim exploicie, nie chcemy przegapić okazji, aby pokazać, jak ominąć SMAP, modyfikując rejestr CR4 za pomocą gadżetu, który znaleźliśmy dzięki niezrównanej interpretacji tych kodów operacji. Ten nowy exploit będzie o wiele bardziej złożony, ponieważ zbudujemy fałszywy stos w przestrzeni adresowej użytkownika za pomocą mmap, a następnie użyjemy gadżetu stack pivot, aby wykonać łańcuch ROP, który zbudowaliśmy, aby eskalować uprawnienia. Wprowadzimy następujące zmiany do naszego exploita:

W punkcie (1) zaczynamy od przypisania rdi wartości 0x6B0, co jest równoważne z ustawieniem bitów rc4 na 20 i 21 (0000000000011010110000). W punkcie (2) gadżet modyfikuje rc4, a my dodajemy dwa rets, aby upewnić się, że stos pozostanie wyrównany. W punkcie (3) wskakujemy do rax na adres naszego fałszywego stosu, 0xc0d30000, ponieważ aby wskoczyć do naszego fałszywego stosu, użyliśmy gadżetu stack pivot mov esp, eax. Zanim nasz ładunek zostanie wysłany, tworzymy nasz fałszywy stos mmap (5) o długości 0x2000 bajtów, zaczynając od przesunięcia c0d2f000. Powodem tego jest zapewnienie wystarczającej ilości miejsca, jeśli stos będzie musiał się rozrosnąć. Skompilujmy i wykonajmy nasz nowy exploit:

Doskonale! Potwierdziliśmy, że możliwe jest nadpisanie cr4 za pomocą ROP

Omijanie ochrony trybu wykonywania nadzorcy (SMEP) i izolacji tablicy stron jądra (KPTI)

https://chacker.pl/

Teraz podniesiemy poprzeczkę i ominiemy szeroko stosowane funkcje łagodzenia eksploatowania jądra SMEP i KPTI. Funkcja łagodzenia eksploatowania SMEP korzysta z nowoczesnego mechanizmu architektury procesora, który zapobiega pobieraniu kodu znajdującego się w przestrzeni adresowej pamięci trybu użytkownika podczas pracy na wysokich poziomach uprawnień (Ring 0). Gdy SMEP jest włączony, skierowanie rejestru RIP na kod znajdujący się w przestrzeni adresowej pamięci trybu użytkownika spowoduje „oops jądra” i przerwanie zadania powodującego problem. Tę funkcję włącza się, ustawiając dwudziesty bit rejestru CR4 na on

Można sprawdzić, czy funkcja SMEP jest włączona w systemie docelowym, odczytując plik /proc/cpuinfo:

KPTI (Kernel Page-Table Isolation) to funkcja bezpieczeństwa, która zapewnia lepszą izolację między przestrzeniami pamięci w trybie użytkownika i trybie jądra, w celu obrony przed obejściami KASLR i innymi lukami w zabezpieczeniach wycieków pamięci, takimi jak Meltdown. Minimalny zestaw pamięci jądra jest obecny na izolowanych stronach pamięci w trybie użytkownika, aby uniknąć wycieków pamięci jądra niezbędnych w typowych łańcuchach eksploatacji jądra. Jądro Linux korzysta z KPTI od wersji 4.15. Możesz potwierdzić, czy funkcja KPTI jest włączona w systemie docelowym, uruchamiając komunikaty debugowania jądra:

KPTI (Kernel Page-Table Isolation) to funkcja bezpieczeństwa, która zapewnia lepszą izolację między przestrzeniami pamięci w trybie użytkownika i trybie jądra, w celu obrony przed obejściami KASLR i innymi lukami w zabezpieczeniach wycieków pamięci, takimi jak Meltdown. Minimalny zestaw pamięci jądra jest obecny na izolowanych stronach pamięci w trybie użytkownika, aby uniknąć wycieków pamięci jądra niezbędnych w typowych łańcuchach eksploatacji jądra. Jądro Linux korzysta z KPTI od wersji 4.15. Możesz potwierdzić, czy funkcja KPTI jest włączona w systemie docelowym, uruchamiając komunikaty debugowania jądra:

  1. Musimy przekazać wartość zwróconą przez wywołanie prepare_kernel_cred(0) do funkcji commit_creds, co oznacza, że ​​musimy znaleźć sposób na skopiowanie wartości z rax do rdi. Oto pierwszy interesujący gadżet, jaki znajdziemy:

Problem polega na tym, że najpierw musimy się upewnić, że rdi i rdx mają tę samą wartość, aby uniknąć warunkowego skoku w jne 0x3b7945. Aby rozwiązać tę przeszkodę, znaleźliśmy następujące dwa gadżety:

Problem polega na tym, że najpierw musimy się upewnić, że rdi i rdx mają tę samą wartość, aby uniknąć warunkowego skoku w jne 0x3b7945. Aby rozwiązać tę przeszkodę, znaleźliśmy następujące dwa gadżety:

Zmodyfikujmy nasze skrypty, aby dodać te gadżety, a następnie skompilujmy i uruchommy nasz exploit, który powinien wyglądać tak:

Mamy to! Teraz włączmy SMAP i zobaczmy, jak ta redukcja exploitów może na nas wpłynąć.

Pokonywanie Stack Canaries

https://chacker.pl/

Pamięć stosu jądra można chronić przed uszkodzeniem pamięci i atakami przepełnienia w taki sam sposób, jak jej odpowiednik w przestrzeni użytkownika, za pomocą Kernel Stack Canaries. Ta funkcja łagodzenia zagrożeń w czasie kompilacji działa jak Stack Canaries w przestrzeni użytkownika, o którym dowiedzieliśmy się i który wykorzystaliśmy w poprzednim rozdziale. Ponownie skompilowaliśmy niestandardowe jądro z włączoną funkcją CONFIG_STACKPROTECTOR, aby używać Stack Canaries w tym i kolejnych laboratoriach. Aby zobaczyć to w akcji, wykonaj run2.sh i spróbuj nadpisać rejestr RIP podczas dołączania GDB do systemu docelowego. Najpierw otwórz okno terminala w folderze ~/GHHv6/ch12 i wykonaj run2.sh, ale nie uruchamiaj jeszcze exploita:

$  ./run2.sh

W nowym oknie terminala dołącz GDB, a następnie ustaw dwa punkty przerwania, aby zobaczyć, kiedy canary zostanie przypisany i kiedy zostanie sprawdzony przed powrotem z podatnej funkcji. Następnie wygenerujemy wzorzec, który pomoże nam zidentyfikować, gdzie w naszym ładunku powinniśmy umieścić canary, aby został naprawiony po nadpisaniu stosu. Na koniec kontynuujemy wykonywanie. Oto kod:

Teraz skopiuj ten cykliczny wzór z terminala QEMU i zapisz go w interfejsie modułu:

W momencie trafienia pierwszego punktu przerwania, kanarek będzie już skopiowany do rbp-0x10. Sprawdźmy jego wartość i przejdźmy do drugiego punktu przerwania:

W tym momencie zapisany kanarek (rbp-0x10) został skopiowany do rejestru rdx i zostanie odjęty od oryginalnego kanarka. Jeśli wynik nie jest zerem, zostanie wykonane __stack_chk_fail zamiast powrotu. Zobaczmy zawartość rdx i użyjmy narzędzia przesunięcia wzorca, aby zidentyfikować, gdzie kanarek musi zostać umieszczony:

Jeśli będziemy kontynuować wykonywanie, w oknie QEMU pojawi się panika jądra:

Naszym ostatnim krokiem jest wykorzystanie luki w zabezpieczeniach arbitralnego odczytu w celu wycieku adresów pamięci i zidentyfikowanie, czy nasz kanarek jest wyciekany i w którym miejscu. W folderze ~/GHHv6/ch12/shared znajduje się mały program C, który otworzy interfejs /proc/ghh, odczyta 40 bajtów do tablicy unsigned long i zapisze nasz ładunek, aby nadpisać RIP. Najpierw skompilujmy ten program i uruchommy run2.sh:

Podłącz GDB w nowym terminalu, ustaw punkt przerwania po skopiowaniu kanarka do rejestru rax (ghh_write+25) i kontynuuj wykonywanie:

Podłącz GDB w nowym terminalu, ustaw punkt przerwania po skopiowaniu kanarka do rejestru rax (ghh_write+25) i kontynuuj wykonywanie:

Podłącz GDB w nowym terminalu, ustaw punkt przerwania po skopiowaniu kanarka do rejestru rax (ghh_write+25) i kontynuuj wykonywanie:

Podłącz GDB w nowym terminalu, ustaw punkt przerwania po skopiowaniu kanarka do rejestru rax (ghh_write+25) i kontynuuj wykonywanie:

Teraz, gdy udało nam się ominąć ochronę Stack Canary, włączmy ochronę SMEP i KPTI i zobaczmy, jak możemy ją obejść.