[SOLVED]Automat sprawdzający - niebepieczne funkcje w kodzie

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
Awatar użytkownika
kabanek
Zakręcona Traszka
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

Post autor: kabanek »

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?
Awatar użytkownika
dawwin
Serdeczny Borsuk
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

Post autor: dawwin »

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.
Masz na myśli program, który będzie uruchamiał na serwerze kod wykonywalny stworzony przez innych użytkowników?
kabanek 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.
Definicje funkcji można dodać sobie samemu. Brak nagłówka tego nie zablokuje
kabanek pisze: Jakie funkcje (c/c++) mogą być niepożądane?
Szybciej będzie stworzyć listę tych porządanych, bo funkcji z glibc jest naprawdę sporo. Cały wykaz TUTAJ

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
Awatar użytkownika
kabanek
Zakręcona Traszka
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

Post autor: kabanek »

dawwin pisze:Masz na myśli program, który będzie uruchamiał na serwerze kod wykonywalny stworzony przez innych użytkowników?
kod programu będzie wysyłany przez stronę www na serwer, tam kompilowany i uruchamiany.
dawwin pisze:Ogólnie sprawdzania funkcji powinieneś dokonywać dopiero po uruchonieniu preprocesora, ponieważ zablokowane funkcje możnaby obchodzić chociażby tak:
też pomyślałem o makrach, stąd lista "zakazanych" bibliotek i funkcji.

Zastanawiałem się, czy istnieje możliwość napisania tego, bez parsera.
Awatar użytkownika
dawwin
Serdeczny Borsuk
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

Post autor: dawwin »

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ć
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Awatar użytkownika
kabanek
Zakręcona Traszka
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

Post autor: kabanek »

Ale wywołania systemowe i tak musiałbyś jakoś inaczej zablokować
masz na myśli funkcje system();?
Awatar użytkownika
dawwin
Serdeczny Borsuk
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

Post autor: dawwin »

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
Awatar użytkownika
kabanek
Zakręcona Traszka
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

Post autor: kabanek »

to prościej będzie chyba zrobić tylko parser i tam wszystko od razu poblokować.
Awatar użytkownika
dawwin
Serdeczny Borsuk
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

Post autor: dawwin »

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:

Kod: Zaznacz cały

#include <stdio.h>
#include <unistd.h>

int main()
{
   printf("%p\n", write);
   return 0;
}
To potwierdza, że mogę odwołać się do funkcji write() w taki sposób

Kod: Zaznacz cały

int (*bezpieczna_funkcja)(int, char *, size_t) = 0x8048384;
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().
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Awatar użytkownika
kabanek
Zakręcona Traszka
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

Post autor: kabanek »

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ś:

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;
}
Awatar użytkownika
dawwin
Serdeczny Borsuk
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

Post autor: dawwin »

kabanek pisze:no tak, ale skąd ma ten ktoś poznać jaki jest adres pamięci na serwerze dla tej funkcji?
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. xprobe2
kabanek pisze: Użytkownik nie będzie znać wyników wyjścia swojego programu, tylko odpowiedź, czy jest poprawna, czy też nie.
Nie bardzo rozumiem. Chcesz tylko zwrócić użytkownikowi informację, czy program jest poprawny, czy nie bez zwracania jakiegokolwiek wyniku pracy?
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Awatar użytkownika
kabanek
Zakręcona Traszka
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

Post autor: kabanek »

Nie bardzo rozumiem. Chcesz tylko zwrócić użytkownikowi informację, czy program jest poprawny, czy nie bez zwracania jakiegokolwiek wyniku pracy?
dokładnie
Awatar użytkownika
dawwin
Serdeczny Borsuk
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

Post autor: dawwin »

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
Awatar użytkownika
kabanek
Zakręcona Traszka
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

Post autor: kabanek »

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
Awatar użytkownika
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

Post autor: ethanak »

kabanek pisze:
Nie bardzo rozumiem. Chcesz tylko zwrócić użytkownikowi informację, czy program jest poprawny, czy nie bez zwracania jakiegokolwiek wyniku pracy?
dokładnie
Czy ten program jest poprawny?

Kod: Zaznacz cały

int main(int argc,char *argv[])
{
   int i;
   for (i=0;i<1;);
   printf("Skończyłem\m");
}
A ten?

Kod: Zaznacz cały

int main()
{
   for (;;) {
      if (!fork()) for(;;);
   }
}
Кто жопой родился, чижиком не помрёт
Awatar użytkownika
kabanek
Zakręcona Traszka
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

Post autor: kabanek »

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
Awatar użytkownika
dawwin
Serdeczny Borsuk
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

Post autor: dawwin »

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ć
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Awatar użytkownika
kabanek
Zakręcona Traszka
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

Post autor: kabanek »

dawwin pisze:-Robisz listę funkcji dozwolonych i blokujesz te niedozwolone
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.
Bo przecież rzeczy w stylu:

Kod: Zaznacz cały

pfnWskaznik = &zakazanaFunkcja;
można by było w ten sposób wyłapać
Awatar użytkownika
dawwin
Serdeczny Borsuk
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

Post autor: dawwin »

Ale jak wyłapiesz nadużycie w pierwszym programie wklejonym przez ethanaka?

Kod: Zaznacz cały

int main(int argc,char *argv[])
{
   int i;
   for (i=0;i<1;);
   printf("Skończyłem\n");
}
Albo jak się zabezpieczysz przed podawaniem adresów w ten sposób?

Kod: Zaznacz cały

int (*bezpieczna_funkcja)(int, char *, size_t) = 0x8048384;
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

Kod: Zaznacz cały

#include <stdio.h>

void fnc()
{
   printf("abc\n");
}

int main()
{
   fnc();
   return 0;
}
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ć
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
Awatar użytkownika
kabanek
Zakręcona Traszka
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

Post autor: kabanek »

przed tym

Kod: Zaznacz cały

int main(int argc,char *argv[])
{
   int i;
   for (i=0;i<1;);
   printf("Skończyłem\n");
}
zabezpieczę się programem nakładającym limit czasu trwania programu. To samo z próbą zapchania ramu.

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;
}
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ł.

Kod: Zaznacz cały

int (*bezpieczna_funkcja)(int, char *, size_t) = 0x8048384;
to myślę, że też jest do zrobienia za pomocą wyrażeń regularnych.
Chodzi mi o coś w stylu:

Kod: Zaznacz cały

[dowolny_kod]*(nazwa_zakazanej_funkcji)(dowolny_kod)=0xdowolny_kod;
Awatar użytkownika
dawwin
Serdeczny Borsuk
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

Post autor: dawwin »

kabanek pisze: można chyba wygenerować kod już po działaniu preprocesora.
można

Kod: Zaznacz cały

gcc main.c -E > preproc.c
A reszta tak, jak napisałeś i powinno być ok :)
Moje programy - http://dawwin.users.sourceforge.net/
Nie pomagam na PW
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 0 gości