Manipulace s výsledky internetových soutěží (6)

Zdroj: SOOM.cz [ISSN 1804-7270]
Autor: .cCuMiNn.
Datum: 5.10.2015
Hodnocení/Hlasovalo: 1.44/16

Z minulého dílu seriálu o manipulaci soutěží založených na hlasování uživatelů vyplynulo, že kontrolovat a znemožňovat opakované hlasování na základě údajů uložených v cookies není pro pořadatele soutěží tím nejlepším nápadem. Vzhledem k tomu, že informace uložené na straně uživatele je možné velice snadno zmanipulovat, bude nutné použít pro kontrolu a zamezení vícenásobného hlasování kontrolu až na straně serveru.

Kontrola IP adresy

HlasováníVe chvíli, kdy budete chtít kontrolovat vícenásobné hlasování na straně serveru, se pravděpodobně uchýlíte k tomu, že budete omezovat počty hlasů odeslaných z jedné IP adresy. Vždy, když přijde na server soutěžní hlas, uložíte si do databáze IP adresu, ze které tento hlas přišel, a při příštím hlasování si pak pouze v této databázi ověříte, zda z dané IP adresy nebylo hlasováno již v minulosti. Pokud zjistíte, že se z dané IP adresy již hlasovalo, jednoduše tuto skutečnost hlasujícímu oznámíte a hlas nezapočtete.

Opakované hlasování si opět můžete vyzkoušet v hlasovací soutěži: tentokrát O nejhezčí kočku. Zvolte jednu z fotografií, kterou byste si přáli, aby v soutěži zvítězila a pokuste se jí přidat několik hlasů.


Úskalí lokálních sítí

S kontrolou IP adresy ovšem koliduje skutečnost, že pouze málokdo z uživatelů disponuje veřejnou IP adresou. Většina hlasujících bude do internetu napojena prostřednictvím internetových providerů, kteří provozují lokální sítě připojené do internetu prostřednictvím gatewaye. Představme si jednu takovou lokální síť, ke které je připojeno tisíc uživatelů. Pokud se stovka z těchto uživatelů rozhodne, že odešle do soutěže svůj hlas, uvidí webový server, na kterém soutěž běží, pouze veřejnou IP adresu gatewaye, která bude pro všechny tyto uživatele stejná. Zahlasuje si tak pouze ten nejrychlejší z nich. Všchni ostatní pak bohužel obdrží zprávu, že se z jejich IP adresy již hlasovalo, a že tedy mají smůlu.

Měníme svou IP adresu

Uživatelům, kteří budou chtít opakovaně hlasovat v soutěžích, které kontrolují vícenásobné hlasování na základě IP adresy tak nezbude, než se pokusit svou IP adresu změnit. To ovšem, jak víme, není záležitost, kterou bychom mohli nějak snadno provést. Schopni jsme změnit si maximálně svou IP adresu v rámci lokální sítě, což nám příliš platné nebude. Veřejnou IP adresu, pod kterou vystupujeme navenek, máme přidělenu od našeho providera, nebo náleží již zmíněné gateway a její změna pro nás proto bude tabu.

Nehažme však předčasně flintu do žita. Na internetu najdeme velké množství free HTTP proxy serverů, které naší komunikaci rádi přesměrují tak, aby se na webovém serveru zdálo, že hlas přichází z IP adresy, která patří právě proxy serveru. Pokud po uskutečněném hlasování proxy server zaměníme za jiný, získáme tak i novou IP adresu.


Rizika spojená s využíváním proxy serverů

Pokud se podíváte na diagram výše, který zobrazuje, kudy budou putovat vaše data, nemůžete si nevšimnout skutečnosti, že proxy server stojí v pozici MiTM a provozovatel tohoto serveru tak bude schopen veškerá naše nešifrovaná data prohlížet a případně i editovat. Při použití proxy serveru proto buďte ostražití. Snadno se může stát, že si do počítače stáhnete i nějaký ten malware, apd. Pokud vám to ale z nějakého důvodu vyhovuje, tak proti gustu žádný dišputát.

Uvedeného principu lze snadno využít v případech, kdy vám bude postačovat pár desítek (max. stovek) hlasů. Při požadavku na tisíce nebo statisíce hlasů tato metoda už ale stačit nebude. Pokud se ptáte proč, tak jednoduše proto, že nenajdete tolik dostupných proxy serverů, které byste pro tento účel mohli zneužít. Jejich množství je přecijen omezeno.

X-Forwarded-For

S použitím proxy serverů je navíc vázána ještě jedna záležitost. Většina HTTP proxy serverů do komunikace totiž přidává novou HTTP hlavičku pojmenovanou X-Forwarded-For. Ta cílovému webovému serveru oznamuje, že IP adresa, ze které požadavek přišel, patří právě proxy serveru, který pouze přesměrovává komunikaci pro někoho jiného. Server tak může snadno odhalit Vaší skutečnou IP adresu, a proto se mnoho soutěží na tuto hlavičku rovněž dívá.


Mohlo by se zdát, že ideální bude kontrolovat, zda requesty, které přichází od uživatelů, obsahují HTTP hlavičku X-Forwarded-For, a pokud ano, tak ji brát za skutečnou IP adresu uživatele. V opačném případě, kdy tato hlavička přítomna není, bychom naopak za legitimní IP adresu považovli skutečnou adresu, ze které požadavek přichází. Rozhodovali bychom se tedy takto:

$ip = $_SERVER["HTTP_X_FORWARDED_FOR"] ? $_SERVER["HTTP_X_FORWARDED_FOR"] : $_SERVER["REMOTE_ADDR"];

Vypadá to hezky, a zdá se, že to nebude lehké obejít. Opak je ovšem pravdou. Pokud totiž vývojáři použijí uvedený kód, útočníkům tím velice usnadní práci. HTTP hlavičku X-Forwarded-For totiž není žádný problém spoofovat. Co vám brání, abyste ze svého počítače odesílali soutěžní hlasy a pokaždé do komunikace uměle vložili hlavičku X-Forwarded-For s jiným obsahem? Serveru byste tak sdělovali, že vy jste pouze proxy, který komunikaci směřuje pro někoho jiného. Rázem můžete hlasovat dle libosti.

FOR /L %%i IN (1,1,10) DO (
  ECHO GET /index.php?name=projects/forarticles/game_hlas_2^&vote=1 HTTP/1.1> request.txt
  ECHO Host: www.soom.cz>> request.txt
  ECHO X-Forwarded-For: 1.2.3.%%i>> request.txt
  COPY /b request.txt+blankline.txt
  TYPE request.txt | nc www.soom.cz 80 > NUL
)


Modifikaci nebo přidávání HTTP hlaviček přitom nemusíte dělat pouze skriptem. Existují různé nástroje, které vám jsou schopny tyto hlavičky přidávat/měnit za běhu při běžném surfování po internetu. Jedním z těchto nástrojů je například addon Modify Headers pro webový prohlížeč Firefox.

SQL Truncation

Ve skutečnosti to jde často ještě snadněji. Vzpomeňte na článek o zranitelnosti SQL Truncation, ve kterém jsem vám představoval záludné chování MySQL. Představte si, že provozovatel soutěže ukládá IP adresy hlasujících do tabulky, kde sloupci pro ukládání IP adres přiřadil datový typ varchar(15), neboť delší IP adresy ipv4 být nemohou. Dále si představte, že tento vývojář založil kontrolu předchozího hlasování na tomto kódu:

$ip = $_SERVER["HTTP_X_FORWARDED_FOR"] ? $_SERVER["HTTP_X_FORWARDED_FOR"] : $_SERVER["REMOTE_ADDR"];
$ip = mysql_real_escape_string($ip);
$volba = intval($_GET["volba"]);
$result = mysql_query("SELECT 1 FROM hlasy WHERE ip = '$ip'");
if (mysql_fetch_array($resource)) {
  echo "V této soutěži už jste hlasoval/a";
} else {
  mysql_query("INSERT hlasy(volba, ip) VALUES('$volba', '$ip')");
  echo "Děkujeme za Váš hlas";
}

Co se stane, pokud si útočník do hlavičky X-Forwarded-For naspoofuje IP adresu, která bude delší než uvedených 15 znaků? V takovém případě nebude tato IP adresa nikdy nalezena v databázi - nemůže být, protože by sa do uvedeného sloupce nevešla. Vždy proto dojde k započtení hlasu a uložení aktuální dlouhé IP adresy do databáze. Ta ovšem bude vždy oříznuta a proto i při odeslání dalšího hlasu nebude v databázi opět nalezena. Do databáze se nám tímto způsobem podaří uložit množství stejných IP adres, čemuž měla kontrola v uvedeném kódu zabránit. Z uvedeného vyplývá, že pokud je povoleno z každé IP adresy hlasovat skutečně pouze jednou, měl by mít sloupec pro ukládání IP adres nastaven unikátní klíč.

FOR /L %%i IN (1,1,10) DO TYPE request.txt | nc www.soom.cz 80 > NUL
GET /index.php?name=projects/forarticles/game_skatule_1&vote=1 HTTP/1.1
Host: www.soom.cz
X-Forwarded-For: 123.123.123.12345

Závěrem

Co když není možné využít proxy server, protože soutěž známé IP adresy proxy serverů blokuje? Co když server současně nebere zřetel na HTTP hlavičku X-Forwarded-For?Ani v tomto případě nemusíte věšet hlavu. Nic není ztraceno. Budete si ale muset počkat na další díl tohoto seriálu...