اولین تلاش یک مهاجم برای نفوذ به برنامه فهمیدن نحوه عملکرد برنامه شامل چگونگی عملکرد سیستم تشخیص هویت برنامه مثلا چگونگی استفاده از session ها یا کوکی ها ، سیستم پشتیبان گیری برنامه ، نحوه فیلتر کردن ورودی ها ، پیغام های خطا ، الگوریتم های رمز نگاری و ... است.
برای مثال در حملات Sql Injection اولین تلاش مهاجم ورود یک سری کاراکتر های مورد استفاده در نوع حملات مثل ‘ و گرفتن پیغام خطای برنامه می باشد.پیغام های خطای پیش فرض کدی را که موجب ایجاد خطا می گردد رو نمایش داده و در مواردی حتی رشته پرس و جو یا سایر اطلاعات رو نمایش می دهند.
مهاجم با جمع کردن تکنیک های مورد استفاده برای نفوذ بعلاوه نحوه واکنش برنامه در برابر کنش های غیر عادی نقاط ضعف برنامه را شناسایی و از آن ها استفاده می کند.
برای مثال با ساختن دو اکانت مختلف در برنامه هایی که از اعتبار سنجی استفاده می کنند و مقایسه مقادیر و شکل session ها و کوکی ها یک مهاجم به نحوه عملکرد آن ها پی برده و با آنالیز کردن موارد فوق سعی در نفوذ به سیستم می کند.
برای جلوگیری از این گونه مشکلات داده هایی را که در مورد هر کاربر یکتا هستند مثلا پسورد هش شده کاربر ، شماره شناسایی منحصر به فرئ کاربر و ... را در نشت ها یا کوکی ها ست کرده و در هنگام بازخوانی اون ها روبررسی کید.
مورد دیگه عدم نمایش پیغام های خطای پیش فرض در نسخه نهایی برنامه می باشد.برای نمایش پیغام های خطا مواردی را که ممکن است برنامه پیغام خطایی بدهد رو شناسایی و متناسب با آن ها از پیغان های تعریف شده خودتان استفاده کنید مثلا
<?PHP
Mysql_connect(“host”,”user”,”pass” ) or die(“Some problem in connecting database”);
?>
البته در زمان توسعه کد استفاده از روش های مثل کد زیر بسیار مفید خواهد بود اما تا حد امکان در زمان انتشار نسخه نهایی آن ها را اصلاح کنید
<?PHP
Mysql_connect(“host”,”user”,”pass” ) or die(“Some problem in connecting database”.mysql_error());
?>
مورد دیگر را که در Directory Browsing نیز توضیح دادم ذخیره فایل ها با پسوندی غیر قابل تفسیر توسط وب سرور (مثلا SQL ) است.در صورتیکه فکر می کنید چون از الگوریتم های هشینگ مانند md5 یا sha1 استفاده می کنید لو رفتن پسوردهای هش شده چه از این طریق چه از طریق Sql Injection یا هر روش دیگه ای مهم نیست باید بگم در اشتباهید.
چند وقت پیش خبری در زمینه کرک شدن الگوریتم sha1 توسط یک گروه دانشجویان چینی منتشر شد.در مورد md5 هم هماجم با دراختیار داشتن یک rainbow table مناسب توانایی این رو داره که پسوردهای شما را (بسته به قدرت آن ها) در چند ساعت روی یک سیستم عادی کرک کنه.
برای جلوگیری از این گونه مشکلات می تونید از چند لایه رمز نگاری یا ترکیب الگوریتم های رمز نگاری با الگوریتم خودتون استفاده کنید.
<?PHP
$user=”houtanal”;
$hashed_user=md5($user);
$multi_hashed_user=md5(sha1(md5($user& #41;))l
$custom_algorihtm=md5(sha1($user).md5& #40;strlen($user)));
?>
این گونه الگوریتم های شخصی بخصوص زمانی که کاربر شما ممکن است از یک شبکه برای اتصال و استفاده از سیستم استفاده کند یا اصلا نرم افزار تحت اینترانت باشئ مفید است.زیرا در صورت دزدیده شدن بسته ها در بین راه و عدم وجود امکان SSL باز هم مهاجم زمان زیادی زو برای آنالیز کار ما باید صرف کند.
توجه کنید که مقصود از تمامی روش های امنیتی صرفا کم کردن ضریب ریسک و بالا بردن ضریب اطمینان برنامه می باشد.بسیاری از مهاجمان در مراحل اول با صرف زمانی خاص و نگرفتن نتیجه نا امید می شوند.
یکی دیگر از روش های نسبتا مفید در این زمینه استفاده از جاوااسکریپت یا کلا اسکریپت ها کلاینت ساید برای جلوگیری از ارسال داده ها به شکل معمول است.مثلا پس او کایک کردن کاربر بر روی دکمه login بوسیله یک اسکریپت کلاینت ساید محتوی فرم را با الگوریتم خودتان کد کرده و در سمت سرور ساید دیکود کنید.البته راه چندان جالبی نیست چون در اختیار بودن سورس اسکریپت این امکان رو به مهاجم میده تا با خواندن آن این الگوریتم رو کرک کند.اما به هر حال بودش از نبودش بهتر است.
فراموش نکنید که اعتبار سنجی و بررسی مقادیر فرم ها را صرفا در سمت سرور ساید برنامه انجام دهید.
همان طور که گفتم یک مهاجم با در نظر گرفتن کنش و واکنش برنامه شما سعی در نفوذ به آن می کند.مثلا شما سیستمی دارید که به هر کاربر بر اساس اعتبار امکان دانلود میدهید.مثلا کاربری با اعتبار X امکان دانلود و دسترسی به یک سری فایل و کاربری با اعتبار Y امکان دسترسی به کل فایل ها را داراست.
شما با روش هایی که پیش تر گفته شد امکان Directory Browsing رو هم از بین برده اید.
کاربر X در هنگام دانلود به مکانی از سرور که فایل از آن دانلود می گردد توجه می کند.(حتی اگر با توابعی مثل header سعی در مخفی کردن آن کنید بار هم به سادگی می توان منبع فایل را فهمید) سپس مستقیما در مرورگر آدرس مربوطه (مثلا فولدر files ) را به همراه نام فایلی که مجاز به دسترسی آ« نیست وارد می کند!
برای جلوگیری از این مسئله نام فایل های خود را توسط یک برنامه با الگوریتم رمزنگتری یا هشینگ خودتان رمز نگاری یا هش کرده و سپس یا آدرس آن ها را در یک دیتابیس ذخیره کنید با الگوریتم را به گونه ای طراحی کنید که مثلا فایلی با نام test.zip همواره رشته رمزنگاری شده ثابت و یکتا داشته باشد سپس در هنگام درخواست کاربر نام فایل درخواست شده را سمت سرورساید برنامه با الگوریتمی که استفاده کرده اید رمزنگاری و سپس فایل مربوطه را به کاربر بدهید. حسن این روش در این است که تا زمانی که الگوریتم شما برای رمزنگاری نام فایل ها لو نرفته باشد کاربران دیگر نام فایل ها را نمی دانند بنابراین توانایی فای هایی که به آن دسترسی ندارند را از طریق وارد کردن نام آن ها در مرورگر ندارند.(توجه کنید که در صورتیکه جلوی حملات Directory Browsing گرفته نشده باشد تمامی کارهای فوق بی مورد و بیفایده است)
یک مورد دیگر
فکر کنید شما مثلا عبارت script رو برای جلوگیری از XSS در رشته ورودی حذف می کنید.مثلا این عبارت <script>alert(document.domain)</script> تبدیل به <>alert(document.domain)</> می گردد .حال چه اتفاقی میافته اگر مهاجم چنین چیزی وارد کنه
<scrscriptipt>alert(document.domain)</scrscriptipt> :wink:
کلا نتیجه و مقصود این نوشته ها پنهان سازی روش و نحوه کارکرد برنامه از دید کاربران و مهاجمان است که با کمی خلاقیت خودتان باید آن را توسعه و در برنامه های خود بکار گیرید.
استفاده از sha1 و md5 در C#
private void btnSubmit_Click(object sender, System.EventArgs e)
{
String userName = TextBox1.Text;
userName = hashSHA1( hashMD5(userName));
Response.Write(userName);
}
string hashMD5 (string val){
System.Security.Cryptography.MD5 md5serv = System.Security.Cryptography.MD5CryptoServiceProvi der.Create();
byte[] hash;
System.Text.StringBuilder stringbuff = new System.Text.StringBuilder();
System.Text.ASCIIEncoding asciienc = new System.Text.ASCIIEncoding();
byte[] buffer = asciienc.GetBytes(val);
hash = md5serv.ComputeHash(buffer);
foreach (byte b in hash)
stringbuff.Append(b.ToString("x2")) ;;
return ( stringbuff.ToString());
}
string hashSHA1 (string val)
{
System.Security.Cryptography.SHA1 sha1serv = System.Security.Cryptography.SHA1CryptoServiceProv ider.Create();
byte[] hash;
System.Text.StringBuilder stringbuff = new System.Text.StringBuilder();
System.Text.ASCIIEncoding asciienc = new System.Text.ASCIIEncoding();
byte[] buffer = asciienc.GetBytes(val);
hash = sha1serv.ComputeHash(buffer);
foreach (byte b in hash)
stringbuff.Append(b.ToString("x2")) ;;
return ( stringbuff.ToString());
}