در این نوشتار دو تکنیک دور زدن auditd در لینوکس بررسی میشن. هدف، مقایسهی واقعی توانایی هر روش در evasion کامل هست.
وضعیت فعلی
اگر بزرگان واقعی این حوزه هنوز در ایران فعال بودند، شاید امروز کمتر شاهد موج ادعاهای بیپشتوانه بودیم و پیش از رد یا نقد یک روش، تلاش میکردیم آن را بفهمیم. اما حالا که ظاهراً بار یادآوری مفاهیم پایه روی دوش ما افتاده، بد نیست این موضوع را صریح و بیپرده روشن کنیم.
مقدمه
چند روز پیش یک PoC برای دور زدن auditd در لینوکس منتشر کردم؛ تکنیکی که اجازه میدهد یک فرایند بدون ثبت هیچگونه لاگی در auditd اجرا شود. پس از انتشار، برخی از همکاران امنیتی نقدهایی نسبت به درستی، یا حتی اصالت این PoC مطرح کردند. اما از نگاه من، این فراتر از یک اختلافنظر ساده بود — آنچه مشاهده شد، ناشی از یک سوءبرداشت فنی عمیق است که شایستهی بررسی دقیقتریست.
در دنیای امنیت لینوکس، ابزارهایی مانند auditd نقش کلیدی در پایش فعالیتهای سیستم دارند. این ابزارها به توسعهدهندگان و تیمهای دفاعی کمک میکنند تا رویدادهای حساسی مانند اجرای فرآیندها، تغییر در فایلها یا دسترسی به منابع مهم را رصد کنند. اما همانطور که در مورد هر مکانیزم امنیتی صدق میکند، auditd نیز بدون نقص نیست — و این نقاط ضعف، گاهی دریچههایی برای دور زدن آن توسط مهاجمان باز میکنند.
در این نوشتار، دو PoC منتشرشده با هدف دور زدن مکانیزم لاگگذاری auditd مورد بررسی و مقایسه قرار میگیرند. هدف صرفاً تحلیل فنی نیست، بلکه تلاش بر این است که درکی عمیقتر از سطوح دسترسی و تمایزهای ظریف میان «اجرای یک فرآیند» و «پنهانسازی آن از دید سیستمهای نظارتی» ارائه شود.
در ابتدا لازم است بار دیگر نگاهی دقیق و صحیح به تعریف Defence Evasion داشته باشیم:
به زبان ساده، این مفهوم به تکنیکهایی اشاره دارد که مهاجم با استفاده از آنها میکوشد فعالیتهای خود را در سیستم قربانی به گونهای انجام دهد که توسط آنتیویروس، EDR، سایر مکانیزمهای امنیتی یا تیم آبی شناسایی نشود.
این تکنیکها معمولاً با اهداف زیر بهکار گرفته میشوند:
- جلوگیری از شناسایی فایل یا فرآیند مخرب
- پنهانسازی ارتباطات مهاجم با سیستم
- حذف یا دستکاری شواهد (مانند پاکسازی لاگها)
- و سایر روشهایی که منجر به کاهش قابلیت کشف فعالیت مهاجم میشوند.
تفاوت میان euid و auid در لینوکس
موارد | euid (Effective UID) | auid (Audit UID) |
---|---|---|
مفهوم | کاربری که الان سیستم فکر میکنه داره پروسه رو اجرا میکنه. | کاربری که اصلیترین عامل اجرای پروسه بوده. |
تغییرپذیری | میتونه تغییر کنه! مثلا با sudo یا setuid برنامه. | تقریباً ثابته. از لحظهی login اولیه ثبت میشه. |
کی تعیین میشه؟ | هر وقت پروسه اجرا میشه یا دسترسی عوض میشه (مثلاً با sudo). | وقتی کاربر login میکنه. (توسط pam) |
مثال مهم | وقتی یه یوزر sudo میکنه، euid میشه 0 (root)، ولی auid همون یوزر اصلی باقی میمونه.(1000<=auid) | همیشه میگه چه کسی اول کار وارد سیستم شده. |
مقایسه دو PoC – واقعیتها و ناگفته ها
تحلیل PoC اول (execveat) : منتشر شده توسط آقای Vahid Malekmohammad
سیس کال execveat
مشابه execve
است، اما با ویژگی اضافهای که به شما این امکان را میدهد تا مسیر فایلهای اجرایی را نسبی را به یک دایرکتوری باز شده (dirfd
) ارزیابی کنید.
execveat
این امکان را میدهد که از یک دایرکتوری خاص برای ارزیابی مسیرهای نسبی به فایلها استفاده کنید. بهعبارتی، به جای استفاده از یک مسیر کامل، میتوانید مسیر را نسبت به یک دایرکتوری مشخص تعریف کنید.
از آنجا که execveat
در تنظیمات پیشفرض auditd
ثبت نمیشود، این موضوع میتواند به مهاجمان این امکان را بدهد که باینریهای خود را اجرا کنند بدون اینکه در لاگهای امنیتی ثبت شوند. این نقطه ضعف امنیتی میتواند بهویژه در تستهای نفوذ و بهرهبرداری از آسیبپذیریها مفید باشد.
ایراد این تکنیک در این است که شما بایستی با سطح دسترسی root (euid=0) آن را اجرا کنید که خود این کار منجر به ثبت لاگ شما توسط auditd می شود و مشخصا نرخ شناسایی شما را بالا می برد – و در سناریوهای واقعی رسیدن به سطح دسترسی root به راحتی امکان پذیر نمی باشد و همچنین تمامی دستورات root مانیتور می شود.

رفتار auditd نیز در ثبت لاگ syscall=59 که متعلق به اجرای خود poc می باشد قابل مشاهده است – تولید شدن این لاگ به معنای انجام ناقص Defence Evasion می باشد، چرا که ردپایی از اجرای باینری در auditd ثبت شده است-

همانطور که مشاهده میکنید، زمانی که باینری PoC اجرا میشود، Auditd چندین خط لاگ مربوط به آن ثبت میکند که بهوضوح شامل نام باینری و مسیر اجرای آن است. این موضوع نشان میدهد که تلاش برای مخفیکاری با این روش بهطور کامل موفق نبوده، چرا که همچنان ردپایی از اجرای فایل در لاگها باقی میماند — مسئلهای که در یک سناریوی واقعی دفاعی، میتواند به شناسایی فعالیت مهاجم منجر شود.
اگرچه این تکنیک تا حدی موفق عمل میکند و یافتن آن حقیقتا نشان از دانش ایشان دارد، اما به دلیل اجرای آن با دسترسی root، در سناریوهای واقعی Red Team کاربرد چندانی ندارد. چرا که مهاجمی که به سطح دسترسی root رسیده باشد، عملاً از اغلب مکانیزمهای دفاعی عبور کرده و دیگر نیازی به چنین روشهایی برای پنهانکاری ندارد. بنابراین، استفاده از این تکنیک در آن شرایط بیشتر یک اقدام اضافی و غیرضروری محسوب میشود.
تحلیل PoC دوم (fexecve) – مربوط به اینجانب
fexecve
یک تابع (systemcall) در کتابخانه libc است که مشابه execve
عمل میکند؛ یعنی:
یک فایل اجرایی را در همان پروسس فعلی اجرا میکند و برنامهی فعلی را با آن جایگزین میکند.
ولی تفاوت مهمش با execve
اینه که به جای مسیر فایل، از file descriptor (fd) استفاده میکنه. (همانند execveat)
fexecve()
در فضای کاربر (user-space) فقط یک abstraction ساده است که از قابلیت سطح پایینتر execveat
استفاده میکنه تا امکان اجرای فایل با فایلدسکریپتور فراهم بشه.
در glibc، تابع fexecve
اینطوری پیادهسازی شده:
int fexecve(int fd, char *const argv[], char *const envp[]) {
return execveat(fd, "", argv, envp, AT_EMPTY_PATH);
}
در واقع، در سطح کرنل execveat
رو صدا میزنه، مسیر فایل رو ""
میذاره و از فلگ AT_EMPTY_PATH
استفاده میکنه تا به کرنل بگه که مسیر خالیه، ولی فایل اجرایی همون fd
هست.
fexecve(fd, argv, envp)
↓
glibc
↓
execveat(fd, "", argv, envp, AT_EMPTY_PATH)
↓
syscall در کرنل
↓
اجرای فایل اجرایی از طریق فایلدسکریپتور
تفاوتش در چیه؟
وضعیت اجرا : برخلاف poc قبلی این poc با کاربر معمولی (euid=1000) اجرا میشه! (یک مرحله قبل از Privilege Escalation)

خروجی لاگ فایل Auditd : بدون هیچگونه ثبت لاگی در auditd، حتی یک “حرف”

پاسخ به نقدها:
برخی افراد اشاره کردند که روش من «PoC نیست چون از syscall استفاده نکردم» — اما اجازه بدید این سوال رو مطرح کنم:
آیا هدف PoC ، اجرای مستقیم syscall است؟ یا رسیدن به یک هدف مشخص امنیتی (در اینجا evasion)؟
اگر فرض شما این باشد که PoC باید فقط syscall محور باشد، در واقع دارید مفهوم PoC را محدود میکنید. مهمترین ویژگی یک PoC قابلیت بازتولید آسیبپذیری یا تکنیک حمله است — نه اینکه حتماً در سطح syscall باشه.
مورد دیگری که حقیقتا خنده دار تر است، از طرف شخصی به بنده اعلام شد که اولین نفر من این syscall را (execveat) پیدا کردم- گویا ایشان فکر می کنند این syscall ارث پدری است و کسی حق ندارد آن را call کند!
جمعبندی فنی و اخلاقی
مسئله این نیست که PoC کدام یک از ما «درستتر» است. مسئله این است که آیا این PoCها چیزی به فهم ما از سیستم امنیتی اضافه میکنند یا نه؟
وقتی مهاجمی بتواند بدون ایجاد حتی یک خط لاگ، برنامهای را در سیستم اجرا کند، این برای تیمهای دفاعی یک زنگ خطر جدی است.
حالا وقت آن است که دقیقتر نگاه کنیم — نه بلندتر حرف بزنیم.
با تشکر از توجه شما.
دیدگاهتان را بنویسید