Loading presentation...

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Bezpieczeństwo aplikacji desktopowych

No description
by

Hubert O

on 10 January 2017

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of Bezpieczeństwo aplikacji desktopowych

Geneza bezpieczeństwa aplkacji
Metody zabezpieczenia oprogramowania dostępne w systemach operacyjnych
Zautomatyzowane mechanizmy wykrania błędów w aplkacjach
Wprowadzenie do języka assembly oraz architektury INTEL x86
Podstawy budowania
bezpiecznego oprogramowania

Bezpieczeństwo aplikacji desktopowych
Rodzaje błędów:
Składniowe.

Semantyczne.

Logiczne.

Rok
Konsekwencja błędu
Zgony
Awaria wirówek do wzbogacnia uranu w Iranie (Stuxnet)
0?
2001
Błąd podczas naświetlania nowotoru, spowodował przekroczenie dopuszczalnej dawki
5
1997
Błąd w oprogramowaniu radaru doprowadził do katastrofy koreańskiego odrzutowca
225
1997
1
W wyniu błędu oprogramowania, podano pacjętowi śmiertelną dawkę morfiny
28
1991
Błąd w oprogramowaniu rakiet patryio, umożliwił skuteczny atak rakiety SCUD w Iraku
2010
Przykłady błędów w oprogramowaniu
Rejestry
Instrukcje
Ramka stosu
Kolejność bajtów w pamięci
Proces kompilacji
Wywołania funkcji
Rejestry ogólnego przeznaczenia
Rejestry indeksowe
Rejestry wskaźnikowe
Accumulator
General
Purpose
Counter
Data
EDX
(32-bit)
DX ( 16-bit)
DH
DL
Source
ESI
(32-bit)
SI ( 16-bit)
Destinant
EDI
(32-bit)
DI ( 16-bit)
Stackpoint
ESP
(32-bit)
SP ( 16-bit)
Basepoint
EBP
(32-bit)
BP ( 16-bit)
EBP - wskazuje na podstawe aktualnej ramki stosu
ESP - wskazuje na wierzcholek stosu
EIP - adres kolejnej instrukcji do wykonania
Rejestry segmentowe:
Code Degment - CS
Data Segment - DS
Stack Segment - SS
Extra Segment - ES
Extra Segment - FS
Extra Segment - GS
Możliwe postacie offsetów:
SS : SP
SS : BP
ES : DI
DS : SI
CS : BX
EAX
(32-bit)
AX ( 16-bit)
AH
AL
EBX
(32-bit)
BX ( 16-bit)
BH
BL
ECX
(32-bit)
CX ( 16-bit)
CH
CL
1. Powodują błędne działanie aplikacji,

2. Umożliwiają wykonanie nieautoryzowanego kodu,

3. ...
Rejestr flag
0 - 15
16 - 31
32 -63
FLAGS
EFLAGS
RFLAGS
flaga przeniesienia jest ustawiana jeżeli wynikiem operacji arytmetycznej jest przeniesienie lub zapożyczenie.
CF - Carry Flag
flaga parzystości jest ustawiana, gdy
w wyniku operacji arytmetycznej otrzymano parzystą ilość jedynek.
PF - Parity Flag
flaga ta jest ustawiana jeżeli wynikiem przeprowadzonej operacji arytmetycznej jest zero.
ZF - Zero Flag
Flagi zarezerwowane
flaga ta jest ustawiana, gdy w wyniku operacji arytmetycznej otrzymano liczbę ujemną.
SF - Sign Flag
zapalona flaga sygnalizuje przepełnienie dopuszczalnego rozmiaru dla operacji arytmetycznej.
OF - Overflow Flag
Male błędy, poważne konsekwencje
EAX - używany podczas operacji arytmetycnych
EBP - w połączeniu z DS tworzą wskaźnik na dane
ECX - licznik w pętlach
EDX - operacje we/wy oraz arytmetyczne
Przesyłanie danych w pamięci
MOV cel, źródło / Move
LEA cel, źródło / Load Efective Address
MOV EAX, 1
- przeniesienie danej natychmiastowej
MOV EBX, ECX
- przeniesienie 32-bitowej danej rejestrowej
MOV EBX , [ECX]
- przeniesienie danej spod adresu w ECX
int y = points[i].ycoord -> MOV EDX, [EBX + 8*EAX + 4]

LEA EAX, zmienna
- adres zmiennej zapisany do EAX
int *p = &points[i].ycoord; -> LEA ESI, [EBX + 8*EAX + 4]
struct Point
{
int xcoord;
int ycoord;
};
PUSH, POP
Operacja arytmetyczne
Operacje logiczne
Skoki
Dyrektywa ptr
Przerwania i funkcje DOSu
ADD cel, źródło - wynik zapisany w celu.
SUB cel, źródło - wynik zapisany w celu.
INC - inkrementacja
DEC - dekrementacja
INC EAX
DEC EBX

MUL / IMUL
DIV / IDIV
MUL EBX => EBX * EAX -> EAX
AND cel, źródło - wynik zapisany w celu.
XOR cel, źródło - wynik zapisany w celu.
SHL - Przesunięcie logiczne w lewo
SHR - przesunięcie logiczne w prawo
SHL mem, 1
SHR mem, 1
TEST cel, źródło - logiczny AND bez zapisywania wartości ale z ustawieniem flag.
JMP etykieta - skok bezwarunkowy
JE/JZ ; JL/JNG - skoki warunkowe
JE Etykieta
Skoki najcześciej występują po instrukcji CMP, która porównuje dwa operandy, a następnie ustawia odpowiednie flagi na podstawie których wykonywany jest skok.
RET / IRET - powrót z podprogramu / procedury
CALL - skok do podprogramu, procedury
LOOP - CX jest zmiejszany o 1, wykonuje pętlę do czasu aż CX = 0
byte ptr - traktuj wskazany operad jako bajt
add ah, byte ptr [ds:dx]
mov byte ptr [ESI], 5
word ptr - trakuj wskazany operand jako słowo (16 bit)
mov ax, word ptr [es:bx]
mov word ptr [ESI], 5
dword ptr - trakuj operand jako podwójne słowo
mov dword ptr [ESI], 5
INT numer przerwania - wykonuje funkcje określną numerem przerwania
INT 20H - zakończenie pracy programu
INT 21H - wywołanie funkcji DOS o numerze w AH np:
13h - usunięcie pliku
08h - czytanie znaku
Dane zapisywane są w pamięci za pomocą bajtów (8-bitów).
W celu zapisu lub transmisji muszą być uporządkowane.
Istnieje wiele sposob uporządkowania bajtów, analogicznie do pisam.
Addres
Little Endian
Big Endian
Middle Endian
0x11223344
0x1000
0x1001
0x1002
0x1003
44
33
22
11
11
33
44
22
44
33
22
11
Zapis danej
pod adress
0x1000
Start
Stop
Edytor
*.ASM
MASM
TASM
*.obj
*.obj
*.obj
*.obj
LINKER
*.exe
debugger
Funkcje / procedury wywoływane są poprzez CALL
Jak przekazać parametry?
Jak uzyskać wynik ?
Cdcel
Położenie argumentów: STOS.

Kolejność przekazywania argumentów na stos: od prawej do lewej.

Funkcja wywołująca zna ilość argumentów.

Za sprzątanie stosu po funkcji odpowiedzialny jest funkcja wywołująca.

Pierwszy parametr trafia na szczyt stosu.

Wynik znajduje się w EAX (wartość lub adres).
Stdcall
Położenie argumentów: STOS.

Kolejność przekazywania argumentów na stos: od prawej do lewej.

Konwencja szybsza od cdcel.

Za sprzątanie stosu po funkcji odpowiedzialny jest funkcja wywołująca.

Funkcja wywoływana nie zna ilości argumentów.

Wynik znajduje się w EAX (wartość lub adres).
Fastcall
Położenie argumentów: pierwsze dwa w rejestrach ECX, EDX a resta na stosi

Kolejność przekazywania argumentów na stos: od prawej do lewej

Za sprzątanie stosu po funkcji odpowiedzialny jest funkcja wywoływana

Wynik znajduje się w EAX (wartość lub adres)
.model SMALL
.386

.data
tekst db "Hello World!\n"
.stack 100h
.code
.startup
mov eax, 4
mov ebx, 1
mov ecx, offset tekst
mov edx, 13
int 80h
.exit
end
void f1(int param1, int param 2 int param3) {
int flaga;
char buffor[10];

flaga = 256;
buffor[0] = 'F';
}

int main() {
f1(1,2,3,4);
}
Wygląd ramki stosu jest zalezny m.in od kompilatora oraz konwencji wywołań funkcji.
Stos to liniowa struktura danych, która działa na zasadzie bufora typu LIFO (Last In, First Out).
Przed rozpoczęciem funkcji należy najpierw odłożyć jej paramtry na stos.
Działanie funkcji podrzędnej rozpoczyna się od zapisania aktualnego EBP do SFP (Saved Frame Pointer).
Gdy funkcja podrzędna kończy działanie, jej ramka stosu zostaje zdjęta ze stosu, a do rejestru EBP zapisywana jest wartość, która znajdowała się w SFP .
Przepełnienie bufora na stosie
Przepełnienie bufora na stercie
Zastępowanie struktury SEH*
(Stack-based buffer overflow)
int sprawdz_haslo(char *pass)
{
int auth = 0;
char pass_buf[16];
strcpy(pass_buf, pass);
if(strcmp(pass_buf,"haslo1") == 0)
auth = 1;
if(strcmp(pass_buf,"haslo2") == 1
auth = 1;
return auth;
}

int main(int argc, char *argv[])
{
if(sprawdz_haslo(argv[1]))
{
printf("haslo poprawne");
}
else
{
printf("haslo niepoprawne");
}
}

CEL: Zapisanie w EIP adresu miejsca,
w którym rozpoczynie się wykonanie "nieautoryzowanego" kodu (shellcode'u)
Rejestr EIP jest tylko do odczytu
Paramtr *pass nie jest weryfikowany pod kątem objętości danych, które mają trafić na stos.

Dobranie odpwiedniej długości ciągu wejściowego spowoduje wyjście poza ramkę stosu i nadpisanie Adresu Powrotu.
słabe punkty programu ?
int main (int argc, char*argv[])
{
HANDLE h = HeapCreate(0,0,0);
void *mem = HeapAlloc(h,NULL, 16);

strcpy((char*)mem, argv[1]);
HeapAlloc(h,NULL,16);
return 0;
}


int main(int argc, char **argv)
{
char *a;

a = malloc(1024);
if (argc >= 2)
strcpy(p, argv[1]);
free(a);
return 0;
}
Przykład 1
Przykład 2
Sterta rośnie w kierunku przeciwnym do stosu.
Najmniejszy alkokowalny obszar to jedna strona.
W systemie Windows strony pamięci wynoszą 4kB.
W odległości 0x178 bajtów od początku sterty znajduje się 128 struktur _LIST_ENTRY, które razem tworzą strukture FreeList.
Struktury te służą do zarządzania wolnymi blokami pamięci.
typedef struct _LIST_ENTRY
{
sturct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blinkl;
} LIST_ENTRY, *PLIST_ENTRY
$ ./app `perl -e 'print "A"x5000'`
Segmentation fault
$ ./app `perl -e 'print "A"x5000'`
Segmentation fault
Zabezpieczenia stosu
Bezpieczna obsługa wyjątków
Zabezpieczenia sterty
Data Execution Prevention
(DEP)
Jeden z najważniejszych zabezpieczń w sytemi Windows.

Zapobiega wykonywaniu danych, znajdujących się w specjalnie oznaczonych miejscach w pamięci.

Zabezpieczeńie DEP może być realizowne sprzętowo (bit NX) jak
i programowo.

System Windows ma zaimplementowane czetry różne typy konfiguracji mechanizmu DEP:
OptIn
- konfiguracja domyślna, chronione są jedynie elementy systemu operacyjnego.
OptOut
- domyślnie jest włączona dla wszystkich procesów. Można zdefiniować listę programów niechronionych.
AlwayOn
- pełna ochrona całego systemu.
AlwaysOff
- wyłączenie funkcji DEP
Address Space Layout Randomization
(ASLR)
Tabela. Mechanizmy bezpieczeństwa w poszczególnych wersjach systemów z rodziny Windows.
Bogdan Drozdowski.Bezpieczeństwo Aplikacji Windows str. 60
Zestawienie mechanizmów bezieczeńśtwa
w systemach operacyjnych z rodziny Windows
Schemat. Chris Valasek.Understanding the Low Fragmentation Heap, str. 17
Systemy z rodziny Windows obsługują wyjątki za pomocą mechanizmu SEH (Structured Exception Handlers).
Wygenerowanie wyjątku powoduje przekazanie sterowania do procedur SEH, z których każda ma swój indywidualny numer rejestracyjny.
Często aplikacje wykorzystyją jedynie systemowe procedury, jednak dobrą praktyka jest pisanie własnych precedur obsługi wyjątków (try/catch).

Ciasteczko na stosie
.....
push ebp
mov ebp,esp
sub esp,20h
mov eax, dword_40D000
xor eax,ebp
mov [ebp+var_4],eax
....
[CIAŁO FUNKCJI]
....
mov ecx,[ebp+var_4]
xor ecx,ebp
call @__security_check_cookie@4
mov esp,ebp
pop ebp
retn 4
Wspierane od Visual Studio 2002 ( \GS)

Ze względu na znaczne spowowolnienie w działaniu programu, ciasteczka nie są dokładane do wszystkich funkcji
Zmiana kolejności zmiennych na stosie
void funkcja_1(char* wejscie)
{
char bufor[10];
int zmienna_1
strcpy(bufor,wejscie)
...
}
Gdy zastosowany jest tylko mechanizm ciasteczek mozliwe jest nadpisanie zmiennych bez nadpisywania ciasteczka i adresu powrotu.

Zmianna kolejności zmiennych jest uzupełnieniem dla mechanizmu ciasteczek.
Mechanizm SafeSEH
Mechanizm SEHOP
int main()
{
__try
{
_asm
{
xor eax,eax;
mov dword ptr [eax],eax
}
}
__except(EXCEPTION_EXECUTE_HANDE)
{
printf("Wyjątek");
}
}
Przykład obsługi wyjątków
Wywołanie kompilatora z funkcją /SAFESEH spwoduje dodanie do wynikowego pliku binarnego nagłówku ze spisem wszysthich zarejestrowanych funkcji obsługi wyjątków.
Przed wywołaniem funkcji obsługi wyjątku, jest ona sprawdzana czy występuje w rejestrze zarejestrowanych funkcji.
Gdy program korzysta z biblioteki, która nie została skompilowana z opcją /SAFESEH ?
Dostępny w systemach operacyjnych z rodziny Windows od wersji 2008.

Idea tego mechanizmu polega na weryfikacji ciągłości całego łańcucha SEH.

Zastosowanie tego mechanzmu nie wymaga ponownej kompilacji.

Połączenie SEHOP z ASLR stanowi ciągle bardzo dobre zabeczpieczeńie oprogramowania.
Bezpieczeńśtwo struktur FreeList
Implementaja mechanizmu weryfikującego ciągłość powiązań pomiędzy elementami w FreeList.

Weryfikacja na etapie uwalniania zaalokowanej pamięci.

Sprawdzane jest czy pomiędzy elementami block->blink a block-flink znajduje się obecnie usuwany blok pamięci.
Ciasteczka na stercie
Po raz pierwszy zaimplementowany w systemie Windows XP.

Zajmuje jedynie 1 bajt a nie tak jak ciasteczko na stosie 4 bajty.

Weryfikacja ciasteczka następuje w momencie zwalniania zaalokowanej pamięci.

Istnieje 256 różych ciasteczek co stanowi wystarczającą ilość do zabezpieczenia.
Umożliwia pseudolosowe rozmieszczenie w pamięci takich elementów jak: sterta, stos, TEB, PEB.
Przepełnienie bufora wymagało użycia instrukcji, które znajdowały się pod okreslonym adresem w pamięci np. call esp pod adresem 0x77568439.
Adresy w pamięci
Kolejne uruchomienia
kernel32.dll
NTDLL.dll
program.exe
kernel32.dll
kernel32.dll
program.exe
program.exe
NTDLL.dll
NTDLL.dll
Cyfrowe podpisywanie kodu
Fuzzing
metoda polegająca n awysyłaniu do programu różnego rodzaju danych wejściowych i sprawdzaniu czy zareaguje on w nieprzewidziany przez autora sposób.
Z dostępem do kodu źródłowego
Bez dostępu do kodu źródłowego
Korpus
Generator
Mutator
Aplikacja
Debugger
Deduplikacja
Zbiór znalezionych blędów
Programista 7/2016(50), Fuzzing
1 bajt
(max 0xFF)
Full transcript