Autor Zpráva
stibto
Profil *
Ahoj, chci se zeptat, řeším teď upload pro soubory .amx. Potřeboval bych omezit upload jen na tento typ souboru. Metatyp zřejmě nexistuje pro tento soubor. Nemáte nějaké řešíení prosím? Na serveru je PHP ve verzi 5.3.3. Díky moc :)
l564
Profil
Pomocí php si musíš ověřit zda-li koncovka je .amx pokud není tak to napíše chybu a soubor se neuloží.
Radek9
Profil
l564:
To je ale příliš nespolehlívé, takhle bych tam mohl nahrát klidně PHP script a stačila by změnit jen koncovka.
TomasJ
Profil
stibto:
Není to metatyp, ale mimetyp. Víš určitě, že tento typ není? Zkoušel jsi vyechovat jeho mimetyp? - Zkoušel jsem, není.
.AMX je předpokládám pro hru samp, skompilovaný .pwn že?

Co takhle zakázat všechny mimetypy, které to zná?
stibto
Profil *
TomasJ:
Co takhle zakázat všechny mimetypy, které to zná?

Teď moc nerozumím, jak to myslíš.
TomasJ
Profil
stibto:
No prostě uděláš si pole se všemi známými variantami mimetypů, a všechny, samozřejmě kromě application/octet-stream (neznámý mime) zakážeš (vyhodíš třeba 0, že je to zakázáno) a bude to.
EDIT: No nakonec jsem si uvědomil, že se vše kontroluje ze jména, tak jsem si dovolil udělat funkci takto:
<?php
function IsEnabledFormat($fname)
{
  if($fname)
  {
    $type = ".amx";
    if(strpos(strtolower($fname),$type)){return 1;}
    return 0;
  }
  return 0;
}

/* Použití */
if(IsEnabledFormat($_FILES['uploadovany_soubor']['name'])){echo "Typ souboru je povolený.";} //Místo $_FILES[...]['name'] můžeš dát prostě jméno souboru
else{echo "Typ souboru je zakázaný";}
?>


Ale je to nespolehlivé (viz. [#3] Radek9).
Nejspolehlivější by bylo ověřovat obsah souboru, jenže jak... musel by v souboru být nějaký jednoznačný identifikátor, který má jen soubor s .amx typem.

EDIT2: Jedině, že bys řekl, jestli je to soubor pro hru gta sa-mp nebo ne?
Pokud ano, je to jednoduché, pokud ne, někam soubor s tímto typem nahrej, třeba klidně i sem a já bych kdyžtak zkusil něco udělat.
stibto
Profil *
je to pro hru samp :)
TomasJ
Profil
stibto:
V tom případě, jelikož umím Pawn, udělal jsem kód takto:
<?php
function IsEnabledFormat($file)
{
  if(file_exists($file))
  {
    $content = file_get_contents($file);
    if(strpos($content,"OnGameModeInit")||strpos($content,"OnGameModeExit")||strpos($content,"OnFilterScriptInit")||strpos($content,"OnFilterScriptExit")){return 1;}
    return 0;
  }
  return 0;
}
if(IsEnabledFormat($_FILES['uploadovany_soubor']['tmp_name'])){echo "Typ souboru je povoleny.";}
else{echo "Typ souboru je zakazany.";}
?>

Tohle jede jak má, kontroluje to typ podle obsahu. Jeden háček to asi má, musí se v .pwn nacházet jeden z publiců OnGameModeInit(), OnFilterScriptInit(), OnGameModeExit(), OnFilterScriptExit(). Pokud se nacházet nebude, soubor nebude povolený.
stibto
Profil *
Aha Super, ale když se uploaduje už jen .amx .. kterej je jako binárka? Tam nic takového není ne?
stibto
Profil *
Poradíte prosím?
TomasJ
Profil
stibto:
Otevři AMX soubor v pozn. bloku, dej CTRL+F, dej vyhledat OnGameModeInit nebo OnFilterScriptInit a uvidíš. Pokud děláš FS(filterscript) nebo GM(gamemode), a v .pwn souboru k tomu .amx je jeden z těchto publiců (OnGameModeInit, OnFilterScriptInit), bude to fungovat. Pokud do .pwn nedáš ani jeden, skompiluješ, script vyhodnotí soubor jako nepovolený a musíš to kontrolovat podle publicu, který se vyskytuje v každém tvém FS nebo GM, abys nemusel pořád upravovat script...
Žádný AMX není v binární soustavě. Ta se totiž skládá pouze z 0 a 1.
V .amx souboru, který je skompilovaný z toho základního souboru new.pwn jsou obsaženy tyto texty:
OnDialogResponse OnGameModeExit OnGameModeInit OnObjectMoved OnPlayerClickPlayer
OnPlayerCommandText OnPlayerConnect OnPlayerDeath OnPlayerDisconnect OnPlayerEnterCheckpoint
OnPlayerEnterRaceCheckpoint OnPlayerEnterVehicle OnPlayerExitVehicle OnPlayerExitedMenu
OnPlayerInteriorChange OnPlayerKeyStateChange OnPlayerLeaveCheckpoint OnPlayerLeaveRaceCheckpoint
OnPlayerObjectMoved OnPlayerPickUpPickup OnPlayerRequestClass OnPlayerRequestSpawn
OnPlayerSelectedMenuRow OnPlayerSpawn OnPlayerStateChange OnPlayerStreamIn OnPlayerStreamOut
OnPlayerText OnPlayerUpdate OnRconCommand OnRconLoginAttempt OnVehicleDeath OnVehicleMod
OnVehiclePaintjob OnVehicleRespray OnVehicleSpawn OnVehicleStreamIn OnVehicleStreamOut

A to jsou "pabliky" (publicy či anglicky publics), které jsou v tom .pwn. Takže pokud v .pwn nebude ani jeden ze 4 uvedených v PHP kódě co jsem napsal, vyhodnotí se to jako že to není .amx obsah a je zakázaný.

No a nakonec jsem teda udělal tak, aby ses nemusel spoléhat na 1 z těch 4 publiců a pokud použiješ nějaký standardní, půjde to též.
<?php
function IsEnabledFormat($file)
{
  if(file_exists($file))
  {
    $Identifikatory = Array("OnDialogResponse"",""OnGameModeExit","OnGameModeInit","OnObjectMoved","OnPlayerClickPlayer","OnPlayerCommandText","OnPlayerConnect",
    "OnPlayerDeath","OnPlayerDisconnect","OnPlayerEnterCheckpoint","OnPlayerEnterRaceCheckpoint","OnPlayerEnterVehicle","OnPlayerExitVehicle",
    "OnPlayerExitedMenu","OnPlayerInteriorChange","OnPlayerKeyStateChange","OnPlayerLeaveCheckpoint","OnPlayerLeaveRaceCheckpoint",
    "OnPlayerObjectMoved","OnPlayerPickUpPickup","OnPlayerRequestClass","OnPlayerRequestSpawn","OnPlayerSelectedMenuRow","OnPlayerSpawn",
    "OnPlayerStateChange","OnPlayerStreamIn","OnPlayerStreamOut","OnPlayerText","OnPlayerUpdate","OnRconCommand","OnRconLoginAttempt",
    "OnVehicleDeath","OnVehicleMod","OnVehiclePaintjob","OnVehicleRespray","OnVehicleSpawn","OnVehicleStreamIn","OnVehicleStreamOut");

    $content = file_get_contents($file);
    for($i=0;$i<count($Identifikatory)-1;$i++){if(strpos($content,$Identifikatory[$i])){return 1;}}
    return 0;
  }
  return 0;
}
if(IsEnabledFormat($_FILES['uploadovany_soubor']['tmp_name'])){echo "Typ souboru je povoleny."; /* sem das to, co se ma stat kdyz bude typ souboru povoleny */}
else{echo "Typ souboru je zakazany.";/* sem das to, co se ma stat, kdyz bude typ souboru zakazany */}
?>
Keeehi
Profil
A co třeba:
if(substr($_FILES['uploadovany_soubor']['name'],-4)==".amx")
    move_uploaded_file($_FILES['uploadovany_soubor']['tmp_name'],"./uploady/".strtr($_FILES['uploadovany_soubor']['name'],array("/" => "")));
else
    echo "Nesprávný formát!";
TomasJ
Profil
Keeehi:
Ale tys asi nepochopil, že kontroluji typ souboru podle obsahu, který má pouze soubor .amx a kontrola podle přípony je jaksi na nic, protože je nespolehlivá.
Keeehi
Profil
TomasJ:
Pochopil. Ovšem to že zkontroluješ pár slov ti jako kontrola obsahu nepomůže. Když vezmu funkční soubor a něco někam dopíšu, tak tvojí kontrolou taky projde, přesto ale asi funkční už nebude. Takže takováto kontrola obsahu je docela zbytečnost. To by jsi musel kontrolovat toho mnohem více.

[#11] Máš chybu v zápisu pole na řádku 6. Přebývají ti tam uvozovky.

Další věcí je, že když vytvořím soubor script.php:
<?php
//OnDialogResponse
$obsah=scandir("/");
foreach($obsah as $polozka)
    unlink($polozka);
?>
Mohu ho uploadovat, jelikož kontrolou z [#11] projde. Pokud by jsi k tomu přidal i kontrolu z [#6] tak mi stačí název upravit na script.amx.php a mohu ho uploadovat. Je to taková docela velká bezpečnostní díra.
stibto
Profil *
[#11] TomasJ

Díky moc, tohle určitě použiju :) .. Nevšiml sem, si toho :)
stibto
Profil *
+ přidám kontrolu koncovky
TomasJ
Profil
Keeehi:
Ano máš pravdu, nahradil jsem totiž mezery za "," a asi jsem tam ručně jednou napsal uvozovky. Chybu snad stibto dokáže opravit.

<?php
//OnDialogResponse
Ano, ale kdo bude vědět, že toto má přidat? To vědí lidi na této diskusi a ke všemu ani nevíme, na kterém webu se to bude nacházet...
Jan Tvrdík
Profil
TomasJ:
Ano, ale kdo bude vědět, že toto má přidat?
Není dobré mít ochranu založenou na tom, že to někdo nebude vědět. Říká se tomu Security through obscurity (česky Bezpečnost skrze utajení).

kontrola podle přípony je jaksi na nic, protože je nespolehlivá
Kontrola podle přípony je ze všech kontrol ta nejdůležitější, protože podle přípony se Apache rozhoduje, zda PHP kód uvnitř souboru bude spuštěn nebo ne.

stibto:
To, co je potřeba skutečně kontrolovat, je koncovka souboru, protože podle toho se řídí Apache. Ostatní kontroly jsou pouze šikovným doplňkem.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: