الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

لإكتشاف العمليات المخفية

مغلق
بدأه BESHEER في 7 يوليو 2006 · 1 رد · 484 مشاهدة · في نظام تشغيل Unix & Linux
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

JAAScois.com » أبحاث ودراسات » الكاتب: JAAScois تاريخ النشر: 27/02/2006 م في هذا الموضوع سنأخذ مثال لإكتشاف العمليات المخفية Hidden processes

في الأنظمة مفتوحة المصدر وسنطبق المثال على نظامي Linux RedHat و Unix OpenBSD

والإختلاف بسيط . يفيدنا هذا الموضوع في إكتشاف الملفات الخبيثة التي تستخدم تقنيات الاخفاء

نبدأ الموضوع

أولاً: إستخدام مجلد proc في إكتشاف العمليات

العمليات بإختصار هي البرامج والملفات التنفيذية التي تعمل في الذاكرة

فعندما تقوم بتشغيل برنامج ما يقوم النظام بتعريفه في الذاكرة وإعطائه رقم عمليه

في الأنظمة مفتوحة المصدر يعمل النظام على توفير مجلد proc في الجذر /

هذا المجلد يعمل على ترتيب كل العمليات وتخزين اهم المعلومات عنها

مثلاً لو فتحت المجلد proc لوجدت مجلدات كثيرة عبارةعن ارقام هذه الارقام

تمثل PID او معرف العملية , لاحظ الصورة unixproc001.gif

لو دخلت مجلد اي عمليه لوجدت تفاصيل عنها.

مثل الحاله والمسار وحيز الذاكرة stat و cmdline و mem

وكأنك بداخل ال task manager في نظام وندوز

لاحظ العملية 3033 :

unixproc002.gif

والآن سنأخذ مشروع او برنامج مفتوح المصدر كتب بواسطة security-projects.com

هذا البرنامج يقوم بعرض العمليات المخفية

تجد الكود هنا

unhide.c

في البداية سنقوم بتحليل كود البرنامج وكيف يظهر العمليات

توجد طريقتين يستخدمها البرنامج

الاولى طريقه proc ,, تبدأ بالداله checkproc لعرض العمليات ثم checkps لإظهار معلومات pid

طريقة عمل داله سرد العمليات checkproc

int maxpid= 999999;

void checkproc()

{

int procpids ;

char sendto[100];

int statusproc;

struct stat buffer;

printf ("[*]Searching for Hidden processes trougth /proc scanning\n\n") ;

//بداية دورة للبحث عن PID تبدأ ب 1 إلى 999999

for ( procpids = 1; procpids <= maxpid; procpids = procpids +1 ) {

char directory[100] ;

//

بناء المسار /proc/pid = مأخوذ من الدورة

sprintf(directory,"/proc/%d",procpids);

// إختبار إذا كان مجلد رقم العملية موجود

statusproc = stat(directory, &buffer) ;

if (statusproc == 0) {

// إذا كان موجود نكون قد إستخرجنا رقم عملية تعمل في الذاكرة

checkps(procpids);

}

}

تلاحظ ان الطريقة بسيطة بداية بتنفيذ دورة من 1 إلى 9999

في كل دورة يعمل البرنامج على إضافة الرقم للمسار proc

فتنتج المسارات بهذا الشكل

/proc/1

/proc/2

/proc/3

/proc/4

....

إلى 9999

بعد ان يقوم ببناء مسار يعتقد انها رقم عملية ينفذ داله stat وهي داله لجلب معلومات الملف

هذه الداله تعيد قيمتين إما 0 إذا نفذت بنجاح بمعنى الملف المحدد موجود و-1 إذا حدث خطأ في الدالة

وفي النهاية المعنى واضح إذا نفذت الداله stat بنجاح في دورة معنى ذلك ان المسار عباره عن عمليه مقيمه في الذاكرة

وبهذا نكون إستخرجنا pid ,, بعد إستخراجه يمرر إلى الداله checkps لقرائة معلوماته الاضافيه لمعرفه إذا كان مخفي ام لا

الآن سنأخذ الطريقة التي يقوم بهاالبرنامج لإظهار معلومات pid وهي الداله checkps

// Linux

#define COMMAND "ps -eLf | awk '{ print $2 }' | grep -v PID"

//OpenBSD

// #define COMMAND "ps -axk | awk '{ print $1 }' | grep -v PID"

void checkps(int tmppid)

{

int statusfile;

int statcommand;

int ok = 0;

char pids[30];

char compare[100];

FILE *fich_tmp ;

// تنفيذ ps وهو برنامج command line في نظام لينكس

fich_tmp=popen (COMMAND, "r") ;

// قرائة النتائج التي اظهرها الامر ps

while (!feof(fich_tmp) && ok == 0) {

fgets(pids, 30, fich_tmp);

sprintf(compare,"%i\n",tmppid);

// مقارنة رقم العملية التي إسخرجناها مسبقا مع العمليات التي يظهرها ps

// إذا كانت موجودة معنى ذلك انها ليست مخفية وإذا لم تظهر معنى ذلك انها مخفية

if (strcmp(pids, compare) == 0) {ok = 1;}

}

pclose(fich_tmp);

if ( ok == 0 ) {

int statuscmd ;

int posicion;

char cmd[100] ;

struct stat buffer;

printf ("Found HIDDEN PID: %i\n", tmppid) ;

sprintf(cmd,"/proc/%i/cmdline",tmppid);

statuscmd = stat(cmd, &buffer);

if (statuscmd == 0) {

FILE *cmdfile ;

char cmdcont[1000];

// قرائة ملف cmdline للبرنامج وإظهار المسار

cmdfile=fopen (cmd, "r") ;

while (!feof (cmdfile)) {

fgets (cmdcont, 1000, cmdfile);

printf ("Command: %s\n\n", cmdcont);

}

}

}

}

يبدأ البرنامج بتنفيذ برنامج نظام وهو ps وهو الخاص بالعمليات

وينفذ برامج إظافية للتنسيق مثل awk و grep لاحظ الامر

fich_tmp=popen (COMMAND, "r") ;

عبارة عن كتابه ps -eLf | awk '{ print $2 }' | grep -v PID في سطر الاوامر لنظام لينكس

لاحظ الصورة توضح لك برامج سطر الاوامر وإستخدام ps -elf

unixproc003.gif

تلاحظ ظهور اكثر من جدول لخصائص العملية ونحن بدورنا نريد جدول واحد وهو PID

ولذلك إستخدمنا الامرين awk '{ print $2 }' | grep -v PID

بعد ذلك ينفذ البرنامج امر قرائة المخرجات او قرائة الذي يظهر في سطر الاوامر

بواسطة داله fgets(pids, 30, fich_tmp);

ويتم مقارنة معرف العملية للتأكد من وجودة

إذا كان غير موجود يقوم برنامجنا بإظهاره على انه عملية مخفية.

=======================================

الطريقة الثانية بإستخدام دوال وخدمات العمليات

1- بإستخدام getpriority

void checkgetpriority() {

int syspids ;

char sendto[100];

printf ("[*]Searching for Hidden processes trougth getpriority() scanning\n\n") ;

for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

int ret;

errno= 0 ;

ret = getpriority(PRIO_PROCESS, syspids);

if ( errno == 0) {

checkps(syspids);

}

}

}

لاحظ البرنامج مشابه لماسبق ,, يبدأ بدورة من 1 إلى 9999

ولتحقق من وجود العملية يستخدم الداله getpriority

النقطة الي تبالها توضيح هنا المتغير errno ولماذا قارناه ب الصفر

هذا المتغير يعرف بحاله الأخطاء إذا كنت مبرمج سي على نظام وندوز أكيد مرت

عليك داله GetLastError وتستخدم لمعرفه إذا كان قد حدث خطأ في آخر داله

وهنا الموضوع مشابه وبنفس الطريقة إذا كان errno =0 معنا ذلك انه لم يحدث اي خطأ والنتيجة ان

معرف العملية PID الذي مرر للدالة موجود .

-

2- بإستخدام getpgid

void checkgetpgid() {

int syspids ;

char sendto[100];

printf ("[*]Searching for Hidden processes trougth getpgid() scanning\n\n") ;

for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

int ret;

errno= 0 ;

ret = getpgid(syspids);

if ( errno == 0) {

checkps(syspids);

}

}

}

3 بإستخدام getsid

void checkgetsid() {

int syspids ;

char sendto[100];

printf ("[*]Searching for Hidden processes trougth getsid() scanning\n\n") ;

for ( syspids = 1; syspids <= maxpid; syspids = syspids +1 ) {

int ret;

errno= 0 ;

ret = getsid(syspids);

if ( errno == 0) {

checkps(syspids);

}

}

} وبهذا نكون قد تعرفنا على طرق وأساليب إظهار العمليات المخفية في أنظمة لينكس ويونكس

بقي ان اضيف مثال آخر عن إظهار المنافذة المخفية

هذا المثال مشابة لماسبق ويعمل على Linux و OpenBSD و Solaris

unhide-tcp.c

فكرة البرنامج بسيطة جدا ,, يبدأ بدورة من 1 إلى 65535 وهو مجال المنافذ لبروتوكولات TCP و UDP

المهم بعد ذلك يمسك البرنامج اي منفذ ويحاول فتحه بداله listen

إذا اعطت الداله خطأ معنى ذلك ان المنفذ محجوز ومعناه انه مفتوح ,, هذه هي فكرة عمل برامج ال port scanner

او مسح المنافذ ,, بهذا الشكل

printf ("Starting TCP checking\n\n") ;

for (i =1; i < 65535; i++) {

int socket_desc;

struct sockaddr_in address;

socket_desc=socket(AF_INET,SOCK_STREAM,0);

address.sin_family = AF_INET;

address.sin_addr.s_addr = INADDR_ANY;

address.sin_port = htons(i);

errno= 0 ;

bind(socket_desc,(struct sockaddr *)&address,sizeof(address));

listen(socket_desc,1);

if ( errno != 0) {

close(socket_desc);

checkport(i, tcpcommand);

}

close(socket_desc);

}

وبعد أن يظهر البرامج المنافذ المفتوحة يتأكد من ان النظام يعرفها او لا عن طريق الامرالمعروف في كل الانظمة netstat

وإذا لم يظهرها برنامج النظام يستنتج برنامجنا انه منفذ مخفي

// Linux

char tcpcommand[]= "netstat -tan | sed -e '/[\\.:][0-9]/!d' -e 's/.*[\\.:]\\([0-9]*\\) .*[\\.:].*/\\1/'" ;

char udpcommand[]= "netstat -uan | sed -e '/[\\.:][0-9]/!d' -e 's/.*[\\.:]\\([0-9]*\\) .*[\\.:].*/\\1/'" ;

// OpenBSD

// char tcpcommand[]= "netstat -an -p tcp | sed -e '/[\\.:][0-9]/!d' -e 's/.*[\\.:]\\([0-9]*\\) .*[\\.:].*/\\1/'" ;

// char udpcommand[]= "netstat -an | -p udp| sed -e '/[\\.:][0-9]/!d' -e 's/.*[\\.:]\\([0-9]*\\) .*[\\.:].*/\\1/'" ;

// Solaris

// char tcpcommand[]= "netstat -an -P tcp | sed -e '/[\\.:][0-9]/!d' -e 's/.*[\\.:]\\([0-9]*\\) .*[\\.:].*/\\1/'" ;

// char udpcommand[]= "netstat -an | -P udp| sed -e '/[\\.:][0-9]/!d' -e 's/.*[\\.:]\\([0-9]*\\) .*[\\.:].*/\\1/'" ;

void checkport(int port, char command[]) {

int statusfile;

int statcommand;

int ok = 0;

char ports[30];

char compare[100];

FILE *fich_tmp ;

fich_tmp=popen (command, "r") ;

while (!feof(fich_tmp) && ok == 0) {

fgets(ports, 30, fich_tmp);

sprintf(compare,"%i\n",port);

if (strcmp(ports, compare) == 0) {ok = 1;}

}

pclose(fich_tmp);

if ( ok == 0 ) {

printf ("Found Hidden port that not appears in netstat: %i\n", port) ;

}

}

وكذلك نفس الطريقة مع بروتوكول UDP

وبهذا نكون قد أخذنا أساسيات عن عمليات الأخفاء في أنظمة لينكس ويونكس

في المواضيع القادمة سنحاول مناقشة تفاصيل اكثر

بالتوفيق ,,,

022.gif

***********************************************

043.gif

#2

السلام عليكم

هل تقصد من Hidden processes ، ال background process(Daemon) أم ماذا؟

System Engineer

Red Hat Certified Engineer

Red Hat Certificate Number

805010381752078

هذا الموضوع مغلق.

مواضيع مشابهة