PDA

View Full Version : سوال: امنیت فرم آپلود فایل



ravand
سه شنبه 26 دی 1391, 08:21 صبح
من با استفاده از دستور زیر mime فایل رو گرفتم و با mime مورد نظر مقایسه کردم و به این صورت اعتبارسنجی انجام دادم.

$_FILES['aks']['type']
ولی وقتی توی نت در مورد امنیت فرم آپلود فایل سرچ زدم . دیدم روش های مختلفی رو در موردش گفته وقتی اون روش ها رو دیدم فهمیدم این روش برای امنیت هیچ ارزشی نداره. یکی از مطالب رو که برای امنیت خوب که خوندم دیدم نوشته این روش رو هم هکر میتونه دور بزنه. اخرش نفهمیدم چه روش رو برای امنیت فرم آپلود فایل استفاده کنم امن تره؟ مثلا من میخوام کسی غیر از یک عکس با فرمت gif و jpg فایل دیگه ای رو با فرمتی دیگه آپلود نکنه.
متشکرم.

Unique
سه شنبه 26 دی 1391, 13:37 عصر
یکبار بحث مفصلی شد جستجو کنید پیدا میکنید. در کل بررسی extension عاملی نیست که کاربر مطمئنا jpg داده یا حتی Mime type ! میتونید از getimagesize استفاده کنید تا یه جورایی مطمئن بشین عکسه یک راه حل دیگه هم Magic Numbers هستش ! که اینجا اطلاعات خوبی وجود داره (http://en.wikipedia.org/wiki/Magic_number_%28programming%29#Magic_numbers_in_fi les)

ravand
سه شنبه 26 دی 1391, 13:45 عصر
استفاده از getimagesize رو یه جا دیدم راحت دور زده بود اونون دیگه نمیدونم

ravand
سه شنبه 26 دی 1391, 14:14 عصر
من مشکلم اینه که هک بلد نیستم برای همین نمیدونم چجوری طرف هک میشه که بخوام اصلا فکر کنم چه دستوراتی برای جلوگیریش بنویسم. حالا میشه برام توضیح بدید که چطوری طرف هک میشه؟ یه جا خوندم که طرف میاد به جای یه فایل عکس یه فایل php یا فایل های دیگه رو آپلود میکنه.
میشه توضیح بدید ؟
متشکرم.

engmmrj
سه شنبه 26 دی 1391, 14:24 عصر
اینو رو هم مطالعه کن
http://www.hamidreza-mz.tk/?p=640

ravand
سه شنبه 26 دی 1391, 14:29 عصر
خب نمیشه محتوای فایل رو اینطوری چک کرد؟

<?php
$file="test.txt";
$chap=file_get_contents($file);
if (ctype_alnum($chap)) {
echo "این فایل یک عکس نیست.";
}else{
echo "این یک عکس است.";
}
?>
اول میایم فایل رو میگیریم بعد بررسی میکنیم که آیا مقادیر داخل فایل شامل حروف و اعداد هست ؟ اگه هست که پیام بده بگه این فایل عکس نیست.
نظرم شما چیه؟

siavashsay
سه شنبه 26 دی 1391, 17:03 عصر
راوند جان !
شما 2 تا حالت رو بررسی کن !
1- هم مایم رو بگیر !
2- هم سایز !
مایم که معلومه ! نوع فایل رو تشخیص میده ! اما خوب اگر بشه اون رو دور زد شما باز با گرفتن سایز فایل مقدار اون رو مشخص کنی ! مثلا عکس کمتر از 50 کیلوبایت نباشه ! این راه نسبتا خوبیه ! چون یک فایل txt یا php واسه اینکه بخواد به 50 کیلوبایت برسه باید خیلی محتویات داشته باشه !
حالا راه دیگه ......
شما علاوه بر موارد فوق موقع دریافت فایل عکس اون رو rename کن !
به اینصورت که اول type فایل رو از خود فایل بگیر ! مثلا اگر هکر فایل image.php.png بزنه شما تایپ اون رو میگیری میشه png
بعد کل نام عکس رو بگیر و حذف کن و یک نام رندم واسش انتخاب کن مثلا asd123 !
بعد اون png رو دوباره به آخر فایل اضافه کن و فایل رو آپلود کن رو هاستت !
نتیجه میشه asd123.png
دیگه ازون php خبری نیست :)
بازم اگر نیاز به کد داشتی بگو واست بذارم :)

Mohsen.
سه شنبه 26 دی 1391, 17:12 عصر
من در جایی خونده بودم که علاوه بر اینها باید فایل بیرون از root ذخیره کرد.


If your document root is /var/www/html, create a directory /var/www/uploads and use it to store uploaded files. That way, an attacker will not be able to retrieve the file directly. This will allow you to provide fine grained access control. The file will not be parsed by the server's application language module but the source of the file will be streamed.

خب بعد چطوری باید به اون دسترسی داشت؟

ravand
سه شنبه 26 دی 1391, 17:20 عصر
متشکرم.
ولی این راهی که خودم گفتم اصلا قابل اعتماد نیست؟:لبخند:


شما علاوه بر موارد فوق موقع دریافت فایل عکس اون رو rename کن !
به اینصورت که اول type فایل رو از خود فایل بگیر ! مثلا اگر هکر فایل image.php.png بزنه شما تایپ اون رو میگیری میشه png
بعد کل نام عکس رو بگیر و حذف کن و یک نام رندم واسش انتخاب کن مثلا asd123 !
بعد اون png رو دوباره به آخر فایل اضافه کن و فایل رو آپلود کن رو هاستت !
نتیجه میشه asd123.png
دیگه ازون php خبری نیست :)
این روش هم روش خوبیه. من توی فرم آپلود فایلم ازش استفاده کرده بودم به طوری که شماره ی id هر رکوردی رو از دیتایس می گرفتم و میدادم به جای نام فایل. ولی فکر نمیکردم برای امنیت هم خوب باشه.
متشکرم.

siavashsay
سه شنبه 26 دی 1391, 17:31 عصر
من که خودم از این سیستم استفاده میکنم ! :)
به هر حال خواهش میکنم :)

Unique
چهارشنبه 27 دی 1391, 00:12 صبح
اگه پسوند شما قطعا به صورت یک پسوند عکسی ذخیره بشه من بسیار بعید میدونم بشه روی سرور کار خطرناکی انجام دادم ، شما میتونید امکان Execute را از پوشه حاوی فایل ها بگیرین تا خیالتون راحت تر باشه ! میمونه کسانی که عکس را میبینند که البته برای یکسری از مرورگر ها bug وجود داره ، در مورد getimagesize میشه بگین کجا چی خوندین ؟
راهکار دیگه اینه که با توابع gd فایل را بخونین ! من بعید میدونم GD فایل دستکاری شده را تشخیص بده! اون magic numbers هم که گفتم خیلی استفاده میشه و جواب میده.

ravand
چهارشنبه 27 دی 1391, 08:11 صبح
متشکرم راهکارهای شما خیلی راهکار های خوبی هست.

در مورد getimagesize میشه بگین کجا چی خوندین ؟
این مطلب رو در یکی از تاپیک های انجمن آشیانه خوندم ولی ادرسش رو یادم نیست.

امکان Execute که فرمودید. یعنی جلوگیری از اجرا؟ حالا چجوری میشه این کار رو کرد؟
ممنون.

Unique
چهارشنبه 27 دی 1391, 15:38 عصر
permission فایلها و دایرکتوری را تغییر بدین با chmod ! اگه بلد نیستین جستجو کنین توی همین انجمن زیاد بحث شده

mamali-mohammad
چهارشنبه 27 دی 1391, 16:32 عصر
بهترین روش اینه :

<?php
if (isset($_POST['Upload'])) {

$target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename($_FILES['uploaded']['name']);
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1);
$uploaded_size = $_FILES['uploaded']['size'];

if (($uploaded_ext == "jpg" || $uploaded_ext == "JPG" || $uploaded_ext == "jpeg" || $uploaded_ext == "JPEG") && ($uploaded_size < 100000)){


if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {

echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';

} else {

echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>';

}
}

else{

echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';

}
}

?>
در آخر rename هم کن مشکل دیگه حله ( برای اطمینان )

siavashsay
چهارشنبه 27 دی 1391, 16:36 عصر
در آخر rename هم کن مشکل دیگه حله ( برای اطمینان )
محمد جان ! همه جا گفتن که به نوع پسوند فایل کفایت نکن !
شما در این کد فقط پسوند رو چک کردی که اگه jpg - JPG - JEPG و ... بود فایل رو قبول کنه ! ( حالا سایز رو هم اوکی کردی ! ) اما به پسوند فایل و یک reanem نمیشه اکتفا کرد !
توضیه میشه علاوه بر این موارد حتما از MIME هم استفاده شه :)
موفق باشید !

mamali-mohammad
چهارشنبه 27 دی 1391, 17:28 عصر
محمد جان ! همه جا گفتن که به نوع پسوند فایل کفایت نکن !
شما در این کد فقط پسوند رو چک کردی که اگه jpg - JPG - JEPG و ... بود فایل رو قبول کنه ! ( حالا سایز رو هم اوکی کردی ! ) اما به پسوند فایل و یک reanem نمیشه اکتفا کرد !
توضیه میشه علاوه بر این موارد حتما از MIME هم استفاده شه :)
موفق باشید !

MIME رو میشه دور زد با header
اما اینو نمیشه فکر کنم

siavashsay
چهارشنبه 27 دی 1391, 18:26 عصر
اونم میشه دور زد !
گرچه ما هم نگفتیم روش شما نادرست هست !گفتیم از هر 3 روش استفاده شه بهتره :)

h00manb
چهارشنبه 27 دی 1391, 19:36 عصر
سلام
میشه نام بعضی توابع پر کاربرد php را در متن فایل جستجو کرد (یا چیزی شبیه به این) که اگر وجود داشت معلومه که متنه