خبر و ترفند روز

خبر و ترفند های روز را اینجا بخوانید!

درک تماس های سیستم لینوکس با دستور strace

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

هنگامی که برنامه های در حال اجرا بر روی لینوکس می خواهند از منابع مدیریت شده توسط سیستم عامل (خواندن فایل ها، ایجاد فرآیندها و غیره) استفاده کنند، آنها سیستم عامل را فراخوانی می کنند. فراخوانی های سیستم در سطح هسته کار می کنند و عملیات لازم را انجام می دهند و کنترل را به برنامه فراخوانی باز می گردانند. ابزار strace امکان ردیابی این تماس های سیستمی را در لینوکس فراهم می کند.

استفاده معمولی از دستور strace

برای نظارت بر فراخوان های سیستم برای یک برنامه، کافیست دستور با strace را در قالب زیر فراخوانی کنید:

strace ls /tmp

با این حال، اغلب فرآیندهایی وجود دارند که خیلی زودتر شروع می شوند و در پس زمینه به کار خود ادامه می دهند. با توجه به هر گونه مشکل، ممکن است بخواهید اطلاعات اضافی مرتبط با چنین فرآیندهایی را جمع آوری کنید. با دادن شناسه فرآیند فرآیند به پارامتر -p می‌توانید strace را به هر برنامه در حال اجرا متصل کنید:

strace -p 2759

خروجی:

دستور strace p

موضوعات و فورک های یک برنامه را پیگیری کنید

با strace، می‌توانید تمام رشته‌ها و سایر پردازش‌های فرزند را که یک فورک برنامه هستند با استفاده از پرچم -f بررسی کنید.

strace -f -p 2759

خروجی:

دستور strace -f -p

تماس های سیستمی خاص را با strace بررسی کنید

خروجی strace پیش‌فرض می‌تواند گاهی اوقات بسیار شلوغ باشد. اگر فقط می خواهید تماس های سیستمی خاصی را ردیابی کنید، می توانید این کار را با پارامتر -e انجام دهید:

strace -f -e trace=open,write,close,connect,select -p 19770

برای ردیابی فقط تماس های سیستمی مربوط به عملیات فایل، از -e trace=file استفاده کنید:

strace -e trace=file -p 19770

برای فیلتر کردن فقط تماس های سیستمی مرتبط با شبکه، -e trace=network را در دستور مشخص کنید:

strace -e trace=network -p 19770

دریافت اطلاعات زمان در ثانیه

هنگام خروجی تماس های سیستمی، می توانید از پارامتر -t برای دریافت اطلاعات زمان با دقت در چند ثانیه استفاده کنید. بیشتر اوقات دقت برای نیازهای شما کافی نخواهد بود. در چنین شرایطی، می توانید از پارامتر -tt برای دریافت اطلاعات زمان با دقت میکروثانیه استفاده کنید:

strace -tt ls /tmp

دستور strace tt ls tmp

جمع آوری آمار در مورد تماس های سیستمی

با پارامتر -c، می توانید آمار تماس های سیستم را تا زمانی که بخواهید جمع آوری کنید:

strace -f -c -p 19770

دستور strace-f-c-p

گزارش‌ها را در یک فایل ذخیره کنید

اگر strace را برای مدت طولانی اجرا می‌کنید و می‌خواهید گزارش‌های حاصل را بعداً با جزئیات بیشتری بررسی کنید، باید لاگ‌ها را ذخیره کنید. با پارامتر -o می توانید فایلی را مشخص کنید که در آن strace باید لاگ ها را ذخیره کند:

strace -f -o /tmp/strace.log -e trace=file ls /tmp

فرآیند مسدود کردن ptrace

با استفاده از فراخوانی سیستم prctl، هر برنامه ای تحت لینوکس می تواند از کنترل خود توسط کاربران غیر ریشه با استفاده از ptrace جلوگیری کند. اگر برنامه از طریق prctl پرچم PR_SET_DUMPABLE را برای خود پاک کند، کاربرانی غیر از root نمی توانند این برنامه را با ptrace کنترل کنند، حتی اگر حق سیگنال دادن به برنامه را داشته باشند.

مطلب مرتبط:   کدام در مقابل whatis در مقابل whatis در لینوکس: چه تفاوت هایی وجود دارد؟

یکی از معمولی ترین کاربردهای این ویژگی در نرم افزار عامل احراز هویت OpenSSH دیده می شود. بنابراین، کنترل برنامه توسط برنامه دیگری با ptrace در احراز هویت کاربر جلوگیری می شود.

ptrace و امنیت

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

در پاسخ به این وضعیت که بسیاری از کاربران از آن اطلاعی ندارند، مکانیزم حفاظتی با ماژول امنیتی به نام Yama در هسته لینوکس ایجاد شده است.

شما می توانید پاسخ به تماس سیستم ptrace را از طریق فایل /proc/sys/kernel/yama/ptrace_scope کنترل کنید. به طور پیش فرض، این فایل مقدار 0 را می نویسد.

مقادیر زیر قابل قبول است:

ارزش

معنی

0

رفتار متعارف: همه برنامه هایی که حق ردیابی دارند قابل بررسی هستند.

1

Ptrace محدود: فقط والد مستقیم برنامه یا برنامه‌های اشکال‌زدایی مجاز توسط برنامه با گزینه PR_SET_PTRACER کنترل را دارند. بنابراین، استفاده از gdb program_name و strace program_name به کار خود ادامه می‌دهد، اما پس از آن نمی‌توانید یک برنامه در حال اجرا را پیوست کنید.

2

Ptrace به مدیر سیستم: فقط برنامه هایی با ویژگی CAP_SYS_PTRACE تعریف شده یا پردازش های فرزند که گزینه PTRACE_TRACEME را با prctl تعریف می کنند، قابل کنترل هستند.

مطلب مرتبط:   آیا می خواهید کالی لینوکس را امتحان کنید؟ در اینجا نحوه نصب آن در VirtualBox آورده شده است

3

کاملاً غیر فعال شده: تحت هیچ شرایطی هیچ اثری مجاز نیست. اگر این ویژگی یک بار تعریف شده باشد، در زمان اجرا نمی توانید دوباره آن را تغییر دهید.

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

اخیراً، برخی از توزیع‌های لینوکس شروع به تنظیم مقدار پیش‌فرض فایل ptrace_scope، که در بالا توضیح داده شد، روی 1 کرده‌اند. بنابراین، با محدود شدن عملیات ptrace، محیط کاری امن‌تری در سراسر سیستم فراهم می‌شود.

با استفاده از یک نمونه خطی

نمونه درخواست زیر را با نام ministrace.c ثبت کنید. سپس با دستور زیر می توانید آن را کامپایل کنید:

gcc -o ministrace ministrace.c

کد:

#include <sys/ptrace.h>
#include <sys/reg.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

int wait_for_syscall (pid_t child)
{
int status;
while (1) {
ptrace(PTRACE_SYSCALL, child, 0, 0);
waitpid(child, &status, 0);
if (WIFSTOPPED(status) && WSTOPSIG(status) & 0x80)
return 0;
if (WIFEXITED(status))
return 1;
}
}

int do_child (int argc, char **argv)
{
char *args [argc+1];
memcpy(args, argv, argc * sizeof(char*));
args[argc] = NULL;
ptrace(PTRACE_TRACEME);
kill(getpid(), SIGSTOP);
return execvp(args[0], args);
}

int do_trace (pid_t child)
{
int status, syscall, retval;
waitpid(child, &status, 0);
ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACESYSGOOD);
while(1) {
if (wait_for_syscall(child) != 0) break;

syscall = ptrace(PTRACE_PEEKUSER, child, sizeof(long)*ORIG_RAX);
fprintf(stderr, "syscall(%d) = ", syscall);

if (wait_for_syscall(child) != 0) break;

retval = ptrace(PTRACE_PEEKUSER, child, sizeof(long)*RAX);
fprintf(stderr, "%d\n", retval);
}
return 0;
}

int main (int argc, char **argv)
{
if (argc < 2) {
fprintf(stderr, "Usage: %s prog args\n", argv[0]);
exit(1);
}
pid_t child = fork();
if (child == 0) {
return do_child(argc-1, argv+1);
} else {
return do_trace(child);
}
}

پس از کامپایل برنامه، می توانید هر دستوری را با ministrace اجرا کنید و خروجی را بررسی کنید:

مطلب مرتبط:   من همیشه یک کپی از این USB نجات را نگه می دارم (و شما هم باید این کار را انجام دهید)

وزارت - تاریخ - فرماندهی

شما می توانید از strace برای بسیاری از اهداف استفاده کنید

strace می تواند به یافتن اشکالات در برنامه هایی که به طور غیر ضروری از منابع سیستم استفاده می کنند کمک کند. به همین ترتیب، مشخصه ای که یک برنامه در هنگام استفاده از منابع سیستم عامل نشان می دهد نیز می تواند با strace آشکار شود.

از آنجایی که strace مستقیماً به تماس‌های سیستم گوش می‌دهد، می‌تواند پویایی زمان اجرا را بدون توجه به باز/بسته بودن کد برنامه در حال اجرا آشکار کند. این امکان وجود دارد که در مورد این که چرا برنامه ها هنگام شروع استفاده از strace خطا می دهند، ایده ای دریافت کنید.

به طور مشابه، strace به شما کمک می کند تا بفهمید چرا یک برنامه به طور غیر منتظره خاتمه می یابد. بنابراین، آشنایی با strace در توسعه هسته لینوکس و مدیریت سیستم بسیار مهم است.