Funkcje PHP do wykorzystania

277

Próbuję zbudować listę funkcji, których można użyć do wykonania dowolnego kodu. Celem nie jest wylistowanie funkcji, które powinny być na czarnej liście lub w inny sposób zabronione. Chciałbym raczej mieć pod ręką grepmożliwą do użycia listę słów kluczowych z czerwoną flagą podczas przeszukiwania zaatakowanego serwera dla tylnych drzwi.

Chodzi o to, że jeśli chcesz zbudować wielozadaniowy złośliwy skrypt PHP - taki jak skrypt „powłoki sieciowej”, taki jak c99 lub r57 - będziesz musiał użyć jednej lub więcej stosunkowo niewielkiego zestawu funkcji gdzieś w pliku, aby umożliwić użytkownikowi wykonanie dowolnego kodu. Wyszukiwanie tych funkcji pomaga szybciej zawęzić stóg siana dziesiątek tysięcy plików PHP do stosunkowo niewielkiego zestawu skryptów, które wymagają dokładniejszego zbadania.

Oczywiście na przykład dowolne z poniższych byłoby uważane za złośliwe (lub straszne kodowanie):

<? eval($_GET['cmd']); ?>

<? system($_GET['cmd']); ?>

<? preg_replace('/.*/e',$_POST['code']); ?>

i tak dalej.

Pewnego dnia przeszukując zaatakowaną witrynę, nie zauważyłem złośliwego kodu, ponieważ nie zdawałem sobie sprawy, preg_replaceże użycie /eflagi może być niebezpieczne ( co, na serio? Dlaczego nawet tam jest ?). Czy są jeszcze jakieś inne, za którymi tęskniłem?

Oto moja lista do tej pory:

Shell Execute

  • system
  • exec
  • popen
  • backtick operator
  • pcntl_exec

PHP Wykonaj

  • eval
  • preg_replace(z /emodyfikatorem)
  • create_function
  • include[ _once] / require[ _once] ( szczegółowe informacje na temat wykorzystania znajdują się w odpowiedzi Mario )

Przydatna może być również lista funkcji zdolnych do modyfikowania plików, ale wyobrażam sobie, że 99% kodu wykorzystującego czas będzie zawierało przynajmniej jedną z powyższych funkcji. Ale jeśli masz listę wszystkich funkcji zdolnych do edytowania lub wysyłania plików, opublikuj ją, a ja ją tutaj dołączę. (I nie liczę mysql_execute, ponieważ jest to część innej klasy exploita.)

tylerl
źródło
43
na marginesie, chciałbym zobaczyć tę listę opublikowaną w najbliższej przyszłości, jeśli to możliwe :)
yoda
16
@yoda: opublikowano gdzie? Będę aktualizował listę tutaj, ponieważ SO jest źródłem wszelkiej wiedzy.
tylerl
3
Co robi /emodyfikator?
Billy ONeal,
6
@Billy: emodyfikator sprawia, że ​​ciąg zastępujący jest oceniany jako kod PHP.
nikc.org,
1
Trzeba powiedzieć: wykonywanie kodu w wyrażeniu regularnym to coś, co robią Perl i prawdopodobnie Python, a nie coś wyłącznego dla PHP. Jednak nie znam szczegółów.
Adriano Varoli Piazza

Odpowiedzi:

205

Do zbudowania tej listy wykorzystałem 2 źródła. A Study In Scarlet and RATS . Dodałem też własne do miksu i ludzie z tego wątku pomogli.

Edycja: Po opublikowaniu tej listy skontaktowałem się z założycielem RIPS i odtąd narzędzia przeszukują kod PHP pod kątem użycia każdej funkcji z tej listy.

Większość tych wywołań funkcji jest sklasyfikowanych jako zlewy. Kiedy zmienna skażona (np. $ _REQUEST) jest przekazywana do funkcji sink, masz lukę. Programy takie jak szczurów i rozrywa użyć grep jak funkcjonalność zidentyfikować wszystkie umywalki w aplikacji. Oznacza to, że programiści powinni zachować szczególną ostrożność podczas korzystania z tych funkcji, ale jeśli wszystkie zostały zbanowane, nie będziesz w stanie wiele zrobić.

Z wielką mocą wiąże się wielka odpowiedzialność ”.

- Stan Lee

Wykonanie polecenia

exec           - Returns last line of commands output
passthru       - Passes commands output directly to the browser
system         - Passes commands output directly to the browser and returns last line
shell_exec     - Returns commands output
`` (backticks) - Same as shell_exec()
popen          - Opens read or write pipe to process of a command
proc_open      - Similar to popen() but greater degree of control
pcntl_exec     - Executes a program

Wykonanie kodu PHP

Poza evaltym istnieją inne sposoby wykonania kodu PHP: include/ requiremożna wykorzystać do zdalnego wykonania kodu w postaci luk w zabezpieczeniach Local File Include i Remote File Include .

eval()
assert()  - identical to eval()
preg_replace('/.*/e',...) - /e does an eval() on the match
create_function()
include()
include_once()
require()
require_once()
$_GET['func_name']($_GET['argument']);
$func = new ReflectionFunction($_GET['func_name']); $func->invoke(); or $func->invokeArgs(array());

Lista funkcji akceptujących wywołania zwrotne

Funkcje te akceptują parametr ciągu, który może być użyty do wywołania funkcji wybranej przez atakującego. W zależności od funkcji atakujący może, ale nie musi, przekazać parametr. W takim przypadku można użyć Information Disclosurefunkcji podobnej do phpinfo().

Function                     => Position of callback arguments
'ob_start'                   =>  0,
'array_diff_uassoc'          => -1,
'array_diff_ukey'            => -1,
'array_filter'               =>  1,
'array_intersect_uassoc'     => -1,
'array_intersect_ukey'       => -1,
'array_map'                  =>  0,
'array_reduce'               =>  1,
'array_udiff_assoc'          => -1,
'array_udiff_uassoc'         => array(-1, -2),
'array_udiff'                => -1,
'array_uintersect_assoc'     => -1,
'array_uintersect_uassoc'    => array(-1, -2),
'array_uintersect'           => -1,
'array_walk_recursive'       =>  1,
'array_walk'                 =>  1,
'assert_options'             =>  1,
'uasort'                     =>  1,
'uksort'                     =>  1,
'usort'                      =>  1,
'preg_replace_callback'      =>  1,
'spl_autoload_register'      =>  0,
'iterator_apply'             =>  1,
'call_user_func'             =>  0,
'call_user_func_array'       =>  0,
'register_shutdown_function' =>  0,
'register_tick_function'     =>  0,
'set_error_handler'          =>  0,
'set_exception_handler'      =>  0,
'session_set_save_handler'   => array(0, 1, 2, 3, 4, 5),
'sqlite_create_aggregate'    => array(2, 3),
'sqlite_create_function'     =>  2,

Ujawnienie informacji

Większość tych wywołań funkcji nie jest zlewami. Ale może to być luka, jeśli jakiekolwiek zwrócone dane będą widoczne dla atakującego. Jeśli atakujący może phpinfo()to zobaczyć, jest to z pewnością luka.

phpinfo
posix_mkfifo
posix_getlogin
posix_ttyname
getenv
get_current_user
proc_get_status
get_cfg_var
disk_free_space
disk_total_space
diskfreespace
getcwd
getlastmo
getmygid
getmyinode
getmypid
getmyuid

Inny

extract - Opens the door for register_globals attacks (see study in scarlet).
parse_str -  works like extract if only one argument is given.  
putenv
ini_set
mail - has CRLF injection in the 3rd parameter, opens the door for spam. 
header - on old systems CRLF injection could be used for xss or other purposes, now it is still a problem if they do a header("location: ..."); and they do not die();. The script keeps executing after a call to header(), and will still print output normally. This is nasty if you are trying to protect an administrative area. 
proc_nice
proc_terminate
proc_close
pfsockopen
fsockopen
apache_child_terminate
posix_kill
posix_mkfifo
posix_setpgid
posix_setsid
posix_setuid

Funkcje systemu plików

Według RATS wszystkie funkcje systemu plików w php są nieprzyjemne. Niektóre z nich nie wydają się bardzo przydatne atakującemu. Inne są bardziej przydatne niż mogłoby się wydawać. Na przykład, jeśli allow_url_fopen=Onadres URL może być użyty jako ścieżka do pliku, więc copy($_GET['s'], $_GET['d']);można użyć wywołania do przesłania skryptu PHP w dowolnym miejscu w systemie. Również jeśli witryna jest podatna na żądanie wysyłane przez GET, każda z funkcji systemu plików może zostać wykorzystana do kierowania i atakowania innego hosta za pośrednictwem serwera.

// open filesystem handler
fopen
tmpfile
bzopen
gzopen
SplFileObject->__construct
// write to filesystem (partially in combination with reading)
chgrp
chmod
chown
copy
file_put_contents
lchgrp
lchown
link
mkdir
move_uploaded_file
rename
rmdir
symlink
tempnam
touch
unlink
imagepng   - 2nd parameter is a path.
imagewbmp  - 2nd parameter is a path. 
image2wbmp - 2nd parameter is a path. 
imagejpeg  - 2nd parameter is a path.
imagexbm   - 2nd parameter is a path.
imagegif   - 2nd parameter is a path.
imagegd    - 2nd parameter is a path.
imagegd2   - 2nd parameter is a path.
iptcembed
ftp_get
ftp_nb_get
// read from filesystem
file_exists
file_get_contents
file
fileatime
filectime
filegroup
fileinode
filemtime
fileowner
fileperms
filesize
filetype
glob
is_dir
is_executable
is_file
is_link
is_readable
is_uploaded_file
is_writable
is_writeable
linkinfo
lstat
parse_ini_file
pathinfo
readfile
readlink
realpath
stat
gzfile
readgzfile
getimagesize
imagecreatefromgif
imagecreatefromjpeg
imagecreatefrompng
imagecreatefromwbmp
imagecreatefromxbm
imagecreatefromxpm
ftp_put
ftp_nb_put
exif_read_data
read_exif_data
exif_thumbnail
exif_imagetype
hash_file
hash_hmac_file
hash_update_file
md5_file
sha1_file
highlight_file
show_source
php_strip_whitespace
get_meta_tags
Wieżowiec
źródło
37
@whatnick Właściwie nie widzę znaczącej różnicy między PHP a innymi językami aplikacji internetowych. Na koniec programiści potrzebują umiejętności eval()kodowania, wykonywania poleceń systemowych, uzyskiwania dostępu do bazy danych oraz odczytu / zapisu do plików. Atakujący może mieć wpływ na ten kod i jest to luka w zabezpieczeniach.
wieża
8
Tyle funkcji zablokowanych! Czy jesteś gospodarzem mojej witryny przez przypadek?
Randy the Dev
2
@Andrew Dunn haha, nie. Jeśli zablokowałeś wszystkie te funkcje, żadna aplikacja PHP nie działałaby. Szczególnie obejmują funkcje (), wymagają () i funkcje systemu plików.
wieża
2
@Rook: dokładnie moje myśli, ale dotyczą one potencjalnych problemów, a nie określonych. Przy prawidłowym użyciu żaden z nich nie stanowi bezpośredniego zagrożenia; ale jeśli można ich uniknąć, powinny.
Geekster
3
Imho preg_matchz enie szkodzi. Instrukcja mówi: „Tylko preg_replace () używa tego modyfikatora; jest on ignorowany przez inne funkcje PCRE”.
NikiC,
59

Będziesz musiał skanować w poszukiwaniu include ($ tmp) i wymagać także (HTTP_REFERER) i * _once. Jeśli skrypt exploita może zapisać do pliku tymczasowego, może po prostu dołączyć go później. Zasadniczo ewolucja dwuetapowa.

Możliwe jest nawet ukrycie zdalnego kodu za pomocą obejść takich jak:

 include("data:text/plain;base64,$_GET[code]");

Ponadto, jeśli twój serwer został już skompromitowany, nie zawsze zobaczysz niezakodowane zło. Często powłoka exploita jest zakodowana w gzipie. Pomyśl o include("zlib:script2.png.gz");Brak ewaluacji tutaj, wciąż ten sam efekt.

mario
źródło
1
W zależności od konfiguracji PHP, include może faktycznie zawierać kod z dowolnych adresów URL. Coś takiego jak „ example.com/code.phps ”; Widziałem skompromitowaną witrynę, na którą włamano się, używając kombinacji tej funkcji i register_globals.
BlackAura,
@BlackAura, jak regiser_globals wpasowało się w atak? Czy jest to coś, co można było wyciągnąć równie łatwo, używając, $_GET[xyz]a nie $xyz? A może było w tym coś głębszego?
tylerl
Nie jestem do końca pewien, dlaczego tak się stało, ale witryna wciąż robiła takie rzeczy: include (prefiks $. '/Filename.php'); Myślę, że pomysł polegał na tym, że można przenieść kod podstawowy poza katalog główny, ustawiając zmienną $ prefix w pliku konfiguracyjnym. Jeśli atakujący ustawi tę wartość na coś takiego jak „ example.com/code.phps ?”, PHP w zamian uwzględni ten plik zdalny. Niemal, jak mogę stwierdzić, botowi udało się włamać przy użyciu ogólnego exploita. Wygląda na to, że wiele starego kodu PHP popełniło ten błąd. Zasadniczo, NIGDY nie pozwól, aby jakakolwiek wartość przesłana przez użytkownika znajdowała się w pobliżu instrukcji include.
BlackAura
Myślę, że możesz uogólnić to na dołączenia, które zawierają „:” w nazwie pliku ... z wyjątkiem tego, że nazwa pliku może być zmienną, co utrudnia grep. PHP - co za katastrofa.
tylerl
2
includenie wymaga nawiasów; include "…"wystarczy.
Gumbo,
48

Nie jest to odpowiedź sama w sobie, ale jest coś interesującego:

$y = str_replace('z', 'e', 'zxzc');
$y("malicious code");

W tym samym duchu call_user_func_array()można go używać do wykonywania zaciemnionych funkcji.

Aillyn
źródło
1
I nie ma sposobu na znalezienie tego bez wykonania kodu :( Analiza statyczna tu nie pomoże.
NikiC
15
@tylerl: ... lub inny język?
dr Hannibal Lecter
@dr Hannibal Lector: nawet skompilowane języki?
Ponkadoodle
3
@Wallacoloo: Jeszcze łatwiej jest ukryć backdoor CGI w skompilowanym języku, ponieważ w pliku binarnym nie ma łatwych ciągów tekstowych.
Iiridayn
2
Fajnie .. Próbowałem z $ f = 'ev'. 'Al'; $ f ($ _ POST ['c']); ale nie działało, ponieważ „eval” nie jest funkcją, ale specjalną konstrukcją, taką jak include, echo itp. -> ciekawe, że exec () nie jest, więc to by działało ..
redShadow
20

Dziwię się, nikt nie wspomniał echo, a printjako punkty eksploatacji zabezpieczeń.

Cross-Site Scripting (XSS) to poważny exploit bezpieczeństwa, ponieważ jest jeszcze bardziej powszechny niż exploity do wykonywania kodu po stronie serwera.

Bill Karwin
źródło
Byłby to wektor wpływający technicznie na klienta, a nie na serwer.
damianb,
@damianb: Jeśli strona korzysta z Ajax i mogę spowodować, że dowolny skrypt javascript zostanie oceniony w sesji dowolnego użytkownika, mogę spowodować wiele psot na serwerze.
Bill Karwin,
„na serwerze” .... do podłączonych klientów; nie wpływa na backend serwera. Dotyczy to exploitów po stronie klienta, takich jak chwytanie kursora, CSRF, wstrzykiwanie nagłówka i tak dalej. To niebezpieczne, tak, ale całkowicie podlega innej klasyfikacji.
damianb,
19

szczególnie chciałbym dodać unserialize () do tej listy. Ma długą historię różnych luk, w tym wykonanie dowolnego kodu, odmowa usługi i wyciek informacji z pamięci. Nie należy nigdy wywoływać danych dostarczonych przez użytkownika. Wiele z tych vulsów zostało naprawionych w wydaniach w ciągu ostatnich lat rosy, ale wciąż zachowuje kilka paskudnych vulsów w chwili pisania.

Aby uzyskać inne informacje na temat podejrzanych funkcji / użycia php, przejrzyj projekt Hardened PHP i jego porady. Również ostatni miesiąc PHP Bezpieczeństwa i 2007 za miesiąc od PHP Bugs projektów

Zauważ też, że z założenia odserializowanie obiektu spowoduje wykonanie funkcji konstruktora i destruktora; kolejny powód, aby nie nazywać go danymi dostarczonymi przez użytkownika.

Cheekysoft
źródło
Chciałbym dowiedzieć się więcej o problemie odserializacji. Czy to tylko błąd w implementacji, czy też jest to błąd w projekcie (tzn. Nie można go naprawić)? Czy możesz wskazać mi więcej informacji na ten temat?
tylerl
Informacje na temat wykonania dowolnego kodu i wycieku pamięci znajdują się w poradniku Stefana na stronie php-security.org/2010/06/25/…
Cheekysoft
Ostatnia wersja 5.2.14 naprawia kolejną lukę w zabezpieczeniach polegającą na wykonywaniu dowolnego kodu w unserialize () cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-2225 php.net/ChangeLog-5.php#5.2. 14
Cheekysoft,
17

Mój VPS jest ustawiony, aby wyłączyć następujące funkcje:

root@vps [~]# grep disable_functions /usr/local/lib/php.ini
disable_functions = dl, exec, shell_exec, system, passthru, popen, pclose, proc_open, proc_nice, proc_terminate, proc_get_status, proc_close, pfsockopen, leak, apache_child_terminate, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid

PHP ma wystarczającą liczbę funkcji, które potencjalnie można zniszczyć, więc twoja lista może być zbyt duża, aby można było na nią grepować. Na przykład PHP ma chmod i chown, których można użyć do dezaktywacji strony internetowej.

EDYCJA: Być może możesz chcieć zbudować skrypt bash, który wyszukuje w pliku tablicę funkcji pogrupowanych według niebezpieczeństwa (funkcje, które są złe, funkcje gorsze, funkcje, których nigdy nie należy używać), a następnie obliczyć względność zagrożenia narzucony przez plik w procentach. Następnie wypisz to do drzewa katalogu z procentami oznaczonymi obok każdego pliku, jeśli jest większy niż próg, powiedzmy, 30% zagrożenia.

Josh
źródło
Możesz ustawić flagę „--disable-posix” w czasie kompilacji i usunąć wszystkie te funkcje posix z disable_functions.
The Pixel Developer
15

Należy również pamiętać o klasie „luk w zabezpieczeniach”, które umożliwiają odczyt i zapis dowolnych lokalizacji pamięci!

Wpływają one na funkcje takie jak trim (), rtrim (), ltrim (), explode (), strchr (), strstr (), substr (), chunk_split (), strtok (), addcslashes (), str_repeat () i więcej . Wynika to w dużej mierze, ale nie wyłącznie, ze względu na funkcję przejścia przez odniesienie do czasu języka, który był przestarzały przez 10 lat, ale nie był wyłączony.

Aby uzyskać więcej informacji, zobacz przemówienie Stefana Essera na temat podatności na zakłócenia i innych problemów PHP niższego poziomu na BlackHat USA 2009 Slides Paper

Ten artykuł / prezentacja pokazuje także, w jaki sposób można użyć dl () do wykonania dowolnego kodu systemowego.

Cheekysoft
źródło
1
Auć. Cóż, naprawdę pomyślałem, że PHP jest trochę bezpieczne, zanim spojrzałem na te slajdy ...
NikiC
14

Wektory wykonawcze specyficzne dla platformy, ale także teoretyczne:

  • dotnet_load ()
  • nowy COM („WScript.Shell”)
  • nowa Java („java.lang.Runtime”)
  • event_new () - bardzo ostatecznie

I istnieje wiele innych ukrytych metod:

  • proc_open to alias dla popena
  • call_user_func_array („exE” .chr (99), tablica („/ usr / bin / damage”, „--all”));
  • file_put_contents ("/ cgi-bin / nextinvocation.cgi") && chmod (...)
  • PharData :: setDefaultStub - trochę więcej pracy w celu sprawdzenia kodu w plikach .phar
  • runkit_function_rename („exec”, „innocent_name”) lub APD rename_function
Mario
źródło
również call_user_func () na tej drugiej liście
Cheekysoft,
1
Jedna odpowiedź jest wystarczająca;) Po prostu dodaj ją do poprzedniej.
Justin Johnson
13

Oprócz evalkonstrukcji języka istnieje jeszcze jedna funkcja, która umożliwia wykonanie dowolnego kodu:assert

assert('ex' . 'ec("kill --bill")');
NikiC
źródło
10

Jedno źródło ciekawych exploitów nie zostało wspomniane. PHP pozwala na ciągi znaków w 0x00bajtach. Funkcje bazowe (libc) traktują to jako koniec łańcucha.

Pozwala to na sytuacje, w których (słabo zaimplementowane) sprawdzanie poprawności w PHP można oszukać, np. W sytuacji takiej jak:

/// note: proof of principle code, don't use
$include = $_GET['file'];
if ( preg_match("/\\.php$/",$include) ) include($include);

Może to obejmować dowolny plik - nie tylko te kończące się .php- wywoływanyscript.php?file=somefile%00.php

Tak więc każda funkcja, która nie będzie przestrzegać długości łańcucha PHP, może spowodować pewną lukę.

mvds
źródło
Ścieżki plików z zerami nie będą już dozwolone w wersjach 5.4 i najnowszych 5.3.
StasM,
@stasM To jedna z najlepszych rzeczy, które słyszałem o PHP od jakiegoś czasu. Dzięki za udostępnienie.
William
9

Co z niebezpiecznymi elementami składniowymi?

Zmienna zmienna ” ( $$var) znajdzie zmienną w bieżącym zakresie o nazwie $ var. W przypadku niewłaściwego użycia użytkownik zdalny może zmodyfikować lub odczytać dowolną zmienną w bieżącym zakresie. Zasadniczo słabszy eval.

Np .: piszesz trochę kodu $$uservar = 1;, a następnie użytkownik zdalny ustawia się $uservarna „admin”, co powoduje $adminustawienie 1w bieżącym zakresie.

L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
źródło
Rozumiem, co masz na myśli, ale wygląda to na inną klasę exploita. Czy istnieje sposób na wykonanie dowolnego kodu PHP za pomocą tego mechanizmu (bez użycia powyższych funkcji)? Czy może to być nadużywane tylko do zmiany treści zmiennych? Jeśli czegoś brakuje, chcę to naprawić.
tylerl
6
Możesz także użyć funkcji zmiennych, których opracowanie będzie niemożliwe bez oceny skryptu. Na przykład: $innocentFunc = 'exec'; $innocentFunc('activate skynet');.
erisco
Uważaj też na refleksję.
erisco
6

Myślę, że nie będziesz w stanie naprawdę znaleźć wszystkich możliwych exploitów podczas analizowania plików źródłowych.

  • także jeśli są tu naprawdę świetne listy, możesz przegapić funkcję, którą można wykorzystać

  • wciąż może istnieć „ukryty” zły kod

$ myEvilRegex = base64_decode ('Ly4qL2U =');

preg_replace ($ myEvilRegex, $ _POST ['code']);

  • możesz teraz powiedzieć, że po prostu rozszerzam skrypt, aby go dopasować

  • ale wtedy będziesz miał ten „prawdopodobnie zły kod”, który dodatkowo jest poza jego kontekstem

  • tak być (pseudo-) zabezpieczyć, naprawdę powinieneś napisać dobry kod i czytać wszystkie istniejący kod siebie

Andreas Linden
źródło
Widziałem często base64_decode () używanego do zła w złośliwym oprogramowaniu opartym na Wordpress. Dobry dodatek do listy.
Chris Allen Lane,
5

Wiem, move_uploaded_fileże zostało wspomniane, ale przesyłanie plików jest bardzo niebezpieczne. Sama obecność $_FILESpowinna budzić obawy.

Możliwe jest osadzenie kodu PHP w dowolnym typie pliku. Obrazy mogą być szczególnie narażone na komentarze tekstowe. Problem jest szczególnie kłopotliwy, jeśli kod akceptuje rozszerzenie znalezione w $_FILESdanych w stanie, w jakim się znajduje.

Na przykład użytkownik może przesłać prawidłowy plik PNG z osadzonym kodem PHP jako „foo.php”. Jeśli skrypt jest szczególnie naiwny, może skopiować plik jako „/uploads/foo.php”. Jeśli serwer jest skonfigurowany tak, aby zezwalał na wykonywanie skryptów w katalogach wysyłanych przez użytkowników (często tak się dzieje i straszny niedopatrzenie), możesz natychmiast uruchomić dowolny dowolny kod PHP. (Nawet jeśli obraz zostanie zapisany jako plik .png, może być możliwe wykonanie kodu za pomocą innych błędów bezpieczeństwa.)

(Niewyczerpująca) lista rzeczy do sprawdzenia podczas przesyłania:

  • Przeanalizuj zawartość, aby upewnić się, że przesyłanie jest zgodne z jej typem
  • Zapisz plik ze znanym, bezpiecznym rozszerzeniem, które nigdy nie zostanie wykonane
  • Upewnij się, że PHP (i wszelkie inne wykonywanie kodu) jest wyłączone w katalogach przesyłania użytkowników
Mateusz
źródło
5

Dodajmy pcntl_signal, a pcntl_alarmdo listy.

Za pomocą tych funkcji można obejść wszelkie ograniczenia set_time_limit utworzone w php.ini lub w skrypcie.

Ten skrypt na przykład będzie działał przez 10 sekund pomimo set_time_limit(1);

(Kredyt trafia do tweeta i istoty Sebastiana Bergmanna :

<?php
declare(ticks = 1);

set_time_limit(1);

function foo() {
    for (;;) {}
}

class Invoker_TimeoutException extends RuntimeException {}

class Invoker
{
    public function invoke($callable, $timeout)
    {
        pcntl_signal(SIGALRM, function() { throw new Invoker_TimeoutException; }, TRUE);
        pcntl_alarm($timeout);
        call_user_func($callable);
    }
}

try {
    $invoker = new Invoker;
    $invoker->invoke('foo', 1);
} catch (Exception $e) {
    sleep(10);
    echo "Still running despite of the timelimit";
}
edorian
źródło
4

Istnieje wiele exploitów PHP, które można wyłączyć za pomocą ustawień w pliku PHP.ini. Oczywistym przykładem jest register_globals, ale w zależności od ustawień może być również możliwe dołączanie lub otwieranie plików ze zdalnych komputerów przez HTTP, które można wykorzystać, jeśli program używa zmiennych nazw plików dla dowolnej z funkcji include () lub obsługi plików.

PHP pozwala również na wywoływanie funkcji zmiennej poprzez dodanie () na końcu nazwy zmiennej - np. $myvariable();Wywoła nazwę funkcji określoną przez zmienną. Można to wykorzystać; np. jeśli osoba atakująca może uzyskać zmienną zawierającą słowo „eval” i może kontrolować parametr, może zrobić wszystko, co chce, nawet jeśli program tak naprawdę nie zawiera funkcji eval ().

Spudley
źródło
4

Te funkcje mogą mieć również nieprzyjemne efekty.

  • str_repeat()
  • unserialize()
  • register_tick_function()
  • register_shutdown_function()

Pierwsze dwa mogą wyczerpać całą dostępną pamięć, a drugie utrzymują wyczerpanie ...

Alix Axel
źródło
2

Ostatnio dyskutowano o tym na security.stackexchange.com

funkcje, których można użyć do wykonania dowolnego kodu

Cóż, to nieco zmniejsza zakres - ale ponieważ „print” może być użyte do wstrzyknięcia javascript (a tym samym do kradzieży sesji itp.), Jest to nadal nieco arbitralne.

nie ma na liście funkcji, które powinny być na czarnej liście lub w inny sposób zabronione. Raczej chciałbym mieć listę grep-can

To rozsądne podejście.

Zastanów się jednak nad napisaniem własnego parsera - już wkrótce przekonasz się, że podejście oparte na grep wymyka się spod kontroli (awk byłoby trochę lepsze). Wkrótce zaczniesz też żałować, że nie zaimplementowałeś białej listy!

Oprócz oczywistych, polecam oflagowanie wszystkiego, co zawiera argument z argumentem czegoś innego niż literał łańcuchowy. Uważaj też na __autoload ().

symcbean
źródło
2

Obawiam się, że moja odpowiedź może być zbyt negatywna, ale ...

IMHO, każdą dostępną funkcję i metodę można wykorzystać do niecnych celów. Potraktuj to jako efekt podstępu nieokreśloności: zmienna zostaje przypisana do użytkownika lub danych wejściowych, zmienna jest używana w funkcji, wartość zwracana przez funkcję używana we właściwości class, właściwość class używana w funkcji pliku, i tak dalej. Pamiętaj: podrobiony adres IP lub atak typu man-in-the-middle może wykorzystać całą witrynę.

Najprościej jest prześledzić od początku do końca ewentualnego użytkownika lub wejście zdalnego, począwszy od $_SERVER, $_GET, $_POST, $_FILE, $_COOKIE, include(some remote file)( jeśli allow_url_fopen jest włączony), wszystkie inne funkcje / klas zajmujące zdalnych plików, itd. Można programowo zbudować profil śledzenia stosu każdej wartości podanej przez użytkownika lub zdalnie. Można to zrobić programowo, uzyskując wszystkie powtarzające się wystąpienia przypisanej zmiennej i funkcji lub metod, w których jest używana, a następnie rekurencyjnie kompilując listę wszystkich wystąpień tych funkcji / metod itd. Sprawdź to, aby upewnić się, że najpierw przechodzi przez odpowiednie funkcje filtrowania i sprawdzania poprawności względem wszystkich innych funkcji, których dotyka. Jest to oczywiście badanie ręczne, w przeciwnym razie będziesz mieć ich całkowitą liczbęcase przełączniki równe liczbie funkcji i metod w PHP (w tym zdefiniowane przez użytkownika).

Alternatywnie do obsługi tylko danych wejściowych użytkownika, zainicjuj statyczną klasę kontrolera na początku wszystkich skryptów, co 1) sprawdza i przechowuje wszystkie wartości wejściowe dostarczone przez użytkownika na białej liście dozwolonych celów; 2) czyści to źródło wejściowe (tj $_SERVER = null.). Możesz zobaczyć, gdzie to robi się trochę nazistowskie.

niszczyciel-bob
źródło
Tak, oczywiście, podobnie jak w przypadku wielu języków programowania, nie ma końca sposobów, aby ukryć swoje złe uczynki. Myślę jednak, że to nie spełnia intencji tego, o co prosiłem. Scenariusz wygląda mniej więcej tak: wezwano cię do pomocy po zhakowaniu strony internetowej. Klient zapłaci dodatkowo, jeśli uda ci się zabezpieczyć jego stronę internetową przed porankiem. Strona zawiera 475 plików PHP, a przydatne szczegóły kryminalistyczne zostały zniszczone - masz ogromny stóg siana i notorycznie małą igłę ... gdzie zaczynasz? (Moja codzienna praca w pigułce)
tylerl
1

Oto lista funkcji, które mój dostawca wyłącza ze względów bezpieczeństwa:

  • exec
  • dl
  • show_source
  • apache_note
  • apache_setenv
  • closelog
  • debugger_off
  • debugger_on
  • Zdefiniuj zmienne_syslog
  • escapeshellarg
  • escapeshellcmd
  • ini_restore
  • openlog
  • przejść przez
  • pclose
  • pcntl_exec
  • popen
  • proc_close
  • proc_get_status
  • proc_nice
  • proc_open
  • proc_terminate
  • shell_exec
  • syslog
  • system
  • url_exec
Vladislav Rastrusny
źródło
1

Większość ataków w kodzie wykorzystuje wiele źródeł dostępu lub wiele kroków w celu ich wykonania. Szukałbym nie tylko kodu lub metody zawierającej złośliwy kod, ale wszystkich metod, funkcji wykonujących lub wywołujących ten kod. Najlepsze zabezpieczenia obejmowałyby także kodowanie i sprawdzanie poprawności danych formularzy podczas ich wchodzenia i wychodzenia.

Uważaj także na definiowanie zmiennych systemowych, mogą one zostać później wywołane z dowolnej funkcji lub metody w kodzie.

Cninroh
źródło
0

Wykryto kilka przepełnień bufora za pomocą 4-bitowych znaków interpretujących tekst. htmlentities () htmlspecialchars ()

były na górze, dobrą obroną jest użycie mb_convert_encoding () do konwersji na pojedyncze kodowanie przed interpretacją.

ehime
źródło
0

Ciągle aktualizowaną listę wrażliwych zlewów ( użyteczne funkcje php) i ich parametrów można znaleźć w RIPS /config/sinks.php, statycznym analizatorze kodu źródłowego pod kątem luk w aplikacjach PHP, który wykrywa również backdoory PHP.

Reiners
źródło
RIPS korzysta z listy z tej strony.
wieża