This commit is contained in:
mcoder 2026-04-14 18:19:01 +03:30
parent c0b2ef78d2
commit 2f0ee79a1b
4 changed files with 184 additions and 51 deletions

View File

@ -0,0 +1,105 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
// ==========================================
// صفحه اصلی
// ==========================================
public function home()
{
return redirect()->route('login');
}
// ==========================================
// راه‌اندازی آزمایشگاه
// ==========================================
public function setupLab()
{
User::firstOrCreate(
['email' => 'victim@webapp.kr-rezvan.ir'],
[
'name' => 'کاربر قربانی',
'password' => Hash::make('12345678')
]
);
return "<div style='font-family:tahoma,serif; padding:20px; text-align:center;'>
<h2>آزمایشگاه آماده شد! 🧪</h2>
<p>کاربر هدف (victim@webapp.kr-rezvan.ir) با رمز عبور (12345678) در دیتابیس ساخته شد.</p>
<a href='" . route('login') . "' style='padding:10px 20px; background:blue; color:white; text-decoration:none; border-radius:5px;'>رفتن به صفحه لاگین</a>
</div>";
}
// ==========================================
// نمایش فرم ورود
// ==========================================
public function showLogin()
{
return view('user.login');
}
// ==========================================
// پردازش ورود کاربر
// ==========================================
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
return redirect()->route('user.profile');
}
return back()->withErrors(['message' => 'اطلاعات ورود صحیح نیست.']);
}
// ==========================================
// خروج کاربر
// ==========================================
public function logout()
{
Auth::logout();
return redirect()->route('login');
}
// ==========================================
// نمایش پروفایل کاربری
// ==========================================
public function profile()
{
return view('user.profile', ['user' => Auth::user()]);
}
// ==========================================
// متد آسیب‌پذیر تغییر ایمیل (CSRF Target)
// ==========================================
public function updateEmail(Request $request)
{
// بررسی اعتبار کوکی نشست (آیا SameSite اجازه ارسال کوکی را داده است؟)
if (!Auth::check()) {
return response()->json([
'error' => 'شما لاگین نیستید. مرورگر کوکی نشست را بلاک کرده است! (محافظت SameSite عمل کرد)'
], 401);
}
$user = Auth::user();
$oldEmail = $user->email;
// اعمال تغییرات مخرب در دیتابیس
$user->email = $request->input('email');
$user->save();
return response()->json([
'status' => 'success',
'message' => 'حمله موفق! ایمیل کاربر در دیتابیس تغییر یافت.',
'old_email' => $oldEmail,
'new_email' => $user->email
]);
}
}

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<title>ورود به سیستم | آزمایشگاه امنیت</title>
<style>
body { font-family: Tahoma, sans-serif; background-color: #f4f4f9; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
.login-box { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); width: 100%; max-w-width: 400px; text-align: center; border-top: 4px solid #10b981;}
input { width: 90%; padding: 10px; margin: 10px 0; border: 1px solid #ccc; border-radius: 4px;
font-family: Tahoma, serif;}
button { width: 95%; padding: 10px; background: #10b981; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px;}
button:hover { background: #059669; }
.error { color: red; font-size: 14px; margin-bottom: 15px; }
</style>
</head>
<body>
<div class="login-box">
<h2>ورود به حساب کاربری</h2>
@if($errors->any())
<div class="error">{{ $errors->first() }}</div>
@endif
<form action="{{ route('login.submit') }}" method="POST">
<!-- توکن CSRF برای فرم لاگین فعال است تا خود لاگین امن باشد -->
@csrf
<input type="email" name="email" value="victim@webapp.kr-rezvan.ir" placeholder="ایمیل" required>
<input type="password" name="password" value="12345678" placeholder="رمز عبور" required>
<button type="submit">ورود به پنل</button>
</form>
<p style="font-size: 12px; color: #666; margin-top: 20px;">برای تنظیم اولیه پایگاه داده <a href="{{ route('setup.lab') }}">اینجا کلیک کنید</a>.</p>
</div>
</body>
</html>

View File

@ -0,0 +1,7 @@
<div style="font-family: tahoma,serif; padding: 20px; border: 1px solid #ccc;">
<h2>پنل کاربری (سایت قربانی)</h2>
<p>سلام <b>{{ $user->name }}</b> خوش آمدید.</p>
<p>ایمیل فعلی شما: <span style="color: blue;">{{ $user->email }}</span></p>
<hr>
<a href="{{ route('logout') }}">خروج از سیستم</a>
</div>

View File

@ -1,59 +1,41 @@
<?php <?php
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use App\Http\Controllers\UserController;
// ۱. مرحله اول: مقداردهی اولیه پایگاه داده (ساخت کاربر قربانی) // ==========================================
Route::get('/setup-lab', function () { // صفحه اصلی
$user = User::firstOrCreate( // ==========================================
['email' => 'victim@webapp.kr-rezvan.ir'], Route::get('/', [UserController::class, 'home'])->name('home');
[
'name' => 'کاربر قربانی',
'password' => Hash::make('12345678') // ==========================================
] // ۱. راه‌اندازی سریع آزمایشگاه (مرحله اول)
); // ==========================================
return "آزمایشگاه آماده شد! کاربر هدف (victim@webapp.kr-rezvan.ir) در دیتابیس ساخته شد."; Route::get('/setup-lab', [UserController::class, 'setupLab'])->name('setup.lab');
// ==========================================
// ۲. سیستم احراز هویت (Authentication)
// ==========================================
Route::get('/login', [UserController::class, 'showLogin'])->name('login');
Route::post('/login', [UserController::class, 'login'])->name('login.submit');
// نکته امنیتی: خروج در حالت استاندارد باید POST باشد اما برای راحتی تست در لابراتوار GET قرار دادیم
Route::get('/logout', [UserController::class, 'logout'])->name('logout');
// ==========================================
// ۳. پنل کاربری (محافظت شده با نشست)
// ==========================================
Route::middleware(['web', 'auth'])->group(function () {
Route::get('/profile', [UserController::class, 'profile'])->name('user.profile');
}); });
// ۲. شبیه‌سازی ورود کاربر به سیستم
Route::get('/login-victim', function () {
if (Auth::attempt(['email' => 'victim@webapp.kr-rezvan.ir', 'password' => '12345678'])) {
return "هویت شما تایید شد. کوکی نشست صادر و در دیتابیس ثبت گردید.";
}
return "خطا در ورود.";
});
// ۳. بررسی وضعیت پروفایل (برای بررسی موفقیت‌آمیز بودن حمله) // ==========================================
Route::get('/profile', function () { // ۴. هدف حمله CSRF (آسیب‌پذیر)
if (Auth::check()) { // ==========================================
return "شما لاگین هستید. ایمیل فعلی شما: <b>" . Auth::user()->email . "</b>"; Route::post('/update-email', [UserController::class, 'updateEmail'])
} ->withoutMiddleware([VerifyCsrfToken::class])
return "شما لاگین نیستید! (احتمالاً کوکی به درستی ارسال نشده است)."; ->name('vulnerable.update.email');
});
// ۴. نقطه آسیب‌پذیر (هدف حمله CSRF)
Route::post('/update-email', function (Request $request) {
// اگر کوکی معتبر ارسال نشود، لاراول این کاربر را ناشناس می‌داند
if (!Auth::check()) {
return response()->json(['error' => 'دسترسی غیرمجاز. مرورگر کوکی نشست را ارسال نکرد.'], 401);
}
$user = Auth::user();
$oldEmail = $user->email;
// تغییر در دیتابیس واقعی
$user->email = $request->input('email');
$user->save();
return response()->json([
'status' => 'success',
'message' => 'ایمیل در دیتابیس تغییر یافت!',
'old' => $oldEmail,
'new' => $user->email,
'session_id' => session()->getId()
]);
})->withoutMiddleware([VerifyCsrfToken::class]);