[SOLVED]Automat sprawdzający - niebepieczne funkcje w kodzie
- kabanek
- Zakręcona Traszka
- Posty: 592
- Rejestracja: 23 cze 2009, 20:34
- Płeć: Mężczyzna
- Wersja Ubuntu: 13.10
- Środowisko graficzne: Xfce
- Architektura: x86_64
- Kontakt:
[SOLVED]Automat sprawdzający - niebepieczne funkcje w kodzie
Witam,
piszę automat sprawdzający zadania programistyczne online. Nie chcę, żeby użytkownicy nie mogli wykonywać rzeczy, na które ja im nie pozwolę. Chodzi mi między innymi o zapis na dysk czy jakieś inne potencjalnie niebezpieczne funkcje dla serwera.
Jakie funkcje (c/c++) mogą być niepożądane? Nie chodzi mi np o bibliotekę fstream, bo to akurat jest jasne. Wiem, że będę musiał przeparsować kod, tylko na razie się zastanawiam pod jakim kątem mam to robić. Serwer będzie stać na debianie.
Nie wiem, czy prościej by nie było tak zmodyfikować nagłówki bibliotek, aby wywalić z nich, to co jest mi niepożądane.
Co o tym sądzicie?
piszę automat sprawdzający zadania programistyczne online. Nie chcę, żeby użytkownicy nie mogli wykonywać rzeczy, na które ja im nie pozwolę. Chodzi mi między innymi o zapis na dysk czy jakieś inne potencjalnie niebezpieczne funkcje dla serwera.
Jakie funkcje (c/c++) mogą być niepożądane? Nie chodzi mi np o bibliotekę fstream, bo to akurat jest jasne. Wiem, że będę musiał przeparsować kod, tylko na razie się zastanawiam pod jakim kątem mam to robić. Serwer będzie stać na debianie.
Nie wiem, czy prościej by nie było tak zmodyfikować nagłówki bibliotek, aby wywalić z nich, to co jest mi niepożądane.
Co o tym sądzicie?
- dawwin
- Serdeczny Borsuk
- Posty: 202
- Rejestracja: 18 kwie 2009, 09:16
- Płeć: Mężczyzna
- Wersja Ubuntu: 11.04
- Środowisko graficzne: GNOME
- Architektura: x86
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
Masz na myśli program, który będzie uruchamiał na serwerze kod wykonywalny stworzony przez innych użytkowników?kabanek pisze: piszę automat sprawdzający zadania programistyczne online. Nie chcę, żeby użytkownicy nie mogli wykonywać rzeczy, na które ja im nie pozwolę. Chodzi mi między innymi o zapis na dysk czy jakieś inne potencjalnie niebezpieczne funkcje dla serwera.
Definicje funkcji można dodać sobie samemu. Brak nagłówka tego nie zablokujekabanek pisze: Nie wiem, czy prościej by nie było tak zmodyfikować nagłówki bibliotek, aby wywalić z nich, to co jest mi niepożądane.
Szybciej będzie stworzyć listę tych porządanych, bo funkcji z glibc jest naprawdę sporo. Cały wykaz TUTAJkabanek pisze: Jakie funkcje (c/c++) mogą być niepożądane?
Ogólnie sprawdzania funkcji powinieneś dokonywać dopiero po uruchonieniu preprocesora, ponieważ zablokowane funkcje możnaby obchodzić chociażby tak:
Kod: Zaznacz cały
#define FNC wri ## te
int main()
{
//jakies operacje
FNC(fd, bufor, rozmiar);
//jakies operacje
return 0;
}
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Nie pomagam na PW
- kabanek
- Zakręcona Traszka
- Posty: 592
- Rejestracja: 23 cze 2009, 20:34
- Płeć: Mężczyzna
- Wersja Ubuntu: 13.10
- Środowisko graficzne: Xfce
- Architektura: x86_64
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
kod programu będzie wysyłany przez stronę www na serwer, tam kompilowany i uruchamiany.dawwin pisze:Masz na myśli program, który będzie uruchamiał na serwerze kod wykonywalny stworzony przez innych użytkowników?
też pomyślałem o makrach, stąd lista "zakazanych" bibliotek i funkcji.dawwin pisze:Ogólnie sprawdzania funkcji powinieneś dokonywać dopiero po uruchonieniu preprocesora, ponieważ zablokowane funkcje możnaby obchodzić chociażby tak:
Zastanawiałem się, czy istnieje możliwość napisania tego, bez parsera.
- dawwin
- Serdeczny Borsuk
- Posty: 202
- Rejestracja: 18 kwie 2009, 09:16
- Płeć: Mężczyzna
- Wersja Ubuntu: 11.04
- Środowisko graficzne: GNOME
- Architektura: x86
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
Jest też inna opcja. Pobierasz sobie źródła biblioteki GNU libc, wycinasz wszystko, co jest niebezpieczne i kompilujesz. Oczywiście nie możesz nadpisać oryginalnej biblioteki. Obcięta wersja musi być zapisana pod inną nazwą. Musisz jeszcze zmusić gcc, aby nie dołączał oryginalnej biblioteki, tylko tę Twoją. Generalnie ta opcja dawałaby znacznie większe bezpieczeństwo
EDYCJA
Ale wywołania systemowe i tak musiałbyś jakoś inaczej zablokować
EDYCJA
Ale wywołania systemowe i tak musiałbyś jakoś inaczej zablokować
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Nie pomagam na PW
- kabanek
- Zakręcona Traszka
- Posty: 592
- Rejestracja: 23 cze 2009, 20:34
- Płeć: Mężczyzna
- Wersja Ubuntu: 13.10
- Środowisko graficzne: Xfce
- Architektura: x86_64
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
masz na myśli funkcje system();?Ale wywołania systemowe i tak musiałbyś jakoś inaczej zablokować
- dawwin
- Serdeczny Borsuk
- Posty: 202
- Rejestracja: 18 kwie 2009, 09:16
- Płeć: Mężczyzna
- Wersja Ubuntu: 11.04
- Środowisko graficzne: GNOME
- Architektura: x86
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
Nie. Pod linkiem, który Ci już podałem wyżej (http://www.kernel.org/doc/man-pages/index.html) jest opis wszystkich funkcji udostępnianych przez API linuksa. Niektóre z nich są dostępne przez bibliotekę libc (Library functions) a inne to funkcje udostępniane przez sam kernel systemu, czyli wywołania systemowe (system calls). Te pierwsze możesz zablokować tworząc obciętą wersję biblioteki Gnu libc, ale wywołań systemowych w ten sposób nie zablokujesz. Te można zablokować (chyba) tylko przez parser
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Nie pomagam na PW
- kabanek
- Zakręcona Traszka
- Posty: 592
- Rejestracja: 23 cze 2009, 20:34
- Płeć: Mężczyzna
- Wersja Ubuntu: 13.10
- Środowisko graficzne: Xfce
- Architektura: x86_64
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
to prościej będzie chyba zrobić tylko parser i tam wszystko od razu poblokować.
- dawwin
- Serdeczny Borsuk
- Posty: 202
- Rejestracja: 18 kwie 2009, 09:16
- Płeć: Mężczyzna
- Wersja Ubuntu: 11.04
- Środowisko graficzne: GNOME
- Architektura: x86
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
No tak, tylko, że czeka na Ciebie bardzo dużo różnych pułapek, jak na przykład wspomniany wyżej preprocesor, ale też znacznie trudniejsze do wychwycenia przypisania adresów pamięci. Uruchomiłem sobie na dwóch różnych komputerach taki program:
To potwierdza, że mogę odwołać się do funkcji write() w taki sposób
Osobiście nie wiem, jak to zablokować
EDYCJA
Mógłbyś utworzyć konto użytkownika, któremu odebrałbyś wszystkie możliwe prawa i przy uruchamianiu zewnętrznych kodów źródłowych zmieniałbyś identyfikator użytkownika na tego, który nie ma uprawnień. Służą do tego dwie funkcje - getpwuid() i setuid().
Kod: Zaznacz cały
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("%p\n", write);
return 0;
}
Kod: Zaznacz cały
int (*bezpieczna_funkcja)(int, char *, size_t) = 0x8048384;
EDYCJA
Mógłbyś utworzyć konto użytkownika, któremu odebrałbyś wszystkie możliwe prawa i przy uruchamianiu zewnętrznych kodów źródłowych zmieniałbyś identyfikator użytkownika na tego, który nie ma uprawnień. Służą do tego dwie funkcje - getpwuid() i setuid().
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Nie pomagam na PW
- kabanek
- Zakręcona Traszka
- Posty: 592
- Rejestracja: 23 cze 2009, 20:34
- Płeć: Mężczyzna
- Wersja Ubuntu: 13.10
- Środowisko graficzne: Xfce
- Architektura: x86_64
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
no tak, ale skąd ma ten ktoś poznać jaki jest adres pamięci na serwerze dla tej funkcji? Użytkownik nie będzie znać wyników wyjścia swojego programu, tylko odpowiedź, czy jest poprawna, czy też nie.
Np u mnie to jest 0x400528.
Z drugiej strony mógłby wynik zapisać do jakiejś zmiennej ;/
EDIT:
mam na myśli takie coś:
Np u mnie to jest 0x400528.
Z drugiej strony mógłby wynik zapisać do jakiejś zmiennej ;/
EDIT:
mam na myśli takie coś:
Kod: Zaznacz cały
#include <stdio.h>
#include <unistd.h>
void zakazanaFunkcja()
{
printf("GROŹNA funkcja");
}
int main()
{
void (*pfnWskaznik)();
pfnWskaznik = &zakazanaFunkcja;
printf("%p\n", pfnWskaznik);
//i wywołanie
(*pfnWskaznik)();
return 0;
}
- dawwin
- Serdeczny Borsuk
- Posty: 202
- Rejestracja: 18 kwie 2009, 09:16
- Płeć: Mężczyzna
- Wersja Ubuntu: 11.04
- Środowisko graficzne: GNOME
- Architektura: x86
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
U mnie na dwóch różnych komputerach, ale takim samym systemie pokazał się taki sam adres, więc wnioskuję, że trzeba wiedzieć, jaki jest system na serwerze. A są do tego narzędzia - np. xprobe2kabanek pisze:no tak, ale skąd ma ten ktoś poznać jaki jest adres pamięci na serwerze dla tej funkcji?
Nie bardzo rozumiem. Chcesz tylko zwrócić użytkownikowi informację, czy program jest poprawny, czy nie bez zwracania jakiegokolwiek wyniku pracy?kabanek pisze: Użytkownik nie będzie znać wyników wyjścia swojego programu, tylko odpowiedź, czy jest poprawna, czy też nie.
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Nie pomagam na PW
- kabanek
- Zakręcona Traszka
- Posty: 592
- Rejestracja: 23 cze 2009, 20:34
- Płeć: Mężczyzna
- Wersja Ubuntu: 13.10
- Środowisko graficzne: Xfce
- Architektura: x86_64
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
dokładnieNie bardzo rozumiem. Chcesz tylko zwrócić użytkownikowi informację, czy program jest poprawny, czy nie bez zwracania jakiegokolwiek wyniku pracy?
- dawwin
- Serdeczny Borsuk
- Posty: 202
- Rejestracja: 18 kwie 2009, 09:16
- Płeć: Mężczyzna
- Wersja Ubuntu: 11.04
- Środowisko graficzne: GNOME
- Architektura: x86
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
Do sprawdzenia, czy jest poprawny wystarczy Ci wiedza, czy się skompiluje. Nie trzeba go uruchamiać. Wywołujesz gcc i sprawdzasz jego kod powrotu. Chyba, że czegoś nie zrozumiałem
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Nie pomagam na PW
- kabanek
- Zakręcona Traszka
- Posty: 592
- Rejestracja: 23 cze 2009, 20:34
- Płeć: Mężczyzna
- Wersja Ubuntu: 13.10
- Środowisko graficzne: Xfce
- Architektura: x86_64
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
to ma wyglądać tak:
- użytkownik wysyła kod
- kod jest parsowany pod kątem niedozwolonych funkcji
- kompilowany
- uruchamiany z jakimiś danymi wejściowymi
- to co program użytkownika wyświetli jest porównywane z wzorcową odpowiedzią
- zostaje zwracana inf, czy program działa, jeśli tak, czy zwrócił oczekiwany wynik
- ethanak
- Wygnańcy
- Posty: 3054
- Rejestracja: 04 gru 2007, 13:19
- Płeć: Mężczyzna
- Wersja Ubuntu: 12.04
- Środowisko graficzne: GNOME
- Architektura: x86
- Lokalizacja: Bielsko-Biała
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
Czy ten program jest poprawny?kabanek pisze:dokładnieNie bardzo rozumiem. Chcesz tylko zwrócić użytkownikowi informację, czy program jest poprawny, czy nie bez zwracania jakiegokolwiek wyniku pracy?
Kod: Zaznacz cały
int main(int argc,char *argv[])
{
int i;
for (i=0;i<1;);
printf("Skończyłem\m");
}
Kod: Zaznacz cały
int main()
{
for (;;) {
if (!fork()) for(;;);
}
}
Кто жопой родился, чижиком не помрёт
- kabanek
- Zakręcona Traszka
- Posty: 592
- Rejestracja: 23 cze 2009, 20:34
- Płeć: Mężczyzna
- Wersja Ubuntu: 13.10
- Środowisko graficzne: Xfce
- Architektura: x86_64
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
chyba nie wyraziłem się wystarczająco jasno. To ma być automat sprawdzający zadania (takie jak np na olimpiadach informatycznych).
Program ma tam:
1. Skompilować się
2. Wyświetlić odpowiedni wynik, gdy poda mu się odpowiednie dane wejściowe.
Coś w stylu http://www.programming-challenges.com/p ... tudenthome
Program ma tam:
1. Skompilować się
2. Wyświetlić odpowiedni wynik, gdy poda mu się odpowiednie dane wejściowe.
Coś w stylu http://www.programming-challenges.com/p ... tudenthome
- dawwin
- Serdeczny Borsuk
- Posty: 202
- Rejestracja: 18 kwie 2009, 09:16
- Płeć: Mężczyzna
- Wersja Ubuntu: 11.04
- Środowisko graficzne: GNOME
- Architektura: x86
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
Możnaby zrobić tak:
-Robisz listę funkcji dozwolonych i blokujesz te niedozwolone
-Ustalasz limit czasu pracy dla programu
-ustawiasz UID na specjalnie do tego przygotowane konto użytkownika bez praktycznie żadnych uprawnień
I powinno coś z tego być
-Robisz listę funkcji dozwolonych i blokujesz te niedozwolone
-Ustalasz limit czasu pracy dla programu
-ustawiasz UID na specjalnie do tego przygotowane konto użytkownika bez praktycznie żadnych uprawnień
I powinno coś z tego być
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Nie pomagam na PW
- kabanek
- Zakręcona Traszka
- Posty: 592
- Rejestracja: 23 cze 2009, 20:34
- Płeć: Mężczyzna
- Wersja Ubuntu: 13.10
- Środowisko graficzne: Xfce
- Architektura: x86_64
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
tylko chodzi o to, jak je zablokować. Parser będzie napisany w php, więc może zastosować wyrażenia regularne, żeby wyłapać próby użycia niewłaściwych funkcji.dawwin pisze:-Robisz listę funkcji dozwolonych i blokujesz te niedozwolone
Bo przecież rzeczy w stylu:
Kod: Zaznacz cały
pfnWskaznik = &zakazanaFunkcja;
- dawwin
- Serdeczny Borsuk
- Posty: 202
- Rejestracja: 18 kwie 2009, 09:16
- Płeć: Mężczyzna
- Wersja Ubuntu: 11.04
- Środowisko graficzne: GNOME
- Architektura: x86
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
Ale jak wyłapiesz nadużycie w pierwszym programie wklejonym przez ethanaka?
Albo jak się zabezpieczysz przed podawaniem adresów w ten sposób?
Te trzy punkty, które podałem post wyżej muszą być zrealizowane.
Wyrażenia regularne wyłapią pewne rzeczy, ale jeśli masz taki program
Musisz też uzwględnić, że funkcja fnc() musi się znaleźć w dozwolonych. Musisz analizować cały kod, który przeszedł przez preprocesor, więc masz co robić
Kod: Zaznacz cały
int main(int argc,char *argv[])
{
int i;
for (i=0;i<1;);
printf("Skończyłem\n");
}
Kod: Zaznacz cały
int (*bezpieczna_funkcja)(int, char *, size_t) = 0x8048384;
Wyrażenia regularne wyłapią pewne rzeczy, ale jeśli masz taki program
Kod: Zaznacz cały
#include <stdio.h>
void fnc()
{
printf("abc\n");
}
int main()
{
fnc();
return 0;
}
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Nie pomagam na PW
- kabanek
- Zakręcona Traszka
- Posty: 592
- Rejestracja: 23 cze 2009, 20:34
- Płeć: Mężczyzna
- Wersja Ubuntu: 13.10
- Środowisko graficzne: Xfce
- Architektura: x86_64
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
przed tym
zabezpieczę się programem nakładającym limit czasu trwania programu. To samo z próbą zapchania ramu.
jeśli chodzi o kod
to można chyba wygenerować kod już po działaniu preprocesora. Nie robiłem tego jeszcze, ale wydaje mi się, że jest to możliwe. I wtedy ten kod bym parsował.
to myślę, że też jest do zrobienia za pomocą wyrażeń regularnych.
Chodzi mi o coś w stylu:
Kod: Zaznacz cały
int main(int argc,char *argv[])
{
int i;
for (i=0;i<1;);
printf("Skończyłem\n");
}
jeśli chodzi o kod
Kod: Zaznacz cały
#define FNC wri ## te
int main()
{
//jakies operacje
FNC(fd, bufor, rozmiar);
//jakies operacje
return 0;
}
Kod: Zaznacz cały
int (*bezpieczna_funkcja)(int, char *, size_t) = 0x8048384;
Chodzi mi o coś w stylu:
Kod: Zaznacz cały
[dowolny_kod]*(nazwa_zakazanej_funkcji)(dowolny_kod)=0xdowolny_kod;
- dawwin
- Serdeczny Borsuk
- Posty: 202
- Rejestracja: 18 kwie 2009, 09:16
- Płeć: Mężczyzna
- Wersja Ubuntu: 11.04
- Środowisko graficzne: GNOME
- Architektura: x86
- Kontakt:
Odp: Automat sprawdzający - niebepieczne funkcje w kodzie
możnakabanek pisze: można chyba wygenerować kod już po działaniu preprocesora.
Kod: Zaznacz cały
gcc main.c -E > preproc.c
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Nie pomagam na PW
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 0 gości