برنامه نويسي امن

ramram

New Member
منم بگم ديگه

دوستان خوب تاپيك جالبي زده شده ايشالا در اولين فرصت تمام تجربياتم يكجا تو همين تاپيك مينويسم اما دوتا چيز خيلي مهم اولين اينكه اگه مي خواين يك كدنويس ماهر پي اچ پي يا اي اس پي بشين حتما چندتا كتاب هك بخونين دوم
آخرين متد براي بالا بردن امنيت ساده ترين متد كه بسيار مورد توجه قرار گرفته حدس زدنش راحت بله جلوي ديد نگذاشتن تا حد امكان آدرس صفحات را در لينكها و مقابل ديد كاربران قرار ندين البته اين موضوع زمان زيادي را براي طراح طلف مي كند تا جاي ممكن سعي كنيد فايلهاي پيكر بندي را در شاخهايي با نام هاي نا متعارف ذخيره كنيد تا جايي كه ممكن است غير قابل پيش بيني باشيد فراموش نكنيد كه هكرها عموما از چند راه مشخص نفوذ مي كنند و خيلي به تكرار معتقدند يعني مي دانند كه در اكثر موارد مثلا فايلهاي پيكر بندي كه حاوي اطلاعات بانكهاي اطلاعاتي است معمولا در شاخه هايي با نام كانفيگ ذخيره مي شوند و از اين دست.
لطفا منتظر بمانيد تا يكجا ده ها مورد امنيتي را كه عمليتر از اين پاسخ هستند برايتان بنويسم فعلا
 

BeHnAm_akb

Active Member
بابا اي ول ما منتظريم
راستي ميشه چند تا از اين كتاب ها نام ببريد


در مورد لينك و فولدر فكر كنم برنامه هايي هست كه همه فايل هاي سرور رو (جا و اسمشو) نشون مي ده
 

ramram

New Member
بله درست چنين برنامه هايي وجود داره براي همين كه مي گم هميشه غير قابل پيش بيني باشيد و از نام هاي نا متعارف استفاده كنيد در مورد كتاب هم من شخصا كتاب ها و نوشته هاي اي دي اسكوديس رو پيشنهاد مي كنم ترجمه روان اين كتاب توسط موسسه سيمرغ و گروه مهندسي ساحر صورت گرفته قيمتش هم اگه اشتباه نكنم الان حدود چهارهزار تومن كه خوب بهتر از كتابخونه اي چيزي بگيرين و بخونينش
 

BeHnAm_akb

Active Member
ممنون چه عجب يكي از اين انتشارات تعريف كرد آخه كتاب پي اچ پيش واقعا بد ترجمه شده
 

ramram

New Member
بهنام جان پي اچ پيش بد ترجمه نشده فقط حجم زياد از حد اون كه مطالعش و سخت كرده و گرنه اين كتاب الان يكي از مراجع اصلي دانشگاهي براي پي اچ پي به حساب مياد كه طبق آخرين خبرايي كه من دارم اكثر اساتيد دادنشگاههاي مختلف ايران اون رو به دانشجويان به عنوان مرجع پيش نهاد مي كنند ضمن اينكه زماني كه به يك چيزي مي گيم بد يا ضعيف بايد بهترش هم باشه شما براي پي اچ پي كتاب ترجمه شده خوبي سراغ داري البته اگر از من بپرسي منوال ترجمه نشده رو ترجيح ميدم ولي ترجمه شده چيز بهتري در دسترس لااقل من نديدم
 

NabiKAZ

Well-Known Member
با سلام
آقا چرا قضيه رو مي پيچونيد ؟
موضوع خيلي ساده تر از اين حرفاست
آخه مگه چند تا كتاب php ترجمه شده وجود داره كه داريد راجعشون بحث ميكنيد و عمل مقايشه رو انجام ميديد؟!
تا اونجايي كه من ميدونم و ايران رو زير رو رو كردم 2 تا كتاب بيشتر نيست يكي همين مرجع انتشارات ساحر يكي هم محتر مفيد انتشارات ناقوس ! ديگه چي ميگيد اين خوبه اون يكي بده !
غير از اينا هم دادن بيرون ؟!

تشكر
نبي
 

BeHnAm_akb

Active Member
اگه ميشه بحث رو منحرف نكنيم


در مورد كتاب منظورم ترجمه گنگ اون بود نسبت به انگليسيش.اساتيد هم به خاطر اين كه كتاب فارسي ديگه اي نيست اينو معرفي ميكنن
 

ramram

New Member
دوستان سلام :
قول دادم كه اينجا رو حسابي خوندني كنم پاش هستم منتهي به پايان ترم داريم نزديك مي شيم اين استادا هم آخر ترم يادشون مي يفته بايد درس بدن خلاصه كه سرم بدجور شلوغه فقط تا پايان امتحانا همه دوستان كه مي خوان مقالات رو بخونن و بفهمن لطفا چند كتاب راجب به تي سي پي آي پي و ويندوز سرور و ليناكس حتما بخونن البته من سعي مي كنم خيلي خوب و واضح توضيح بدم ضمنا چون كه اصولا كتاب درست و حسابي راجب امنيت نيست مقالاتم و بر اساس علاقه شخصي مي يارم براي اينكه سورپرايز بشين نمي گم چيا مي خوام بنويسم ولي درس اول نحوي ساختن يك لاگين امن امن امن

قربان همگي راستي بچه ها شما بي كار نشينين منم از شما ها چيز ياد بگيرم

تا بعد
 

Ali_Farhadi

Member
سلام

روش Sql Injection كه دوستان توضيح دادند زياد مورد استفاده قرار نميگيره چون همونطور كه آقا مجيد گفتن ‍PHP به صورت پيشفرض مقاديري رو كه از طريق Post و Get و Cookie دريافت ميكنه با استفاده از تابع addslashes اونها رو escape ميكنه.
در اينصورت استفاده از توابعي نظير addslashes يا mysql_escape_string نه تنها مفيد نيست بلكه ممكنه دردسر ساز هم بشه.
مثلا اگر كاربر كلمه Taher's رو توي يك فرم وارد كنه، به صورت پيشفرض php اون رو به Taher\'s تبديل ميكنه و اگر شما از تابع addslashes يا mysql_escape_string استفاده كنيد. اون رو به Taher\\\'s تبديل خواهيد كرد كه اگر اون رو توي ديتابيس ذخيره كنيد به جاي اينكه Taher's ذخيره بشه Taher\'s رو ذخيره خواهيد كرد.
لذا نيازي به استفاده از توابع addslashes و mysql_escape_string نيست. مگر اينكه نسبت به تنظيمات php شك داشته باشيد. در اين صورت ميتونيد از تابع get_magic_quotes_gpc به صورت زير استفاده كنيد :
کد:
if (!get_magic_quotes_gpc()) {
    $lastname = addslashes($_POST['lastname']);
} else {
    $lastname = $_POST['lastname'];
}
$sql = "INSERT INTO lastnames (lastname) VALUES ('$lastname')";


اما نوع ديگري از SQL Injection هم وجود داره كه بيشتر استفاده ميشه (اكثر دوستاني كه از nuke استفاده ميكردن خاطره بدي از اين نوع SQL Injection دارن)


روش: SQL Injection 2
سطح: متوسط
زبان: PHP
بانک اطلاعاتی: MySQL
حد خطر: زیاد
قسمت: 12


اين نوع Injection زماني پيش مياد كه متغير مورد نظر رو درون كوتيشن ( ' ) نگذاشته باشيد.
براي مثال به كد زير توجه كنيد:
کد:
$sql = "SELECT * FROM users WHERE user_id = $user_id AND user_password = '$user_password'";
در اين صورت هكر محترم مي تونه هر كاري بكنه. براي مثال :
کد:
script.php?user_id=1%20/*
با استفاده از كد بالا بدون اينكه پسورد چك بشه user_id شماره 1 انتخاب ميشه.
براي مثال حتي اگر هكر شماره user_id رو هم نداشته باشه و فقط مثلا ايميل كاربر رو داشته باشه باز هم ميتونه با استفاده از كد زير نفوذ كنه:
کد:
script.php?user_id=-1 UNION SELECT * FROM users WHERE user_email = CHAR(117,115,101,114,64,101,120,97,109,112,108,101,46,99,111,109)/*
كد بالا كاربري كه ايميلش [email protected] باشه رو برميگردونه.
توجه !
- استفاده از دستور UNION فقط در mysql ورژن 4 به بالا support ميشه.
- استفاده از /* براي جلوگيري از اجراي بقيه query هستش.
- استفاده از تابع CHAR براي جلوگيري از استفاده مستقيم از كوتيشن ( ' ) هستش.(اگر جناب هكر مستقيما ايميل رو تايپ ميكرد بايد اون رو درون كوتيشن ( ' ) قرار مي داد. كه در اون صورت توسط php به طور خود كار escape ميشد. اما تابع CHAR مجموعه اي از كدهاي ASCII رو ميگيره و يك رشته بر ميگردونه)

همونطور كه مي بينيد اگر جناب هكر محترم به زبان SQL مسلط باشه كارهاي زيادي ميتونه انجام بده.

و اما راه حل :
بايد متغيرهاي int رو با استفاده از تابع intval ايمن كنيد:
کد:
$user_id = intval($user_id);
$sql = "SELECT * FROM users WHERE user_id = $user_id AND user_password = '$user_password'";
راه حل ديگه اينه كه تمام متغيرها رو داخل كوتيشن ( ' ) بگذاريد:
کد:
$sql = "SELECT * FROM users WHERE user_id = '$user_id' AND user_password = '$user_password'";

موفق باشيد :wink:
 
از اينكه براي بالا بردن سطح امنيت تلاش ميكنيد بسيار متشكرم
فقط اميدوارم راه حل هاي ضد امنيتي را آموزش ندهيد :)
 

ramram

New Member
اين آموزش رو تكميل كردم و همش رو يكجا آوردم



سرفصل‌ها :
1ـ اين اسكريپت چگونه كار مي كند | پيشنيازها | الگوي بانك اطلاعاتي
2ـ اتصال به بانك اطلاعاتي |‌ متغيرهاي جلسات
3ـ هسته اسكريپت | ورود كاربران
4ـ كنترل مداوم اعتبار ورود | اطمينان از معتبر بودن اطلاعات جلسات


ــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ
اين آموزش در سطح متوسط طراحي گرديده و به شما خواهد آموخت كه چگونه يك برنامه لاگين امن و حرفه اي طراحي كنيد . بزودي ياد مي گيريم كه چگونه با استفاده از توابع كوكي ها دسترسي به جلسات را قانوني كنيم و از سرقت جلسات جلوگيري كنيم.

1ـ اين اسكريپت چگونه كار مي كند ؟
در اين قسمت مي خواهم برايتان دليل انتخاب اين متد براي لاگين امن را برايتان توضيح دهم فراموش نكنيد كه اصولا امنيت قانون ندارد و شما نيز با استفاده از تجربيات و توانايي هاي هوشي خود بايد به فكر توسعه و طراحي موارد مشابه و امن تر نمائيد و به هيچ وجه به اين حد بسنده نكنيد:
/tmpكاربراني كه قادرند تا به سرور دست يابي داشته باشند مي تواند جلسات معتبر لاگينها را از شاخه پيش فرض
كه به منظور ذخيره سازي اطلاعات جلسات استفاده ميشود مشاهده نمايند روش جلوگيري از اين نوع حمله كنترل آي پي مي باشد.
كساني كه بر روي ميزبان شما سايتي دارند قادرند جلسات معتبر براي سايت شما توليد كنند توجه بفرمائيد كه برخي سايتها سرورهاي اختصاصي دارند كه به لحاظ امنيتي بسيار مطلوبترند مثل سايت پرشين بلاگ
برخي از اون آدمايي كه به قول خودمون آخرشن و اند حكن مي تونن شبكه رو بو بكشن و كوكي‌ها رو بقاپن
كنترل آي پي اين مشكل رو هم حل مي كنه

2-1ـ اما پيش نيازها
شما اول از همه بايد بدونين كه چه اطلاعاتي از كاربران قرار كه در سايت ذخيره بشه در اين مثال براي سهولت آموزش ساده ترين شكل ممكن رو فرض قرار دادم ضمنن چون الان همه ديگه پي اچ پي 4.1 به بالا دارن من هم از استفاده كردم اگر مي خواين كه اين اسكريپت رو روي نسخه هاي قديمي تر اجرا كنين شما super global arrays
مجبوريد كه از
$GLOBALS['HTTP_SESSION_VARS']
استفاده كنيد.

الگوي بانك اطلاعاتي ـ1-3
اين فقط يك مثال ساده با ساختاري مناسب براي مديريت اگر كه مايليد اين مثال را براي كاربران ثبت نام شده استفاده كنيد مي توانيد ستونهاي را به دلخواه اضافه كنيد
من الگوي بانك اطلاعاتي را كه از ماي اس كيو ال استفاده مي كنه اينجا گذاشتم شما مي تونين از ديگر بانكهاي اطلاعاتي نيز استفاده كنيد:
کد:
CREATE TABLE member (
id int NOT NULL auto_increment,
username varchar(20) NOT NULL default '',
password char(32) binary NOT NULL default '',
cookie char(32) binary NOT NULL default '',
session char(32) binary NOT NULL default '',
ip varchar(15) binary NOT NULL default '',
PRIMARY KEY (id),
UNIQUE KEY username (username)
);
فيلدهاي پسورد و كوكي براي استفاده از ام دي فايو طراحي شدن كوكي مقدارش براي زمانيست كه كاربر بخواهد اطلاعات برايش ذخيره شود و فيلدهاي جلسه و آي پي براي جلسه آي دي و آي پي كاربر استفاده مي شوند.


ــــــــــــــــــــــــــــــــــــــ
2ـ اتصال به بانك اطلاعاتي
کد:
function &db_connect() {

require_once 'DB.php';

PEAR::setErrorHandling(PEAR_ERROR_DIE);

$db_host = 'localhost';
$db_user = 'root';
$db_pass = '';
$db_name = 'shaggy';

$dsn = "mysql://$db_user:$db_pass@unix+$db_host/$db_name";

$db = DB::connect($dsn);

$db->setFetchMode(DB_FETCHMODE_OBJECT);
return $db;

}

اين تابع شما را به بانك اطلاعاتي متصل مي كند و يك اشاره گر به شي بانك اطلاعاتي پير باز مي گرداند

2-2ـ متغيرهاي جلسات:
براي سهولت در امر دستيابي به اطلاعات كاربران من اون رو يك متغير جلسه ثبت مي كنم ولي براي جلوگيري از پيغام خطا و همچنين ست كردن برخي پيش فرض ها از تابع زير استفاده مي كنم:
کد:
function session_defaults() {

$_SESSION['logged'] = false;
$_SESSION['uid'] = 0;
$_SESSION['username'] = '';
$_SESSION['cookie'] = 0;
$_SESSION['remember'] = false;
}

براي ست كردن يه مقادير پيش فرض از تابع بالا و براي چك كردن از تابع زير
کد:
if (!isset($_SESSION['uid']) ) {
session_defaults();
}

رو فرا خواني كنيمsession_startالبته فراموش نمي كنيم كه قبل از اينها بايد تابع

3ـ هسته اسكريپت:
براي ايجاد يكپارچگي ساده تر با ديگر اسكريپتها و ساخت مدوله شده تر هسته اسكريپت رو يك آبجكت با ظاهري خيلي ساده مي سازم
کد:
class User {

var $db = null; // PEAR::DB pointer
var $failed = false; // failed login attempt
var $date; // current date GMT
var $id = 0; // the current user's id

function User(&$db) {

$this->db = $db;
$this->date = $GLOBALS['date'];

if ($_SESSION['logged']) {
$this->_checkSession();
} elseif ( isset($_COOKIE['mtwebLogin']) ) {
$this->_checkRemembered($_COOKIE['mtwebLogin']);

}

}
اين كلاس كه تعريف ميشه آبجكت ما رو ميسازه البته اين كاملا مدوله شده نيست اما يك تاريخ مشكل بزرگي نيست و شما مي تونين اونو با اسكريپتهايي كه بقيه دوستان نوشتن به صورت شمسي توليد كنيد در اينجا ما چنين چيزي رو مي سازيم:
کد:
$date = gmdate("'Y-m-d'");
$db = db_connect();
$user = new User($db);
حالا براي روشن شدن هدف كد يعني لاگين كردن تلاش مي كنيم ما ابتدا كنترل مي كنيم كه آيا كاربر لاگين كرده يا نه اگر اين كار رو كرده بود ما جلسات رو چك مي كنيم(فراموش نكنين كه اين يك كد امنيتي) وگرنه يك كوكي رو نام گذاري مي كنيم براي كنترل كردن اين به ما اجازه مي ده كه بينندگان سايت رو شناسايي كنيم

3-1ـ لاگين كردن كاربران:

براي اجازه دادن به كاربران براي لاگين كردن شما بايد يك فرم وب بسازيد پس از اعتبار سنجي فرم شما مي تونيد اعتبار كاربر رو براي تائيد اطلاعات وارد شده كنترل كنيد كه براي اينكار از
$user->_checkLogin('username', 'password', remember)
استفاده مي كنيم
خاطر نشان مي كنيم كه يوزر نيم و پسورد البته نبايد ثابت باشند و ريممبر يك مقدار بولين است كه به كاربر اجازه مي دهد تا با درست قرار دادن مقدار آن لاگين خودكار را فعال بسازد
کد:
function _checkLogin($username, $password, $remember) {

$username = $this->db->quote($username);
$password = $this->db->quote(md5($password));

$sql = "SELECT * FROM member WHERE " .
"username = $username AND " .
"password = $password";

$result = $this->db->getRow($sql);

if ( is_object($result) ) {
$this->_setSession($result, $remember);
return true;
} else {
$this->failed = true;
$this->_logout();
return false;
}

}

تعريف تابع بايد در مكاني كنار كلاس تعريف شده يوزر باشه مانند تمام كدهاي پائين در تابع از متد
PEAR::DB's quote
استفاده كردم تا اطلاعات با امنيت كامل به بانك اطلاعاتي انتقال پيدا كنند و به صورت بي ختري نيز از آن رهاي يابند و باز گردنند من از تابع ام دي فايو ترجيحا به جاي توابع ماي اسكيو ال استفاده كردم تا شما اگر مايل بوديد بتوانيد از بانكهاي اطلاعاتي ديگر نيز استفاده كنيد.
حلقه ور بهينه شده زيراكه يوزرنيم به صورت منفرد تعريف شده است
نيازي به كنترل خطاهاي بانك اطلاعاتي نيست زيراكه خطاهاي پيشفرض قبلا در بالا ست شدند
چنانچه آبجكت با رزالت بانك اطلاعاتي متچ شود لذا متغير جلسات ست مي شوند و مقدار ترو باز ميگردد وگرنه
مقدار فلد با ترو برابر مي گردد شما مي تونين اينجا يك دستور كنترلي قرار دهيد تا پيغام سقوط عمليات لاگين رو اعلام كنه و براي انجام لاگ اوت براي اين بيننده كافيست تا
session_defaults()
را اجرا كنيم

3-3ـ وضع كردن جلسه:
کد:
function _setSession(&$values, $remember, $init = true) {

$this->id = $values->id;
$_SESSION['uid'] = $this->id;
$_SESSION['username'] = htmlspecialchars($values->username);
$_SESSION['cookie'] = $values->cookie;
$_SESSION['logged'] = true;

if ($remember) {

$this->updateCookie($values->cookie, true);

}

if ($init) {

$session = $this->db->quote(session_id());
$ip = $this->db->quote($_SERVER['REMOTE_ADDR']);

$sql = "UPDATE member SET session = $session, ip = $ip WHERE " .
"id = $this->id";
$this->db->query($sql);

}

}

اين متد متغير جلسه را ست مي كند و همچنين اگر در خواست كوكي براي داشتن لاگين مسمتر (خودكار) ارسال شده باشد
همچنين اين متد يك پارامتر دارد كه معين مي كند كه اين بار اول لاگين كردن است يا نه (از طريق فرم يا كوكي)
يا كنترل جلسه براي اولين بار نيست.

4ـ لاگين خود كار:
اگر بينندگان در خواست كنند كه كوكي ارسال بشه تا دفعات بعدي از لاگين كردن در هر مشاهده از سايت بپريد
اين دو متد به شما براي رسيدن به اين مهم كمك خواهد كرد
کد:
function updateCookie($cookie, $save) {

$_SESSION['cookie'] = $cookie;
if ($save) {

$cookie = serialize(array($_SESSION['username'], $cookie) );
set_cookie('mtwebLogin', $cookie, time() + 31104000, '/directory/');
}

}

4-1ـ كنترل لاگين خود كار:
اگر كاربران لاگين خودكار را انتاخاب كرده باشند كه به اسكريپت اجازه ذخيره كوكي را مي دهد كه كنترل مي شه از طريق متد زير
کد:
function _checkRemembered($cookie) {

list($username, $cookie) = @unserialize($cookie);
if (!$username or !$cookie) return;

$username = $this->db->quote($username);
$cookie = $this->db->quote($cookie);

$sql = "SELECT * FROM member WHERE " .
"(username = $username) AND (cookie = $cookie)";

$result = $this->db->getRow($sql);

if (is_object($result) ) {
$this->_setSession($result, true);
}

}
اين تابع هرگز نبايد توسط پيغام خطايي متوقف شود براي ساختن چيزهاي امن تر با كوكي ها مقدار كوكي در كوكي ذخير مي شود نه پسورد كاربر يكي از اين راه ها مي تونه درخواست يك لغت عبور باشه براي ناحيه اي كه به امنيت بيشتري نياز دارد

5-5ـ مطمئن شدن از اعتبار جلسه:
کد:
function _checkSession() {

$username = $this->db->quote($_SESSION['username']);
$cookie = $this->db->quote($_SESSION['cookie']);
$session = $this->db->quote(session_id());
$ip = $this->db->quote($_SERVER['REMOTE_ADDR']);

$sql = "SELECT * FROM member WHERE " .
"(username = $username) AND (cookie = $cookie) AND " .
"(session = $session) AND (ip = $ip)";

$result = $this->db->getRow($sql);

if (is_object($result) ) {
$this->_setSession($result, false, false);
} else {
$this->_logout();
}

}
پوف بالاخره آخرين قسمت كار ما كنترل مي كنيم كه آيا كوكي ذخيره شده در جلسه درست هست يا نه جلسه آي دي و آي پي كاربر
با يك پارامتر كه اجازه مي ده كه بفهميم كه اين اولين بار لاگين كردن در سيستم هست بنابراين setSessionفراخواني
مقدار آي پي و آي دي در جلسه بروز رساني نشود كه در بقيه موارد بطور معمول انجام مي شود


آقا مردم موقعي كه مي خواستم براي خودم بنويسمش نيم ساعتم وقت نبرد ولي چقدر اينجوري درس دادن سخته خداييش آخه من تدريسم مي كنم اما خيلي اين چند خط خستم كرد شرمنده اصلا حوصله ويرايش لغتيش رو ندارم مي دونم احتمالا خيلي تيكه تيكه نوشته شده چون تو چند روز نوشتمش يه دست نيست
فقط دوستان خبره لطفا نظر بدين...
شب و روز بر همگي خوش
راستي برام دعا كنين رياضي 1و فيزيك 1 رو پاس كنم و گرنه كه انا بدخت مي شم
 

ramram

New Member
ساخت تصاوير امنيتي با php
چندي پيش در يکي از انجمنها بحث داغي در مورد برتري php بر asp.net و يا برعکس asp.net بر php شکل گرفته بود طرفداران asp.net در موضوعاتي در همان انجمن سوالي در مورد ساخت و توليد تصاوير امنيتي که روبوتها قابل به خواندن آنها نيستند مطرح کرده بودند و پاسخ آن موضوع را يکي از دوستان ارجمند با تابعي مخصوص در asp.net داده بودند من به فکر ساخت چيز مشابهي با php افتادم و سري هم به سيت محبوبمان php.net زدم تا ببينم چيز بدرد بخوري گير مياد يا نه باورتون نميشه تو کمتر از چند ثانيه زدم تو خال هموني که مي خواستم رو گير آوردم يکمي هم انگولکش کردم تا جالب تر بشه و توضيح کاملش رو براتون ميارم مثل ينکه همينطوري الکي الکي من دارم فقط از مسائل امنيتي براتون مقاله مينويسم نه!!!!!؟؟؟؟؟
بگذريم ابتدا کد ين برنامه که در سه صفحه مجزا بيد نوشته بشه


صفحه اول که من اون رو تو فيلي به نام encod.php ذخيره مي کنم
کد:
<?php
function get_rnd_iv($iv_len){
$iv = '';
while ($iv_len-- > 0) {
$iv .= chr(mt_rand() & 0xff);
}
return $iv;
}
function md5_encrypt($plain_text, $password, $iv_len = 16){
$plain_text .= "\x13";
$n = strlen($plain_text);
if ($n % 16) $plain_text .= str_repeat("\0", 16 - ($n % 16));
$i = 0;
$enc_text = get_rnd_iv($iv_len);
$iv = substr($password ^ $enc_text, 0, 512);
while ($i < $n) {
$block = substr($plain_text, $i, 16) ^ pack('H*', md5($iv));
$enc_text .= $block;
$iv = substr($block . $iv, 0, 512) ^ $password;
$i += 16;
}
return base64_encode($enc_text);
}
function md5_decrypt($enc_text, $password, $iv_len = 16){
$enc_text = base64_decode($enc_text);
$n = strlen($enc_text);
$i = $iv_len;
$plain_text = '';
$iv = substr($password ^ substr($enc_text, 0, $iv_len), 0, 512);
while ($i < $n) {
$block = substr($enc_text, $i, 16);
$plain_text .= $block ^ pack('H*', md5($iv));
$iv = substr($block . $iv, 0, 512) ^ $password;
$i += 16;
}
return preg_replace('/\\x13\\x00*$/', '', $plain_text);
}
?>
صفحه دوم که مربوط به تولید تصویر و من اونو تو فایلی به نام image.php ذخیره می کنمش
کد:
<?php
require_once "encode.php";
$decid = urldecode(md5_decrypt($_REQUEST['id'], $_REQUEST['key']));


header("Content-type: image/png");
$img = imagecreatetruecolor(75, 25);
$black = imagecolorallocate($img, 0, 0, 0);
$red = imagecolorallocate($img, 236, 134, 72);
$bgline = imagecolorallocate($img, 81, 102, 125);
$bg = imagecolorallocate($img, 131, 152, 175);
imagefill($img, 0, 0, $bg);


imageline($img,0,6,75,6,$bgline);
imageline($img,0,12,75,12,$bgline);
imageline($img,0,18,75,18,$bgline);

imageline($img,7,0,7,25,$bgline);
imageline($img,14,0,14,25,$bgline);
imageline($img,21,0,21,25,$bgline);
imageline($img,28,0,28,25,$bgline);
imageline($img,35,0,35,25,$bgline);
imageline($img,42,0,42,25,$bgline);
imageline($img,49,0,49,25,$bgline);
imageline($img,56,0,56,25,$bgline);
imageline($img,63,0,63,25,$bgline);
imageline($img,70,0,70,25,$bgline);


imageline($img,3,6,70,18,$red);
imagestring($img, 5, 5, 5, $decid, $black);
//imagettftext($img,20,0,10,20,$brown,"/path/arial.ttf",$decid);
imagepng($img, '', 75);
imagedestroy($img);
?>
خوب میمونه صفحه آخر که متعلق به شماست هر کجا که خواستین اون عکس تولید بشه قطعه کد زیر رو قرار بدین
کد:
<?php
require_once "encode.php";
$string = md5(rand(0, microtime()*1000000));
$verify_string = substr($string, 3, 7);
$key = md5(rand(0,999));
$encid = urlencode(md5_encrypt($verify_string, $key));
echo "<img src='image.php?id=$encid&key=$key'><br>";
echo "to verify the user would hve to type in $verify_string";
?>
خوب بریم سراغ توضیحات این کدها:

نمی دونم از md5 چیزی میدونین یا نه به هر حال امیدوارم که بدونین چون این مقاله هدفش توضیح چیز دیگریست ولی اگر مشکلی در فهم کلی قسمت encode.php داشتید برایم پیغام بگذارید تا اگر فرصت شد برایتان md5 را توضیح بدم .

ساختار برنامه به این صورت است که ابتدا قطعه کد سومی که برایتان نوشتم میاد و یک رشته رندم و همچنین یک کلید رندم تولید می کنه نام ایندو به ترتیب string$ و key$ هست که روی همرفته چیز خفنی از کار دراومد و چون میخواستم مثلا امنیت بالایی داشته باشه به این شکل عمل کردم که ایندو مقدار رو با اندکی سیخونک به فایل image.php ارسال کردم حالا همین یه تیکه رو براتون توضیح می دم:

ببینید خیلی سادست تو خط سوم مقدار string$ رو برابر با ام دی فایو مقداری رندم بین صفر تا ثانیه قرار میدهم بعد verify_string$ رو برابر با کاراکترهای سوم تا دهم مقدار string$ قرار میدم و همچنین یک مقدار رندم بین صفر تا 999 تولید می کنم و در key$ قرارش می دیم همونطوری که می بینید در خط ششم مقدار urlencode شده md5_encrypt ایندو مقدار بالا رو در encid$ قرار میده به دلیل پیچیدگی الگوریتم استفاده شده در فایل encode.php از توضیح آن قسمت ها صرفه نظر کردم تا برای مبتدیان زیاد پیچیده نشود نهایتا ما این مقادیر رو همونطوری که میبینید در خط هفتم به فایل image.php می فرستیم تا عکس ما را با مقدار verify_string$ در داخل تصویر تولید کند.

خوب حالا ماهم با این مقادیر میریم به فایل image.php

خوب هرچی کد خفن تولید کرده بودیم به حالت پیش از کد شدن تبدیل می کنیم تا مقدار ما تحت امنیت کامل به درون تصویر منتقل شود در واقع این همه کد گذاری برای انتقال امن داده ها به درون فایل image.php بوده است

همونطوری که به راحتی از قطعه کد دوم مشخص است با توابعی تصویری را تولید می کنم و برای اینکه تصویر زیاد ساده نباشد یک پس زمینه مربعی و یک خط نارنجی رو کاراکترهای امنیتی می کشم در یک خط اضافی هم کدی رو نوشتم که شما با استفاده از اون می تونید حتا فونت نوشته ها رو در تصویرتون تغییر بدید فقط قسمت /path/ رو باید با مسیر فونت عوض کنید ولی من برای راحتی بیشتر از تابع imagestring استفاده کردم

پیشنهاد اکید این کمترین بر همه شما دوستان بزرگوار این است که به دنبال حفظ کردن این کدها و استفاده طوطی وار از آنها نباشید این مقالات باید بهانه برایتان باشند تا شما را به دنبال یادگیر مابقی توابع مرتبط و استفاده از آنها مجاب کنند مثلا خیلی خوب است که manual پی اچ پی رو باز کنید و لغت image رو سرچ کنید وتوابع کامل تصاویر رو ببینید و از آنها استفاده کنید. به همین دلیل است که من هیچ وقت در مقالاتم کد آماده و یک تکه از برنامه قرار نمی دم مگر آنکه توضیح الگوریتم هایی که استفاده کردم وقت گیر و دشوار باشد.

تا مقاله بعد حق یارتان باد

رامین فرمانی زمستان 83

[email protected]
 
اگر امكان داره درباره asp و بانك اطلاعاتي اكسس بيشتر توضيح بدهيد.

ممنون ميشم
 

iranmahfel

Member
سلام رامین جان خیلی عالی بودش
منتها من نفهمیدم که کدهایی که اینجا دادی رو باید کدامش رو در کنار هم یعنی توی یک فایل گزاشت و استفاده کرد
اگه ممکنه زحمتش رو بکش و بگو یا اینکه یک سورس آماده در اختیار من بزار عزیز

قربونت خیلی چاکرتم بای
 
Majid گفت:
روش: چك كردن محل درخواست برنامه
سطح: متوسط
زبان: PHP
بانک اطلاعاتی: -------
حد خطر: كم
قسمت: 11

کد:
// آدرس فرم ما
$my_form_URL = "http://domain.net/my_form.html"; 

// آدرس ورودي 
$incoming_URL = $_SERVER['HTTP_REFERER']; 

if ($my_form_URL == $incoming_URL) { 
// همه چيز درست است، ادامه برنامه 
} else { 
// يه نفر قصد اذيت داره 
echo "Access Denied."; 
exit;

http://security.majidonline.com/phpsm/phpsm8.htm
مجيد

ايني كه آقا مجيد نوشته مي تونه خيلي از راههاي نفوذ رو ببنده اما اگر كه مي خوايد بهتر كار بده به اين صورت پيادش كنيد:
PHP:
  $url= array('http://domain.net/my_form.html','http://www.domain.net/my_form.html');
    if ((($url[0].$_SERVER['PHP_SELF']) == $_SERVER['HTTP_REFERER']) || (($url[1].$_SERVER['PHP_SELF']) == $_SERVER['HTTP_REFERER'])){
    }
    else{
    echo "Access Denied.";
    exit;
    }
 
آخرین ویرایش:
تا حالا هرچي گفته شد مستقيما مربوط به كد نويسي بود.
اگه ممكنه يه مقداري راجع به راههاي ديگه كه ممكنه ريسك پذير باشن توضيح بديد.
براي آپلود كننده ها (بخصوص عكس) كه در پورتال ها خيلي خيلي لازم و پر كار برده چه مسائلي امنيتي ممكنه مطرح باشه؟ چه اقداماتي لازمه؟ راهي وجود نداره كه بدون استفاده از پرميشن 777 آپلود انجام بشه؟

مدتهاست براي من اين سؤال هست كه چجوري مي شه به فايلها يا پوشه هاي 777 حمله كرد. اصلا از جانب پرميشن هاي آزاد 777 ممكنه خطري باشه. اگه آره چه خطرايي، اگه نه، چرا؟ مگه ما دسترسي نوشتن، خواندن و اجرا رو براي user,group,world آزاد نذاشتيم؟
 

NabiKAZ

Well-Known Member
با سلام
یه سوال کوچیک
وقتی با php میخوایم فایلی آپ لود کنیم دسترسی شاخه رو روی 777 تنظیم میکنیم . و فایلها رو توش آپ لود میکنیم . اما این کار باعث میشه کاربر عادی با مراجعه مستقیم به اون شاخه ، به لیست فایلهای اپ لود شده دسترسی داشته باشه. چطور میشه که اینطوری نشه !!!

نبی
 

mehdvirus

Member
خوب یه فایل ایندکس اپلود کن
4.gif
 

NabiKAZ

Well-Known Member
mehdvirus گفت:
خوب یه فایل ایندکس اپلود کن
4.gif


گاهی اوقات آدم به خودشم شک میکنه !!! نمیدونم چرا این به فکر خودم نرسیده بود...
جالبیش اینه که پستت رو چندین دفعه خوندم تا تازه فهمیدیم !!! ای کیوم پایینه دیگه باید ببخشید...

تشکر
نبی
 

جدیدترین ارسال ها

بالا