• 0 رای - 0 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
حفرهء امنیتی کدهای بدست آوردن IP واقعی کاربر
#1
اینطور کدها که IP رو از HTTP_CLIENT_IP و HTTP_X_FORWARDED_FOR (و امثالهم)، یعنی هدرهای HTTP، میگیرن، حفرهء امنیتی ایجاد میکنن:

کد پی‌اچ‌پی:
<?php

function getRealIpAddr()
{
 if (!empty(
$_SERVER['HTTP_CLIENT_IP'])) //check ip from share internet
 
{
   
$ip=$_SERVER['HTTP_CLIENT_IP'];
   }
  else
 if (!empty(
$_SERVER['HTTP_X_FORWARDED_FOR'])) //to check ip is pass from proxy
 
{
   
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
 } else
 {
   
$ip=$_SERVER['REMOTE_ADDR'];
 } return 
$ip;
}
 echo 
'Your real IP is: 'getRealIpAddr();
 
?>

این کد اغلب برای محدود کردن دسترسی بر اساس IP استفاده میشه، درحالیکه هر سایتی که از این کد استفاده کنه این قابلیت رو به هکر میده که IP خودش رو براحتی جعل کنه.
خب با این حساب این کد دیگه به چه دردی میخوره؟
همون REMOTE_ADDR به تنهایی که بهتر بود! چون حداقل قابل جعل نیست و حداقل کاربر برای دور زدنش با نیاز به و محدودیتهای پراکسی ها مواجه هست.

این کد فقط برای مقاصد Logging احتمالا بدرد میخوره و نه بیشتر. چون به IP هایی که بدست میده اطمینان کافی نیست از نظر امنیتی.
البته یک وقت هست که براتون حفاظت فقط در برابر کاربران عادی که نهایت استفاده از پراکسی و اینطور چیزها رو بلدن، و نه هکرهای واقعی، مهمه، اونوقت فرق میکنه.
وگرنه حدس زدن/تست کردن اینکه یه سایتی از این کد استفاده میکنه برای یک هکر حرفه ای اونقدر هم سخت نیست و براحتی هم میتونه ازش سوء استفاده کنه. گذشته از اینکه در پروژه های بازمتن قابل استفاده نیست. کلا هم که استفاده ازش باوجود آگاهی از این حفره، میشه «امنیت از طریق تیرگی».

جایی که از این کد برای تشخیص IP کاربر جهت اعمال محدودیت هایی استفاده بشه (مثلا محدودیت تعداد ثبت نام از یک IP در یک بازهء زمانی مشخص)، هکر میتونه ازش سوء استفاده کنه و اون محدودیت ها رو براحتی دور بزنه؛ چون میتونه با ست کردن هدرهای HTTP مربوطه، هر IP ای رو که میخواد بعنوان IP خودش معرفی کنه. اینطوری حتی میتونه خودش رو بجای کاربران دیگری جا بزنه و کاری کنه تا دسترسی اونا به سایت ما قطع بشه.
استفاده از این متغییرها که مقدار اونا از هدرهای HTTP گرفته میشه باعث میشه که هر کس بتونه حتی بدون استفاده از پراکسی یک IP جعلی به سیستم معرفی کنه بعنوان IP خودش. اونم هر IP دلخواه (نه IP واقعی هر پراکسی که در کنترل کاربر نیست).

ضمنا اون کسی که از این کد استفاده میکنه فکر میکنه حتما یک رشته با فرمت IP میگیره، بنابراین احتمال زیاد موقع درج اون رشته در کوئری های SQL اونو Escape نمیکنه.
اما مشکل همینجاست که با این کد، هکر میتونه دقیقا هر رشته ای رو با هر فرمتی، یعنی حتی شامل دستورات SQL و کاراکترهای خاص اون، بجای IP خودش ست کنه. بنابراین باگ SQL Injection هم در بقیه کد خیلی از استفاده کنندگان از این کد وجود خواهد داشت!

تست آنلاین هم صورت گرفت.
من نمونه اون کد حفره دار رو روی سایت خودم گذاشتم تا هرکس میخواد تست کنه: http://hamidreza-mz.tk/real_ip.php

با این کد هم میتونید جعل IP رو تست کنید:

کد پی‌اچ‌پی:
<?php
  
$service_port 
getservbyname('www''tcp');
  
$target='hamidreza-mz.tk';
$fake_ip='1.1.1.1';

$address gethostbyname($target);
  
$socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
if (
$socket 0) {
    echo 
"socket_create() failed: reason: " socket_strerror($socket) . "\n";
}
  
$result socket_connect($socket$address$service_port);
if (
$result 0) {
    echo 
"socket_connect() failed.\nReason: ($result) " socket_strerror($result) . "\n";
}
  
$in "GET /real_ip.php HTTP/1.1\r\n";
$in .= "Host: $target\r\n";
$in .= "X-FORWARDED-FOR: $fake_ip\r\n";
$in .= "X_FORWARDED_FOR: $fake_ip\r\n";
$in .= "CLIENT-IP: $fake_ip\r\n";
$in .= "CLIENT_IP: $fake_ip\r\n";
$in .= "Connection: Close\r\n\r\n";
$out '';
  
socket_write($socket$instrlen($in));

header('Content-type: text/plain');

while (
$out socket_read($socket2048)) {
    echo 
$out;
}
  
socket_close($socket);
  
?>

عملا با این حفره نه تنها جعل IP، بلکه SQL Injection و حتی در مواردی XSS میشه انجام داد. چون اون افرادی که از این کدها استفاده میکنن فکر میکنن حتما یک چیزی با فرمت IP دریافت میکنن، و در نتیجه نه موقع درج در کوئری اون رو Escape میکنن و نه موقع درج در متن صفحه HTML (مثلا موقع مشاهده لاگ ها از طریق اینترفیس برنامشون) اون رو مثلا از تابع htmlspecialchars عبور میدن.
  پاسخ
تشکر شده توسط : Reza ali786 admin Bojbaj mr_irani mortaza mohammadhosain
#2
خوب پس راه حل چیه؟
  پاسخ
تشکر شده توسط :
#3
(۱۳۹۴ آذر ۲۴, ۱۰:۰۲ ب.ظ)ahmaduse نوشته: خوب پس راه حل چیه؟

شاید بهتر باشه که REMOTE_ADDR رو در ابتدای شرط بنویسی...
که اگر موجود نبود بناچار از دیگر مقادیر استفاده بشه

کد پی‌اچ‌پی:
// TODO: Add 'filter_var' for IPv4/IPv6.
function getClientIP()
{
    static 
$_list = array
    (
        
'REMOTE_ADDR''HTTP_CLIENT_IP'/* Shared internet/ISP IP */'CLIENT_IP''HTTP_X_REAL_IP''HTTP_PROXY_CONNECTION''HTTP_FORWARDED''HTTP_CF_CONNECTING_IP''HTTP_X_CLUSTER_CLIENT_IP''HTTP_X_FORWARDED''HTTP_X_FORWARDED_HOST''HTTP_X_FORWARDED_SERVER''FORWARDED_FOR_IP''HTTP_FORWARDED_FOR''HTTP_FORWARDED_FOR_IP''HTTP_X_FORWARDED_FOR''FORWARDED''X_FORWARDED_FOR''FORWARDED_FOR''X_FORWARDED''HTTP_VIA''VIA'
    
);

    foreach (
$_list as $_value)
    {
        if (isset (
$_SERVER[$_value]) && !empty($_SERVER[$_value])) return $_SERVER[$_value];
        elseif (
getenv($_value)) return getenv($_value);
        elseif (isset (
$HTTP_SERVER_VARS[$_value]) && !empty($HTTP_SERVER_VARS[$_value])) return $HTTP_SERVER_VARS[$_value];
        elseif (@
apache_getenv($_valueTRUE)) return apache_getenv($_valueTRUE);
        elseif (isset (
$_ENV[$_value]) && !empty($_ENV[$_value])) return $_ENV[$_value];
        else continue;
    }

    return 
FALSE;

وبلاگ: Yousha.Blog.ir

صدام: "اگر با ارتش شاه ایران طرف بودیم، یک ماهه جنگ را می بردیم"
http://gulfnews.com/opinion/thinkers/ira...i-1.500997
  پاسخ
تشکر شده توسط :
#4
خوب چه فرقی کرد شد همون آخه!!!!!
کسی که میاد هک کنه با آیپی واقعی که نمیاد remot_addr پس تو شرط اول اجرا نمیشه
پس باز همون آش و همون کاسه هست !!!!
  پاسخ
تشکر شده توسط :
#5
گفتم که:
نقل قول:شاید بهتر باشه که REMOTE_ADDR رو در ابتدای شرط بنویسی...

1- اون مثال اول از اینجا برگرفته شده که در جوابش هم پاسخ داده شده:
نقل قول:If the reason why you want to find out the client's IP address is really important, screw all this stuff.

Any one of these header values can be freely spoofed.
دوره زمونه بلاک کردن آی پی هم گذشته دیگه، و تقریباً بی فایدست... بیشتر واسه محیط ها و برنامه های live مفیده و نه برنامه های تحت وب
2- با دقت کد من رو نگاه کنی می بینی که تفاوت مهمی داره... در همون مثال اول شما خودت رو بسادگی تو تله میندازی، و بصورت قطعی IP fake رو میگیری یا حتی IP local رو! چون داری اول HTTP_CLIENT_IP و HTTP_X_FORWARDED_FOR رو میگیری، و بعد remote_addr.
باز هم در جاهای دیگه گفتند:
نقل قول:Do not check any HTTP_* headers for the client IP unless you specifically know your application is configured behind a reverse proxy.
نقل قول:HTTP_X_FORWARDED_FOR sometimes returns internal or local IP address, which is not usually useful. Also, it would return a comma separated list if it was forwarded from multiple ipaddresses
نقل قول:$_SERVER['REMOTE_ADDR'] still represents the most reliable source of an IP address. The other $_SERVER variables mentioned above can be spoofed by a remote client very easily.
3- دلیل کد من هم برای گرفتن آی پی کاربر در محیط های ناسازگار، قدیمی، جدید، foolish و مختلفه... و اگه بگم 200% IP رو برمی گردونه اغراق نکردم
وبلاگ: Yousha.Blog.ir

صدام: "اگر با ارتش شاه ایران طرف بودیم، یک ماهه جنگ را می بردیم"
http://gulfnews.com/opinion/thinkers/ira...i-1.500997
  پاسخ
تشکر شده توسط :


پرش به انجمن:


کاربران در حال بازدید این موضوع: 1 مهمان